Skip to content

Commit 1ba8e0e

Browse files
authored
sync features and bugfixs from 25a535d (#1669)
1 parent 7739d90 commit 1ba8e0e

File tree

251 files changed

+3171
-3641
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

251 files changed

+3171
-3641
lines changed

.sync

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
f9b619e8a4dfcf524a7f4fa2cf8aed7452d2273d
1+
25a535d1b5764390c1d0407963d4bc6bf4a9f3e4
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module.exports = require('babel-jest').createTransformer({
1+
module.exports = require('babel-jest').default.createTransformer({
22
ignore: [/node_modules/],
33
rootMode: 'upward',
44
});

packages/babel-settings/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
},
3232
"peerDependencies": {
3333
"@babel/polyfill": "^7.10.4",
34-
"babel-jest": "^26.3.0"
34+
"babel-jest": "^27.0.1"
3535
},
3636
"ci": {
3737
"ringcentral-js-widgets": "**"

packages/core/README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,45 @@ class Counter extends RcModuleV2<Deps> {
333333
}
334334
```
335335
336+
- `watchEffect`
337+
338+
It is used to watch multiple states, where the callback with the second parameter returns an array of dependency collection.
339+
340+
341+
```ts
342+
class Counter extends RcModuleV2<Deps> {
343+
constructor(deps: Deps) {
344+
super({
345+
deps,
346+
});
347+
const dispose = watchEffect(
348+
this,
349+
() => [this.a, this.b],
350+
(newValue, oldValue) => {
351+
// do something
352+
},
353+
);
354+
}
355+
356+
@state
357+
a = 0;
358+
359+
@state
360+
b = 0;
361+
362+
@action
363+
increaseA() {
364+
this.a += 1;
365+
}
366+
367+
@action
368+
increaseB() {
369+
this.b += 1;
370+
}
371+
}
372+
```
373+
374+
336375
- `subscribe`
337376
338377
The subscribed function will be triggered after each Redux dispatch action update event. It has a similar mechanism to the RcModuleV2 API `onStateChange()`, except that `onStateChange()` cannot be unsubscribed, but the unsubscribed function returned by `subscribe()` can be used to cancel the subscription.

packages/core/lib/RcModule/RcModule.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
computed,
77
createStore,
88
watch,
9+
watchEffect,
910
Service,
1011
storeKey,
1112
identifierKey,
@@ -50,8 +51,11 @@ export const spawnStorageReducersKey: unique symbol = Symbol(
5051
'spawnStorageReducers',
5152
);
5253

53-
interface Options<T> {
54-
deps?: T;
54+
export interface RcModuleOptions<T> {
55+
deps?: T & {
56+
storage?: any;
57+
globalStorage?: any;
58+
};
5559
enableCache?: boolean;
5660
enableGlobalCache?: boolean;
5761
storageKey?: string;
@@ -106,7 +110,7 @@ abstract class RcModuleV2<T = {}> {
106110
enableCache = false,
107111
enableGlobalCache = false,
108112
...options
109-
}: Options<T & { storage?: any; globalStorage?: any }> = {}) {
113+
}: RcModuleOptions<T> = {}) {
110114
this._deps = deps;
111115
this[storageKey] = options.storageKey;
112116
this[enableCacheKey] = enableCache;
@@ -439,6 +443,7 @@ export {
439443
computed,
440444
createStore,
441445
watch,
446+
watchEffect,
442447
stateKey,
443448
storeKey,
444449
identifierKey,

packages/core/lib/track.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export const track = (trackEvent: TrackEvent) => {
5959
}
6060
} catch (e) {
6161
console.warn(`Analytics Error: ${target[identifierKey]}.${name}`);
62+
console.error(e);
6263
}
6364
return result;
6465
};

packages/core/lib/usm-redux/createStore.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ export const createStore = (
144144
},
145145
{},
146146
);
147+
// support custom reducers
148+
service._reducers = serviceReducers;
147149
const reducer = combineReducers(serviceReducers);
148150
Object.assign(reducers, {
149151
[identifier]: reducer,

packages/core/lib/usm-redux/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export { createStore, setPatchesToggle } from './createStore';
2-
export { subscribe, watch } from './subscribe';
2+
export { subscribe, watch, watchEffect } from './subscribe';
33
export { action, computed, state } from './decorators/index';
44
export { getStagedState } from './utils/index';
55
export * from 'immer';

packages/core/lib/usm-redux/interface.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,9 @@ export type Watch = <T>(
6161
selector: () => T,
6262
watcher: (newValue: T, oldValue: T) => void,
6363
) => Unsubscribe;
64+
65+
export type WatchEffect = <T extends any[]>(
66+
module: any,
67+
selector: () => [...T],
68+
watcher: (newValue: T, oldValue: T) => void,
69+
) => Unsubscribe;

packages/core/lib/usm-redux/subscribe.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
Unsubscribe,
55
Subscription,
66
Service,
7+
WatchEffect,
78
} from './interface';
89
import { storeKey, subscriptionsKey } from './constant';
910
import { isEqual } from './utils/index';
@@ -60,4 +61,32 @@ const watch: Watch = (module, selector, watcher) => {
6061
});
6162
};
6263

63-
export { subscribe, watch };
64+
const watchEffect: WatchEffect = (module, selector, watcher) => {
65+
if (typeof watcher !== 'function') {
66+
const className = Object.getPrototypeOf(module).constructor.name;
67+
throw new Error(
68+
`The 'watcher' should be a function in the class '${className}'.`,
69+
);
70+
}
71+
let oldValues = selector();
72+
if (!Array.isArray(oldValues)) {
73+
const className = Object.getPrototypeOf(module).constructor.name;
74+
throw new Error(
75+
`The 'selector' should be a function that returns an array in the class '${className}'.`,
76+
);
77+
}
78+
return subscribe(module, () => {
79+
const newValues = selector();
80+
const length = oldValues.length;
81+
for (let i = 0; i < length; i++) {
82+
if (!isEqual(newValues[i], oldValues[i])) {
83+
const lastValues = oldValues;
84+
oldValues = newValues;
85+
watcher(newValues, lastValues);
86+
break;
87+
}
88+
}
89+
});
90+
};
91+
92+
export { subscribe, watch, watchEffect };

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ringcentral-integration/core",
3-
"version": "0.12.0",
3+
"version": "0.13.0",
44
"description": "The foundation package for RingCentral Integration products.",
55
"main": "index.js",
66
"directories": {

packages/core/test/features/usm-redux.test.tsx

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
watch,
1818
subscribe,
1919
Store,
20+
watchEffect,
2021
} from '../../lib/usm-redux/index';
2122

2223
@autorun(test)
@@ -694,6 +695,133 @@ export class WatchBasic extends Step {
694695
}
695696
}
696697

698+
@autorun(test)
699+
@title('watchEffect::basic')
700+
export class WatchEffect extends Step {
701+
run() {
702+
const fn = jest.fn();
703+
class Counter {
704+
constructor() {
705+
watchEffect(
706+
this,
707+
() => [this.count.sum, this.a],
708+
(...args) => {
709+
fn(...args);
710+
},
711+
);
712+
}
713+
714+
@state
715+
count = { sum: 0 };
716+
717+
@state
718+
a = 0;
719+
720+
@state
721+
b = 0;
722+
723+
@action
724+
increaseA() {
725+
this.a += 1;
726+
}
727+
728+
@action
729+
increaseB() {
730+
this.b += 1;
731+
}
732+
733+
@action
734+
increase() {
735+
this.count.sum += 1;
736+
}
737+
}
738+
let counter: Counter;
739+
let store: Store;
740+
return (
741+
<Scenario desc="">
742+
<Given
743+
desc="create instances and create store"
744+
action={() => {
745+
counter = new Counter();
746+
747+
store = createStore({
748+
modules: [counter],
749+
});
750+
751+
const oldState = Object.values(store.getState())[0] as Counter;
752+
expect(oldState.count).toEqual({ sum: 0 });
753+
}}
754+
/>
755+
<When
756+
desc="call counter 'increase'"
757+
action={() => {
758+
counter.increase();
759+
}}
760+
/>
761+
<Then
762+
desc="'count' in counter should be updated and 'watchEffect' should be triggered"
763+
action={() => {
764+
const newState = Object.values(store.getState())[0] as Counter;
765+
expect(newState.count).toEqual({ sum: 1 });
766+
expect(fn.mock.calls).toEqual([
767+
[
768+
[1, 0],
769+
[0, 0],
770+
],
771+
]);
772+
}}
773+
/>
774+
<When
775+
desc="call counter 'increaseA'"
776+
action={() => {
777+
counter.increaseA();
778+
}}
779+
/>
780+
<Then
781+
desc="'a' in counter should be updated and 'watchEffect' should be triggered"
782+
action={() => {
783+
const newState = Object.values(store.getState())[0] as Counter;
784+
expect(newState.a).toEqual(1);
785+
expect(fn.mock.calls).toEqual([
786+
[
787+
[1, 0],
788+
[0, 0],
789+
],
790+
[
791+
[1, 1],
792+
[1, 0],
793+
],
794+
]);
795+
}}
796+
/>
797+
<When
798+
desc="call counter 'increaseB'"
799+
action={() => {
800+
counter.increaseB();
801+
}}
802+
/>
803+
<Then
804+
desc="'b' in counter should be updated and 'watchEffect' should not be triggered"
805+
action={() => {
806+
const newState = Object.values(store.getState())[0] as Counter;
807+
expect(newState.b).toEqual(1);
808+
expect(fn.mock.calls).toEqual([
809+
[
810+
[1, 0],
811+
[0, 0],
812+
],
813+
[
814+
[1, 1],
815+
[1, 0],
816+
],
817+
]);
818+
}}
819+
/>
820+
</Scenario>
821+
);
822+
}
823+
}
824+
697825
@autorun(test)
698826
@title('createStore::inheritance')
699827
export class CreateStoreInheritance extends Step {

packages/engage-voice-widget/components/ActiveCallListPanel/i18n/en-US.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ export default {
44
everyone: 'Everyone',
55
caller: 'Caller',
66
callee: 'Callee',
7-
unKnown: 'Unknown',
7+
unknown: 'Unknown',
88
};

packages/engage-voice-widget/components/ActivityCallLogPanel/ActivityCallLogPanel.spec.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ const getControlButton = (type) => {
138138
};
139139
};
140140

141-
describe('<ActivityCallLogPanel />:: Call Disposition', async () => {
141+
describe('<ActivityCallLogPanel />:: Call Disposition', () => {
142142
const status = 'callEnd';
143143
it('When call is ended, user will on disposition page and can dispose the call', () => {
144144
const disposeCall = jest.fn();
@@ -196,7 +196,7 @@ describe('<ActivityCallLogPanel />:: Call Disposition', async () => {
196196
});
197197
});
198198

199-
describe('<ActivityCallLogPanel />', async () => {
199+
describe('<ActivityCallLogPanel />', () => {
200200
it('When call is onHold, HoldCallButton should display and work correctly', () => {
201201
const onHold = jest.fn();
202202
const onUnHold = jest.fn();

packages/engage-voice-widget/components/AlertRenderer/EvCallAlert/EvCallAlert.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@ EvCallAlert.handleMessage = ({ message }: { message: string }) =>
2929
messageTypes.DROP_SESSION_ERROR,
3030
messageTypes.HOLD_ERROR,
3131
messageTypes.LOGOUT_FAIL_WITH_CALL_CONNECTED,
32-
messageTypes.RECORD_PAUSE,
32+
messageTypes.RECORD_PAUSED,
3333
messageTypes.RECORD_RESUME,
3434
]);

packages/engage-voice-widget/components/AlertRenderer/EvCallAlert/i18n/en-US.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export default {
1414
[messageTypes.HOLD_ERROR]: 'Internal error hold/unhold call occurred.',
1515
[messageTypes.LOGOUT_FAIL_WITH_CALL_CONNECTED]:
1616
'Logout is not working while the call is still connected.',
17-
[messageTypes.RECORD_PAUSE]: 'Call recording paused.',
17+
[messageTypes.RECORD_PAUSED]: 'Call recording paused.',
1818
[messageTypes.RECORD_RESUME]: 'Call recording resumed.',
1919
[messageTypes.INTERCEPT]:
2020
'The dial result for your manual outbound call was INTERCEPT.',

packages/engage-voice-widget/components/BasicSessionPanel/BasicSessionPanel.spec.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ afterEach(async () => {
102102
wrapper.unmount();
103103
});
104104

105-
describe('<BasicSessionPanel />', async () => {
105+
describe('<BasicSessionPanel />', () => {
106106
// TODO
107107

108108
// it("Page display user's selected Inbound queue, and navigate to InboundQueuesPage when click the field.", () => {

0 commit comments

Comments
 (0)