@subiz/widget-v4 4.1.210 → 4.1.212
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/README.md +21 -2
- package/assets/img/dot_chat.svg +3 -0
- package/assets/less/chatbox.less +9 -0
- package/assets/less/form.less +10 -0
- package/assets/less/message.less +114 -13
- package/assets/less/widget.less +15 -18
- package/compiled_src/call/css.js +1 -1
- package/compiled_src/chatbox/Buttons.js +7 -4
- package/compiled_src/chatbox/ChatButton.js +127 -29
- package/compiled_src/chatbox/Event.js +37 -5
- package/compiled_src/chatbox/Events.js +348 -129
- package/compiled_src/chatbox/FormAttachment.js +1 -1
- package/compiled_src/chatbox/Header.js +7 -2
- package/compiled_src/chatbox/InfoMessage.js +1 -1
- package/compiled_src/chatbox/MessageInput.js +24 -9
- package/compiled_src/chatbox/OrderAttachments.js +13 -13
- package/compiled_src/chatbox/QuoteMessage.js +3 -2
- package/compiled_src/chatbox/TextMessage.js +22 -18
- package/compiled_src/chatbox/Widget.js +200 -129
- package/compiled_src/chatbox/block.js +39 -29
- package/compiled_src/chatbox/conversation-history.js +44 -0
- package/compiled_src/chatbox/event-layout.js +59 -0
- package/compiled_src/chatbox/greeting.js +32 -0
- package/compiled_src/chatbox/main.js +3 -0
- package/compiled_src/common.js +13 -9
- package/compiled_src/form/css.js +1 -1
- package/compiled_src/lib.js +22 -32
- package/compiled_src/notif/css.js +1 -1
- package/compiled_src/plugin.js +11 -18
- package/compiled_src/popup/css.js +1 -1
- package/compiled_src/popup/popup.js +1 -1
- package/compiled_src/store/api.js +0 -2
- package/compiled_src/store/api_fake.js +1 -1
- package/compiled_src/store/attachments.js +28 -0
- package/compiled_src/store/chain.js +24 -10
- package/compiled_src/store/kv.js +9 -13
- package/compiled_src/store/lsdb.js +1 -1
- package/compiled_src/store/store.js +356 -117
- package/compiled_src/util/common.js +48 -41
- package/compiled_src/util/event.js +15 -0
- package/compiled_src/util/pubsub.js +28 -13
- package/compiled_src/util/url.js +18 -0
- package/dist/127.js +13 -13
- package/dist/132.js +1 -1
- package/dist/1a0f6f3ff1a.127.js +1 -0
- package/dist/{1a0d80f6e72.132.js → 1a0f6f3ff1a.132.js} +1 -1
- package/dist/{1a0d80f6e72.27.js → 1a0f6f3ff1a.27.js} +1 -1
- package/dist/1a0f6f3ff1a.278.js +1 -0
- package/dist/{1a0d80f6e72.339.js → 1a0f6f3ff1a.339.js} +1 -1
- package/dist/1a0f6f3ff1a.459.js +1 -0
- package/dist/1a0f6f3ff1a.app.js +1 -0
- package/dist/{1a0d80f6e72.chat.html → 1a0f6f3ff1a.chat.html} +1 -1
- package/dist/1a0f6f3ff1a.chat.js +1 -0
- package/dist/{1a0d80f6e72.form.html → 1a0f6f3ff1a.form.html} +1 -1
- package/dist/1a0f6f3ff1a.form.js +1 -0
- package/dist/{1a0d80f6e72.index.html → 1a0f6f3ff1a.index.html} +1 -1
- package/dist/{1a0d80f6e72.library.html → 1a0f6f3ff1a.library.html} +1 -1
- package/dist/1a0f6f3ff1a.library.js +1 -0
- package/dist/{1a0d80f6e72.preview.html → 1a0f6f3ff1a.preview.html} +1 -1
- package/dist/1a0f6f3ff1a.preview.js +1 -0
- package/dist/1a0f6f3ff1a.webview.js +1 -0
- package/dist/27.js +2 -2
- package/dist/459.js +2 -2
- package/dist/HASH +1 -1
- package/dist/assets/img/dot_chat.335fd8a.svg +3 -0
- package/dist/screenshoot.js +1523 -619
- package/package.json +12 -5
- package/src/chatbox/Buttons.js +5 -4
- package/src/chatbox/ChatButton.js +133 -39
- package/src/chatbox/Event.js +38 -5
- package/src/chatbox/Events.js +306 -134
- package/src/chatbox/FormAttachment.js +1 -1
- package/src/chatbox/Header.js +5 -4
- package/src/chatbox/InfoMessage.js +1 -1
- package/src/chatbox/MessageInput.js +15 -10
- package/src/chatbox/OrderAttachments.js +13 -13
- package/src/chatbox/QuoteMessage.js +3 -2
- package/src/chatbox/TextMessage.js +21 -20
- package/src/chatbox/Widget.js +150 -150
- package/src/chatbox/block.js +29 -27
- package/src/chatbox/conversation-history.js +37 -0
- package/src/chatbox/event-layout.js +72 -0
- package/src/chatbox/greeting.js +13 -0
- package/src/chatbox/main.js +3 -0
- package/src/common.js +15 -9
- package/src/lib.js +22 -35
- package/src/plugin.js +11 -13
- package/src/popup/popup.js +1 -1
- package/src/store/api.js +0 -2
- package/src/store/api_fake.js +1 -1
- package/src/store/attachments.js +21 -0
- package/src/store/chain.js +25 -12
- package/src/store/kv.js +10 -19
- package/src/store/lsdb.js +1 -1
- package/src/store/store.js +313 -130
- package/src/util/common.js +48 -43
- package/src/util/event.js +7 -0
- package/src/util/pubsub.js +27 -8
- package/src/util/url.js +14 -0
- package/test.cjs +59 -0
- package/assets/less/contact.less +0 -126
- package/compiled_src/util/common.test.js +0 -414
- package/compiled_src/util/event.test.js +0 -38
- package/compiled_src/util/extractor.test.js +0 -299
- package/compiled_src/util/extractor.test2.js +0 -61
- package/compiled_src/util/gate.test.js +0 -18
- package/compiled_src/util/pubsub.test.js +0 -35
- package/dist/1a0d80f6e72.127.js +0 -1
- package/dist/1a0d80f6e72.278.js +0 -1
- package/dist/1a0d80f6e72.459.js +0 -1
- package/dist/1a0d80f6e72.74.js +0 -1
- package/dist/1a0d80f6e72.997.js +0 -1
- package/dist/1a0d80f6e72.app.js +0 -1
- package/dist/1a0d80f6e72.chat.js +0 -1
- package/dist/1a0d80f6e72.form.js +0 -1
- package/dist/1a0d80f6e72.library.js +0 -1
- package/dist/1a0d80f6e72.preview.js +0 -1
- package/dist/1a0d80f6e72.webview.js +0 -1
- package/dist/74.js +0 -376
- package/dist/997.js +0 -37
- package/src/contact/contact.js +0 -400
- package/src/contact/css.js +0 -1
- package/src/util/common.test.js +0 -301
- package/src/util/event.test.js +0 -31
- package/src/util/extractor.test.js +0 -240
- package/src/util/extractor.test2.js +0 -56
- package/src/util/gate.test.js +0 -20
- package/src/util/pubsub.test.js +0 -37
- /package/dist/{1a0d80f6e72.185.js → 1a0f6f3ff1a.185.js} +0 -0
- /package/dist/{1a0d80f6e72.490.js → 1a0f6f3ff1a.490.js} +0 -0
|
@@ -11,6 +11,7 @@ var _chain = _interopRequireDefault(require("./chain.js"));
|
|
|
11
11
|
var _kv = _interopRequireDefault(require("./kv.js"));
|
|
12
12
|
var _api_fake = _interopRequireDefault(require("./api_fake.js"));
|
|
13
13
|
var _realtime_fake = _interopRequireDefault(require("./realtime_fake.js"));
|
|
14
|
+
var _attachments = require("./attachments.js");
|
|
14
15
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
15
16
|
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
16
17
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
@@ -24,7 +25,6 @@ cookie.defaults.expires = 3650;
|
|
|
24
25
|
let memlocalStorage = require('./inmem_localstorage.js');
|
|
25
26
|
const MAX_CONVO = 20;
|
|
26
27
|
const page_loaded = _index.default.Date.now();
|
|
27
|
-
const DEBUG_ACCOUNT_IDS = ['acqsulrowbxiugvginhw', 'acryguzgwxmamhzmqlyx'];
|
|
28
28
|
class Store {
|
|
29
29
|
constructor(ApiURL, FileURL, RealtimeURL, inmem, fakeapi) {
|
|
30
30
|
_defineProperty(this, "inmem", false);
|
|
@@ -95,14 +95,23 @@ class Store {
|
|
|
95
95
|
if (this._die) return dieErr;
|
|
96
96
|
await this.readyGate.entry();
|
|
97
97
|
await this.reconnectGate.entry(undefined, true);
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
98
|
+
try {
|
|
99
|
+
if (this._die || this.isInsync(cid)) return;
|
|
100
|
+
this.convoFetchAfter = this.convoFetchAfter || {};
|
|
101
|
+
if (_index.default.Date.now() < (this.convoFetchAfter[cid] || 0)) return;
|
|
102
|
+
this.convoFetchAfter[cid] = _index.default.Date.now() + 15_000;
|
|
103
|
+
let {
|
|
104
|
+
body: convo,
|
|
105
|
+
error
|
|
106
|
+
} = await this.api.getConversation(cid);
|
|
107
|
+
if (convo && !error) this._setConvo(convo);
|
|
108
|
+
} catch (error) {
|
|
109
|
+
return {
|
|
110
|
+
error
|
|
111
|
+
};
|
|
112
|
+
} finally {
|
|
113
|
+
this.reconnectGate.open();
|
|
114
|
+
}
|
|
106
115
|
});
|
|
107
116
|
_defineProperty(this, "list_provinces", () => this.api.list_provinces());
|
|
108
117
|
_defineProperty(this, "list_districts", p => this.api.list_districts(p));
|
|
@@ -113,25 +122,48 @@ class Store {
|
|
|
113
122
|
if (id.startsWith('cslight')) return _index.default.get(this.lightConvos, [id, 'events'], []);
|
|
114
123
|
return this.chain.listM(id);
|
|
115
124
|
});
|
|
116
|
-
_defineProperty(this, "fetchMoreEvents",
|
|
117
|
-
|
|
118
|
-
if (
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
+
_defineProperty(this, "fetchMoreEvents", (cid, limit = 150) => {
|
|
126
|
+
this.historyRequests = this.historyRequests || new Map();
|
|
127
|
+
if (this.historyRequests.has(cid)) return this.historyRequests.get(cid);
|
|
128
|
+
this.historyFailures = this.historyFailures || {};
|
|
129
|
+
const failure = this.historyFailures[cid];
|
|
130
|
+
if (failure && _index.default.Date.now() < failure.retryAt) return Promise.resolve({
|
|
131
|
+
error: failure.error
|
|
132
|
+
});
|
|
133
|
+
const request = this._fetchMoreEvents(cid, limit).then(result => {
|
|
134
|
+
if (result.error) this.historyFailures[cid] = {
|
|
135
|
+
error: result.error,
|
|
136
|
+
retryAt: _index.default.Date.now() + 15_000
|
|
137
|
+
};else delete this.historyFailures[cid];
|
|
138
|
+
return result;
|
|
139
|
+
}).finally(() => {
|
|
140
|
+
if (this.historyRequests.get(cid) === request) this.historyRequests.delete(cid);
|
|
141
|
+
});
|
|
142
|
+
this.historyRequests.set(cid, request);
|
|
143
|
+
return request;
|
|
144
|
+
});
|
|
145
|
+
_defineProperty(this, "syncConvoEvents", cid => {
|
|
146
|
+
if (this._die || !cid || cid.startsWith('cslight')) return Promise.resolve({});
|
|
147
|
+
this.messageSyncRequests = this.messageSyncRequests || new Map();
|
|
148
|
+
if (this.messageSyncRequests.has(cid)) return this.messageSyncRequests.get(cid);
|
|
149
|
+
this.messageSyncNextAt = this.messageSyncNextAt || {};
|
|
150
|
+
if (_index.default.Date.now() < (this.messageSyncNextAt[cid] || 0)) return Promise.resolve({
|
|
151
|
+
skipped: true
|
|
152
|
+
});
|
|
153
|
+
const chain = this.chain;
|
|
154
|
+
const request = this._syncConvoEvents(cid, chain).then(result => {
|
|
155
|
+
if (chain === this.chain && !this._die) {
|
|
156
|
+
this.messageSyncFailures = this.messageSyncFailures || {};
|
|
157
|
+
const failures = result.error ? Math.min((this.messageSyncFailures[cid] || 0) + 1, 4) : 0;
|
|
158
|
+
this.messageSyncFailures[cid] = failures;
|
|
159
|
+
this.messageSyncNextAt[cid] = _index.default.Date.now() + (failures ? 15_000 * 2 ** (failures - 1) : 15_000);
|
|
125
160
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
return out;
|
|
133
|
-
}
|
|
134
|
-
return this._doFetchMsg(convoid);
|
|
161
|
+
return result;
|
|
162
|
+
}).finally(() => {
|
|
163
|
+
if (this.messageSyncRequests.get(cid) === request) this.messageSyncRequests.delete(cid);
|
|
164
|
+
});
|
|
165
|
+
this.messageSyncRequests.set(cid, request);
|
|
166
|
+
return request;
|
|
135
167
|
});
|
|
136
168
|
_defineProperty(this, "reloadConvoEvents", async convoid => {
|
|
137
169
|
await this.chain.reload(convoid, () => {
|
|
@@ -148,10 +180,10 @@ class Store {
|
|
|
148
180
|
error
|
|
149
181
|
};
|
|
150
182
|
});
|
|
151
|
-
_defineProperty(this, "_doFetchMsg", async convoid => {
|
|
183
|
+
_defineProperty(this, "_doFetchMsg", async (convoid, limit = 150) => {
|
|
152
184
|
let {
|
|
153
185
|
error
|
|
154
|
-
} = await this.chain.fetchMore(convoid,
|
|
186
|
+
} = await this.chain.fetchMore(convoid, limit, async (type, anchor, limit) => {
|
|
155
187
|
if (this.outofmsgM[convoid]) return [[], ''];
|
|
156
188
|
let [events, newanchor, error, outofmsg] = await this.listmessageapi(type, anchor, limit);
|
|
157
189
|
if (outofmsg) this.outofmsgM[convoid] = true;
|
|
@@ -190,17 +222,6 @@ class Store {
|
|
|
190
222
|
_defineProperty(this, "now", () => _index.default.Date.now() + this.timeDiff);
|
|
191
223
|
_defineProperty(this, "seenQueue", []);
|
|
192
224
|
_defineProperty(this, "matchTrafficSource", () => this.kv.match('traffic_source'));
|
|
193
|
-
_defineProperty(this, "sendBugReport", str => this.api.sendBugReport(str));
|
|
194
|
-
_defineProperty(this, "matchDebugAccountIds", () => DEBUG_ACCOUNT_IDS);
|
|
195
|
-
_defineProperty(this, "sbzListConversations", () => {
|
|
196
|
-
return this.api.listConversations();
|
|
197
|
-
});
|
|
198
|
-
_defineProperty(this, "sbzListMessages", cid => {
|
|
199
|
-
return this.api.listMessages(cid, 100, '');
|
|
200
|
-
});
|
|
201
|
-
_defineProperty(this, "listAgentRealtimeMessageSent", () => {
|
|
202
|
-
return this.agent_rt_message_sent_dict;
|
|
203
|
-
});
|
|
204
225
|
_defineProperty(this, "_alreadyReceived", {});
|
|
205
226
|
_defineProperty(this, "_typing", _index.default.throttle(convoid => this.api.sendTyping(convoid), 3000, {
|
|
206
227
|
trailing: false
|
|
@@ -236,7 +257,6 @@ class Store {
|
|
|
236
257
|
this.CONNECTION_CHECK_INTERVAL = 3000;
|
|
237
258
|
this.reconnectTimestamp = 0;
|
|
238
259
|
this.g_sync = {};
|
|
239
|
-
this.agent_rt_message_sent_dict = {};
|
|
240
260
|
this._die = false;
|
|
241
261
|
this.forceDevice = null;
|
|
242
262
|
this.forcePlugins = {};
|
|
@@ -268,15 +288,22 @@ class Store {
|
|
|
268
288
|
this.getLocaleContent = this.api.getLocaleContent;
|
|
269
289
|
this.g_haveSentSeenM = {};
|
|
270
290
|
this.last_focused = this.now();
|
|
271
|
-
|
|
291
|
+
this._onBlur = () => {
|
|
292
|
+
if (this._die) return;
|
|
272
293
|
this.last_focused = this.now();
|
|
273
294
|
this.sendPresence();
|
|
274
|
-
}
|
|
275
|
-
|
|
295
|
+
};
|
|
296
|
+
this._onFocus = () => {
|
|
297
|
+
if (this._die) return;
|
|
276
298
|
this.last_focused = 0;
|
|
277
299
|
this.sendPresence();
|
|
278
|
-
}
|
|
279
|
-
|
|
300
|
+
};
|
|
301
|
+
this._onBeforeUnload = () => {
|
|
302
|
+
if (!this._die) this.api.sendLostFocus();
|
|
303
|
+
};
|
|
304
|
+
window.addEventListener('blur', this._onBlur);
|
|
305
|
+
window.addEventListener('focus', this._onFocus);
|
|
306
|
+
window.addEventListener('beforeunload', this._onBeforeUnload);
|
|
280
307
|
this._lastPresenceURL = window.location.href;
|
|
281
308
|
this._urlCheckInterval = _index.default.setInterval(() => {
|
|
282
309
|
if (this._die) return _index.default.clearInterval(this._urlCheckInterval);
|
|
@@ -303,19 +330,20 @@ class Store {
|
|
|
303
330
|
}
|
|
304
331
|
this.sendPresence();
|
|
305
332
|
}, 60000);
|
|
306
|
-
onVisibilityChange(val => {
|
|
333
|
+
this._visibilityCleanup = onVisibilityChange(val => {
|
|
307
334
|
if (this._die) return;
|
|
308
335
|
this.browserVisibility = val;
|
|
309
336
|
this.sendPresence();
|
|
310
337
|
});
|
|
311
338
|
this.loopTime();
|
|
312
339
|
this.device = this.getDeviceInfo();
|
|
313
|
-
|
|
340
|
+
this._gaInterval = _index.default.setInterval(() => {
|
|
341
|
+
if (this._die) return;
|
|
314
342
|
let user = this.cache.match('user') || {};
|
|
315
343
|
if (!user.id) return;
|
|
316
344
|
var dev = this.getDeviceInfo();
|
|
317
345
|
if (!dev.ga_tracking_ids || !dev.ga_client_id) return;
|
|
318
|
-
_index.default.clearInterval(_gaInterval);
|
|
346
|
+
_index.default.clearInterval(this._gaInterval);
|
|
319
347
|
this.device = dev;
|
|
320
348
|
let ga_client_id = dev.ga_client_id;
|
|
321
349
|
if (ga_client_id !== _index.default.getUserAttr(user, 'ga_client_id', 'text')) {
|
|
@@ -343,8 +371,28 @@ class Store {
|
|
|
343
371
|
console.log('publish connectionStatus', this.connectionStatus);
|
|
344
372
|
this.pubsub.publish('connection');
|
|
345
373
|
}
|
|
374
|
+
if (this.connectionStatus === 'active' && (this._needsMessageSync || currentStatus !== 'active')) {
|
|
375
|
+
this._needsMessageSync = false;
|
|
376
|
+
this.syncKnownConvoEvents();
|
|
377
|
+
}
|
|
346
378
|
}
|
|
347
379
|
}
|
|
380
|
+
syncKnownConvoEvents() {
|
|
381
|
+
if (this._die) return Promise.resolve();
|
|
382
|
+
if (this.knownConvoSyncRequest) return this.knownConvoSyncRequest;
|
|
383
|
+
const chain = this.chain;
|
|
384
|
+
const request = (async () => {
|
|
385
|
+
const convos = _index.default.filter(this.cache.all(), (value, key) => key.startsWith('convo_'));
|
|
386
|
+
for (const convo of convos) {
|
|
387
|
+
if (this._die || chain !== this.chain) break;
|
|
388
|
+
await this.syncConvoEvents(convo.id);
|
|
389
|
+
}
|
|
390
|
+
})().finally(() => {
|
|
391
|
+
if (this.knownConvoSyncRequest === request) this.knownConvoSyncRequest = null;
|
|
392
|
+
});
|
|
393
|
+
this.knownConvoSyncRequest = request;
|
|
394
|
+
return request;
|
|
395
|
+
}
|
|
348
396
|
linkProduct(p) {
|
|
349
397
|
if (!p) {
|
|
350
398
|
this._currentViewingProduct = {};
|
|
@@ -488,7 +536,90 @@ class Store {
|
|
|
488
536
|
async _touchAcc() {
|
|
489
537
|
if (this.isInsync('account')) return;
|
|
490
538
|
await this.readyGate.entry();
|
|
491
|
-
if (!this.isInsync('account')) this.
|
|
539
|
+
if (!this.isInsync('account')) this.refreshAccount();
|
|
540
|
+
}
|
|
541
|
+
refreshAccount() {
|
|
542
|
+
if (this._die || _index.default.Date.now() < (this.accountRefreshAfter || 0)) return;
|
|
543
|
+
this.accountRefreshAfter = _index.default.Date.now() + 30_000;
|
|
544
|
+
return this.reconnect();
|
|
545
|
+
}
|
|
546
|
+
async _fetchMoreEvents(convoid, limit = 150) {
|
|
547
|
+
if (!convoid || convoid.startsWith('cslight')) return {};
|
|
548
|
+
await this.readyGate.entry();
|
|
549
|
+
await this.reconnectGate.entry(undefined, true);
|
|
550
|
+
try {
|
|
551
|
+
if (this._die) return dieErr;
|
|
552
|
+
const refresh = !this.isInsync('events' + convoid);
|
|
553
|
+
if (refresh) {
|
|
554
|
+
this.chain.anchorCache[convoid] = '';
|
|
555
|
+
delete this.outofmsgM[convoid];
|
|
556
|
+
}
|
|
557
|
+
const out = await this._doFetchMsg(convoid, limit);
|
|
558
|
+
if (!out.error) this.markSync('events' + convoid);
|
|
559
|
+
return out;
|
|
560
|
+
} catch (error) {
|
|
561
|
+
return {
|
|
562
|
+
error
|
|
563
|
+
};
|
|
564
|
+
} finally {
|
|
565
|
+
this.reconnectGate.open();
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
async _syncConvoEvents(cid, chain) {
|
|
569
|
+
await this.readyGate.entry();
|
|
570
|
+
await this.reconnectGate.entry(undefined, true);
|
|
571
|
+
try {
|
|
572
|
+
if (this._die || chain !== this.chain) return dieErr;
|
|
573
|
+
this.messageSyncTimes = this.messageSyncTimes || {};
|
|
574
|
+
this.messageSyncProgress = this.messageSyncProgress || {};
|
|
575
|
+
let progress = this.messageSyncProgress[cid];
|
|
576
|
+
if (!progress) {
|
|
577
|
+
const cached = Object.values(chain.listM(cid));
|
|
578
|
+
const boundary = this.messageSyncTimes[cid] || cached.reduce((min, ev) => Math.min(min, _index.default.getMs(ev.created)), Infinity);
|
|
579
|
+
progress = this.messageSyncProgress[cid] = {
|
|
580
|
+
boundary,
|
|
581
|
+
anchor: '',
|
|
582
|
+
newest: 0,
|
|
583
|
+
visited: new Set()
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
for (let page = 0; page < 5; page++) {
|
|
587
|
+
const wait = (this.nextMessageSyncRequestAt || 0) - _index.default.Date.now();
|
|
588
|
+
if (wait > 0) await _index.default.sleep(wait);
|
|
589
|
+
if (this._die || chain !== this.chain) return dieErr;
|
|
590
|
+
this.nextMessageSyncRequestAt = _index.default.Date.now() + 250;
|
|
591
|
+
const [items, next, error, end] = await this.listmessageapi(cid, progress.anchor, 150);
|
|
592
|
+
if (this._die || chain !== this.chain) return dieErr;
|
|
593
|
+
if (error) return {
|
|
594
|
+
error
|
|
595
|
+
};
|
|
596
|
+
chain.merge(cid, items);
|
|
597
|
+
for (const item of items) progress.newest = Math.max(progress.newest, item.index);
|
|
598
|
+
this.pubsub.publish('account');
|
|
599
|
+
if (end || !items.length || items.some(item => item.index < progress.boundary)) {
|
|
600
|
+
if (progress.newest) this.messageSyncTimes[cid] = progress.newest;
|
|
601
|
+
delete this.messageSyncProgress[cid];
|
|
602
|
+
return {};
|
|
603
|
+
}
|
|
604
|
+
progress.visited.add(progress.anchor);
|
|
605
|
+
if (!next || progress.visited.has(next)) {
|
|
606
|
+
delete this.messageSyncProgress[cid];
|
|
607
|
+
return {
|
|
608
|
+
error: 'message_cursor_stalled'
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
progress.anchor = next;
|
|
612
|
+
}
|
|
613
|
+
return {
|
|
614
|
+
pending: true
|
|
615
|
+
};
|
|
616
|
+
} catch (error) {
|
|
617
|
+
return {
|
|
618
|
+
error
|
|
619
|
+
};
|
|
620
|
+
} finally {
|
|
621
|
+
this.reconnectGate.open();
|
|
622
|
+
}
|
|
492
623
|
}
|
|
493
624
|
async init(accid, mask, userRef, options) {
|
|
494
625
|
this.g_sync = {};
|
|
@@ -569,7 +700,6 @@ class Store {
|
|
|
569
700
|
}
|
|
570
701
|
async _initResource(accid, auth, realtimep) {
|
|
571
702
|
this.g_sync = {};
|
|
572
|
-
this._current_acc_id = accid;
|
|
573
703
|
let user = await this.api.setAuth(auth);
|
|
574
704
|
if (typeof sbz_info != 'undefined') sbz_info.store_7 = true;
|
|
575
705
|
if (user.error) {
|
|
@@ -581,6 +711,7 @@ class Store {
|
|
|
581
711
|
let lightConvos = this.kv.match('light_convos') || {};
|
|
582
712
|
this.lightConvos = {};
|
|
583
713
|
_index.default.map(lightConvos, convo => {
|
|
714
|
+
if (convo.light_type === 'widget' && (convo.account_id !== accid || convo.initial_by !== user.id)) return;
|
|
584
715
|
let in7Day = convo.created > _index.default.Date.now() - 7 * 24 * 3_600_000;
|
|
585
716
|
let events = _index.default.filter(convo.events, ev => ev.type === 'message_sent');
|
|
586
717
|
let messages = _index.default.map(events, ev => _index.default.get(ev, 'data.message') || {});
|
|
@@ -594,8 +725,10 @@ class Store {
|
|
|
594
725
|
if (this.fake) this.realtime = new _realtime_fake.default();else this.realtime = new Realtime(this.RealtimeURL, realtimep, xhrsend, accid);
|
|
595
726
|
this.realtime.onEvent(this.onWs.bind(this));
|
|
596
727
|
this.realtime.onInterrupted(async () => {
|
|
728
|
+
if (this._die) return;
|
|
729
|
+
this._needsMessageSync = true;
|
|
597
730
|
await this.reconnectWs(accid, user.id);
|
|
598
|
-
this.
|
|
731
|
+
await this.refreshAccount();
|
|
599
732
|
});
|
|
600
733
|
if (typeof sbz_info != 'undefined') sbz_info.store_8 = true;
|
|
601
734
|
this.seenLoop();
|
|
@@ -643,7 +776,7 @@ class Store {
|
|
|
643
776
|
var lastmsgsent = events[_index.default.size(events) - 1];
|
|
644
777
|
if (!lastmsgsent) return;
|
|
645
778
|
if (this.g_haveSentSeenM[lastmsgsent.id]) return;
|
|
646
|
-
if (lastmsgsent.id === lastmsgsent.
|
|
779
|
+
if (lastmsgsent.id === lastmsgsent.source_event_id) return;
|
|
647
780
|
this.pubsub.publish('events', {
|
|
648
781
|
created: this.now(),
|
|
649
782
|
type: 'message_pong',
|
|
@@ -685,34 +818,52 @@ class Store {
|
|
|
685
818
|
await this.realtime.subscribe([`conversation_state_updated.account.${accid}.user.${userid}`, `conversation_joined.account.${accid}.user.${userid}`, `conversation_typing.account.${accid}.user.${userid}`, `message_sent.account.${accid}.user.${userid}`, `message_pong.account.${accid}.user.${userid}`, `conversation_rating_requested.account.${accid}.user.${userid}`, `conversation_rated.account.${accid}.user.${userid}`, `conversation_events.account.${accid}.user.${userid}`]);
|
|
686
819
|
await this.readyGate.entry();
|
|
687
820
|
}
|
|
688
|
-
|
|
821
|
+
reconnect(p) {
|
|
822
|
+
if (this.reconnectRequest) return this.reconnectRequest;
|
|
823
|
+
const request = this._reconnect(p).finally(() => {
|
|
824
|
+
if (this.reconnectRequest === request) this.reconnectRequest = null;
|
|
825
|
+
});
|
|
826
|
+
this.reconnectRequest = request;
|
|
827
|
+
return request;
|
|
828
|
+
}
|
|
829
|
+
async _reconnect(p) {
|
|
689
830
|
if (this._die) return;
|
|
690
831
|
await this.reconnectGate.entry(undefined, true);
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
832
|
+
try {
|
|
833
|
+
let fetchuser = p && p.user ? Promise.resolve({
|
|
834
|
+
body: p.user
|
|
835
|
+
}) : this.api.getUser();
|
|
836
|
+
let outs = await Promise.all([fetchuser, this.api.getAccountSetting({
|
|
837
|
+
bot_id: this.forceBotId
|
|
838
|
+
})]);
|
|
839
|
+
let error = _index.default.find(outs, out => out.error);
|
|
840
|
+
if (error) return error;
|
|
841
|
+
let set = outs[1].body;
|
|
842
|
+
set.user = outs[0].body;
|
|
843
|
+
await this._setSetting(set);
|
|
844
|
+
let convob = await this.api.listConversations();
|
|
845
|
+
error = convob.error;
|
|
846
|
+
let body = convob.body;
|
|
847
|
+
if (!error) {
|
|
848
|
+
let convos = _index.default.get(body, 'conversations', []);
|
|
849
|
+
_index.default.map(this.cache.all(), (value, k) => {
|
|
850
|
+
if (k.startsWith('convo_')) {
|
|
851
|
+
if (this.now() - _index.default.getMs(_index.default.get(value, 'actived')) > 1209600000) this.cache.del(k);
|
|
852
|
+
}
|
|
853
|
+
});
|
|
854
|
+
_index.default.map(convos, convo => this._setConvo(convo));
|
|
855
|
+
}
|
|
856
|
+
if (error) return {
|
|
857
|
+
error
|
|
858
|
+
};
|
|
859
|
+
this.markSync('account');
|
|
860
|
+
} catch (error) {
|
|
861
|
+
return {
|
|
862
|
+
error
|
|
863
|
+
};
|
|
864
|
+
} finally {
|
|
865
|
+
this.reconnectGate.open();
|
|
714
866
|
}
|
|
715
|
-
return this.reconnectGate.open();
|
|
716
867
|
}
|
|
717
868
|
async submitForm(formid, data, user) {
|
|
718
869
|
await this.readyGate.entry();
|
|
@@ -826,20 +977,19 @@ class Store {
|
|
|
826
977
|
return this.api.sendEvent(e);
|
|
827
978
|
}
|
|
828
979
|
async onWs(ev) {
|
|
829
|
-
await this.wsGate.entry();
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
980
|
+
await this.wsGate.entry(undefined, true);
|
|
981
|
+
try {
|
|
982
|
+
await this._onWs(ev);
|
|
983
|
+
} catch (error) {
|
|
984
|
+
console.error(error);
|
|
985
|
+
return {
|
|
986
|
+
error
|
|
987
|
+
};
|
|
988
|
+
} finally {
|
|
989
|
+
this.wsGate.open();
|
|
990
|
+
}
|
|
840
991
|
}
|
|
841
992
|
async _onWs(ev) {
|
|
842
|
-
this.handleLogCompare(ev);
|
|
843
993
|
if (this._die) return;
|
|
844
994
|
if (!ev || !ev.type) return;
|
|
845
995
|
ev.created = _index.default.getMs(ev.created);
|
|
@@ -908,7 +1058,7 @@ class Store {
|
|
|
908
1058
|
}
|
|
909
1059
|
}
|
|
910
1060
|
if (_index.default.startsWith(ev.type, 'message_') || _index.default.startsWith(ev.type, 'conversation_')) {
|
|
911
|
-
this.restConvoEvent(ev);
|
|
1061
|
+
await this.restConvoEvent(ev);
|
|
912
1062
|
if (ev.type === 'message_sent' && _index.default.get(ev, 'by.id') !== user.id) {
|
|
913
1063
|
sendEventToThirdParty('SUBIZ Chat', 'Received', 'User');
|
|
914
1064
|
}
|
|
@@ -957,8 +1107,8 @@ class Store {
|
|
|
957
1107
|
}
|
|
958
1108
|
if (ev.type !== 'message_pong' && ev.type !== 'conversation_typing') {
|
|
959
1109
|
if (ev.type === 'message_sent') {
|
|
960
|
-
let
|
|
961
|
-
let found = _index.default.find(this.listEvents(cid), oldev => oldev.id ===
|
|
1110
|
+
let sourceEventId = _index.default.get(ev, 'source_event_id');
|
|
1111
|
+
let found = _index.default.find(this.listEvents(cid), oldev => oldev.id === sourceEventId);
|
|
962
1112
|
if (found) {
|
|
963
1113
|
this.chain.del(cid, found.id);
|
|
964
1114
|
ev.created = found.created;
|
|
@@ -984,6 +1134,58 @@ class Store {
|
|
|
984
1134
|
delete this.lightConvos[id];
|
|
985
1135
|
this.kv.put('light_convos', this.lightConvos);
|
|
986
1136
|
}
|
|
1137
|
+
startWidgetConvo(greeting, locale) {
|
|
1138
|
+
const user = this.matchUser();
|
|
1139
|
+
const existing = _index.default.find(this.lightConvos, convo => convo.light_type === 'widget' && convo.account_id === user.account_id && convo.initial_by === user.id);
|
|
1140
|
+
if (existing) return {
|
|
1141
|
+
convo: existing
|
|
1142
|
+
};
|
|
1143
|
+
const id = 'cslightwidget_' + _index.default.randomString(24);
|
|
1144
|
+
const ev = _index.default.cloneDeep(greeting);
|
|
1145
|
+
ev.data.message.conversation_id = id;
|
|
1146
|
+
const convo = {
|
|
1147
|
+
id,
|
|
1148
|
+
account_id: user.account_id,
|
|
1149
|
+
initial_by: user.id,
|
|
1150
|
+
locale,
|
|
1151
|
+
light_type: 'widget',
|
|
1152
|
+
state: 'pending',
|
|
1153
|
+
created: ev.created,
|
|
1154
|
+
members: [{
|
|
1155
|
+
id: user.id,
|
|
1156
|
+
type: 'user',
|
|
1157
|
+
seen_at: ev.created + 1
|
|
1158
|
+
}],
|
|
1159
|
+
events: [ev],
|
|
1160
|
+
last_message_sent: ev,
|
|
1161
|
+
touchpoint: {
|
|
1162
|
+
id,
|
|
1163
|
+
channel: 'subiz',
|
|
1164
|
+
source: 'web'
|
|
1165
|
+
}
|
|
1166
|
+
};
|
|
1167
|
+
this.lightConvos[id] = convo;
|
|
1168
|
+
this.kv.put('light_convos', this.lightConvos);
|
|
1169
|
+
this.pubsub.publish('account');
|
|
1170
|
+
return {
|
|
1171
|
+
convo
|
|
1172
|
+
};
|
|
1173
|
+
}
|
|
1174
|
+
promoteWidgetConvo(localId, cid) {
|
|
1175
|
+
this.widgetConvoOrigins = this.widgetConvoOrigins || {};
|
|
1176
|
+
this.widgetConvoOrigins[cid] = localId;
|
|
1177
|
+
const greeting = _index.default.cloneDeep(_index.default.get(this.lightConvos, [localId, 'events', 0]));
|
|
1178
|
+
if (greeting) {
|
|
1179
|
+
greeting.source_event_id = greeting.id;
|
|
1180
|
+
greeting.data.message.conversation_id = cid;
|
|
1181
|
+
this.chain.merge(cid, [{
|
|
1182
|
+
id: greeting.id,
|
|
1183
|
+
index: greeting.created,
|
|
1184
|
+
value: greeting
|
|
1185
|
+
}]);
|
|
1186
|
+
}
|
|
1187
|
+
this.deleteLightConvo(localId);
|
|
1188
|
+
}
|
|
987
1189
|
startLightConvo(botid, messages, locale, is_testing, botversion) {
|
|
988
1190
|
let convoid = 'cslight' + botid + '_' + this.now();
|
|
989
1191
|
let user = this.cache.match('user') || {};
|
|
@@ -1077,10 +1279,10 @@ class Store {
|
|
|
1077
1279
|
}
|
|
1078
1280
|
async sendConvoEvent(cid, type, data) {
|
|
1079
1281
|
await this.readyGate.entry();
|
|
1080
|
-
var
|
|
1282
|
+
var sourceEventId = _index.default.randomString(36);
|
|
1081
1283
|
let user = this.cache.match('user') || {};
|
|
1082
1284
|
var event = {
|
|
1083
|
-
id:
|
|
1285
|
+
id: sourceEventId,
|
|
1084
1286
|
by: {
|
|
1085
1287
|
id: user.id,
|
|
1086
1288
|
type: 'user',
|
|
@@ -1093,7 +1295,7 @@ class Store {
|
|
|
1093
1295
|
_index.default.convoToEv(cid, event);
|
|
1094
1296
|
let files = [];
|
|
1095
1297
|
if (type === 'message_sent') {
|
|
1096
|
-
event.
|
|
1298
|
+
event.source_event_id = sourceEventId;
|
|
1097
1299
|
event.data.message.conversation_id = cid;
|
|
1098
1300
|
await flow.map(event.data.message.attachments, 2, async (att, i) => {
|
|
1099
1301
|
if (att.type !== 'file') return;
|
|
@@ -1113,18 +1315,9 @@ class Store {
|
|
|
1113
1315
|
}
|
|
1114
1316
|
this.onWs(event);
|
|
1115
1317
|
await this.convoGate.entry();
|
|
1116
|
-
await
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
url,
|
|
1120
|
-
error
|
|
1121
|
-
} = await this.api.uploadToS3(att._file);
|
|
1122
|
-
if (_index.default.get(body, 'code') == 'invalid_field_size') {
|
|
1123
|
-
event._error_message = 'cannot_send_too_big_file';
|
|
1124
|
-
}
|
|
1125
|
-
event._error = error;
|
|
1126
|
-
att.url = url;
|
|
1127
|
-
});
|
|
1318
|
+
const uploaded = await (0, _attachments.uploadAttachments)(files, file => this.api.uploadToS3(file));
|
|
1319
|
+
event._error = uploaded.error;
|
|
1320
|
+
if (uploaded.errorMessage) event._error_message = uploaded.errorMessage;
|
|
1128
1321
|
if (event._error) return this.onWs(event);
|
|
1129
1322
|
if (cid && cid.startsWith('cslight')) return;
|
|
1130
1323
|
let {
|
|
@@ -1233,13 +1426,20 @@ class Store {
|
|
|
1233
1426
|
}
|
|
1234
1427
|
async listmessageapi(type, anchor, limit) {
|
|
1235
1428
|
let convoid = type;
|
|
1236
|
-
if (convoid && convoid.startsWith('cslight'))
|
|
1429
|
+
if (convoid && convoid.startsWith('cslight')) {
|
|
1430
|
+
let events = _index.default.map(this.listEvents(convoid), ev => ({
|
|
1431
|
+
id: ev.id,
|
|
1432
|
+
index: ev.created,
|
|
1433
|
+
value: ev
|
|
1434
|
+
}));
|
|
1435
|
+
return [events, '', undefined, true];
|
|
1436
|
+
}
|
|
1237
1437
|
let {
|
|
1238
1438
|
body: events,
|
|
1239
1439
|
code,
|
|
1240
1440
|
error
|
|
1241
1441
|
} = await this.api.listMessages(convoid, -limit, anchor);
|
|
1242
|
-
if (error || code !== 200) return [[], anchor, error];
|
|
1442
|
+
if (error || code !== 200) return [[], anchor, error || 'message_fetch_failed'];
|
|
1243
1443
|
anchor = _index.default.get(_index.default.last(events), 'id');
|
|
1244
1444
|
events = _index.default.map(events, event => {
|
|
1245
1445
|
event.created = _index.default.getMs(event.created);
|
|
@@ -1268,17 +1468,18 @@ class Store {
|
|
|
1268
1468
|
async loopTime() {
|
|
1269
1469
|
if (this._die) return;
|
|
1270
1470
|
let startms = this.now();
|
|
1271
|
-
if (!this.cache || !_index.default.get(this.cache.match('user'), 'id')) return _index.default.setTimeout(() => this.loopTime(), 240000);
|
|
1471
|
+
if (!this.cache || !_index.default.get(this.cache.match('user'), 'id')) return this._timeTimeout = _index.default.setTimeout(() => this.loopTime(), 240000);
|
|
1272
1472
|
let {
|
|
1273
1473
|
body: t,
|
|
1274
1474
|
error
|
|
1275
1475
|
} = await this.api.time();
|
|
1276
|
-
if (
|
|
1476
|
+
if (this._die) return;
|
|
1477
|
+
if (error) return this._timeTimeout = _index.default.setTimeout(() => this.loopTime(), 30000);
|
|
1277
1478
|
var latences = Math.abs(this.now() - startms) / 2;
|
|
1278
1479
|
var serverMs = new _index.default.Date(t).getTime() + latences;
|
|
1279
1480
|
var localMs = this.now();
|
|
1280
1481
|
this.timeDiff = Math.floor(serverMs - localMs);
|
|
1281
|
-
_index.default.setTimeout(() => this.loopTime(), 240000);
|
|
1482
|
+
this._timeTimeout = _index.default.setTimeout(() => this.loopTime(), 240000);
|
|
1282
1483
|
}
|
|
1283
1484
|
replaceFileUrl(src) {
|
|
1284
1485
|
if (!src) return '';
|
|
@@ -1310,6 +1511,14 @@ class Store {
|
|
|
1310
1511
|
this.kv = new _kv.default(new _lsdb.default('sbz2023', this.inmem), 'kv');
|
|
1311
1512
|
if (this.chain) this.chain.destroy();
|
|
1312
1513
|
this.chain = new _chain.default(new _lsdb.default('cbz2023', true), 'ch');
|
|
1514
|
+
this.outofmsgM = {};
|
|
1515
|
+
this.messageSyncTimes = {};
|
|
1516
|
+
this.messageSyncNextAt = {};
|
|
1517
|
+
this.messageSyncFailures = {};
|
|
1518
|
+
this.messageSyncProgress = {};
|
|
1519
|
+
this.accountRefreshAfter = 0;
|
|
1520
|
+
this.historyFailures = {};
|
|
1521
|
+
this.convoFetchAfter = {};
|
|
1313
1522
|
if (this.realtime) this.realtime.stop();
|
|
1314
1523
|
if (this.cache) this.cache.destroy();
|
|
1315
1524
|
this.pubsub.publish('destroy');
|
|
@@ -1318,14 +1527,22 @@ class Store {
|
|
|
1318
1527
|
return this._die;
|
|
1319
1528
|
}
|
|
1320
1529
|
destroy() {
|
|
1530
|
+
if (this._die) return;
|
|
1321
1531
|
this._die = true;
|
|
1322
1532
|
this.clearBrowserData();
|
|
1323
1533
|
_index.default.clearInterval(this._seenInterval);
|
|
1324
1534
|
_index.default.clearInterval(this._urlCheckInterval);
|
|
1535
|
+
_index.default.clearInterval(this._presenceInterval1);
|
|
1536
|
+
_index.default.clearInterval(this._presenceInterval2);
|
|
1537
|
+
_index.default.clearInterval(this._gaInterval);
|
|
1538
|
+
_index.default.clearTimeout(this._timeTimeout);
|
|
1325
1539
|
if (this.realtime) this.realtime.stop();
|
|
1326
|
-
this.readyGate.close();
|
|
1327
|
-
window.removeEventListener('blur', this.
|
|
1328
|
-
window.removeEventListener('focus', this.
|
|
1540
|
+
if (this.readyGate) this.readyGate.close();
|
|
1541
|
+
window.removeEventListener('blur', this._onBlur);
|
|
1542
|
+
window.removeEventListener('focus', this._onFocus);
|
|
1543
|
+
window.removeEventListener('beforeunload', this._onBeforeUnload);
|
|
1544
|
+
if (this._visibilityCleanup) this._visibilityCleanup();
|
|
1545
|
+
this.pubsub.clear();
|
|
1329
1546
|
}
|
|
1330
1547
|
}
|
|
1331
1548
|
exports.default = Store;
|
|
@@ -1350,7 +1567,23 @@ function loadImage(file) {
|
|
|
1350
1567
|
const ImageTypes = ['image/gif', 'image/jpeg', 'image/png', 'image/svg+xml'];
|
|
1351
1568
|
function onVisibilityChange(cb) {
|
|
1352
1569
|
var hidden = 'hidden';
|
|
1353
|
-
|
|
1570
|
+
let target = document,
|
|
1571
|
+
eventName;
|
|
1572
|
+
let previous = {};
|
|
1573
|
+
if (hidden in document) eventName = 'visibilitychange';else if ((hidden = 'mozHidden') in document) eventName = 'mozvisibilitychange';else if ((hidden = 'webkitHidden') in document) eventName = 'webkitvisibilitychange';else if ((hidden = 'msHidden') in document) eventName = 'msvisibilitychange';else if ('onfocusin' in document) {
|
|
1574
|
+
previous = {
|
|
1575
|
+
onfocusin: document.onfocusin,
|
|
1576
|
+
onfocusout: document.onfocusout
|
|
1577
|
+
};
|
|
1578
|
+
document.onfocusin = document.onfocusout = onchange;
|
|
1579
|
+
} else {
|
|
1580
|
+
target = window;
|
|
1581
|
+
for (const key of ['onpageshow', 'onpagehide', 'onfocus', 'onblur']) {
|
|
1582
|
+
previous[key] = window[key];
|
|
1583
|
+
window[key] = onchange;
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
if (eventName) target.addEventListener(eventName, onchange);
|
|
1354
1587
|
function onchange(evt) {
|
|
1355
1588
|
var v = 'visible';
|
|
1356
1589
|
var h = 'hidden';
|
|
@@ -1368,6 +1601,12 @@ function onVisibilityChange(cb) {
|
|
|
1368
1601
|
if (document[hidden] !== undefined) onchange({
|
|
1369
1602
|
type: document[hidden] ? 'blur' : 'focus'
|
|
1370
1603
|
});
|
|
1604
|
+
return () => {
|
|
1605
|
+
if (eventName) target.removeEventListener(eventName, onchange);
|
|
1606
|
+
for (const key of Object.keys(previous)) {
|
|
1607
|
+
if (target[key] === onchange) target[key] = previous[key];
|
|
1608
|
+
}
|
|
1609
|
+
};
|
|
1371
1610
|
}
|
|
1372
1611
|
const inmemCookie = {
|
|
1373
1612
|
data: {},
|