@ermis-network/ermis-chat-sdk 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +330 -0
  2. package/dist/encryption/index.browser.cjs +13045 -0
  3. package/dist/encryption/index.browser.cjs.map +1 -0
  4. package/dist/encryption/index.browser.mjs +12959 -0
  5. package/dist/encryption/index.browser.mjs.map +1 -0
  6. package/dist/encryption/index.cjs +13045 -0
  7. package/dist/encryption/index.cjs.map +1 -0
  8. package/dist/encryption/index.d.mts +3 -0
  9. package/dist/encryption/index.d.ts +3 -0
  10. package/dist/encryption/index.mjs +12959 -0
  11. package/dist/encryption/index.mjs.map +1 -0
  12. package/dist/index-CcvHIY5q.d.mts +4988 -0
  13. package/dist/index-CcvHIY5q.d.ts +4988 -0
  14. package/dist/index.browser.cjs +20192 -5766
  15. package/dist/index.browser.cjs.map +1 -1
  16. package/dist/index.browser.full-bundle.min.js +20 -16
  17. package/dist/index.browser.full-bundle.min.js.map +1 -1
  18. package/dist/index.browser.mjs +20106 -5731
  19. package/dist/index.browser.mjs.map +1 -1
  20. package/dist/index.cjs +20191 -5765
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.mts +15 -1337
  23. package/dist/index.d.ts +15 -1337
  24. package/dist/index.mjs +20106 -5731
  25. package/dist/index.mjs.map +1 -1
  26. package/dist/wasm_worker.worker.mjs +8 -4
  27. package/dist/wasm_worker.worker.mjs.map +1 -1
  28. package/package.json +21 -6
  29. package/public/e2ee-media-stream-worker.js +627 -0
  30. package/public/openmls_wasm_bg.wasm +0 -0
  31. package/src/attachment_utils.ts +0 -148
  32. package/src/auth.ts +0 -352
  33. package/src/channel.ts +0 -1879
  34. package/src/channel_state.ts +0 -612
  35. package/src/client.ts +0 -1759
  36. package/src/client_state.ts +0 -55
  37. package/src/connection.ts +0 -587
  38. package/src/ermis_call_node.ts +0 -1046
  39. package/src/errors.ts +0 -60
  40. package/src/events.ts +0 -46
  41. package/src/hevc_decoder_config.ts +0 -305
  42. package/src/index.ts +0 -17
  43. package/src/media_stream_receiver.ts +0 -593
  44. package/src/media_stream_sender.ts +0 -465
  45. package/src/shims/empty.ts +0 -1
  46. package/src/signal_message.ts +0 -171
  47. package/src/system_message.ts +0 -259
  48. package/src/token_manager.ts +0 -48
  49. package/src/types.ts +0 -594
  50. package/src/utils.ts +0 -553
  51. package/src/wasm/ermis_call_node_wasm.d.ts +0 -156
  52. package/src/wasm/ermis_call_node_wasm.js +0 -1568
  53. package/src/wasm_worker.ts +0 -219
  54. package/src/wasm_worker_proxy.ts +0 -244
