@amityco/ts-sdk 7.8.3-1fdb2885.0 → 7.8.3-b5109db.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/@types/domains/client.d.ts +2 -0
  2. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/@types/domains/client.d.ts.map +1 -1
  3. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/@types/domains/client.js.map +1 -1
  4. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/createClient.d.ts.map +1 -1
  5. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/createClient.js +2 -1
  6. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/createClient.js.map +1 -1
  7. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/isConnected.d.ts.map +1 -1
  8. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/isConnected.js +5 -1
  9. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/isConnected.js.map +1 -1
  10. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/login.d.ts.map +1 -1
  11. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/login.js +6 -0
  12. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/login.js.map +1 -1
  13. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/logout.d.ts.map +1 -1
  14. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/logout.js +9 -2
  15. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/logout.js.map +1 -1
  16. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/resumeSession.d.ts.map +1 -1
  17. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/resumeSession.js +13 -0
  18. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/resumeSession.js.map +1 -1
  19. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/tests/createClient.test.js +4 -0
  20. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/tests/createClient.test.js.map +1 -1
  21. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/tests/login.test.js +7 -1
  22. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/tests/login.test.js.map +1 -1
  23. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/tests/logout.test.js +8 -0
  24. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/tests/logout.test.js.map +1 -1
  25. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/tests/resumeSession.test.js +8 -1
  26. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/tests/resumeSession.test.js.map +1 -1
  27. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/tests/terminateClient.test.js +3 -0
  28. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/api/tests/terminateClient.test.js.map +1 -1
  29. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/utils/setClientToken.d.ts.map +1 -1
  30. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/utils/setClientToken.js +3 -0
  31. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/client/utils/setClientToken.js.map +1 -1
  32. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/core/events.d.ts +11 -0
  33. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/core/events.d.ts.map +1 -1
  34. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/core/events.js +17 -0
  35. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/core/events.js.map +1 -1
  36. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/core/transports/index.d.ts +1 -0
  37. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/core/transports/index.d.ts.map +1 -1
  38. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/core/transports/index.js +1 -0
  39. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/core/transports/index.js.map +1 -1
  40. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/core/transports/ws.d.ts +27 -0
  41. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/core/transports/ws.d.ts.map +1 -0
  42. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/core/transports/ws.js +53 -0
  43. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/core/transports/ws.js.map +1 -0
  44. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/utils/tests/client.d.ts.map +1 -1
  45. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/utils/tests/client.js +6 -1
  46. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/dist/utils/tests/client.js.map +1 -1
  47. package/.rollup.cache/home/runner/work/AmityTypescriptSDK/AmityTypescriptSDK/packages/sdk/tsconfig.tsbuildinfo +1 -1
  48. package/dist/@types/domains/client.d.ts +2 -0
  49. package/dist/@types/domains/client.d.ts.map +1 -1
  50. package/dist/client/api/createClient.d.ts.map +1 -1
  51. package/dist/client/api/isConnected.d.ts.map +1 -1
  52. package/dist/client/api/login.d.ts.map +1 -1
  53. package/dist/client/api/logout.d.ts.map +1 -1
  54. package/dist/client/api/resumeSession.d.ts.map +1 -1
  55. package/dist/client/utils/setClientToken.d.ts.map +1 -1
  56. package/dist/core/events.d.ts +11 -0
  57. package/dist/core/events.d.ts.map +1 -1
  58. package/dist/core/transports/index.d.ts +1 -0
  59. package/dist/core/transports/index.d.ts.map +1 -1
  60. package/dist/core/transports/ws.d.ts +27 -0
  61. package/dist/core/transports/ws.d.ts.map +1 -0
  62. package/dist/index.cjs.js +87 -3
  63. package/dist/index.esm.js +86 -3
  64. package/dist/index.umd.js +4 -3
  65. package/dist/utils/tests/client.d.ts.map +1 -1
  66. package/package.json +4 -2
  67. package/src/@types/domains/client.ts +1 -0
  68. package/src/client/api/createClient.ts +1 -0
  69. package/src/client/api/isConnected.ts +8 -1
  70. package/src/client/api/login.ts +6 -0
  71. package/src/client/api/logout.ts +8 -1
  72. package/src/client/api/resumeSession.ts +12 -0
  73. package/src/client/api/tests/createClient.test.ts +6 -0
  74. package/src/client/api/tests/login.test.ts +51 -42
  75. package/src/client/api/tests/logout.test.ts +12 -1
  76. package/src/client/api/tests/resumeSession.test.ts +111 -102
  77. package/src/client/api/tests/terminateClient.test.ts +6 -0
  78. package/src/client/utils/setClientToken.ts +3 -0
  79. package/src/core/events.ts +18 -0
  80. package/src/core/transports/index.ts +1 -0
  81. package/src/core/transports/ws.ts +60 -0
  82. package/src/utils/tests/client.ts +7 -1
  83. package/tsconfig.tsbuildinfo +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/utils/tests/client.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,UAAU,YAAS,CAAC;AAYjC,eAAO,MAAM,MAAM,cAA4B,CAAC;AAMhD,eAAO,MAAM,aAAa,qBAiBzB,CAAC;AAEF,eAAO,MAAM,gBAAgB,qBAE5B,CAAC;;AAEF,wBAAkB"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/utils/tests/client.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,UAAU,YAAS,CAAC;AAYjC,eAAO,MAAM,MAAM,cAA4B,CAAC;AAMhD,eAAO,MAAM,aAAa,qBAuBzB,CAAC;AAEF,eAAO,MAAM,gBAAgB,qBAE5B,CAAC;;AAEF,wBAAkB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amityco/ts-sdk",
