@nomalism-com/api 0.45.6 → 0.45.7
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/index.js +127 -0
- package/dist/main.d.ts +2 -0
- package/dist/modules/view/webSocket.d.ts +58 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -127,6 +127,132 @@ __export(main_exports, {
|
|
|
127
127
|
import axios, { AxiosHeaders } from "axios";
|
|
128
128
|
import Nomalism from "@nomalism-com/types";
|
|
129
129
|
|
|
130
|
+
// src/modules/view/webSocket.ts
|
|
131
|
+
var CLOSE_AUTH_REJECTED = 4401;
|
|
132
|
+
var CLOSE_AUTH_UNAVAILABLE = 4503;
|
|
133
|
+
var PING_INTERVAL_MS = 25e3;
|
|
134
|
+
var MAX_BACKOFF_MS = 3e4;
|
|
135
|
+
var BASE_BACKOFF_MS = 1e3;
|
|
136
|
+
var Service = class {
|
|
137
|
+
constructor({ route }) {
|
|
138
|
+
this.route = route;
|
|
139
|
+
}
|
|
140
|
+
openChatSocket({
|
|
141
|
+
token,
|
|
142
|
+
onEvent,
|
|
143
|
+
onOpen,
|
|
144
|
+
onReconnect,
|
|
145
|
+
onClose,
|
|
146
|
+
onAuthUnverified
|
|
147
|
+
}) {
|
|
148
|
+
let ws = null;
|
|
149
|
+
let attempts = 0;
|
|
150
|
+
let opensSoFar = 0;
|
|
151
|
+
let pingTimer = null;
|
|
152
|
+
let reconnectTimer = null;
|
|
153
|
+
let closedByCaller = false;
|
|
154
|
+
const subprotocol = `bearer.${token}`;
|
|
155
|
+
const stopPing = () => {
|
|
156
|
+
if (pingTimer !== null) {
|
|
157
|
+
window.clearInterval(pingTimer);
|
|
158
|
+
pingTimer = null;
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
const startPing = () => {
|
|
162
|
+
stopPing();
|
|
163
|
+
pingTimer = setInterval(() => {
|
|
164
|
+
if (ws?.readyState === WebSocket.OPEN) {
|
|
165
|
+
try {
|
|
166
|
+
ws.send(JSON.stringify({ type: "ping" }));
|
|
167
|
+
} catch (err) {
|
|
168
|
+
console.warn("[chatSocket] ping failed", err);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}, PING_INTERVAL_MS);
|
|
172
|
+
};
|
|
173
|
+
const scheduleReconnect = () => {
|
|
174
|
+
if (closedByCaller) return;
|
|
175
|
+
const delay = Math.min(MAX_BACKOFF_MS, BASE_BACKOFF_MS * 2 ** Math.min(attempts, 6));
|
|
176
|
+
attempts += 1;
|
|
177
|
+
reconnectTimer = setTimeout(connect, delay);
|
|
178
|
+
};
|
|
179
|
+
const connect = () => {
|
|
180
|
+
if (closedByCaller) return;
|
|
181
|
+
try {
|
|
182
|
+
ws = new WebSocket(this.route, [subprotocol]);
|
|
183
|
+
} catch (err) {
|
|
184
|
+
console.error("[chatSocket] WebSocket constructor threw", err);
|
|
185
|
+
scheduleReconnect();
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
ws.onopen = () => {
|
|
189
|
+
attempts = 0;
|
|
190
|
+
opensSoFar += 1;
|
|
191
|
+
startPing();
|
|
192
|
+
if (opensSoFar === 1) {
|
|
193
|
+
onOpen?.();
|
|
194
|
+
} else {
|
|
195
|
+
onReconnect?.();
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
ws.onmessage = (msg) => {
|
|
199
|
+
let payload;
|
|
200
|
+
try {
|
|
201
|
+
payload = JSON.parse(msg.data);
|
|
202
|
+
} catch {
|
|
203
|
+
console.warn("[chatSocket] received non-JSON frame", msg.data);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
if (payload.type === "ping" || payload.type === "pong") return;
|
|
207
|
+
try {
|
|
208
|
+
onEvent(payload);
|
|
209
|
+
} catch (err) {
|
|
210
|
+
console.error("[chatSocket] event handler threw", err, payload);
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
ws.onerror = (err) => {
|
|
214
|
+
console.warn("[chatSocket] error", err);
|
|
215
|
+
};
|
|
216
|
+
ws.onclose = (e) => {
|
|
217
|
+
stopPing();
|
|
218
|
+
ws = null;
|
|
219
|
+
onClose?.();
|
|
220
|
+
if (e.code === CLOSE_AUTH_REJECTED) {
|
|
221
|
+
console.error("[chatSocket] auth rejected by server, not reconnecting");
|
|
222
|
+
closedByCaller = true;
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
if (e.code === CLOSE_AUTH_UNAVAILABLE) {
|
|
226
|
+
console.warn("[chatSocket] auth verifier unavailable, retrying");
|
|
227
|
+
attempts = Math.min(attempts, 2);
|
|
228
|
+
onAuthUnverified?.();
|
|
229
|
+
scheduleReconnect();
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
scheduleReconnect();
|
|
233
|
+
};
|
|
234
|
+
};
|
|
235
|
+
connect();
|
|
236
|
+
return {
|
|
237
|
+
close: () => {
|
|
238
|
+
closedByCaller = true;
|
|
239
|
+
if (reconnectTimer !== null) {
|
|
240
|
+
window.clearTimeout(reconnectTimer);
|
|
241
|
+
reconnectTimer = null;
|
|
242
|
+
}
|
|
243
|
+
stopPing();
|
|
244
|
+
if (ws && ws.readyState <= WebSocket.OPEN) {
|
|
245
|
+
try {
|
|
246
|
+
ws.close(1e3, "client unmount");
|
|
247
|
+
} catch {
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
ws = null;
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
|
|
130
256
|
// src/modules/user/bankData.ts
|
|
131
257
|
var bankData_exports = {};
|
|
132
258
|
__export(bankData_exports, {
|
|
@@ -4206,6 +4332,7 @@ var API = class {
|
|
|
4206
4332
|
api: this.client,
|
|
4207
4333
|
route: `${this.services[service]}${module}/`
|
|
4208
4334
|
});
|
|
4335
|
+
this.WebSocket = new Service(getModuleParams("view", "ws"));
|
|
4209
4336
|
this.BankData = new Repository(getModuleParams("users", Nomalism.BankData.Route));
|
|
4210
4337
|
this.Client = new Repository2(getModuleParams("users", Nomalism.Client.Route));
|
|
4211
4338
|
this.ClientType = new Repository3(getModuleParams("users", Nomalism.ClientType.Route));
|
package/dist/main.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AxiosInstance } from 'axios';
|
|
2
|
+
import WebSocketClass from './modules/view/webSocket';
|
|
2
3
|
import BankDataClass from './modules/user/bankData';
|
|
3
4
|
import ClientClass from './modules/user/clients';
|
|
4
5
|
import ClientTypeClass from './modules/user/clientType';
|
|
@@ -254,6 +255,7 @@ export declare class API {
|
|
|
254
255
|
processEnvironment: IEnvironment;
|
|
255
256
|
client: AxiosInstance;
|
|
256
257
|
services: Record<IService, string>;
|
|
258
|
+
WebSocket: WebSocketClass;
|
|
257
259
|
BankData: BankDataClass;
|
|
258
260
|
Client: ClientClass;
|
|
259
261
|
ClientType: ClientTypeClass;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type Nomalism from '@nomalism-com/types';
|
|
2
|
+
import type { IModuleConstructor } from '../../main';
|
|
3
|
+
export type ChatSocketEvent = {
|
|
4
|
+
type: 'chat.translation.updated';
|
|
5
|
+
chat_id: string;
|
|
6
|
+
translation: string;
|
|
7
|
+
target_language_id: string;
|
|
8
|
+
} | {
|
|
9
|
+
type: 'chat.message.created';
|
|
10
|
+
balloon: Nomalism.Chat.IChatBalloon;
|
|
11
|
+
} | {
|
|
12
|
+
type: 'chat.message.updated';
|
|
13
|
+
chat_id: string;
|
|
14
|
+
patch: Partial<NonNullable<Nomalism.Chat.IChatBalloon['chat']>>;
|
|
15
|
+
} | {
|
|
16
|
+
type: 'chat.message.deleted';
|
|
17
|
+
chat_id: string;
|
|
18
|
+
} | {
|
|
19
|
+
type: 'chat.file.deleted';
|
|
20
|
+
file_id: string;
|
|
21
|
+
} | {
|
|
22
|
+
type: 'chat.read_state.updated';
|
|
23
|
+
chat_document_header_id: string;
|
|
24
|
+
client_read: boolean;
|
|
25
|
+
chat_id?: string;
|
|
26
|
+
file_id?: string;
|
|
27
|
+
} | {
|
|
28
|
+
type: 'chat.tags.updated';
|
|
29
|
+
chat_document_header_id: string;
|
|
30
|
+
tags: Nomalism.Portal.ITags[];
|
|
31
|
+
} | {
|
|
32
|
+
type: 'persona.updated';
|
|
33
|
+
persona: NonNullable<Nomalism.Portal.IPublicFindBySubscriberId['persona']>;
|
|
34
|
+
} | {
|
|
35
|
+
type: 'document.updated';
|
|
36
|
+
document: Nomalism.Portal.IPublicDocument;
|
|
37
|
+
} | {
|
|
38
|
+
type: 'ping';
|
|
39
|
+
} | {
|
|
40
|
+
type: 'pong';
|
|
41
|
+
};
|
|
42
|
+
interface ChatSocketOptions {
|
|
43
|
+
token: string;
|
|
44
|
+
onEvent: (evt: ChatSocketEvent) => void;
|
|
45
|
+
onOpen?: () => void;
|
|
46
|
+
onReconnect?: () => void;
|
|
47
|
+
onClose?: () => void;
|
|
48
|
+
onAuthUnverified?: () => void;
|
|
49
|
+
}
|
|
50
|
+
interface ChatSocketHandle {
|
|
51
|
+
close: () => void;
|
|
52
|
+
}
|
|
53
|
+
export default class Service {
|
|
54
|
+
route: string;
|
|
55
|
+
constructor({ route }: IModuleConstructor);
|
|
56
|
+
openChatSocket({ token, onEvent, onOpen, onReconnect, onClose, onAuthUnverified, }: ChatSocketOptions): ChatSocketHandle;
|
|
57
|
+
}
|
|
58
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nomalism-com/api",
|
|
3
3
|
"description": "A nomalism API package for performing HTTP requests on API endpoints",
|
|
4
|
-
"version": "0.45.
|
|
4
|
+
"version": "0.45.7",
|
|
5
5
|
"author": "Nomalism <it.nomalism@gmail.com> (https://https://nomalism.com/)",
|
|
6
6
|
"license": "UNLICENSED",
|
|
7
7
|
"type": "module",
|