active-connect-ng2 0.2.49 → 0.3.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.
- package/fesm2022/active-connect-ng2.mjs +1186 -0
- package/fesm2022/active-connect-ng2.mjs.map +1 -0
- package/package.json +11 -17
- package/types/active-connect-ng2.d.ts +254 -0
- package/esm2020/active-connect-ng2.mjs +0 -5
- package/esm2020/lib/active-connect-ng2.module.mjs +0 -42
- package/esm2020/lib/websocket/client.mjs +0 -442
- package/esm2020/lib/websocket/decorators/function.mjs +0 -40
- package/esm2020/lib/websocket/decorators/websocket/handle.mjs +0 -9
- package/esm2020/lib/websocket/decorators/websocket/on-reconnect.mjs +0 -6
- package/esm2020/lib/websocket/decorators/websocket/on-success.mjs +0 -8
- package/esm2020/lib/websocket/decorators/websocket/outbound.mjs +0 -213
- package/esm2020/lib/websocket/decorators/websocket/route.mjs +0 -31
- package/esm2020/lib/websocket/decorators/websocket/shared.mjs +0 -10
- package/esm2020/lib/websocket/decorators/websocket/websocket-route-service.mjs +0 -2
- package/esm2020/lib/websocket/index.mjs +0 -11
- package/esm2020/lib/websocket/json/json-parser.mjs +0 -23
- package/esm2020/lib/websocket/lifecycle/loading-status.mjs +0 -31
- package/esm2020/lib/websocket/objects/outbound-object.mjs +0 -410
- package/esm2020/public-api.mjs +0 -7
- package/fesm2015/active-connect-ng2.mjs +0 -1285
- package/fesm2015/active-connect-ng2.mjs.map +0 -1
- package/fesm2020/active-connect-ng2.mjs +0 -1267
- package/fesm2020/active-connect-ng2.mjs.map +0 -1
- package/index.d.ts +0 -5
- package/lib/active-connect-ng2.module.d.ts +0 -7
- package/lib/websocket/client.d.ts +0 -65
- package/lib/websocket/decorators/function.d.ts +0 -30
- package/lib/websocket/decorators/websocket/handle.d.ts +0 -1
- package/lib/websocket/decorators/websocket/on-reconnect.d.ts +0 -1
- package/lib/websocket/decorators/websocket/on-success.d.ts +0 -1
- package/lib/websocket/decorators/websocket/outbound.d.ts +0 -1
- package/lib/websocket/decorators/websocket/route.d.ts +0 -1
- package/lib/websocket/decorators/websocket/shared.d.ts +0 -4
- package/lib/websocket/decorators/websocket/websocket-route-service.d.ts +0 -5
- package/lib/websocket/index.d.ts +0 -10
- package/lib/websocket/json/json-parser.d.ts +0 -5
- package/lib/websocket/lifecycle/loading-status.d.ts +0 -9
- package/lib/websocket/objects/outbound-object.d.ts +0 -50
- package/public-api.d.ts +0 -3
|
@@ -0,0 +1,1186 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import { NgModule, signal, untracked } from "@angular/core";
|
|
3
|
+
import * as i1 from "ngx-indexed-db";
|
|
4
|
+
import { NgxIndexedDBModule, NgxIndexedDBService } from "ngx-indexed-db";
|
|
5
|
+
import { Observable } from "rxjs";
|
|
6
|
+
const dbConfig = {
|
|
7
|
+
name: "activeconnect_cache",
|
|
8
|
+
version: 2,
|
|
9
|
+
objectStoresMeta: [{
|
|
10
|
+
store: "outbound",
|
|
11
|
+
storeConfig: {
|
|
12
|
+
keyPath: "method",
|
|
13
|
+
autoIncrement: false
|
|
14
|
+
},
|
|
15
|
+
storeSchema: [
|
|
16
|
+
{
|
|
17
|
+
name: "method",
|
|
18
|
+
keypath: "method",
|
|
19
|
+
options: { unique: true }
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: "data",
|
|
23
|
+
keypath: "data",
|
|
24
|
+
options: { unique: false }
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: "specificHash",
|
|
28
|
+
keypath: "specificHash",
|
|
29
|
+
options: { unique: false }
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: "length",
|
|
33
|
+
keypath: "length",
|
|
34
|
+
options: { unique: false }
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
}]
|
|
38
|
+
};
|
|
39
|
+
var ActiveConnectNg2Module = class ActiveConnectNg2Module {
|
|
40
|
+
static {
|
|
41
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
42
|
+
minVersion: "12.0.0",
|
|
43
|
+
version: "22.2.3",
|
|
44
|
+
ngImport: i0,
|
|
45
|
+
type: ActiveConnectNg2Module,
|
|
46
|
+
deps: [],
|
|
47
|
+
target: i0.ɵɵFactoryTarget.NgModule
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
static {
|
|
51
|
+
this.ɵmod = i0.ɵɵngDeclareNgModule({
|
|
52
|
+
minVersion: "14.0.0",
|
|
53
|
+
version: "22.2.3",
|
|
54
|
+
ngImport: i0,
|
|
55
|
+
type: ActiveConnectNg2Module,
|
|
56
|
+
imports: [i1.NgxIndexedDBModule],
|
|
57
|
+
exports: [NgxIndexedDBModule]
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
static {
|
|
61
|
+
this.ɵinj = i0.ɵɵngDeclareInjector({
|
|
62
|
+
minVersion: "12.0.0",
|
|
63
|
+
version: "22.2.3",
|
|
64
|
+
ngImport: i0,
|
|
65
|
+
type: ActiveConnectNg2Module,
|
|
66
|
+
imports: [NgxIndexedDBModule.forRoot(dbConfig), NgxIndexedDBModule]
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
71
|
+
minVersion: "12.0.0",
|
|
72
|
+
version: "22.2.3",
|
|
73
|
+
ngImport: i0,
|
|
74
|
+
type: ActiveConnectNg2Module,
|
|
75
|
+
decorators: [{
|
|
76
|
+
type: NgModule,
|
|
77
|
+
args: [{
|
|
78
|
+
declarations: [],
|
|
79
|
+
imports: [NgxIndexedDBModule.forRoot(dbConfig)],
|
|
80
|
+
exports: [NgxIndexedDBModule]
|
|
81
|
+
}]
|
|
82
|
+
}]
|
|
83
|
+
});
|
|
84
|
+
var JsonParser = class JsonParser {
|
|
85
|
+
static stringify(obj) {
|
|
86
|
+
return JSON.stringify(obj);
|
|
87
|
+
}
|
|
88
|
+
static parsingFunction(key, value) {
|
|
89
|
+
var a;
|
|
90
|
+
if (typeof value === "string") {
|
|
91
|
+
a = /^[0-9]{4}\-[0-9]{2}\-[0-9]{2}T[0-9]{2}\:[0-9]{2}\:[0-9]{2}\.[0-9]{3}Z$/.exec(value);
|
|
92
|
+
if (a) return new Date(a);
|
|
93
|
+
}
|
|
94
|
+
return value;
|
|
95
|
+
}
|
|
96
|
+
static parse(str) {
|
|
97
|
+
if (str && str != "undefined") return JSON.parse(str, JsonParser.parsingFunction);
|
|
98
|
+
return str;
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
var WebsocketClient = class WebsocketClient {
|
|
102
|
+
constructor(url, supportsCache, dbService) {
|
|
103
|
+
this.url = url;
|
|
104
|
+
this.supportsCache = supportsCache;
|
|
105
|
+
this.dbService = dbService;
|
|
106
|
+
this._connected = signal(false, ...ngDevMode ? [{ debugName: "_connected" }] : /* istanbul ignore next */ []);
|
|
107
|
+
this.requestStack = [];
|
|
108
|
+
this.requestHistoryLogs = [];
|
|
109
|
+
this._token = "";
|
|
110
|
+
this.connectionEstablishedOnce = false;
|
|
111
|
+
this.messageId = 0;
|
|
112
|
+
this.rejectCallbacks = /* @__PURE__ */ new Map();
|
|
113
|
+
this.expectedMethods = /* @__PURE__ */ new Map();
|
|
114
|
+
this.closed = false;
|
|
115
|
+
if (supportsCache) this.initCache();
|
|
116
|
+
if (typeof document === "undefined" || typeof WebSocket === "undefined") return;
|
|
117
|
+
this.setUrl(this.url);
|
|
118
|
+
}
|
|
119
|
+
setUrl(url) {
|
|
120
|
+
if (!url) {
|
|
121
|
+
let protocol;
|
|
122
|
+
let port;
|
|
123
|
+
switch (document.location.protocol) {
|
|
124
|
+
case "https:":
|
|
125
|
+
protocol = "wss:";
|
|
126
|
+
port = ":443";
|
|
127
|
+
break;
|
|
128
|
+
default:
|
|
129
|
+
protocol = "ws:";
|
|
130
|
+
port = ":80";
|
|
131
|
+
}
|
|
132
|
+
url = protocol + "//" + document.location.hostname + port + "/wss";
|
|
133
|
+
}
|
|
134
|
+
this.url = url;
|
|
135
|
+
this.closed = false;
|
|
136
|
+
this.connect(this.url);
|
|
137
|
+
}
|
|
138
|
+
connect(url) {
|
|
139
|
+
if (!this.target.___connectionId) this.target.___connectionId = 0;
|
|
140
|
+
this.target.___connectionId++;
|
|
141
|
+
if (this.ws && (this.ws.readyState === WebSocket.CONNECTING || this.ws.readyState === WebSocket.OPEN)) return;
|
|
142
|
+
this.create(url);
|
|
143
|
+
}
|
|
144
|
+
initTabSuspendedListener() {
|
|
145
|
+
if (typeof document !== "undefined") document.addEventListener("visibilitychange", () => {
|
|
146
|
+
if (document.visibilityState === "hidden") {
|
|
147
|
+
console.log("ActiveConnect: Closing WebSocket due to tab suspension...");
|
|
148
|
+
this.disconnect(true);
|
|
149
|
+
} else if (document.visibilityState === "visible") {
|
|
150
|
+
console.log("ActiveConnect: Reconnecting WebSocket...");
|
|
151
|
+
this.closed = false;
|
|
152
|
+
this.connect(this.url);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
logEntry(method) {
|
|
157
|
+
this.requestHistoryLogs.push({
|
|
158
|
+
timestamp: new Date(Date.now()),
|
|
159
|
+
method
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
get logs() {
|
|
163
|
+
return this.requestHistoryLogs;
|
|
164
|
+
}
|
|
165
|
+
get Token() {
|
|
166
|
+
if (!this._token) try {
|
|
167
|
+
if (typeof window !== "undefined" && window.localStorage) this._token = window.localStorage.getItem("token") || "";
|
|
168
|
+
} catch {}
|
|
169
|
+
return this._token;
|
|
170
|
+
}
|
|
171
|
+
set Token(val) {
|
|
172
|
+
this._token = val;
|
|
173
|
+
try {
|
|
174
|
+
if (typeof window !== "undefined" && window.localStorage) window.localStorage.setItem("token", val);
|
|
175
|
+
} catch {}
|
|
176
|
+
}
|
|
177
|
+
set Connected(value) {
|
|
178
|
+
if (value) {
|
|
179
|
+
this.sendBrowserInfoToServer();
|
|
180
|
+
this.auth(this.Token).catch((err) => {
|
|
181
|
+
console.log("ActiveConnect: auth failed on reconnect: " + err);
|
|
182
|
+
}).then(() => {
|
|
183
|
+
Promise.all(WebsocketClient.onReconnectCallback.map((c) => c.Func ? c.Func() : null)).then(() => {
|
|
184
|
+
setTimeout(() => {
|
|
185
|
+
this.resetRequestedState();
|
|
186
|
+
this.requestStack.forEach((e) => {
|
|
187
|
+
this.sendToSocket(e.method, e.data, false, e.messageId);
|
|
188
|
+
this.requestStack = this.requestStack.filter((e1) => e1 != e);
|
|
189
|
+
});
|
|
190
|
+
}, 2e3);
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
if (this.pool && this.pool.WssConnected) this.pool.WssConnected = value;
|
|
195
|
+
}
|
|
196
|
+
static {
|
|
197
|
+
this.resetRequestedStateCallbacks = [];
|
|
198
|
+
}
|
|
199
|
+
resetRequestedState() {
|
|
200
|
+
if (this.connectionEstablishedOnce) WebsocketClient.resetRequestedStateCallbacks.forEach((reset) => {
|
|
201
|
+
reset(this);
|
|
202
|
+
});
|
|
203
|
+
else this.connectionEstablishedOnce = true;
|
|
204
|
+
}
|
|
205
|
+
static addResetRequestingStateCallback(callback) {
|
|
206
|
+
WebsocketClient.resetRequestedStateCallbacks.push(callback);
|
|
207
|
+
}
|
|
208
|
+
static {
|
|
209
|
+
this.HANDSHAKE_TIMEOUT_MS = 1e4;
|
|
210
|
+
}
|
|
211
|
+
clearHandshakeTimer() {
|
|
212
|
+
if (this.handshakeTimer !== void 0) {
|
|
213
|
+
clearTimeout(this.handshakeTimer);
|
|
214
|
+
this.handshakeTimer = void 0;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
create(url) {
|
|
218
|
+
if (this.ws) {
|
|
219
|
+
this.ws.onopen = null;
|
|
220
|
+
this.ws.onmessage = null;
|
|
221
|
+
this.ws.onerror = null;
|
|
222
|
+
this.ws.onclose = null;
|
|
223
|
+
if (this.ws.readyState === WebSocket.CONNECTING || this.ws.readyState === WebSocket.OPEN) this.ws.close();
|
|
224
|
+
}
|
|
225
|
+
this.clearReconnectTimer();
|
|
226
|
+
this.clearHandshakeTimer();
|
|
227
|
+
this.closed = false;
|
|
228
|
+
this.logEntry("TCP/HTTP:CONNECT-SERVER");
|
|
229
|
+
this.ws = new WebSocket(url + (this.supportsCache ? "?cache=true" : ""));
|
|
230
|
+
this.handshakeTimer = setTimeout(() => {
|
|
231
|
+
if (this.ws && this.ws.readyState === WebSocket.CONNECTING) {
|
|
232
|
+
this.logEntry("TCP/HTTP:HANDSHAKE-TIMEOUT");
|
|
233
|
+
console.log("ActiveConnect: Handshake timed out, retrying connection...");
|
|
234
|
+
this.ws.onopen = null;
|
|
235
|
+
this.ws.onmessage = null;
|
|
236
|
+
this.ws.onerror = null;
|
|
237
|
+
this.ws.onclose = null;
|
|
238
|
+
try {
|
|
239
|
+
this.ws.close();
|
|
240
|
+
} catch (err) {}
|
|
241
|
+
if (!this.closed) {
|
|
242
|
+
this.clearReconnectTimer();
|
|
243
|
+
this.reconnectTimer = setTimeout(() => {
|
|
244
|
+
this.reconnectTimer = void 0;
|
|
245
|
+
this.connect(url);
|
|
246
|
+
}, 1e3);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}, WebsocketClient.HANDSHAKE_TIMEOUT_MS);
|
|
250
|
+
this.ws.onerror = (err) => {
|
|
251
|
+
this.ws.close();
|
|
252
|
+
this.logEntry("TCP/HTTP:ERROR:" + err);
|
|
253
|
+
console.log("ActiveConnect: " + err);
|
|
254
|
+
};
|
|
255
|
+
this.ws.onopen = () => {
|
|
256
|
+
this.clearHandshakeTimer();
|
|
257
|
+
this._connected.set(true);
|
|
258
|
+
this.logEntry("TCP/HTTP:CONNECTED");
|
|
259
|
+
this.Connected = true;
|
|
260
|
+
};
|
|
261
|
+
this.ws.onmessage = (e) => {
|
|
262
|
+
let parsed;
|
|
263
|
+
try {
|
|
264
|
+
parsed = JsonParser.parse(e.data.toString());
|
|
265
|
+
} catch (err) {
|
|
266
|
+
console.log("ActiveConnect: failed to parse incoming message: " + err);
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
this.messageReceived(parsed);
|
|
270
|
+
};
|
|
271
|
+
this.ws.onclose = () => {
|
|
272
|
+
this.clearHandshakeTimer();
|
|
273
|
+
this._connected.set(false);
|
|
274
|
+
this.logEntry("TCP/HTTP:CLOSED");
|
|
275
|
+
if (!this.closed) {
|
|
276
|
+
if (this.pool && this.pool.WssConnected) this.pool.WssConnected = false;
|
|
277
|
+
this.logEntry("TCP/HTTP:RESET-REQUESTED-OUTBOUND-STATE");
|
|
278
|
+
this.resetRequestedState();
|
|
279
|
+
this.clearReconnectTimer();
|
|
280
|
+
this.reconnectTimer = setTimeout(() => {
|
|
281
|
+
this.reconnectTimer = void 0;
|
|
282
|
+
this.connect(url);
|
|
283
|
+
}, 1e3);
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
clearReconnectTimer() {
|
|
288
|
+
if (this.reconnectTimer !== void 0) {
|
|
289
|
+
clearTimeout(this.reconnectTimer);
|
|
290
|
+
this.reconnectTimer = void 0;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
sendToSocket(method, data, dontEnsureTransmission, forcedMessageId) {
|
|
294
|
+
const messageId = forcedMessageId ?? ++this.messageId;
|
|
295
|
+
if (this.ws.readyState != this.ws.OPEN) {
|
|
296
|
+
if (!dontEnsureTransmission) this.requestStack.push({
|
|
297
|
+
method,
|
|
298
|
+
data,
|
|
299
|
+
messageId
|
|
300
|
+
});
|
|
301
|
+
else return false;
|
|
302
|
+
} else this.ws.send(JsonParser.stringify({
|
|
303
|
+
method,
|
|
304
|
+
value: data,
|
|
305
|
+
messageId
|
|
306
|
+
}));
|
|
307
|
+
return messageId;
|
|
308
|
+
}
|
|
309
|
+
async auth(token) {
|
|
310
|
+
return this.sendToSocket("auth.token", token);
|
|
311
|
+
}
|
|
312
|
+
send(method, data, dontEnsureTransmission) {
|
|
313
|
+
this.logEntry("SEND:" + method);
|
|
314
|
+
const messageId = this.sendToSocket(method, data, dontEnsureTransmission || false);
|
|
315
|
+
if (messageId) return this.expectMethod(`m.${method}`, messageId);
|
|
316
|
+
else return new Promise((resolve) => {
|
|
317
|
+
resolve(false);
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
expectMethod(method, messageId) {
|
|
321
|
+
return new Promise((resolve, reject) => {
|
|
322
|
+
if (messageId) {
|
|
323
|
+
this.expectedMethods.set(messageId, [resolve]);
|
|
324
|
+
this.rejectCallbacks.set(messageId, reject);
|
|
325
|
+
} else if (this.expectedMethods.has(method)) this.expectedMethods.get(method).push(resolve);
|
|
326
|
+
else this.expectedMethods.set(method, [resolve]);
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
messageReceived({ method, value, messageId, specificHash, inserted, updated, deleted, length }) {
|
|
330
|
+
this.logEntry("RECEIVED:" + method);
|
|
331
|
+
if (method == "___cache") this.handleOutboundCacheRequest(value);
|
|
332
|
+
if (messageId) {
|
|
333
|
+
if (method == "m.error") {
|
|
334
|
+
const reject = this.rejectCallbacks.get(messageId);
|
|
335
|
+
if (reject) reject(value);
|
|
336
|
+
messageId = -1;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
if (messageId != null) {
|
|
340
|
+
const callback = this.expectedMethods.get(messageId);
|
|
341
|
+
if (callback) {
|
|
342
|
+
const func = callback.shift();
|
|
343
|
+
if (func) func(value);
|
|
344
|
+
this.invokeSuccessHandlers(method);
|
|
345
|
+
} else {
|
|
346
|
+
const callback = this.expectedMethods.get(method);
|
|
347
|
+
if (callback && callback.length > 0) {
|
|
348
|
+
const func = callback.shift();
|
|
349
|
+
if (func) func(value);
|
|
350
|
+
} else {
|
|
351
|
+
const out = WebsocketClient.outbounds.get(method);
|
|
352
|
+
if (out) out(value, specificHash, inserted, updated, deleted, length, this);
|
|
353
|
+
const handle = WebsocketClient.handles.get(method);
|
|
354
|
+
if (handle) handle.Func(value);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
} else throw Error("No MessageId was provided, the connection is not supported.");
|
|
358
|
+
}
|
|
359
|
+
handleOutboundCacheRequest(method) {
|
|
360
|
+
if (this.dbService) try {
|
|
361
|
+
this.dbService.getByKey("outbound", method).subscribe((item) => {
|
|
362
|
+
if (item) this.send("___cache", {
|
|
363
|
+
method,
|
|
364
|
+
specificHash: item.specificHash || null
|
|
365
|
+
});
|
|
366
|
+
else this.send("___cache", {
|
|
367
|
+
method,
|
|
368
|
+
specificHash: null
|
|
369
|
+
});
|
|
370
|
+
});
|
|
371
|
+
} catch (e) {
|
|
372
|
+
this.send("___cache", {
|
|
373
|
+
method,
|
|
374
|
+
specificHash: null
|
|
375
|
+
});
|
|
376
|
+
console.error("ActiveConnect: " + e);
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
this.send("___cache", {
|
|
380
|
+
method,
|
|
381
|
+
specificHash: null
|
|
382
|
+
});
|
|
383
|
+
console.error("Active-Connect: Caching not possible as the indexedDB has not been initialized");
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
static {
|
|
387
|
+
this.outbounds = /* @__PURE__ */ new Map();
|
|
388
|
+
}
|
|
389
|
+
static expectOutbound(method, callback) {
|
|
390
|
+
WebsocketClient.outbounds.set(method, callback);
|
|
391
|
+
}
|
|
392
|
+
static {
|
|
393
|
+
this.handles = /* @__PURE__ */ new Map();
|
|
394
|
+
}
|
|
395
|
+
static registerHandle(method, callback) {
|
|
396
|
+
WebsocketClient.handles.set(method, callback);
|
|
397
|
+
}
|
|
398
|
+
get isConnected() {
|
|
399
|
+
this._connected();
|
|
400
|
+
if (this.ws) return this.ws.readyState == WebSocket.OPEN;
|
|
401
|
+
return true;
|
|
402
|
+
}
|
|
403
|
+
sendBrowserInfoToServer() {
|
|
404
|
+
const browser = this.getBrowser();
|
|
405
|
+
const os = this.getOS();
|
|
406
|
+
this.send("___browser", { browser: `${browser.name} ${browser.version} ${os}` });
|
|
407
|
+
}
|
|
408
|
+
getBrowser() {
|
|
409
|
+
var ua = navigator.userAgent, tem, M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
|
|
410
|
+
if (/trident/i.test(M[1])) {
|
|
411
|
+
tem = /\brv[ :]+(\d+)/g.exec(ua) || [];
|
|
412
|
+
return {
|
|
413
|
+
name: "IE ",
|
|
414
|
+
version: tem[1] || ""
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
if (M[1] === "Chrome") {
|
|
418
|
+
tem = ua.match(/\bOPR\/(\d+)/);
|
|
419
|
+
if (tem != null) return {
|
|
420
|
+
name: "Opera",
|
|
421
|
+
version: tem[1]
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
M = M[2] ? [M[1], M[2]] : [
|
|
425
|
+
navigator.appName,
|
|
426
|
+
navigator.appVersion,
|
|
427
|
+
"-?"
|
|
428
|
+
];
|
|
429
|
+
if ((tem = ua.match(/version\/(\d+)/i)) != null) M.splice(1, 1, tem[1]);
|
|
430
|
+
return {
|
|
431
|
+
name: M[0],
|
|
432
|
+
version: M[1]
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
getOS() {
|
|
436
|
+
var userAgent = window.navigator.userAgent, platform = window.navigator.platform, macosPlatforms = [
|
|
437
|
+
"Macintosh",
|
|
438
|
+
"MacIntel",
|
|
439
|
+
"MacPPC",
|
|
440
|
+
"Mac68K"
|
|
441
|
+
], windowsPlatforms = [
|
|
442
|
+
"Win32",
|
|
443
|
+
"Win64",
|
|
444
|
+
"Windows",
|
|
445
|
+
"WinCE"
|
|
446
|
+
], iosPlatforms = [
|
|
447
|
+
"iPhone",
|
|
448
|
+
"iPad",
|
|
449
|
+
"iPod"
|
|
450
|
+
], os = null;
|
|
451
|
+
if (macosPlatforms.indexOf(platform) !== -1) os = "Mac OS";
|
|
452
|
+
else if (iosPlatforms.indexOf(platform) !== -1) os = "iOS";
|
|
453
|
+
else if (windowsPlatforms.indexOf(platform) !== -1) os = "Windows";
|
|
454
|
+
else if (/Android/.test(userAgent)) os = "Android";
|
|
455
|
+
else if (!os && /Linux/.test(platform)) os = "Linux";
|
|
456
|
+
return os || "";
|
|
457
|
+
}
|
|
458
|
+
static {
|
|
459
|
+
this.onSuccessHandlers = [];
|
|
460
|
+
}
|
|
461
|
+
static onSuccess(callback, regexp) {
|
|
462
|
+
this.onSuccessHandlers.push({
|
|
463
|
+
callback,
|
|
464
|
+
regexp
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
static {
|
|
468
|
+
this.onReconnectCallback = [];
|
|
469
|
+
}
|
|
470
|
+
static onReconnect(callback) {
|
|
471
|
+
WebsocketClient.onReconnectCallback.push(callback);
|
|
472
|
+
}
|
|
473
|
+
invokeSuccessHandlers(method) {
|
|
474
|
+
WebsocketClient.onSuccessHandlers.filter((e) => e.regexp.test(method)).forEach((e) => {
|
|
475
|
+
var res = e.callback.Func();
|
|
476
|
+
if (res && res.then) res.then();
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
disconnect(restart) {
|
|
480
|
+
this.closed = true;
|
|
481
|
+
this._connected.set(false);
|
|
482
|
+
this.clearReconnectTimer();
|
|
483
|
+
this.clearHandshakeTimer();
|
|
484
|
+
if (this.ws) this.ws.close();
|
|
485
|
+
if (!restart && this.ws) {
|
|
486
|
+
this.ws.onopen = null;
|
|
487
|
+
this.ws.onmessage = null;
|
|
488
|
+
this.ws.onerror = null;
|
|
489
|
+
this.ws.onclose = null;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
initCache() {}
|
|
493
|
+
get target() {
|
|
494
|
+
return this.__proto__;
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
var DecorableFunction = class {
|
|
498
|
+
constructor(objConfig) {
|
|
499
|
+
this.objConfig = objConfig;
|
|
500
|
+
const prototype = this.objConfig.target.prototype || this.objConfig.target;
|
|
501
|
+
if (!prototype.___constructorOverridden) prototype.___constructorOverridden = true;
|
|
502
|
+
}
|
|
503
|
+
get Func() {
|
|
504
|
+
if (this.objConfig?.target && this.objConfig.target[this.objConfig.propertyKey]) return this.objConfig.target[this.objConfig.propertyKey].bind(this.getBindObject());
|
|
505
|
+
return null;
|
|
506
|
+
}
|
|
507
|
+
getBindObject() {
|
|
508
|
+
return (this.objConfig.target.prototype || this.objConfig.target).___data._obj;
|
|
509
|
+
}
|
|
510
|
+
};
|
|
511
|
+
function Handle(method) {
|
|
512
|
+
return function _Handle(target, propertyKey) {
|
|
513
|
+
WebsocketClient.registerHandle(method, new DecorableFunction({
|
|
514
|
+
target,
|
|
515
|
+
propertyKey
|
|
516
|
+
}));
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
function OnSuccess(regexp) {
|
|
520
|
+
return function _Route(target, propertyKey) {
|
|
521
|
+
WebsocketClient.onSuccess(new DecorableFunction({
|
|
522
|
+
target,
|
|
523
|
+
propertyKey
|
|
524
|
+
}), regexp);
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
function OnReconnect(target, propertyKey) {
|
|
528
|
+
WebsocketClient.onReconnect(new DecorableFunction({
|
|
529
|
+
target,
|
|
530
|
+
propertyKey
|
|
531
|
+
}));
|
|
532
|
+
}
|
|
533
|
+
function defer(fn) {
|
|
534
|
+
queueMicrotask(fn);
|
|
535
|
+
}
|
|
536
|
+
var ReactiveLoadingMap = class extends Map {
|
|
537
|
+
bump() {
|
|
538
|
+
this._version.update((v) => v + 1);
|
|
539
|
+
}
|
|
540
|
+
get(key) {
|
|
541
|
+
this._version();
|
|
542
|
+
return super.get(key);
|
|
543
|
+
}
|
|
544
|
+
has(key) {
|
|
545
|
+
this._version();
|
|
546
|
+
return super.has(key);
|
|
547
|
+
}
|
|
548
|
+
set(key, value) {
|
|
549
|
+
const changed = !super.has(key) || super.get(key) !== value;
|
|
550
|
+
super.set(key, value);
|
|
551
|
+
if (changed) this.bump();
|
|
552
|
+
return this;
|
|
553
|
+
}
|
|
554
|
+
delete(key) {
|
|
555
|
+
const existed = super.delete(key);
|
|
556
|
+
if (existed) this.bump();
|
|
557
|
+
return existed;
|
|
558
|
+
}
|
|
559
|
+
clear() {
|
|
560
|
+
let hadEntries = false;
|
|
561
|
+
super.forEach(() => hadEntries = true);
|
|
562
|
+
super.clear();
|
|
563
|
+
if (hadEntries) this.bump();
|
|
564
|
+
}
|
|
565
|
+
forEach(callbackfn, thisArg) {
|
|
566
|
+
this._version();
|
|
567
|
+
super.forEach(callbackfn, thisArg);
|
|
568
|
+
}
|
|
569
|
+
constructor() {
|
|
570
|
+
super();
|
|
571
|
+
this._version = signal(0, ...ngDevMode ? [{ debugName: "_version" }] : /* istanbul ignore next */ []);
|
|
572
|
+
this.prunePending = false;
|
|
573
|
+
const nativeSize = Object.getOwnPropertyDescriptor(Map.prototype, "size").get;
|
|
574
|
+
Object.defineProperty(this, "size", {
|
|
575
|
+
configurable: true,
|
|
576
|
+
get: () => {
|
|
577
|
+
this._version();
|
|
578
|
+
return nativeSize.call(this);
|
|
579
|
+
}
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
keys() {
|
|
583
|
+
this._version();
|
|
584
|
+
return super.keys();
|
|
585
|
+
}
|
|
586
|
+
values() {
|
|
587
|
+
this._version();
|
|
588
|
+
return super.values();
|
|
589
|
+
}
|
|
590
|
+
entries() {
|
|
591
|
+
this._version();
|
|
592
|
+
return super.entries();
|
|
593
|
+
}
|
|
594
|
+
[Symbol.iterator]() {
|
|
595
|
+
this._version();
|
|
596
|
+
return super[Symbol.iterator]();
|
|
597
|
+
}
|
|
598
|
+
peek(key) {
|
|
599
|
+
return super.get(key);
|
|
600
|
+
}
|
|
601
|
+
pruneWhenIdle() {
|
|
602
|
+
if (this.prunePending) return;
|
|
603
|
+
this.prunePending = true;
|
|
604
|
+
defer(() => {
|
|
605
|
+
this.prunePending = false;
|
|
606
|
+
let anyTrue = false;
|
|
607
|
+
super.forEach((v) => anyTrue ||= v);
|
|
608
|
+
if (!anyTrue) this.clear();
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
};
|
|
612
|
+
function ensureLoadingMap(target) {
|
|
613
|
+
if (!(target.loading instanceof ReactiveLoadingMap)) target.loading = new ReactiveLoadingMap();
|
|
614
|
+
return target.loading;
|
|
615
|
+
}
|
|
616
|
+
function ticksOf(target) {
|
|
617
|
+
if (!target.___ticks) target.___ticks = {};
|
|
618
|
+
return target.___ticks;
|
|
619
|
+
}
|
|
620
|
+
function readTick(target, key) {
|
|
621
|
+
const ticks = ticksOf(target);
|
|
622
|
+
return (ticks[key] ??= signal(0))();
|
|
623
|
+
}
|
|
624
|
+
function bumpTick(target, key) {
|
|
625
|
+
const ticks = ticksOf(target);
|
|
626
|
+
(ticks[key] ??= signal(0)).update((v) => v + 1);
|
|
627
|
+
}
|
|
628
|
+
const reactiveLoadingElements = /* @__PURE__ */ new WeakSet();
|
|
629
|
+
function isReactiveLoadingElements(obj) {
|
|
630
|
+
return !!obj && typeof obj === "object" && reactiveLoadingElements.has(obj);
|
|
631
|
+
}
|
|
632
|
+
function createLoadingElements(initial) {
|
|
633
|
+
const signals = /* @__PURE__ */ new Map();
|
|
634
|
+
const sigFor = (key) => {
|
|
635
|
+
let s = signals.get(key);
|
|
636
|
+
if (!s) {
|
|
637
|
+
s = signal(0);
|
|
638
|
+
signals.set(key, s);
|
|
639
|
+
}
|
|
640
|
+
return s;
|
|
641
|
+
};
|
|
642
|
+
Object.entries(initial || {}).forEach(([k, v]) => sigFor(k).set(v));
|
|
643
|
+
const proxy = new Proxy({}, {
|
|
644
|
+
get: (_t, key) => typeof key === "string" ? sigFor(key)() : void 0,
|
|
645
|
+
set: (_t, key, value) => {
|
|
646
|
+
if (typeof key === "string") sigFor(key).set(value);
|
|
647
|
+
return true;
|
|
648
|
+
},
|
|
649
|
+
has: (_t, key) => typeof key === "string" && signals.has(key),
|
|
650
|
+
deleteProperty: (_t, key) => {
|
|
651
|
+
if (typeof key === "string") sigFor(key).set(0);
|
|
652
|
+
return true;
|
|
653
|
+
},
|
|
654
|
+
ownKeys: () => Array.from(signals.keys()),
|
|
655
|
+
getOwnPropertyDescriptor: (_t, key) => typeof key === "string" && signals.has(key) ? {
|
|
656
|
+
value: sigFor(key)(),
|
|
657
|
+
enumerable: true,
|
|
658
|
+
configurable: true,
|
|
659
|
+
writable: true
|
|
660
|
+
} : void 0
|
|
661
|
+
});
|
|
662
|
+
reactiveLoadingElements.add(proxy);
|
|
663
|
+
return proxy;
|
|
664
|
+
}
|
|
665
|
+
function Outbound(method, requestingRequired, cached, sortBy) {
|
|
666
|
+
return function _Outbound(target, propertyKey) {
|
|
667
|
+
ensureLoadingMap(target);
|
|
668
|
+
WebsocketClient.expectOutbound(method, function setOutbound(data, specificHash, inserted, updated, deleted, length, _this) {
|
|
669
|
+
if (!target.___received) target.___received = {};
|
|
670
|
+
if (!target.___data) target.___data = {};
|
|
671
|
+
if (!target.___received) target.___received = {};
|
|
672
|
+
if (!target.___requested) target.___requested = {};
|
|
673
|
+
if (!cached) {
|
|
674
|
+
if (_this.dbService) try {
|
|
675
|
+
_this.dbService.deleteByKey("outbound", method).subscribe(() => {});
|
|
676
|
+
} catch (e) {
|
|
677
|
+
console.error("ActiveConnect: could not delete indexdb cache entry");
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
if (data == "cache_restore") {
|
|
681
|
+
if (_this.dbService) try {
|
|
682
|
+
_this.dbService.getByKey("outbound", method).subscribe((result) => {
|
|
683
|
+
target.___received[propertyKey] = true;
|
|
684
|
+
target.___data[propertyKey] = result.data;
|
|
685
|
+
target.loading.set(propertyKey, false);
|
|
686
|
+
bumpTick(target, propertyKey);
|
|
687
|
+
});
|
|
688
|
+
} catch (e) {
|
|
689
|
+
console.error("ActiveConnect: Unable to restore cached data.");
|
|
690
|
+
console.error(e);
|
|
691
|
+
}
|
|
692
|
+
else console.error("ActiveConnect: Caching / restore not possible as the indexedDB is not accessible");
|
|
693
|
+
} else if (data == "cache_delete") {
|
|
694
|
+
if (_this.dbService) try {
|
|
695
|
+
_this.dbService.deleteByKey("outbound", method).subscribe(() => {});
|
|
696
|
+
} catch (e) {
|
|
697
|
+
console.error("ActiveConnect: Unable to delete cached data");
|
|
698
|
+
console.error(e);
|
|
699
|
+
}
|
|
700
|
+
else console.error("ActiveConnect: Caching / restore not possible as the indexedDB is not accessible");
|
|
701
|
+
target.___received[propertyKey] = false;
|
|
702
|
+
target.___data[propertyKey] = void 0;
|
|
703
|
+
target.loading.set(propertyKey, false);
|
|
704
|
+
bumpTick(target, propertyKey);
|
|
705
|
+
} else if (data == "data_delete") {
|
|
706
|
+
target.___data[propertyKey] = void 0;
|
|
707
|
+
target.loading.set(propertyKey, false);
|
|
708
|
+
target.___received[propertyKey] = false;
|
|
709
|
+
target.___requested[propertyKey] = false;
|
|
710
|
+
bumpTick(target, propertyKey);
|
|
711
|
+
} else if (data == "data_diff") {
|
|
712
|
+
var data = [...target.___data[propertyKey] || []];
|
|
713
|
+
inserted?.forEach((e) => {
|
|
714
|
+
const matching = data.filter((d) => d.id == e.id);
|
|
715
|
+
if (matching.length > 0) data[data.indexOf(matching[0])] = e;
|
|
716
|
+
else data.push(e);
|
|
717
|
+
});
|
|
718
|
+
updated?.forEach((e) => {
|
|
719
|
+
const matching = data.filter((d) => d.id == e.id);
|
|
720
|
+
if (matching.length > 0) data[data.indexOf(matching[0])] = e;
|
|
721
|
+
else data.push(e);
|
|
722
|
+
});
|
|
723
|
+
deleted?.forEach((e) => {
|
|
724
|
+
data = data.filter((d) => d.id != e.id);
|
|
725
|
+
});
|
|
726
|
+
if (sortBy && data) data = data.sort(sortBy);
|
|
727
|
+
target.___data[propertyKey] = data;
|
|
728
|
+
target.loading.set(propertyKey, false);
|
|
729
|
+
bumpTick(target, propertyKey);
|
|
730
|
+
if (cached && specificHash) {
|
|
731
|
+
if (_this.dbService) {
|
|
732
|
+
if (data && data?.length > 0) try {
|
|
733
|
+
_this.dbService.update("outbound", {
|
|
734
|
+
method,
|
|
735
|
+
data,
|
|
736
|
+
specificHash
|
|
737
|
+
}).subscribe(() => {});
|
|
738
|
+
} catch (e) {
|
|
739
|
+
console.error("ActiveConnect: Unable to update cached data");
|
|
740
|
+
console.error(e);
|
|
741
|
+
}
|
|
742
|
+
else try {
|
|
743
|
+
_this.dbService.deleteByKey("outbound", method).subscribe(() => {});
|
|
744
|
+
} catch (e) {
|
|
745
|
+
console.error("ActiveConnect: Unable to delete cached data");
|
|
746
|
+
console.error(e);
|
|
747
|
+
}
|
|
748
|
+
} else console.error("ActiveConnect: Caching not possible as the indexedDB has not been initialized");
|
|
749
|
+
}
|
|
750
|
+
} else {
|
|
751
|
+
if (sortBy && data) data = data.sort(sortBy);
|
|
752
|
+
target.___received[propertyKey] = true;
|
|
753
|
+
target.___data[propertyKey] = data;
|
|
754
|
+
target.loading.set(propertyKey, false);
|
|
755
|
+
bumpTick(target, propertyKey);
|
|
756
|
+
if (cached && specificHash) {
|
|
757
|
+
if (_this.dbService) {
|
|
758
|
+
if (data && data?.length > 0) try {
|
|
759
|
+
_this.dbService.update("outbound", {
|
|
760
|
+
method,
|
|
761
|
+
data,
|
|
762
|
+
specificHash
|
|
763
|
+
}).subscribe(() => {});
|
|
764
|
+
} catch (e) {
|
|
765
|
+
console.error("ActiveConnect: Unable to update cached data");
|
|
766
|
+
console.error(e);
|
|
767
|
+
}
|
|
768
|
+
else try {
|
|
769
|
+
_this.dbService.deleteByKey("outbound", method).subscribe(() => {});
|
|
770
|
+
} catch (e) {
|
|
771
|
+
console.error("ActiveConnect: Unable to update cached data");
|
|
772
|
+
console.error(e);
|
|
773
|
+
}
|
|
774
|
+
} else console.error("ActiveConnect: Caching not possible as the indexedDB has not been initialized");
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
});
|
|
778
|
+
if (requestingRequired) WebsocketClient.addResetRequestingStateCallback(function callback(client) {
|
|
779
|
+
if (target.___requested && target.___requested[propertyKey]) client.send("request." + method, null).then();
|
|
780
|
+
});
|
|
781
|
+
const obj = {
|
|
782
|
+
configurable: true,
|
|
783
|
+
get() {
|
|
784
|
+
readTick(target, propertyKey);
|
|
785
|
+
if (!target.___requested) target.___requested = {};
|
|
786
|
+
if (requestingRequired && !target.___requested[propertyKey]) {
|
|
787
|
+
target.___requested[propertyKey] = true;
|
|
788
|
+
defer(() => this.send("request." + method, null).then());
|
|
789
|
+
}
|
|
790
|
+
if (!target.___data) target.___data = {};
|
|
791
|
+
const loadingMap = target.loading;
|
|
792
|
+
if (!target.___data[propertyKey]) {
|
|
793
|
+
if (loadingMap.peek(propertyKey) !== true) defer(() => loadingMap.set(propertyKey, true));
|
|
794
|
+
} else if (loadingMap.peek(propertyKey)) defer(() => loadingMap.set(propertyKey, false));
|
|
795
|
+
return target.___data[propertyKey];
|
|
796
|
+
},
|
|
797
|
+
set(val) {
|
|
798
|
+
if (!target.___data) target.___data = {};
|
|
799
|
+
target.loading.set(propertyKey, false);
|
|
800
|
+
if (sortBy && val) val = val.sort(sortBy);
|
|
801
|
+
target.___data[propertyKey] = val;
|
|
802
|
+
bumpTick(target, propertyKey);
|
|
803
|
+
return val;
|
|
804
|
+
}
|
|
805
|
+
};
|
|
806
|
+
target[propertyKey] = obj;
|
|
807
|
+
return obj;
|
|
808
|
+
};
|
|
809
|
+
}
|
|
810
|
+
function ensureReactiveLoadingElements(service) {
|
|
811
|
+
if (!isReactiveLoadingElements(service.loadingElements)) try {
|
|
812
|
+
service.loadingElements = createLoadingElements(service.loadingElements);
|
|
813
|
+
} catch {}
|
|
814
|
+
}
|
|
815
|
+
function Route(method, loadingKey, dontEnsureTransmission) {
|
|
816
|
+
return function _Route(target, propertyKey) {
|
|
817
|
+
const original = target[propertyKey];
|
|
818
|
+
target[propertyKey] = async function execRoute(...data) {
|
|
819
|
+
if (loadingKey) {
|
|
820
|
+
ensureReactiveLoadingElements(this);
|
|
821
|
+
if (!this.loadingElements[loadingKey]) this.loadingElements[loadingKey] = 0;
|
|
822
|
+
this.loadingElements[loadingKey]++;
|
|
823
|
+
}
|
|
824
|
+
const promise = original.bind(this)(...data);
|
|
825
|
+
let res = null;
|
|
826
|
+
if (this.client) res = await this.client.send(method, data[0], dontEnsureTransmission)?.catch((err) => {
|
|
827
|
+
if (loadingKey && this.loadingElements[loadingKey]) this.loadingElements[loadingKey]--;
|
|
828
|
+
throw err;
|
|
829
|
+
});
|
|
830
|
+
await promise;
|
|
831
|
+
if (loadingKey && this.loadingElements[loadingKey]) this.loadingElements[loadingKey]--;
|
|
832
|
+
return res;
|
|
833
|
+
};
|
|
834
|
+
return target;
|
|
835
|
+
};
|
|
836
|
+
}
|
|
837
|
+
function Shared(defaultValue) {
|
|
838
|
+
if (defaultValue) throw Error("Active-Connect/@Shared: defaultValue is no longer supported, please assign the value to the variable itself.");
|
|
839
|
+
return function _Shared(target, propertyKey) {};
|
|
840
|
+
}
|
|
841
|
+
var LoadingStatus = class extends WebsocketClient {
|
|
842
|
+
get loadingMap() {
|
|
843
|
+
return ensureLoadingMap(Object.getPrototypeOf(this));
|
|
844
|
+
}
|
|
845
|
+
countLoading() {
|
|
846
|
+
const map = this.loadingMap;
|
|
847
|
+
let count = 0;
|
|
848
|
+
map.forEach((e) => {
|
|
849
|
+
if (e) count++;
|
|
850
|
+
});
|
|
851
|
+
if (count == 0) map.pruneWhenIdle();
|
|
852
|
+
return count;
|
|
853
|
+
}
|
|
854
|
+
get isLoading() {
|
|
855
|
+
return this.countLoading() > 0;
|
|
856
|
+
}
|
|
857
|
+
getLoadingMap() {
|
|
858
|
+
return this.loadingMap;
|
|
859
|
+
}
|
|
860
|
+
get getCurrent() {
|
|
861
|
+
return this.countLoading();
|
|
862
|
+
}
|
|
863
|
+
get getTotal() {
|
|
864
|
+
return this.countLoading() > 0 ? this.loadingMap.size : 0;
|
|
865
|
+
}
|
|
866
|
+
};
|
|
867
|
+
var OutboundObject = class {
|
|
868
|
+
constructor(client, method, lazyLoaded, cached, initialLoadingCount, sortBy) {
|
|
869
|
+
this.client = client;
|
|
870
|
+
this.method = method;
|
|
871
|
+
this.lazyLoaded = lazyLoaded;
|
|
872
|
+
this.cached = cached;
|
|
873
|
+
this.initialLoadingCount = initialLoadingCount;
|
|
874
|
+
this.sortBy = sortBy;
|
|
875
|
+
this.dataMap = /* @__PURE__ */ new Map();
|
|
876
|
+
this._dataSig = signal(void 0, ...ngDevMode ? [{ debugName: "_dataSig" }] : /* istanbul ignore next */ []);
|
|
877
|
+
this.loadScheduled = false;
|
|
878
|
+
this.requested = false;
|
|
879
|
+
this._loadingSig = signal(false, ...ngDevMode ? [{ debugName: "_loadingSig" }] : /* istanbul ignore next */ []);
|
|
880
|
+
this._lengthSig = signal(void 0, ...ngDevMode ? [{ debugName: "_lengthSig" }] : /* istanbul ignore next */ []);
|
|
881
|
+
this.requestedId = null;
|
|
882
|
+
this.requestedIdConnectionId = null;
|
|
883
|
+
this.loadedObservable = null;
|
|
884
|
+
this.loadedId = null;
|
|
885
|
+
this.loadedIdData = null;
|
|
886
|
+
this.loadedIdChanged = null;
|
|
887
|
+
this.requestedGroupId = null;
|
|
888
|
+
this.requestedGroupIdConnectionId = null;
|
|
889
|
+
this.loadedGroupObservable = null;
|
|
890
|
+
this.loadedGroupId = null;
|
|
891
|
+
this.loadedGroupData = null;
|
|
892
|
+
this.loadedGroupChanged = null;
|
|
893
|
+
ensureLoadingMap(this.target);
|
|
894
|
+
if (this.client.dbService) try {
|
|
895
|
+
this.client.dbService.getByKey("outbound", method).subscribe((result) => {
|
|
896
|
+
if (result) this.previouslyCachedCount = result.data?.length || null;
|
|
897
|
+
});
|
|
898
|
+
} catch (e) {
|
|
899
|
+
console.error("ActiveConnect: Unable to read cached data");
|
|
900
|
+
console.error(e);
|
|
901
|
+
}
|
|
902
|
+
const _this = this;
|
|
903
|
+
WebsocketClient.expectOutbound(method, function setOutbound(data, specificHash, insertedOrGroupData, updatedOrGroupId, deleted, length, _client) {
|
|
904
|
+
if (!cached) {
|
|
905
|
+
if (_client.dbService) try {
|
|
906
|
+
_client.dbService.deleteByKey("outbound", method).subscribe(() => {});
|
|
907
|
+
} catch (e) {
|
|
908
|
+
console.error("ActiveConnect: Unable to delete cached data");
|
|
909
|
+
console.error(e);
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
if (data == "cache_restore") {
|
|
913
|
+
if (_client.dbService) try {
|
|
914
|
+
_client.dbService.getByKey("outbound", method).subscribe((result) => {
|
|
915
|
+
_this.setData(result.data);
|
|
916
|
+
if (result.length) _this._length = result.length;
|
|
917
|
+
_this.loading = false;
|
|
918
|
+
});
|
|
919
|
+
} catch (e) {
|
|
920
|
+
console.error("ActiveConnect: Unable to restore cached data");
|
|
921
|
+
console.error(e);
|
|
922
|
+
}
|
|
923
|
+
else console.error("ActiveConnect: Caching / restore not possible as the indexedDB is not accessible");
|
|
924
|
+
} else if (data == "cache_delete") {
|
|
925
|
+
if (_client.dbService) try {
|
|
926
|
+
_client.dbService.deleteByKey("outbound", method).subscribe(() => {});
|
|
927
|
+
} catch (e) {
|
|
928
|
+
console.error("ActiveConnect: Unable to delete cached data");
|
|
929
|
+
console.error(e);
|
|
930
|
+
}
|
|
931
|
+
else console.error("ActiveConnect: Caching / restore not possible as the indexedDB is not accessible");
|
|
932
|
+
_this.loading = false;
|
|
933
|
+
_this.requested = false;
|
|
934
|
+
} else if (data == "data_delete") {
|
|
935
|
+
_this.data = void 0;
|
|
936
|
+
_this.dataMap = /* @__PURE__ */ new Map();
|
|
937
|
+
_this.requested = false;
|
|
938
|
+
_this.loadedGroupData = null;
|
|
939
|
+
_this.loadedGroupId = null;
|
|
940
|
+
_this._length = void 0;
|
|
941
|
+
_this.loading = false;
|
|
942
|
+
} else if (data == "data_group") {
|
|
943
|
+
if (_this.requestedGroupId == (updatedOrGroupId ? updatedOrGroupId[0] : 0)) {
|
|
944
|
+
_this.loadedGroupData = insertedOrGroupData;
|
|
945
|
+
_this.loadedGroupId = updatedOrGroupId ? updatedOrGroupId[0] : 0;
|
|
946
|
+
_this.requestedGroupIdConnectionId = _this.target.___connectionId;
|
|
947
|
+
_this.loadedGroupChanged?.next(insertedOrGroupData);
|
|
948
|
+
_this.loading = false;
|
|
949
|
+
}
|
|
950
|
+
} else if (data == "data_id") {
|
|
951
|
+
if (_this.requestedId == (updatedOrGroupId ? updatedOrGroupId[0] : 0)) {
|
|
952
|
+
_this.loadedIdData = (insertedOrGroupData?.length || 0) > 0 ? insertedOrGroupData[0] : null;
|
|
953
|
+
_this.loadedId = updatedOrGroupId ? updatedOrGroupId[0] : 0;
|
|
954
|
+
_this.requestedIdConnectionId = _this.target.___connectionId;
|
|
955
|
+
_this.loadedIdChanged?.next(_this.loadedIdData);
|
|
956
|
+
_this.loading = false;
|
|
957
|
+
}
|
|
958
|
+
} else if (data == "data_diff") {
|
|
959
|
+
insertedOrGroupData?.forEach((e) => {
|
|
960
|
+
_this.dataMap.set(e.id, e);
|
|
961
|
+
if (e.id == _this.loadedId) _this.loadedIdChanged?.next(e);
|
|
962
|
+
});
|
|
963
|
+
updatedOrGroupId?.forEach((e) => {
|
|
964
|
+
_this.dataMap.set(e.id, e);
|
|
965
|
+
if (e.id == _this.loadedId) _this.loadedIdChanged?.next(e);
|
|
966
|
+
});
|
|
967
|
+
deleted?.forEach((e) => {
|
|
968
|
+
_this.dataMap.delete(e.id);
|
|
969
|
+
if (e.id == _this.loadedId) _this.loadedIdChanged?.next(null);
|
|
970
|
+
});
|
|
971
|
+
_this.data = Array.from(_this.dataMap.values());
|
|
972
|
+
if (_this.data && _this.sortBy) _this.data = _this.data.sort(_this.sortBy);
|
|
973
|
+
_this.loading = false;
|
|
974
|
+
if (cached && specificHash) {
|
|
975
|
+
if (_client.dbService) try {
|
|
976
|
+
if (_this.data && _this.data?.length > 0) _client.dbService.update("outbound", {
|
|
977
|
+
method,
|
|
978
|
+
data: _this.data,
|
|
979
|
+
specificHash,
|
|
980
|
+
length
|
|
981
|
+
}).subscribe(() => {});
|
|
982
|
+
else _client.dbService.deleteByKey("outbound", method).subscribe(() => {});
|
|
983
|
+
} catch (e) {
|
|
984
|
+
console.error("ActiveConnect: Unable to update cached data.");
|
|
985
|
+
console.error(e);
|
|
986
|
+
}
|
|
987
|
+
else console.error("ActiveConnect: Caching not possible as the indexedDB has not been initialized");
|
|
988
|
+
}
|
|
989
|
+
} else {
|
|
990
|
+
_this.setData(data);
|
|
991
|
+
if (_this.loadedId) {
|
|
992
|
+
const loadedValue = _this.dataMap.get(_this.loadedId);
|
|
993
|
+
if (loadedValue) {
|
|
994
|
+
_this.loadedIdData = loadedValue;
|
|
995
|
+
_this.loadedIdChanged?.next(_this.loadedIdData);
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
_this.loading = false;
|
|
999
|
+
if (cached && specificHash) {
|
|
1000
|
+
if (_client.dbService) try {
|
|
1001
|
+
if (data && data?.length > 0) _client.dbService.update("outbound", {
|
|
1002
|
+
method,
|
|
1003
|
+
data,
|
|
1004
|
+
specificHash,
|
|
1005
|
+
length
|
|
1006
|
+
}).subscribe(() => {});
|
|
1007
|
+
else _client.dbService.deleteByKey("outbound", method).subscribe(() => {});
|
|
1008
|
+
} catch (e) {
|
|
1009
|
+
console.error("ActiveConnect: Unable to update cached data.");
|
|
1010
|
+
console.error(e);
|
|
1011
|
+
}
|
|
1012
|
+
else console.error("ActiveConnect: Caching not possible as the indexedDB has not been initialized");
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
if (length) _this._length = length;
|
|
1016
|
+
});
|
|
1017
|
+
WebsocketClient.addResetRequestingStateCallback(() => {
|
|
1018
|
+
this.afterServerReconnected();
|
|
1019
|
+
});
|
|
1020
|
+
}
|
|
1021
|
+
get target() {
|
|
1022
|
+
return this.client.__proto__;
|
|
1023
|
+
}
|
|
1024
|
+
get data() {
|
|
1025
|
+
return untracked(this._dataSig);
|
|
1026
|
+
}
|
|
1027
|
+
set data(value) {
|
|
1028
|
+
this._dataSig.set(value);
|
|
1029
|
+
}
|
|
1030
|
+
get(id) {
|
|
1031
|
+
if (this.requestedId == id && this.target.___connectionId == this.requestedIdConnectionId && this.loadedObservable && this.loadedIdData) {
|
|
1032
|
+
if (this.loadedIdData) setTimeout(() => {
|
|
1033
|
+
if (this.loadedIdData) this.loadedIdChanged?.next(this.loadedIdData);
|
|
1034
|
+
}, 50);
|
|
1035
|
+
return this.loadedObservable;
|
|
1036
|
+
}
|
|
1037
|
+
let observablePromise;
|
|
1038
|
+
if (this.requestedId != id || this.target.___connectionId != this.requestedIdConnectionId || !this.loadedObservable) observablePromise = new Promise((resolve) => {
|
|
1039
|
+
this.loadedObservable = new Observable((observer) => {
|
|
1040
|
+
this.loadedIdChanged = observer;
|
|
1041
|
+
resolve();
|
|
1042
|
+
});
|
|
1043
|
+
});
|
|
1044
|
+
Promise.all([observablePromise]).then(() => {
|
|
1045
|
+
new Promise(async (resolve) => {
|
|
1046
|
+
if (!this.requested && this.lazyLoaded) this.load().then();
|
|
1047
|
+
if (this.data) {
|
|
1048
|
+
const res = this.dataMap.get(id);
|
|
1049
|
+
if (res) {
|
|
1050
|
+
this.loadedIdChanged?.next(res);
|
|
1051
|
+
resolve();
|
|
1052
|
+
return;
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
if (this.loadedId == id) this.loadedIdChanged?.next(this.loadedIdData);
|
|
1056
|
+
else await this.requestById(id);
|
|
1057
|
+
resolve();
|
|
1058
|
+
}).then();
|
|
1059
|
+
});
|
|
1060
|
+
return this.loadedObservable;
|
|
1061
|
+
}
|
|
1062
|
+
getForGroup(groupId) {
|
|
1063
|
+
if (this.requestedGroupId == groupId && this.target.___connectionId == this.requestedGroupIdConnectionId && this.loadedGroupObservable && this.loadedGroupData) {
|
|
1064
|
+
setTimeout(() => {
|
|
1065
|
+
if (this.loadedGroupData) this.loadedGroupChanged?.next(this.loadedGroupData);
|
|
1066
|
+
}, 50);
|
|
1067
|
+
return this.loadedGroupObservable;
|
|
1068
|
+
}
|
|
1069
|
+
let observablePromise;
|
|
1070
|
+
if (this.requestedGroupId != groupId || this.target.___connectionId != this.requestedGroupIdConnectionId || !this.loadedGroupObservable) observablePromise = new Promise((resolve) => {
|
|
1071
|
+
this.loadedGroupObservable = new Observable((observer) => {
|
|
1072
|
+
this.loadedGroupChanged = observer;
|
|
1073
|
+
resolve();
|
|
1074
|
+
});
|
|
1075
|
+
});
|
|
1076
|
+
Promise.all([observablePromise]).then(() => {
|
|
1077
|
+
new Promise(async (resolve) => {
|
|
1078
|
+
if (!this.requested && this.lazyLoaded) this.load().then();
|
|
1079
|
+
if (this.loadedGroupId == groupId && this.loadedGroupData) this.loadedGroupChanged?.next(this.loadedGroupData);
|
|
1080
|
+
else await this.requestForGroup(groupId);
|
|
1081
|
+
resolve();
|
|
1082
|
+
}).then();
|
|
1083
|
+
});
|
|
1084
|
+
return this.loadedGroupObservable;
|
|
1085
|
+
}
|
|
1086
|
+
get all() {
|
|
1087
|
+
this.ensureLoaded();
|
|
1088
|
+
return this._dataSig();
|
|
1089
|
+
}
|
|
1090
|
+
ensureLoaded() {
|
|
1091
|
+
if (this.requested || !this.lazyLoaded || this.loadScheduled) return;
|
|
1092
|
+
this.loadScheduled = true;
|
|
1093
|
+
defer(() => {
|
|
1094
|
+
this.loadScheduled = false;
|
|
1095
|
+
if (!this.requested) this.load().catch((e) => console.error("ActiveConnect: lazy load failed", e));
|
|
1096
|
+
});
|
|
1097
|
+
}
|
|
1098
|
+
async load(count) {
|
|
1099
|
+
if (this.lazyLoaded) {
|
|
1100
|
+
const hasBeenRequestedBefore = this.requested;
|
|
1101
|
+
this._loading = true;
|
|
1102
|
+
if (!this.requested) this.loading = true;
|
|
1103
|
+
this.requested = true;
|
|
1104
|
+
await this.client.send("request." + this.method, {
|
|
1105
|
+
count: hasBeenRequestedBefore ? this.data ? count || this.initialLoadingCount ? (count || this.initialLoadingCount) + this.loadedLength : void 0 : void 0 : this.previouslyCachedCount || this.initialLoadingCount,
|
|
1106
|
+
loaded: this.loadedLength
|
|
1107
|
+
});
|
|
1108
|
+
} else throw Error("Active-Connect: Cannot run loading request as this outbound is not lazy-loaded.");
|
|
1109
|
+
}
|
|
1110
|
+
get _loading() {
|
|
1111
|
+
return untracked(this._loadingSig);
|
|
1112
|
+
}
|
|
1113
|
+
set _loading(value) {
|
|
1114
|
+
this._loadingSig.set(value);
|
|
1115
|
+
}
|
|
1116
|
+
set loading(value) {
|
|
1117
|
+
this._loading = value;
|
|
1118
|
+
this.target.loading.set(this.method, value);
|
|
1119
|
+
}
|
|
1120
|
+
get loading() {
|
|
1121
|
+
return this._loadingSig();
|
|
1122
|
+
}
|
|
1123
|
+
get loadedLength() {
|
|
1124
|
+
return this._dataSig()?.length || 0;
|
|
1125
|
+
}
|
|
1126
|
+
get _length() {
|
|
1127
|
+
return untracked(this._lengthSig);
|
|
1128
|
+
}
|
|
1129
|
+
set _length(value) {
|
|
1130
|
+
this._lengthSig.set(value);
|
|
1131
|
+
}
|
|
1132
|
+
get length() {
|
|
1133
|
+
return this._lengthSig();
|
|
1134
|
+
}
|
|
1135
|
+
requestById(id) {
|
|
1136
|
+
this.loading = true;
|
|
1137
|
+
this.requestedId = id;
|
|
1138
|
+
return this.client.send("request." + this.method, { id });
|
|
1139
|
+
}
|
|
1140
|
+
requestForGroup(groupId) {
|
|
1141
|
+
this.loading = true;
|
|
1142
|
+
this.requestedGroupId = groupId;
|
|
1143
|
+
return this.client.send("request." + this.method, { groupId });
|
|
1144
|
+
}
|
|
1145
|
+
setData(data) {
|
|
1146
|
+
const incoming = data;
|
|
1147
|
+
if (this.sortBy) incoming.sort(this.sortBy);
|
|
1148
|
+
const next = [...incoming];
|
|
1149
|
+
this._length = next.length;
|
|
1150
|
+
this.dataMap = /* @__PURE__ */ new Map();
|
|
1151
|
+
next.forEach((d) => {
|
|
1152
|
+
this.dataMap.set(d.id, d);
|
|
1153
|
+
});
|
|
1154
|
+
this.data = next;
|
|
1155
|
+
}
|
|
1156
|
+
get isEmpty() {
|
|
1157
|
+
return this._dataSig() == void 0;
|
|
1158
|
+
}
|
|
1159
|
+
update(callback) {
|
|
1160
|
+
if (this.data) {
|
|
1161
|
+
const updateLengthVariable = this.data.length == this._length;
|
|
1162
|
+
const length = this._length;
|
|
1163
|
+
const copy = [...this.data];
|
|
1164
|
+
callback(copy);
|
|
1165
|
+
this.setData(copy);
|
|
1166
|
+
if (!updateLengthVariable) this._length = length;
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
afterServerReconnected() {
|
|
1170
|
+
if (this.requested && this.lazyLoaded) {
|
|
1171
|
+
this.requested = false;
|
|
1172
|
+
this.load(this.loadedLength).then();
|
|
1173
|
+
}
|
|
1174
|
+
if (this.loadedId) {
|
|
1175
|
+
this.loadedIdData = null;
|
|
1176
|
+
this.requestById(this.loadedId).catch(() => {});
|
|
1177
|
+
}
|
|
1178
|
+
if (this.loadedGroupId) {
|
|
1179
|
+
this.loadedGroupData = null;
|
|
1180
|
+
this.requestForGroup(this.loadedGroupId).catch(() => {});
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
};
|
|
1184
|
+
export { ActiveConnectNg2Module, Handle, LoadingStatus, NgxIndexedDBService, OnReconnect, OnSuccess, Outbound, OutboundObject, ReactiveLoadingMap, Route, Shared, WebsocketClient, bumpTick, createLoadingElements, defer, ensureLoadingMap, isReactiveLoadingElements, readTick };
|
|
1185
|
+
|
|
1186
|
+
//# sourceMappingURL=active-connect-ng2.mjs.map
|