3
- "version": "7.8.3-1fdb2885.0",
3
+ "version": "7.8.3-b5109db.0",
4
4
  "license": "CC-BY-ND-4.0",
5
5
  "author": "amity.co <developers@amity.co> (https://amity.co)",
6
6
  "description": "Amity Social Cloud Typescript SDK",
@@ -43,6 +43,7 @@
43
43
  "@types/jest": "^27.5.1",
44
44
  "@types/node": "^18.6.4",
45
45
  "@types/object-hash": "^3.0.6",
46
+ "@types/socket.io-client": "^1.4.34",
46
47
  "chalk": "^4.1.2",
47
48
  "concurrently": "^6.1.0",
48
49
  "form-data": "^4.0.0",
@@ -66,6 +67,7 @@
66
67
  "mitt": "^3.0.0",
67
68
  "mqtt": "^4.3.7",
68
69
  "object-hash": "^3.0.0",
69
- "react-native-uuid": "^2.0.1"
70
+ "react-native-uuid": "^2.0.1",
71
+ "socket.io-client": "2.2.0"
70
72
  }
71
73
  }
@@ -45,6 +45,7 @@ declare global {
45
45
  http: AxiosInstance;
46
46
  upload: AxiosInstance;
47
47
  mqtt?: Amity.MqttClient;
48
+ ws?: SocketIOClient.Socket;
48
49
  emitter: Emitter<Amity.Events>;
49
50
 
50
51
  hasPermission: (permission: string) => Amity.PermissionChecker;
@@ -73,6 +73,7 @@ export const createClient = (
73
73
  let mqtt;
74
74
 
75
75
  if (rteEnabled) {
76
+ ws = createWebsocketTransport(httpEndpoint);
76
77
  mqtt = createMqttTransport(mqttEndpoint);
77
78
  }
78
79
 
@@ -16,5 +16,12 @@ export const isConnected = (): boolean => {
16
16
  const client = getActiveClient();
17
17
  client.log('client/api/isConnected', client);
18
18
 
19
- return !!(client.userId && String(client.http.defaults.headers.common?.Authorization)?.length);
19
+ // if client is connected to ws, it means client is connected. If ws is undefined, it means ws is not used.
20
+ const isWsConnected = (client.ws && client.ws.connected) || !!client.ws;
21
+
22
+ return !!(
23
+ client.userId &&
24
+ String(client.http.defaults.headers.common?.Authorization)?.length &&
25
+ isWsConnected
26
+ );
20
27
  };
@@ -122,6 +122,12 @@ export const login = async (
122
122
  return false;
123
123
  }
124
124
 
125
+ // FIXME: events are duplicated if connectClient is called few times without disconnectClient
126
+ // wire websocket events to our event emitter
127
+ proxyWebsocketEvents(client.ws, client.emitter);
128
+
129
+ client.ws?.open();
130
+
125
131
  client.userId = user.userId;
126
132
 
127
133
  client.sessionHandler = sessionHandler;
@@ -26,6 +26,10 @@ export const logout = async (): Promise<boolean> => {
26
26
  client.mqtt.disconnect();
27
27
  }
28
28
 
29
+ if (client.ws && client.ws.connected) {
30
+ client.ws.disconnect();
31
+ }
32
+
29
33
  /*
30
34
  * for cases when session state is terminated (example on ban) or token expired,
31
35
  * the terminating block will set session state to terminated or for the or
@@ -42,7 +46,8 @@ export const logout = async (): Promise<boolean> => {
42
46
  setSessionState(Amity.SessionStates.NOT_LOGGED_IN);
43
47
 
44
48
  client.emitter.all.clear();
45
-
49
+ // FIXME: it removes listener in ws.ts, it breaks global ban event
50
+ client.ws?.removeAllListeners();
46
51
  client.mqtt?.removeAllListeners();
47
52
  client.userId = undefined;
48
53
  client.token = undefined;
@@ -54,6 +59,8 @@ export const logout = async (): Promise<boolean> => {
54
59
  isUserDeleted: false,
55
60
  };
56
61
 
62
+ if (client.ws) client.ws.io.opts.query = { token: '' };
63
+
57
64
  if (typeof document !== 'undefined') {
58
65
  document.cookie = '_ascSession=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
59
66
  }
@@ -97,6 +97,9 @@ const validateAccessToken = async ({ token, userId }: Params) => {
97
97
  isUserDeleted: false,
98
98
  };
99
99
 
100
+ // manually setup the token for ws transport
101
+ if (client.ws) client.ws.io.opts.query = { token: token.accessToken };
102
+
100
103
  client.token = token;
101
104
 
102
105
  setSessionState(Amity.SessionStates.ESTABLISHED);
@@ -149,6 +152,9 @@ export const resumeSession = async (
149
152
  if (client.mqtt && client.mqtt.connected) {
150
153
  client.mqtt.disconnect();
151
154
  }
155
+ if (client.ws && client.ws.connected) {
156
+ client.ws.disconnect();
157
+ }
152
158
 
153
159
  // Clear existing subscriptions
154
160
  subscriptions.forEach(fn => fn());
@@ -184,6 +190,12 @@ export const resumeSession = async (
184
190
  return false;
185
191
  }
186
192
 
193
+ // FIXME: events are duplicated if connectClient is called few times without disconnectClient
194
+ // wire websocket events to our event emitter
195
+ proxyWebsocketEvents(client.ws, client.emitter);
196
+
197
+ client.ws?.open();
198
+
187
199
  client.userId = user.userId;
188
200
 
189
201
  client.sessionHandler = sessionHandler;
@@ -13,6 +13,12 @@ describe('createClient', () => {
13
13
  expect(client.http).toBeDefined();
14
14
  });
15
15
 
16
+ test('it should define ws transport', () => {
17
+ const client = createClient('test-api-key');
18
+
19
+ expect(client.ws).toBeDefined();
20
+ });
21
+
16
22
  test('it should define mqtt transport', () => {
17
23
  const client = createClient('test-api-key');
18
24
 
@@ -12,62 +12,71 @@ const sessionHandler: Amity.SessionHandler = {
12
12
  };
13
13
 
14
14
  const onConnect = () =>
15
- describe('login', () => {
16
- beforeEach(() => {
17
- client = createClient('key', 'sg');
18
- client.mqtt.connect = jest.fn();
19
- client.mqtt.subscribe = jest.fn();
20
- client.http.post = jest.fn().mockResolvedValueOnce(sessionResponse);
15
+ setTimeout(() => {
16
+ const CONNECT_PACKET = { type: 0, nsp: client.ws.nsp };
21
17
 
22
- setActiveClient(client);
23
- });
18
+ client.ws.emit('connect');
24
19
 
25
- afterEach(async () => {
26
- if (client.sessionState === Amity.SessionStates.ESTABLISHED) await disconnectClient();
27
- });
20
+ // simulate a connection ack packet from server
21
+ client.ws.io.emit('packet', CONNECT_PACKET);
22
+ }, 50);
28
23
 
29
- test('it should connect client', async () => {
30
- onConnect().unref();
24
+ describe('login', () => {
25
+ beforeEach(() => {
26
+ client = createClient('key', 'sg');
27
+ client.mqtt.connect = jest.fn();
28
+ client.mqtt.subscribe = jest.fn();
29
+ client.http.post = jest.fn().mockResolvedValueOnce(sessionResponse);
31
30
 
32
- const recieved = await login({ userId: user11.userId }, sessionHandler);
31
+ setActiveClient(client);
32
+ });
33
33
 
34
- expect(recieved).toBe(true);
35
- });
34
+ afterEach(async () => {
35
+ if (client.sessionState === Amity.SessionStates.ESTABLISHED) await disconnectClient();
36
+ });
36
37
 
37
- test('it should establish connection', async () => {
38
- onConnect().unref();
38
+ test('it should connect client', async () => {
39
+ onConnect().unref();
39
40
 
40
- await login({ userId: user11.userId }, sessionHandler);
41
- const { sessionState } = client;
41
+ const recieved = await login({ userId: user11.userId }, sessionHandler);
42
42
 
43
- expect(sessionState).toBe(Amity.SessionStates.ESTABLISHED);
44
- });
43
+ expect(recieved).toBe(true);
44
+ });
45
45
 
46
- test('it should have session state establishing while connecting client', () => {
47
- login({ userId: user11.userId }, sessionHandler);
46
+ test('it should establish connection', async () => {
47
+ onConnect().unref();
48
48
 
49
- expect(client.sessionState).toBe(Amity.SessionStates.ESTABLISHING);
50
- });
49
+ await login({ userId: user11.userId }, sessionHandler);
50
+ const { sessionState } = client;
51
+
52
+ expect(sessionState).toBe(Amity.SessionStates.ESTABLISHED);
53
+ });
51
54
 
52
- test('it should have session state notLoggedIn on failure', async () => {
53
- client.http.post = jest
54
- .fn()
55
- .mockRejectedValue(
56
- new ASCApiError('unauthorzed', Amity.ServerError.UNAUTHORIZED, Amity.ErrorLevel.FATAL),
57
- );
55
+ test('it should have session state establishing while connecting client', () => {
56
+ login({ userId: user11.userId }, sessionHandler);
58
57
 
59
- await expect(login({ userId: user11.userId }, sessionHandler)).rejects.toThrow('unauthorzed');
60
- expect(client.sessionState).toBe(Amity.SessionStates.NOT_LOGGED_IN);
61
- });
58
+ expect(client.sessionState).toBe(Amity.SessionStates.ESTABLISHING);
59
+ });
60
+
61
+ test('it should have session state notLoggedIn on failure', async () => {
62
+ client.http.post = jest
63
+ .fn()
64
+ .mockRejectedValue(
65
+ new ASCApiError('unauthorzed', Amity.ServerError.UNAUTHORIZED, Amity.ErrorLevel.FATAL),
66
+ );
67
+
68
+ await expect(login({ userId: user11.userId }, sessionHandler)).rejects.toThrow('unauthorzed');
69
+ expect(client.sessionState).toBe(Amity.SessionStates.NOT_LOGGED_IN);
70
+ });
62
71
 
63
- test('it should terminate session on ban', async () => {
64
- onConnect().unref();
72
+ test('it should terminate session on ban', async () => {
73
+ onConnect().unref();
65
74
 
66
- await login({ userId: user11.userId }, sessionHandler);
75
+ await login({ userId: user11.userId }, sessionHandler);
67
76
 
68
- // ban user
69
- client.emitter.emit('user.didGlobalBan', {} as Amity.UserPayload);
77
+ // ban user
78
+ client.emitter.emit('user.didGlobalBan', {} as Amity.UserPayload);
70
79
 
71
- expect(client.sessionState).toBe(Amity.SessionStates.TERMINATED);
72
- });
80
+ expect(client.sessionState).toBe(Amity.SessionStates.TERMINATED);
73
81
  });
82
+ });
@@ -3,18 +3,23 @@ import { client, connectClient, message11 as message } from '~/utils/tests';
3
3
 
4
4
  import { logout } from '..';
5
5
 
6
+ const disconnect = () => setTimeout(() => client.ws.emit('disconnect'), 500);
7
+
6
8
  describe('logout', () => {
7
9
  beforeEach(async () => {
8
10
  await connectClient();
9
11
  });
10
12
 
11
13
  test('it should disconnect client', async () => {
14
+ disconnect().unref();
15
+
12
16
  const recieved = await logout();
13
17
 
14
18
  expect(recieved).toBe(true);
15
19
  });
16
20
 
17
21
  test('it should set sesion state to notLoggedIn after disconnect', async () => {
22
+ disconnect().unref();
18
23
  await logout();
19
24
 
20
25
  expect(client.sessionState).toBe(Amity.SessionStates.NOT_LOGGED_IN);
@@ -22,6 +27,7 @@ describe('logout', () => {
22
27
 
23
28
  test('it should not update sesion state if session state terminated', async () => {
24
29
  client.sessionState = Amity.SessionStates.TERMINATED;
30
+ disconnect().unref();
25
31
 
26
32
  await logout();
27
33
 
@@ -29,6 +35,8 @@ describe('logout', () => {
29
35
  });
30
36
 
31
37
  test('it should clear userId and accessToken on disconnect', async () => {
38
+ disconnect().unref();
39
+
32
40
  await logout();
33
41
 
34
42
  expect(client.userId).toBeUndefined();
@@ -36,12 +44,15 @@ describe('logout', () => {
36
44
  });
37
45
 
38
46
  test('it should clear auth header on disconnect', async () => {
47
+ disconnect().unref();
48
+
39
49
  await logout();
40
50
 
41
51
  expect(client.http.defaults.headers.common.Authorization).toBeFalsy();
42
52
  });
43
53
 
44
54
  test('it should clear cache on disconnect', async () => {
55
+ disconnect().unref();
45
56
  enableCache();
46
57
 
47
58
  const cacheKey = ['message', 'get', message.messageId];
@@ -54,7 +65,7 @@ describe('logout', () => {
54
65
 
55
66
  test('it should not clear cache if tokenExpired', async () => {
56
67
  client.sessionState = Amity.SessionStates.TOKEN_EXPIRED;
57
-
68
+ disconnect().unref();
58
69
  enableCache();
59
70
 
60
71
  const cacheKey = ['message', 'get', message.messageId];
@@ -24,141 +24,150 @@ const mockUserResponse = {
24
24
  };
25
25
 
26
26
  const onConnect = () =>
27
- describe('resumeSession', () => {
28
- beforeEach(() => {
29
- client = createClient('key', 'sg');
30
- client.mqtt?.connect && (client.mqtt.connect = jest.fn());
31
- client.mqtt?.subscribe && (client.mqtt.subscribe = jest.fn());
32
- client.http.get = jest.fn().mockResolvedValueOnce(mockUserResponse);
33
-
34
- setActiveClient(client);
35
- });
27
+ setTimeout(() => {
28
+ const CONNECT_PACKET = { type: 0, nsp: client.ws?.nsp };
36
29
 
37
- afterEach(async () => {
38
- if (client.sessionState === Amity.SessionStates.ESTABLISHED) await disconnectClient();
39
- });
30
+ client.ws?.emit('connect');
40
31
 
41
- test('it should connect client with access token', async () => {
42
- onConnect().unref();
32
+ // simulate a connection ack packet from server
33
+ client.ws?.io.emit('packet', CONNECT_PACKET);
34
+ }, 50);
43
35
 
44
- const received = await resumeSession(
45
- { userId: user11.userId, token: mockToken },
46
- sessionHandler,
47
- );
36
+ describe('resumeSession', () => {
37
+ beforeEach(() => {
38
+ client = createClient('key', 'sg');
39
+ client.mqtt?.connect && (client.mqtt.connect = jest.fn());
40
+ client.mqtt?.subscribe && (client.mqtt.subscribe = jest.fn());
41
+ client.http.get = jest.fn().mockResolvedValueOnce(mockUserResponse);
48
42
 
49
- expect(received).toBe(true);
50
- });
43
+ setActiveClient(client);
44
+ });
51
45
 
52
- test('it should establish connection', async () => {
53
- onConnect().unref();
46
+ afterEach(async () => {
47
+ if (client.sessionState === Amity.SessionStates.ESTABLISHED) await disconnectClient();
48
+ });
54
49
 
55
- await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
56
- const { sessionState } = client;
50
+ test('it should connect client with access token', async () => {
51
+ onConnect().unref();
57
52
 
58
- expect(sessionState).toBe(Amity.SessionStates.ESTABLISHED);
59
- });
53
+ const received = await resumeSession(
54
+ { userId: user11.userId, token: mockToken },
55
+ sessionHandler,
56
+ );
60
57
 
61
- test('it should have session state establishing while connecting client', () => {
62
- resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
58
+ expect(received).toBe(true);
59
+ });
63
60
 
64
- expect(client.sessionState).toBe(Amity.SessionStates.ESTABLISHING);
65
- });
61
+ test('it should establish connection', async () => {
62
+ onConnect().unref();
66
63
 
67
- test('it should have session state notLoggedIn on failure', async () => {
68
- client.http.get = jest
69
- .fn()
70
- .mockRejectedValue(
71
- new ASCApiError('unauthorized', Amity.ServerError.UNAUTHORIZED, Amity.ErrorLevel.FATAL),
72
- );
73
-
74
- await expect(
75
- resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler),
76
- ).rejects.toThrow('unauthorized');
77
- expect(client.sessionState).toBe(Amity.SessionStates.NOT_LOGGED_IN);
78
- });
64
+ await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
65
+ const { sessionState } = client;
79
66
 
80
- test('it should set authorization header with token', async () => {
81
- onConnect().unref();
67
+ expect(sessionState).toBe(Amity.SessionStates.ESTABLISHED);
68
+ });
82
69
 
83
- await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
70
+ test('it should have session state establishing while connecting client', () => {
71
+ resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
84
72
 
85
- expect(client.http.defaults.headers.common.Authorization).toBe(
86
- `Bearer ${mockToken.accessToken}`,
87
- );
88
- expect(client.upload.defaults.headers.common.Authorization).toBe(
89
- `Bearer ${mockToken.accessToken}`,
73
+ expect(client.sessionState).toBe(Amity.SessionStates.ESTABLISHING);
74
+ });
75
+
76
+ test('it should have session state notLoggedIn on failure', async () => {
77
+ client.http.get = jest
78
+ .fn()
79
+ .mockRejectedValue(
80
+ new ASCApiError('unauthorized', Amity.ServerError.UNAUTHORIZED, Amity.ErrorLevel.FATAL),
90
81
  );
91
- });
92
82
 
93
- test('it should set token metadata', async () => {
94
- onConnect().unref();
83
+ await expect(
84
+ resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler),
85
+ ).rejects.toThrow('unauthorized');
86
+ expect(client.sessionState).toBe(Amity.SessionStates.NOT_LOGGED_IN);
87
+ });
95
88
 
96
- await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
89
+ test('it should set authorization header with token', async () => {
90
+ onConnect().unref();
97
91
 
98
- expect(client.token).toEqual(mockToken);
99
- expect(client.http.defaults.metadata).toEqual({
100
- tokenExpiry: mockToken.expiresAt,
101
- isGlobalBanned: false,
102
- isUserDeleted: false,
103
- });
104
- });
92
+ await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
93
+
94
+ expect(client.http.defaults.headers.common.Authorization).toBe(
95
+ `Bearer ${mockToken.accessToken}`,
96
+ );
97
+ expect(client.upload.defaults.headers.common.Authorization).toBe(
98
+ `Bearer ${mockToken.accessToken}`,
99
+ );
100
+ });
105
101
 
106
- test('it should call user endpoint to validate token', async () => {
107
- onConnect().unref();
102
+ test('it should set token metadata', async () => {
103
+ onConnect().unref();
108
104
 
109
- await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
105
+ await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
110
106
 
111
- expect(client.http.get).toHaveBeenCalledWith(`/api/v3/users/${user11.userId}`);
107
+ expect(client.token).toEqual(mockToken);
108
+ expect(client.http.defaults.metadata).toEqual({
109
+ tokenExpiry: mockToken.expiresAt,
110
+ isGlobalBanned: false,
111
+ isUserDeleted: false,
112
112
  });
113
+ });
113
114
 
114
- test('it should terminate session on ban', async () => {
115
- onConnect().unref();
115
+ test('it should call user endpoint to validate token', async () => {
116
+ onConnect().unref();
116
117
 
117
- await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
118
+ await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
118
119
 
119
- // ban user
120
- client.emitter.emit('user.didGlobalBan', {} as Amity.UserPayload);
120
+ expect(client.http.get).toHaveBeenCalledWith(`/api/v3/users/${user11.userId}`);
121
+ });
121
122
 
122
- expect(client.sessionState).toBe(Amity.SessionStates.TERMINATED);
123
- });
123
+ test('it should terminate session on ban', async () => {
124
+ onConnect().unref();
124
125
 
125
- test('it should reset client state when user is already connected with same userId', async () => {
126
- onConnect().unref();
126
+ await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
127
127
 
128
- // First connection
129
- await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
130
- expect(client.sessionState).toBe(Amity.SessionStates.ESTABLISHED);
131
- expect(client.userId).toBe(user11.userId);
128
+ // ban user
129
+ client.emitter.emit('user.didGlobalBan', {} as Amity.UserPayload);
132
130
 
133
- // Mock the HTTP call for second connection
134
- client.http.get = jest.fn().mockResolvedValueOnce(mockUserResponse);
131
+ expect(client.sessionState).toBe(Amity.SessionStates.TERMINATED);
132
+ });
135
133
 
136
- // Second connection with same userId should treat as token expiry (preserve cache)
137
- onConnect().unref();
138
- await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
134
+ test('it should reset client state when user is already connected with same userId', async () => {
135
+ onConnect().unref();
139
136
 
140
- // Verify that the client is properly reset and reconnected
141
- expect(client.sessionState).toBe(Amity.SessionStates.ESTABLISHED);
142
- expect(client.userId).toBe(user11.userId);
143
- });
137
+ // First connection
138
+ await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
139
+ expect(client.sessionState).toBe(Amity.SessionStates.ESTABLISHED);
140
+ expect(client.userId).toBe(user11.userId);
144
141
 
145
- test('it should preserve cache when resuming session with same userId', async () => {
146
- onConnect().unref();
142
+ // Mock the HTTP call for second connection
143
+ client.http.get = jest.fn().mockResolvedValueOnce(mockUserResponse);
147
144
 
148
- // First connection - set some cache data
149
- await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
150
- if (client.cache) {
151
- client.cache.data = { test: 'data' };
152
- }
145
+ // Second connection with same userId should treat as token expiry (preserve cache)
146
+ onConnect().unref();
147
+ await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
153
148
 
154
- // Mock the HTTP call for second connection
155
- client.http.get = jest.fn().mockResolvedValueOnce(mockUserResponse);
149
+ // Verify that the client is properly reset and reconnected
150
+ expect(client.sessionState).toBe(Amity.SessionStates.ESTABLISHED);
151
+ expect(client.userId).toBe(user11.userId);
152
+ });
156
153
 
157
- // Second connection with same userId
158
- onConnect().unref();
159
- await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
154
+ test('it should preserve cache when resuming session with same userId', async () => {
155
+ onConnect().unref();
160
156
 
161
- // Cache should be preserved when same userId is used
162
- expect(client.cache?.data).toEqual({ test: 'data' });
163
- });
157
+ // First connection - set some cache data
158
+ await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
159
+ if (client.cache) {
160
+ client.cache.data = { test: 'data' };
161
+ }
162
+
163
+ // Mock the HTTP call for second connection
164
+ client.http.get = jest.fn().mockResolvedValueOnce(mockUserResponse);
165
+
166
+ // Second connection with same userId
167
+ onConnect().unref();
168
+ await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
169
+
170
+ // Cache should be preserved when same userId is used
171
+ expect(client.cache?.data).toEqual({ test: 'data' });
164
172
  });
173
+ });
@@ -2,12 +2,16 @@ import { client, connectClient } from '~/utils/tests';
2
2
 
3
3
  import { terminateClient } from '../terminateClient';
4
4
 
5
+ const disconnect = () => setTimeout(() => client.ws.emit('disconnect'), 500);
6
+
5
7
  describe('terminateClient', () => {
6
8
  beforeAll(async () => {
7
9
  await connectClient();
8
10
  });
9
11
 
10
12
  test('it should terminate client session', async () => {
13
+ disconnect().unref();
14
+
11
15
  const expected = Amity.SessionStates.TERMINATED;
12
16
 
13
17
  terminateClient();
@@ -16,6 +20,8 @@ describe('terminateClient', () => {
16
20
  });
17
21
 
18
22
  test('it should clear sessionHandler', async () => {
23
+ disconnect().unref();
24
+
19
25
  terminateClient();
20
26
 
21
27
  expect(client.sessionHandler).toBeUndefined();
@@ -38,6 +38,9 @@ export const setClientToken = async (params: Parameters<typeof getToken>[0]) =>
38
38
  isUserDeleted: false,
39
39
  };
40
40
 
41
+ // manually setup the token for ws transport
42
+ if (client.ws) client.ws.io.opts.query = { token: accessToken };
43
+
41
44
  client.token = { accessToken, issuedAt, expiresAt };
42
45
 
43
46
  setSessionState(Amity.SessionStates.ESTABLISHED);
@@ -43,6 +43,24 @@ export const createEventEmitter = () => {
43
43
  return mitt<Amity.Events>();
44
44
  };
45
45
 
46
+ /**
47
+ * Wraps the websocket events into the client's event emitter for
48
+ * abstraction of transport.
49
+ *
50
+ * @param ws A websocket connection to listen from
51
+ * @param emitter An event emitter to wire the events to
52
+ *
53
+ * @category Transport
54
+ * @hidden
55
+ */
56
+ export const proxyWebsocketEvents = (ws: Amity.Client['ws'], emitter: Amity.Client['emitter']) => {
57
+ WS_EVENTS.forEach(event => {
58
+ ws?.on(event, (param: Amity.Events[typeof event]) => {
59
+ emitter.emit(event, param);
60
+ });
61
+ });
62
+ };
63
+
46
64
  export const proxyMqttEvents = (
47
65
  mqttClient: Amity.Client['mqtt'],
48
66
  emitter: Amity.Client['emitter'],
@@ -1,2 +1,3 @@
1
1
  export * from './http';
2
+ export * from './ws';
2
3
  export * from './mqtt';