package/src/errors.ts DELETED
@@ -1,60 +0,0 @@
1
- import { AxiosResponse } from 'axios';
2
- import { APIErrorResponse } from './types';
3
-
4
- export const APIErrorCodes: Record<string, { name: string; retryable: boolean }> = {
5
- '-1': { name: 'InternalSystemError', retryable: true },
6
- '2': { name: 'AccessKeyError', retryable: false },
7
- '3': { name: 'AuthenticationFailedError', retryable: true },
8
- '4': { name: 'InputError', retryable: false },
9
- '6': { name: 'DuplicateUsernameError', retryable: false },
10
- '9': { name: 'RateLimitError', retryable: true },
11
- '16': { name: 'DoesNotExistError', retryable: false },
12
- '17': { name: 'NotAllowedError', retryable: false },
13
- '18': { name: 'EventNotSupportedError', retryable: false },
14
- '19': { name: 'ChannelFeatureNotSupportedError', retryable: false },
15
- '20': { name: 'MessageTooLongError', retryable: false },
16
- '21': { name: 'MultipleNestingLevelError', retryable: false },
17
- '22': { name: 'PayloadTooBigError', retryable: false },
18
- '23': { name: 'RequestTimeoutError', retryable: true },
19
- '24': { name: 'MaxHeaderSizeExceededError', retryable: false },
20
- '40': { name: 'AuthErrorTokenExpired', retryable: false },
21
- '41': { name: 'AuthErrorTokenNotValidYet', retryable: false },
22
- '42': { name: 'AuthErrorTokenUsedBeforeIssuedAt', retryable: false },
23
- '43': { name: 'AuthErrorTokenSignatureInvalid', retryable: false },
24
- '44': { name: 'CustomCommandEndpointMissingError', retryable: false },
25
- '45': { name: 'CustomCommandEndpointCallError', retryable: true },
26
- '60': { name: 'CoolDownError', retryable: true },
27
- '69': { name: 'ErrWrongRegion', retryable: false },
28
- '70': { name: 'ErrQueryChannelPermissions', retryable: false },
29
- '71': { name: 'ErrTooManyConnections', retryable: true },
30
- '99': { name: 'AppSuspendedError', retryable: false },
31
- };
32
-
33
- type APIError = Error & { code: number; isWSFailure?: boolean };
34
-
35
- export function isAPIError(error: Error): error is APIError {
36
- return (error as APIError).code !== undefined;
37
- }
38
-
39
- export function isErrorRetryable(error: APIError) {
40
- if (!error.code) return false;
41
- const err = APIErrorCodes[`${error.code}`];
42
- if (!err) return false;
43
- return err.retryable;
44
- }
45
-
46
- export function isWSFailure(err: APIError): boolean {
47
- if (typeof err.isWSFailure === 'boolean') {
48
- return err.isWSFailure;
49
- }
50
-
51
- try {
52
- return JSON.parse(err.message).isWSFailure;
53
- } catch (_) {
54
- return false;
55
- }
56
- }
57
-
58
- export function isErrorResponse(res: AxiosResponse<unknown>): res is AxiosResponse<APIErrorResponse> {
59
- return !res.status || res.status < 200 || 300 <= res.status;
60
- }
package/src/events.ts DELETED
@@ -1,46 +0,0 @@
1
- export const EVENT_MAP = {
2
- 'channel.created': true,
3
- 'channel.deleted': true,
4
- 'channel.truncate': true,
5
- 'channel.updated': true,
6
- 'channel.pinned': true,
7
- 'channel.unpinned': true,
8
- 'health.check': true,
9
- 'member.added': true,
10
- 'member.removed': true,
11
- 'member.updated': true,
12
- 'member.joined': true,
13
- 'member.promoted': true,
14
- 'member.demoted': true,
15
- 'member.banned': true,
16
- 'member.unbanned': true,
17
- 'member.blocked': true,
18
- 'member.unblocked': true,
19
- 'message.deleted': true,
20
- 'message.deleted_for_me': true,
21
- 'message.new': true,
22
- 'message.read': true,
23
- 'message.updated': true,
24
- 'message.pinned': true,
25
- 'message.unpinned': true,
26
- 'notification.channel_deleted': true,
27
- 'notification.invite_accepted': true,
28
- 'notification.invite_rejected': true,
29
- 'notification.invite_messaging_skipped': true,
30
- 'pollchoice.new': true,
31
- 'reaction.deleted': true,
32
- 'reaction.new': true,
33
- 'typing.start': true,
34
- 'typing.stop': true,
35
- 'user.watching.start': true,
36
- 'user.watching.stop': true,
37
- 'connection.changed': true,
38
- 'connection.recovered': true,
39
- 'capabilities.changed': true,
40
- 'channel.topic.disabled': true,
41
- 'channel.topic.enabled': true,
42
- 'channel.topic.created': true,
43
- 'channel.topic.closed': true,
44
- 'channel.topic.reopen': true,
45
- 'channel.topic.updated': true,
46
- };
@@ -1,305 +0,0 @@
1
- // 1. Định nghĩa các hằng số NAL Unit
2
- export const NALUnitType = {
3
- VPS_NUT: 32,
4
- SPS_NUT: 33,
5
- PPS_NUT: 34,
6
- PREFIX_SEI_NUT: 39,
7
- SUFFIX_SEI_NUT: 40,
8
-
9
- fromValue(value: number): string | number {
10
- const types: Record<number, string> = {
11
- 32: 'VPS_NUT',
12
- 33: 'SPS_NUT',
13
- 34: 'PPS_NUT',
14
- 39: 'PREFIX_SEI_NUT',
15
- 40: 'SUFFIX_SEI_NUT',
16
- };
17
- return types[value] || value;
18
- },
19
- } as const;
20
-
21
- // 2. Interface cho mảng NAL Unit bên trong config
22
- export interface INALArray {
23
- arrayCompleteness: boolean;
24
- nalUnitType: string | number;
25
- nalus: Uint8Array[];
26
- }
27
-
28
- // 3. Interface cho cấu hình HEVC (giúp strict type checking)
29
- export interface IHEVCConfig {
30
- generalProfileSpace: number;
31
- generalTierFlag: boolean;
32
- generalProfileIdc: number;
33
- generalProfileCompatibilityFlags: number;
34
- generalConstraintIndicatorFlags: number;
35
- generalLevelIdc: number;
36
- minSpatialSegmentationIdc: number;
37
- parallelismType: number;
38
- chromaFormatIdc: number;
39
- bitDepthLumaMinus8: number;
40
- bitDepthChromaMinus8: number;
41
- avgFrameRate: number;
42
- constantFrameRate: number;
43
- numTemporalLayers: number;
44
- temporalIdNested: boolean;
45
- lengthSizeMinusOne: number;
46
- arrays: INALArray[];
47
- }
48
-
49
- export class HEVCDecoderConfigurationRecord implements IHEVCConfig {
50
- // Khai báo các thuộc tính của class
51
- public generalProfileSpace: number = 0;
52
- public generalTierFlag: boolean = false;
53
- public generalProfileIdc: number = 0;
54
- public generalProfileCompatibilityFlags: number = 0;
55
- public generalConstraintIndicatorFlags: number = 0;
56
- public generalLevelIdc: number = 0;
57
- public minSpatialSegmentationIdc: number = 0;
58
- public parallelismType: number = 0;
59
- public chromaFormatIdc: number = 0;
60
- public bitDepthLumaMinus8: number = 0;
61
- public bitDepthChromaMinus8: number = 0;
62
- public avgFrameRate: number = 0;
63
- public constantFrameRate: number = 0;
64
- public numTemporalLayers: number = 0;
65
- public temporalIdNested: boolean = false;
66
- public lengthSizeMinusOne: number = 0;
67
- public arrays: INALArray[] = [];
68
-
69
- constructor(config: IHEVCConfig) {
70
- Object.assign(this, config);
71
- }
72
-
73
- /**
74
- * Demuxes an HEVCDecoderConfigurationRecord from a byte buffer.
75
- * @param data - The byte data to parse
76
- */
77
- static demux(data: ArrayBuffer | Uint8Array): HEVCDecoderConfigurationRecord {
78
- const buffer = data instanceof Uint8Array ? data : new Uint8Array(data);
79
- const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
80
-
81
- let offset = 0;
82
- let bitOffset = 0;
83
-
84
- // Helper to read bits
85
- const readBits = (numBits: number): number => {
86
- let result = 0;
87
- for (let i = 0; i < numBits; i++) {
88
- if (offset >= buffer.length) throw new Error('End of buffer');
89
- const bit = (buffer[offset] >> (7 - bitOffset)) & 1;
90
- result = (result << 1) | bit;
91
- bitOffset++;
92
- if (bitOffset === 8) {
93
- bitOffset = 0;
94
- offset++;
95
- }
96
- }
97
- return result;
98
- };
99
-
100
- // Helper to read a byte
101
- const readU8 = (): number => {
102
- if (bitOffset !== 0) return readBits(8);
103
- if (offset >= buffer.length) throw new Error('End of buffer');
104
- return buffer[offset++];
105
- };
106
-
107
- // Helper to read 16-bit big-endian
108
- const readU16BE = (): number => {
109
- if (bitOffset !== 0) return readBits(16);
110
- const val = view.getUint16(offset, false);
111
- offset += 2;
112
- return val;
113
- };
114
-
115
- // Helper to read 32-bit big-endian
116
- const readU32BE = (): number => {
117
- if (bitOffset !== 0) return readBits(32);
118
- const val = view.getUint32(offset, false);
119
- offset += 4;
120
- return val;
121
- };
122
-
123
- // Helper to read 48-bit big-endian
124
- const readU48BE = (): number => {
125
- const high = readU16BE();
126
- const low = readU32BE();
127
- return high * 0x100000000 + low;
128
- };
129
-
130
- // Helper to read exact bytes
131
- const readExact = (length: number): Uint8Array => {
132
- if (bitOffset !== 0) {
133
- const result = new Uint8Array(length);
134
- for (let i = 0; i < length; i++) {
135
- result[i] = readBits(8);
136
- }
137
- return result;
138
- }
139
- if (offset + length > buffer.length) throw new Error('End of buffer');
140
- const result = buffer.slice(offset, offset + length);
141
- offset += length;
142
- return result;
143
- };
144
-
145
- // Parse configuration version
146
- const configurationVersion = readU8();
147
- if (configurationVersion !== 1) {
148
- throw new Error('Invalid configuration version');
149
- }
150
-
151
- // Parse profile information
152
- const generalProfileSpace = readBits(2);
153
- const generalTierFlag = readBits(1) === 1;
154
- const generalProfileIdc = readBits(5);
155
- const generalProfileCompatibilityFlags = readU32BE();
156
- const generalConstraintIndicatorFlags = readU48BE();
157
- const generalLevelIdc = readU8();
158
-
159
- // Parse spatial segmentation
160
- readBits(4); // reserved_4bits
161
- const minSpatialSegmentationIdc = readBits(12);
162
-
163
- // Parse parallelism type
164
- readBits(6); // reserved_6bits
165
- const parallelismType = readBits(2);
166
-
167
- // Parse chroma format
168
- readBits(6); // reserved_6bits
169
- const chromaFormatIdc = readBits(2);
170
-
171
- // Parse bit depth (luma)
172
- readBits(5); // reserved_5bits
173
- const bitDepthLumaMinus8 = readBits(3);
174
-
175
- // Parse bit depth (chroma)
176
- readBits(5); // reserved_5bits
177
- const bitDepthChromaMinus8 = readBits(3);
178
-
179
- // Parse frame rate and temporal information
180
- const avgFrameRate = readU16BE();
181
- const constantFrameRate = readBits(2);
182
- const numTemporalLayers = readBits(3);
183
- const temporalIdNested = readBits(1) === 1;
184
- const lengthSizeMinusOne = readBits(2);
185
-
186
- if (lengthSizeMinusOne === 2) {
187
- throw new Error('length_size_minus_one must be 0, 1, or 3');
188
- }
189
-
190
- // Parse NALU arrays
191
- const numOfArrays = readU8();
192
- const arrays: INALArray[] = [];
193
-
194
- for (let i = 0; i < numOfArrays; i++) {
195
- const arrayCompleteness = readBits(1) === 1;
196
- readBits(1); // reserved
197
- const nalUnitType = readBits(6);
198
- const nalUnitTypeName = NALUnitType.fromValue(nalUnitType);
199
-
200
- if (
201
- nalUnitType !== NALUnitType.VPS_NUT &&
202
- nalUnitType !== NALUnitType.SPS_NUT &&
203
- nalUnitType !== NALUnitType.PPS_NUT &&
204
- nalUnitType !== NALUnitType.PREFIX_SEI_NUT &&
205
- nalUnitType !== NALUnitType.SUFFIX_SEI_NUT
206
- ) {
207
- // Có thể comment dòng này nếu muốn hỗ trợ các loại NALU khác không chuẩn
208
- // throw new Error('Invalid nal_unit_type');
209
- }
210
-
211
- const numNalus = readU16BE();
212
- const nalus: Uint8Array[] = [];
213
-
214
- for (let j = 0; j < numNalus; j++) {
215
- const nalUnitLength = readU16BE();
216
- const naluData = readExact(nalUnitLength);
217
- nalus.push(naluData);
218
- }
219
-
220
- arrays.push({
221
- arrayCompleteness,
222
- nalUnitType: nalUnitTypeName,
223
- nalus,
224
- });
225
- }
226
-
227
- return new HEVCDecoderConfigurationRecord({
228
- generalProfileSpace,
229
- generalTierFlag,
230
- generalProfileIdc,
231
- generalProfileCompatibilityFlags,
232
- generalConstraintIndicatorFlags,
233
- generalLevelIdc,
234
- minSpatialSegmentationIdc,
235
- parallelismType,
236
- chromaFormatIdc,
237
- bitDepthLumaMinus8,
238
- bitDepthChromaMinus8,
239
- avgFrameRate,
240
- constantFrameRate,
241
- numTemporalLayers,
242
- temporalIdNested,
243
- lengthSizeMinusOne,
244
- arrays,
245
- });
246
- }
247
-
248
- /**
249
- * Converts the HEVC configuration to a codec string (RFC 6381 format).
250
- * @returns Codec string like "hev1.1.6.L93.B0"
251
- */
252
- toCodecString(): string {
253
- const profileSpaceMap: Record<number, string> = { 0: '', 1: 'A', 2: 'B', 3: 'C' };
254
- const generalProfileSpace = profileSpaceMap[this.generalProfileSpace];
255
-
256
- if (generalProfileSpace === undefined) {
257
- throw new Error('Unknown profile space');
258
- }
259
-
260
- const profileAndSpace = `${generalProfileSpace}${this.generalProfileIdc}`;
261
-
262
- // Format profile compatibility flags (reverse hex and strip trailing zeros)
263
- let profileCompatibilityFlagsUnfiltered = this.generalProfileCompatibilityFlags
264
- .toString(16)
265
- .padStart(8, '0')
266
- .split('')
267
- .reverse()
268
- .join('');
269
-
270
- let profileCompatibilityFlags = '';
271
- for (let i = 0; i < profileCompatibilityFlagsUnfiltered.length; i++) {
272
- const char = profileCompatibilityFlagsUnfiltered[i];
273
- if (char !== '0' || i === 0) {
274
- profileCompatibilityFlags += char;
275
- }
276
- }
277
-
278
- // Format tier and level
279
- const generalTierFlag = this.generalTierFlag ? 'H' : 'L';
280
- const tierAndLevel = `${generalTierFlag}${this.generalLevelIdc}`;
281
-
282
- // Format constraint flags (skip first 2 bytes of 48-bit value)
283
- let constraintFlags = '';
284
-
285
- // Convert 48-bit number to 6 bytes
286
- const constraint = this.generalConstraintIndicatorFlags;
287
- const bytes = [
288
- Math.floor(constraint / 0x10000000000) & 0xff,
289
- Math.floor(constraint / 0x100000000) & 0xff,
290
- Math.floor(constraint / 0x1000000) & 0xff,
291
- Math.floor(constraint / 0x10000) & 0xff,
292
- Math.floor(constraint / 0x100) & 0xff,
293
- constraint & 0xff,
294
- ];
295
-
296
- // Skip first 2 bytes (bytes[0] and bytes[1]) per Logic
297
- for (let i = 2; i < 6; i++) {
298
- if (bytes[i] !== 0) {
299
- constraintFlags += `.${bytes[i].toString(16).padStart(2, '0')}`;
300
- }
301
- }
302
-
303
- return `hev1.${profileAndSpace}.${profileCompatibilityFlags}.${tierAndLevel}${constraintFlags}`;
304
- }
305
- }
package/src/index.ts DELETED
@@ -1,17 +0,0 @@
1
- export * from './client';
2
- export * from './client_state';
3
- export * from './channel';
4
- export * from './channel_state';
5
- export * from './connection';
6
- export * from './events';
7
- export * from './token_manager';
8
- export * from './types';
9
- export * from './ermis_call_node';
10
- export * from './auth';
11
- export { chatCodes, logChatPromiseExecution, formatMessage, createForwardMessagePayload } from './utils';
12
- export { parseSystemMessage } from './system_message';
13
- export type { SystemMessageTranslations } from './system_message';
14
- export { parseSignalMessage, CallType } from './signal_message';
15
- export type { SignalMessageResult, CallTypeValue, SignalMessageTranslations } from './signal_message';
16
- export { normalizeFileName, getAttachmentCategory, isVideoFile, isHeicFile, buildAttachmentPayload } from './attachment_utils';
17
- export type { VoiceRecordingMeta } from './attachment_utils';