@mixd-id/web-scaffold 0.1.230406374 → 0.1.230406377
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/package.json +15 -1
- package/src/components/Datepicker.vue +23 -9
- package/src/components/List.vue +35 -25
- package/src/components/PresetSelectorFilterItem.vue +3 -2
- package/src/index.js +1 -0
- package/src/utils/helpers.js +27 -8
- package/src/utils/helpers.mjs +31 -1
- package/src/utils/preset-selector.js +16 -0
- package/src/utils/queue.js +63 -0
- package/src/utils/wss.js +13 -2
- package/src/utils/wss.mjs +3 -3
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mixd-id/web-scaffold",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.230406377",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "vite serve",
|
|
7
7
|
"build": "vite build",
|
|
@@ -20,18 +20,29 @@
|
|
|
20
20
|
"require": "./src/utils/helpers.js",
|
|
21
21
|
"import": "./src/utils/helpers.mjs"
|
|
22
22
|
},
|
|
23
|
+
"./helpers.js": "./src/utils/helpers.js",
|
|
24
|
+
"./helpers.mjs": "./src/utils/helpers.mjs",
|
|
25
|
+
"./queue": "./src/utils/queue.js",
|
|
26
|
+
|
|
23
27
|
"./wss": {
|
|
24
28
|
"require": "./src/utils/wss.js",
|
|
25
29
|
"import": "./src/utils/wss.mjs"
|
|
26
30
|
},
|
|
31
|
+
"./wss.js": "./src/utils/wss.js",
|
|
32
|
+
"./wss.mjs": "./src/utils/wss.mjs",
|
|
33
|
+
|
|
27
34
|
"./importer": "./src/utils/importer.js",
|
|
28
35
|
"./listpage1": "./src/utils/listpage1.js",
|
|
29
36
|
"./dashboard": "./src/utils/dashboard.js",
|
|
30
37
|
"./listview": "./src/utils/listview.js",
|
|
38
|
+
|
|
31
39
|
"./preset-selector": {
|
|
32
40
|
"require": "./src/utils/preset-selector.js",
|
|
33
41
|
"import": "./src/utils/preset-selector.mjs"
|
|
34
42
|
},
|
|
43
|
+
"./preset-selector.js": "./src/utils/preset-selector.js",
|
|
44
|
+
"./preset-selector.mjs": "./src/utils/preset-selector.mjs",
|
|
45
|
+
|
|
35
46
|
"./web": "./src/utils/web.js"
|
|
36
47
|
},
|
|
37
48
|
"dependencies": {
|
|
@@ -40,6 +51,8 @@
|
|
|
40
51
|
"@tailwindcss/line-clamp": "^0.4.0",
|
|
41
52
|
"@vueuse/core": "^9.0.2",
|
|
42
53
|
"adm-zip": "^0.5.10",
|
|
54
|
+
"axios": "^1.7.9",
|
|
55
|
+
"bcrypt": "^5.1.1",
|
|
43
56
|
"chart.js": "^4.2.1",
|
|
44
57
|
"compression": "^1.7.4",
|
|
45
58
|
"cookie-parser": "^1.4.6",
|
|
@@ -58,6 +71,7 @@
|
|
|
58
71
|
"pinia": "^2.3.0",
|
|
59
72
|
"prismjs": "^1.28.0",
|
|
60
73
|
"redis": "^4.6.13",
|
|
74
|
+
"sequelize": "^6.37.5",
|
|
61
75
|
"serve-static": "^1.15.0",
|
|
62
76
|
"tailwindcss": "^3.2.4",
|
|
63
77
|
"vue": "^3.2.25",
|
|
@@ -70,6 +70,7 @@
|
|
|
70
70
|
<div class="grid grid-cols-7 gap-2 mt-2">
|
|
71
71
|
<div v-for="i in 7">{{ getDayOfWeekLabel(i) }}</div>
|
|
72
72
|
<button type="button" :class="buttonStyle(d.value)"
|
|
73
|
+
:disabled="allowedDates && !allowedDates.includes(d.value)"
|
|
73
74
|
v-for="d in contextMenuDates" @click="setValue(d.value)">
|
|
74
75
|
{{ d.date }}
|
|
75
76
|
</button>
|
|
@@ -140,6 +141,8 @@ export default{
|
|
|
140
141
|
|
|
141
142
|
readonly: undefined,
|
|
142
143
|
|
|
144
|
+
allowedDates: Array,
|
|
145
|
+
|
|
143
146
|
},
|
|
144
147
|
|
|
145
148
|
computed:{
|
|
@@ -181,17 +184,22 @@ export default{
|
|
|
181
184
|
for(let i = 1 ; i <= 42 ; i++){
|
|
182
185
|
if(startDayOfMonth > 0){
|
|
183
186
|
startDayOfMonth--
|
|
187
|
+
const value = dayjsInput.subtract(1, 'month')
|
|
188
|
+
.format(`YYYY-MM-${(endDateOfLastMonth - startDayOfMonth).toString().padStart(2, '0')}`)
|
|
189
|
+
|
|
184
190
|
dates.push({
|
|
185
191
|
date: endDateOfLastMonth - startDayOfMonth,
|
|
186
|
-
value
|
|
187
|
-
|
|
192
|
+
value,
|
|
193
|
+
type: -1
|
|
188
194
|
})
|
|
189
195
|
}
|
|
190
196
|
else if(currentDate > endDateOfMonth){
|
|
191
|
-
|
|
197
|
+
const value = dayjsInput.add(1, 'month').format(`YYYY-MM-${nextDate.toString().padStart(2, '0')}`)
|
|
198
|
+
|
|
199
|
+
dates.push({
|
|
192
200
|
date: nextDate,
|
|
193
|
-
value
|
|
194
|
-
|
|
201
|
+
value,
|
|
202
|
+
type: 1
|
|
195
203
|
})
|
|
196
204
|
nextDate++
|
|
197
205
|
}
|
|
@@ -283,21 +291,27 @@ export default{
|
|
|
283
291
|
}
|
|
284
292
|
.datepicker input[type=radio]{
|
|
285
293
|
@apply hidden;
|
|
286
|
-
}
|
|
294
|
+
}K
|
|
287
295
|
.datepicker input[type=radio]:checked + label{
|
|
288
296
|
}
|
|
289
297
|
|
|
290
298
|
.button{
|
|
291
299
|
@apply rounded-full aspect-square;
|
|
292
300
|
}
|
|
293
|
-
.button:
|
|
301
|
+
.button:not(:disabled){
|
|
302
|
+
@apply cursor-default;
|
|
303
|
+
}
|
|
304
|
+
.button:disabled{
|
|
305
|
+
@apply text-text-300;
|
|
306
|
+
}
|
|
307
|
+
.button:not(:disabled):hover{
|
|
294
308
|
@apply bg-primary-200;
|
|
295
309
|
}
|
|
296
310
|
.button.selected{
|
|
297
311
|
@apply bg-primary text-white;
|
|
298
312
|
}
|
|
299
|
-
.button.otherMonth{
|
|
300
|
-
@apply text-text-
|
|
313
|
+
.button:not(:disabled).otherMonth{
|
|
314
|
+
@apply text-text-400;
|
|
301
315
|
}
|
|
302
316
|
|
|
303
317
|
.arrow{
|
package/src/components/List.vue
CHANGED
|
@@ -270,8 +270,9 @@ import VirtualGrid from "./VirtualGrid.vue";
|
|
|
270
270
|
import throttle from "lodash/throttle";
|
|
271
271
|
import PresetSelector from "../widgets/PresetSelector.vue";
|
|
272
272
|
import groupBy from "lodash/groupBy";
|
|
273
|
-
import {
|
|
273
|
+
import {generatePivotColumns, generateTotalColumns, sortsFn} from "../utils/preset-selector.mjs";
|
|
274
274
|
import PresetBar from "../widgets/PresetBar.vue";
|
|
275
|
+
import {queueForLater} from "../utils/helpers.mjs";
|
|
275
276
|
|
|
276
277
|
export default{
|
|
277
278
|
|
|
@@ -315,7 +316,9 @@ export default{
|
|
|
315
316
|
toolbar: {
|
|
316
317
|
type: [ String, Boolean ],
|
|
317
318
|
default: true
|
|
318
|
-
}
|
|
319
|
+
},
|
|
320
|
+
|
|
321
|
+
sorts: Array
|
|
319
322
|
},
|
|
320
323
|
|
|
321
324
|
methods: {
|
|
@@ -394,23 +397,15 @@ export default{
|
|
|
394
397
|
((this.data ?? {}).hasNext !== false) &&
|
|
395
398
|
!(this.preset.pivot ?? {}).enabled) {
|
|
396
399
|
|
|
397
|
-
const afterItem = this.
|
|
398
|
-
console.log('#next', afterItem.id, afterItem.lastMessageAt)
|
|
400
|
+
const afterItem = this.dataItems[this.dataItems.length - 1]
|
|
399
401
|
|
|
400
402
|
this.readyState = 4
|
|
401
403
|
this.socket.send(this.src, {
|
|
402
404
|
...this.preset,
|
|
403
405
|
itemsPerPage: this.data.itemsPerPage,
|
|
404
|
-
afterItem
|
|
406
|
+
afterItem,
|
|
405
407
|
})
|
|
406
408
|
.then(data => {
|
|
407
|
-
const firstItem = data.items[0]
|
|
408
|
-
const lastItem = data.items[data.items.length - 1]
|
|
409
|
-
console.log('#loaded',
|
|
410
|
-
firstItem?.id, firstItem?.lastMessageAt,
|
|
411
|
-
lastItem?.id, lastItem?.lastMessageAt,
|
|
412
|
-
data.items.length)
|
|
413
|
-
|
|
414
409
|
this.data.items.push(...data.items)
|
|
415
410
|
this.loadEnums(data.items)
|
|
416
411
|
})
|
|
@@ -595,6 +590,21 @@ export default{
|
|
|
595
590
|
}
|
|
596
591
|
},
|
|
597
592
|
|
|
593
|
+
loadQueued(items){
|
|
594
|
+
const key = items[0] && items[0].uid ? 'uid' : 'id'
|
|
595
|
+
|
|
596
|
+
this.socket.send(this.src, {
|
|
597
|
+
...this.preset,
|
|
598
|
+
[key]: items.map(item => item[key])
|
|
599
|
+
})
|
|
600
|
+
.then(({ items:nextItems }) => {
|
|
601
|
+
nextItems.forEach(item => this.$util.unshift(this.data.items, item, { highlight: true }))
|
|
602
|
+
|
|
603
|
+
const destroyedItems = items.filter(_ => !nextItems.find(i => i[key] === _[key]))
|
|
604
|
+
this.$util.remove(this.data.items, destroyedItems)
|
|
605
|
+
})
|
|
606
|
+
},
|
|
607
|
+
|
|
598
608
|
onSignal(event, items){
|
|
599
609
|
if(this.pivotEnabled) return
|
|
600
610
|
if(!Array.isArray(items) || items.length < 1) return
|
|
@@ -606,18 +616,7 @@ export default{
|
|
|
606
616
|
break
|
|
607
617
|
|
|
608
618
|
default:
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
this.socket.send(this.src, {
|
|
612
|
-
...this.preset,
|
|
613
|
-
[key]: items.map(item => item[key])
|
|
614
|
-
})
|
|
615
|
-
.then(({ items:nextItems }) => {
|
|
616
|
-
nextItems.forEach(item => this.$util.unshift(this.data.items, item, { highlight: true }))
|
|
617
|
-
|
|
618
|
-
const destroyedItems = items.filter(_ => !nextItems.find(i => i[key] === _[key]))
|
|
619
|
-
this.$util.remove(this.data.items, destroyedItems)
|
|
620
|
-
})
|
|
619
|
+
this.queue(items)
|
|
621
620
|
break
|
|
622
621
|
}
|
|
623
622
|
|
|
@@ -816,6 +815,10 @@ export default{
|
|
|
816
815
|
}
|
|
817
816
|
|
|
818
817
|
window.addEventListener('keydown', this.onKeyDown)
|
|
818
|
+
|
|
819
|
+
this.queue = queueForLater({
|
|
820
|
+
pop: this.loadQueued
|
|
821
|
+
})
|
|
819
822
|
},
|
|
820
823
|
|
|
821
824
|
unmounted() {
|
|
@@ -910,7 +913,13 @@ export default{
|
|
|
910
913
|
},
|
|
911
914
|
|
|
912
915
|
dataItems(){
|
|
913
|
-
|
|
916
|
+
|
|
917
|
+
if((this.sorts ?? []).length > 0){
|
|
918
|
+
return (this.data.items ?? []).sort((a, b) => {
|
|
919
|
+
return sortsFn(a, b, this.sorts, 0)
|
|
920
|
+
})
|
|
921
|
+
}
|
|
922
|
+
else if((this.preset.sorts ?? []).length > 0){
|
|
914
923
|
return (this.data.items ?? []).sort((a, b) => {
|
|
915
924
|
return sortsFn(a, b, this.preset.sorts, 0)
|
|
916
925
|
})
|
|
@@ -978,6 +987,7 @@ export default{
|
|
|
978
987
|
enumCache: {},
|
|
979
988
|
extItems: null,
|
|
980
989
|
lastEnumItems: null,
|
|
990
|
+
queue: null,
|
|
981
991
|
}
|
|
982
992
|
},
|
|
983
993
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<div class="flex-1 flex flex-row gap-2">
|
|
7
7
|
<Dropdown v-model="value.operator"
|
|
8
8
|
:readonly="readonly"
|
|
9
|
-
:class="![ 'yesterday', 'today', 'thisWeek', 'thisMonth', 'lastMonth', 'thisYear' ].includes(value.operator) ? 'w-[100px]' : 'w-full'"
|
|
9
|
+
:class="![ 'yesterday', 'today', 'thisWeek', 'thisMonth', 'lastMonth', 'thisYear', 'null' ].includes(value.operator) ? 'w-[100px]' : 'w-full'"
|
|
10
10
|
@change="apply">
|
|
11
11
|
<option value="=">=</option>
|
|
12
12
|
<option value=">">></option>
|
|
@@ -20,8 +20,9 @@
|
|
|
20
20
|
<option value="thisMonth">This Month</option>
|
|
21
21
|
<option value="lastMonth">Last Month</option>
|
|
22
22
|
<option value="thisYear">This Year</option>
|
|
23
|
+
<option value="null">No Value</option>
|
|
23
24
|
</Dropdown>
|
|
24
|
-
<div v-if="![ 'yesterday', 'today', 'thisWeek', 'thisMonth', 'lastMonth', 'thisYear' ].includes(value.operator)"
|
|
25
|
+
<div v-if="![ 'yesterday', 'today', 'thisWeek', 'thisMonth', 'lastMonth', 'thisYear', 'null' ].includes(value.operator)"
|
|
25
26
|
class="flex-1 flex flex-row gap-2">
|
|
26
27
|
<Datepicker class="flex-1"
|
|
27
28
|
mode="popup"
|
package/src/index.js
CHANGED
package/src/utils/helpers.js
CHANGED
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
const md5 = require("md5");
|
|
2
|
-
const fs = require("fs");
|
|
3
|
-
const { Op } = require('sequelize')
|
|
4
|
-
const axios = require('axios')
|
|
5
|
-
const dayjs = require('dayjs')
|
|
6
|
-
|
|
7
|
-
|
|
8
1
|
const ceil = (num, precision = 0) => {
|
|
9
2
|
var p = Math.pow(10, precision)
|
|
10
3
|
var n = (num * p) * (1 + Number.EPSILON)
|
|
@@ -32,6 +25,7 @@ const ftWildcard = (key) => {
|
|
|
32
25
|
}
|
|
33
26
|
|
|
34
27
|
const moveFile = function(oldPath, newPath, callback) {
|
|
28
|
+
const fs = require("fs");
|
|
35
29
|
|
|
36
30
|
fs.rename(oldPath, newPath, function (err) {
|
|
37
31
|
if (err) {
|
|
@@ -46,6 +40,8 @@ const moveFile = function(oldPath, newPath, callback) {
|
|
|
46
40
|
});
|
|
47
41
|
|
|
48
42
|
function copy() {
|
|
43
|
+
const fs = require("fs");
|
|
44
|
+
|
|
49
45
|
var readStream = fs.createReadStream(oldPath);
|
|
50
46
|
var writeStream = fs.createWriteStream(newPath);
|
|
51
47
|
|
|
@@ -96,6 +92,9 @@ const saveBase64 = async(data, dir = '/storage/files/images') => {
|
|
|
96
92
|
|
|
97
93
|
const saveBuffer = async(buffer, dir = '/storage/files/images') => {
|
|
98
94
|
|
|
95
|
+
const fs = require("fs");
|
|
96
|
+
const md5 = require('md5')
|
|
97
|
+
|
|
99
98
|
const { fileTypeFromBuffer } = await import('file-type')
|
|
100
99
|
|
|
101
100
|
const type = await fileTypeFromBuffer(buffer)
|
|
@@ -111,6 +110,7 @@ const saveBuffer = async(buffer, dir = '/storage/files/images') => {
|
|
|
111
110
|
}
|
|
112
111
|
|
|
113
112
|
const saveFromUrl = async(url, dir = '/storage/files/images') => {
|
|
113
|
+
const axios = require('axios')
|
|
114
114
|
|
|
115
115
|
const res = await axios({
|
|
116
116
|
method: 'GET',
|
|
@@ -153,6 +153,8 @@ const strVars = (text, vars, opt = { emptyUndefined:true }) => {
|
|
|
153
153
|
|
|
154
154
|
const writeStorage = (path, content, append = false) => {
|
|
155
155
|
|
|
156
|
+
const fs = require("fs");
|
|
157
|
+
|
|
156
158
|
if(path.startsWith('/')) path = path.substring(1)
|
|
157
159
|
|
|
158
160
|
if(append){
|
|
@@ -195,6 +197,8 @@ const sequelizeChunk = async (model, opt, callback, chunkSize = 5000) => {
|
|
|
195
197
|
|
|
196
198
|
const getPresetSortWhereParams = (order, afterItem) => {
|
|
197
199
|
|
|
200
|
+
const { Op } = require('sequelize')
|
|
201
|
+
|
|
198
202
|
if(order.filter((_) => _[0] === 'id').length <= 0){
|
|
199
203
|
order.push([ 'id', 'desc' ])
|
|
200
204
|
}
|
|
@@ -505,6 +509,7 @@ const datasourceLoad = async ({ datasource, Models }) => {
|
|
|
505
509
|
}
|
|
506
510
|
|
|
507
511
|
const dayTimeRange = (params, value) => {
|
|
512
|
+
const dayjs = require('dayjs')
|
|
508
513
|
|
|
509
514
|
/*params = {
|
|
510
515
|
'*': [ [ '08:00', '12:00' ], [ '13:00', '18:00' ] ],
|
|
@@ -543,6 +548,18 @@ const removeUnderscoredKey = (obj) => {
|
|
|
543
548
|
}
|
|
544
549
|
}
|
|
545
550
|
|
|
551
|
+
const hashMake = async (text) => {
|
|
552
|
+
const bcrypt = require('bcrypt')
|
|
553
|
+
|
|
554
|
+
return bcrypt.hash(text + (process.env.APP_KEY ?? ''), 10)
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
const hashCheck = (text, hash) => {
|
|
558
|
+
const bcrypt = require('bcrypt')
|
|
559
|
+
|
|
560
|
+
return bcrypt.compare(text + (process.env.APP_KEY ?? ''), hash)
|
|
561
|
+
}
|
|
562
|
+
|
|
546
563
|
module.exports = {
|
|
547
564
|
capitalize,
|
|
548
565
|
ceil,
|
|
@@ -572,5 +589,7 @@ module.exports = {
|
|
|
572
589
|
datasourceGet,
|
|
573
590
|
datasourceLoad,
|
|
574
591
|
dayTimeRange,
|
|
575
|
-
removeUnderscoredKey
|
|
592
|
+
removeUnderscoredKey,
|
|
593
|
+
hashMake,
|
|
594
|
+
hashCheck
|
|
576
595
|
}
|
package/src/utils/helpers.mjs
CHANGED
|
@@ -390,6 +390,35 @@ const invokeAfterIdle = (callback, delay = 1300) => {
|
|
|
390
390
|
}
|
|
391
391
|
}
|
|
392
392
|
|
|
393
|
+
const queueForLater = (params) => {
|
|
394
|
+
|
|
395
|
+
const instance = {
|
|
396
|
+
delay: 1500,
|
|
397
|
+
...params,
|
|
398
|
+
|
|
399
|
+
items: [],
|
|
400
|
+
timeoutId: null,
|
|
401
|
+
|
|
402
|
+
run: () => {
|
|
403
|
+
const items = instance.items.splice(0, instance.items.length);
|
|
404
|
+
typeof instance.pop === 'function' ? instance.pop(items) : null;
|
|
405
|
+
instance.timeoutId = null
|
|
406
|
+
},
|
|
407
|
+
|
|
408
|
+
queue(item) {
|
|
409
|
+
if(Array.isArray(item))
|
|
410
|
+
instance.items.push(...item)
|
|
411
|
+
else
|
|
412
|
+
instance.items.push(item)
|
|
413
|
+
|
|
414
|
+
if(!instance.timeoutId)
|
|
415
|
+
instance.timeoutId = window.setTimeout(instance.run, instance.delay);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
return instance.queue
|
|
420
|
+
}
|
|
421
|
+
|
|
393
422
|
|
|
394
423
|
export {
|
|
395
424
|
capitalize,
|
|
@@ -416,7 +445,8 @@ export {
|
|
|
416
445
|
unslugAndCapitalize,
|
|
417
446
|
applyDatasourceReplacer,
|
|
418
447
|
strVars,
|
|
419
|
-
invokeAfterIdle
|
|
448
|
+
invokeAfterIdle,
|
|
449
|
+
queueForLater
|
|
420
450
|
}
|
|
421
451
|
|
|
422
452
|
function observeInit(){
|
|
@@ -113,6 +113,16 @@ const getValue = (filter, opt) => {
|
|
|
113
113
|
}
|
|
114
114
|
break
|
|
115
115
|
|
|
116
|
+
case 'null':
|
|
117
|
+
withoutKey ?
|
|
118
|
+
whereObj = {
|
|
119
|
+
[Op.eq]: null
|
|
120
|
+
} :
|
|
121
|
+
whereObj[key] = {
|
|
122
|
+
[Op.eq]: null
|
|
123
|
+
}
|
|
124
|
+
break
|
|
125
|
+
|
|
116
126
|
case 'between':
|
|
117
127
|
withoutKey ?
|
|
118
128
|
whereObj = {
|
|
@@ -472,6 +482,12 @@ const filtersToSequelizeWhere = async(filters, opt) => {
|
|
|
472
482
|
}
|
|
473
483
|
break
|
|
474
484
|
|
|
485
|
+
case 'null':
|
|
486
|
+
whereObj = {
|
|
487
|
+
[key]: null
|
|
488
|
+
}
|
|
489
|
+
break
|
|
490
|
+
|
|
475
491
|
case 'between':
|
|
476
492
|
whereObj = {
|
|
477
493
|
[key]:{
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const redis = require('redis');
|
|
2
|
+
const client = redis.createClient();
|
|
3
|
+
client.connect()
|
|
4
|
+
.then(() => console.log('Connected to Redis'))
|
|
5
|
+
.catch((err) => console.error('Redis connection error:', err));
|
|
6
|
+
|
|
7
|
+
const queues = {}
|
|
8
|
+
|
|
9
|
+
const sleep = ms => new Promise(r => setTimeout(r, ms))
|
|
10
|
+
|
|
11
|
+
const processQueue = async(key) => {
|
|
12
|
+
const queue = queues[key]
|
|
13
|
+
if(queue.processing) return
|
|
14
|
+
queue.processing = true
|
|
15
|
+
|
|
16
|
+
const result = await client.hGetAll(key);
|
|
17
|
+
const keys = Object.keys(result ?? {})
|
|
18
|
+
if(keys.length < 1){
|
|
19
|
+
queue.processing = false
|
|
20
|
+
return
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const itemKeys = keys.splice(0, queue.concurrency)
|
|
24
|
+
if(itemKeys.length > 0){
|
|
25
|
+
await Promise.all(itemKeys.map(async itemKey => {
|
|
26
|
+
try{
|
|
27
|
+
const obj = JSON.parse(await client.hGet(key, itemKey))
|
|
28
|
+
await queue.pop(obj)
|
|
29
|
+
}
|
|
30
|
+
finally{
|
|
31
|
+
await client.hDel(key, itemKey)
|
|
32
|
+
}
|
|
33
|
+
}))
|
|
34
|
+
|
|
35
|
+
await sleep(queue.interval ?? 0)
|
|
36
|
+
}
|
|
37
|
+
queue.processing = false
|
|
38
|
+
|
|
39
|
+
await processQueue(key)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const queueItem = async(obj, opt) => {
|
|
43
|
+
if(!queues[opt.key]){
|
|
44
|
+
queues[opt.key] = {
|
|
45
|
+
interval: 16,
|
|
46
|
+
concurrency: 1,
|
|
47
|
+
|
|
48
|
+
...opt
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
await client.del(opt.key)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const { key } = opt
|
|
55
|
+
const subKey = `${key}-${new Date().getTime() + Math.random()}`
|
|
56
|
+
await client.hSet(key, subKey, JSON.stringify(obj));
|
|
57
|
+
|
|
58
|
+
processQueue(key).then()
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
module.exports = {
|
|
62
|
+
queueItem
|
|
63
|
+
}
|
package/src/utils/wss.js
CHANGED
|
@@ -222,7 +222,14 @@ class WSS extends EventEmitter2{
|
|
|
222
222
|
|
|
223
223
|
const token = req.headers['sec-websocket-protocol'];
|
|
224
224
|
try{
|
|
225
|
-
|
|
225
|
+
if(this._opt.auth){
|
|
226
|
+
await this._opt.auth(token, socket)
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
for(let fn of this._authFn) {
|
|
230
|
+
await fn(token, socket)
|
|
231
|
+
}
|
|
232
|
+
|
|
226
233
|
socket.isAuth = true
|
|
227
234
|
socket.send(await this.toBinaryData({ auth:true }))
|
|
228
235
|
|
|
@@ -230,7 +237,7 @@ class WSS extends EventEmitter2{
|
|
|
230
237
|
await subscriber.connect()
|
|
231
238
|
}
|
|
232
239
|
catch(e){
|
|
233
|
-
return socket.close(1002, e.message);
|
|
240
|
+
return socket.close(1002, (e.message ?? '').substring(0, 123));
|
|
234
241
|
}
|
|
235
242
|
|
|
236
243
|
if(this._opt.ping !== false){
|
|
@@ -271,6 +278,10 @@ class WSS extends EventEmitter2{
|
|
|
271
278
|
this._reqFn.push(fn)
|
|
272
279
|
}
|
|
273
280
|
|
|
281
|
+
use(fn){
|
|
282
|
+
this.req.apply(this, arguments)
|
|
283
|
+
}
|
|
284
|
+
|
|
274
285
|
async broadcast(channels, { model, event, items }){
|
|
275
286
|
|
|
276
287
|
if(!Array.isArray(channels))
|
package/src/utils/wss.mjs
CHANGED
|
@@ -69,7 +69,6 @@ class WSS extends EventEmitter2{
|
|
|
69
69
|
this.emit('visibilitychange', this._instance.readyState, [])
|
|
70
70
|
|
|
71
71
|
this.ping().catch(e => {
|
|
72
|
-
console.log('ping error', e)
|
|
73
72
|
this.reconnect().then()
|
|
74
73
|
})
|
|
75
74
|
}
|
|
@@ -128,8 +127,8 @@ class WSS extends EventEmitter2{
|
|
|
128
127
|
|
|
129
128
|
if(this._opt.debug){
|
|
130
129
|
status === 200 ?
|
|
131
|
-
console.log(`${new Date().getTime() - t1}ms`, `l:${JSON.stringify(data ?? '').length}
|
|
132
|
-
console.error(`${new Date().getTime() - t1}ms`, `l:${JSON.stringify(data ?? '').length}
|
|
130
|
+
console.log(`${path} (${new Date().getTime() - t1}ms)`, params, data, `l:${JSON.stringify(data ?? '').length}`) :
|
|
131
|
+
console.error(`${path} (${new Date().getTime() - t1}ms)`, params, data, `l:${JSON.stringify(data ?? '').length}`)
|
|
133
132
|
}
|
|
134
133
|
}
|
|
135
134
|
}
|
|
@@ -185,6 +184,7 @@ class WSS extends EventEmitter2{
|
|
|
185
184
|
|
|
186
185
|
sendSync(path, params, cb, err, override){
|
|
187
186
|
if(!this._instance || this._instance.readyState > 1){
|
|
187
|
+
this._pendingSend.push({ path, params, cb, err })
|
|
188
188
|
return
|
|
189
189
|
}
|
|
190
190
|
else if(!this._instance.isAuth){
|