@pluv/persistence-redis 0.41.7 → 0.43.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/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +23 -0
- package/dist/index.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +43 -1
- package/dist/index.mjs +43 -1
- package/package.json +7 -7
- package/src/PersistenceRedis.ts +59 -2
- package/src/utils/index.ts +1 -0
- package/src/utils/partitionByLength.ts +8 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @pluv/persistence-redis@0.
|
|
2
|
+
> @pluv/persistence-redis@0.43.0 build /home/runner/work/pluv/pluv/packages/persistence-redis
|
|
3
3
|
> tsup src/index.ts --format esm,cjs --dts
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
[34mCLI[39m Target: es6
|
|
9
9
|
[34mESM[39m Build start
|
|
10
10
|
[34mCJS[39m Build start
|
|
11
|
-
[
|
|
11
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m4.81 KB[39m
|
|
12
|
+
[32mESM[39m ⚡️ Build success in 60ms
|
|
13
|
+
[32mCJS[39m [1mdist/index.js [22m[32m5.83 KB[39m
|
|
12
14
|
[32mCJS[39m ⚡️ Build success in 61ms
|
|
13
|
-
[32mESM[39m [1mdist/index.mjs [22m[32m3.37 KB[39m
|
|
14
|
-
[32mESM[39m ⚡️ Build success in 61ms
|
|
15
15
|
[34mDTS[39m Build start
|
|
16
|
-
[32mDTS[39m ⚡️ Build success in
|
|
17
|
-
[32mDTS[39m [1mdist/index.d.mts [22m[32m1.
|
|
18
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[32m1.
|
|
16
|
+
[32mDTS[39m ⚡️ Build success in 4934ms
|
|
17
|
+
[32mDTS[39m [1mdist/index.d.mts [22m[32m1.17 KB[39m
|
|
18
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m1.17 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @pluv/persistence-redis
|
|
2
2
|
|
|
3
|
+
## 0.43.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [e60a677]
|
|
8
|
+
- Updated dependencies [0063e80]
|
|
9
|
+
- Updated dependencies [244a973]
|
|
10
|
+
- Updated dependencies [4b0fbb3]
|
|
11
|
+
- @pluv/io@0.43.0
|
|
12
|
+
- @pluv/types@0.43.0
|
|
13
|
+
|
|
14
|
+
## 0.42.0
|
|
15
|
+
|
|
16
|
+
### Minor Changes
|
|
17
|
+
|
|
18
|
+
- 4ce32ee: **BREAKING** `Persistence.getUsers` now returns a map of connection id strings to user JSON objects instead of an array of user JSON objects. This change is intended to be internal only and generally non-breaking.
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- Updated dependencies [cf1529a]
|
|
23
|
+
- @pluv/io@0.42.0
|
|
24
|
+
- @pluv/types@0.42.0
|
|
25
|
+
|
|
3
26
|
## 0.41.7
|
|
4
27
|
|
|
5
28
|
### Patch Changes
|
package/dist/index.d.mts
CHANGED
|
@@ -8,6 +8,7 @@ interface PersistenceRedisOptions {
|
|
|
8
8
|
}
|
|
9
9
|
declare class PersistenceRedis extends AbstractPersistence {
|
|
10
10
|
private _client;
|
|
11
|
+
private _initialized;
|
|
11
12
|
constructor(options: PersistenceRedisOptions);
|
|
12
13
|
addUser(room: string, connectionId: string, user: JsonObject | null): Promise<void>;
|
|
13
14
|
deleteStorageState(room: string): Promise<void>;
|
|
@@ -16,8 +17,9 @@ declare class PersistenceRedis extends AbstractPersistence {
|
|
|
16
17
|
getStorageState(room: string): Promise<string | null>;
|
|
17
18
|
setStorageState(room: string, state: string): Promise<void>;
|
|
18
19
|
getUser(room: string, connectionId: string): Promise<JsonObject | null>;
|
|
19
|
-
getUsers(room: string): Promise<
|
|
20
|
+
getUsers(room: string): Promise<Map<[connectionId: string][0], JsonObject | null>>;
|
|
20
21
|
getUsersSize(room: string): Promise<number>;
|
|
22
|
+
initialize(roomContext: {}): this;
|
|
21
23
|
private _getClusterKey;
|
|
22
24
|
private _getRoomStorageKey;
|
|
23
25
|
private _getRoomUsersKey;
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ interface PersistenceRedisOptions {
|
|
|
8
8
|
}
|
|
9
9
|
declare class PersistenceRedis extends AbstractPersistence {
|
|
10
10
|
private _client;
|
|
11
|
+
private _initialized;
|
|
11
12
|
constructor(options: PersistenceRedisOptions);
|
|
12
13
|
addUser(room: string, connectionId: string, user: JsonObject | null): Promise<void>;
|
|
13
14
|
deleteStorageState(room: string): Promise<void>;
|
|
@@ -16,8 +17,9 @@ declare class PersistenceRedis extends AbstractPersistence {
|
|
|
16
17
|
getStorageState(room: string): Promise<string | null>;
|
|
17
18
|
setStorageState(room: string, state: string): Promise<void>;
|
|
18
19
|
getUser(room: string, connectionId: string): Promise<JsonObject | null>;
|
|
19
|
-
getUsers(room: string): Promise<
|
|
20
|
+
getUsers(room: string): Promise<Map<[connectionId: string][0], JsonObject | null>>;
|
|
20
21
|
getUsersSize(room: string): Promise<number>;
|
|
22
|
+
initialize(roomContext: {}): this;
|
|
21
23
|
private _getClusterKey;
|
|
22
24
|
private _getRoomStorageKey;
|
|
23
25
|
private _getRoomUsersKey;
|
package/dist/index.js
CHANGED
|
@@ -46,26 +46,44 @@ module.exports = __toCommonJS(index_exports);
|
|
|
46
46
|
|
|
47
47
|
// src/PersistenceRedis.ts
|
|
48
48
|
var import_io = require("@pluv/io");
|
|
49
|
+
|
|
50
|
+
// src/utils/partitionByLength.ts
|
|
51
|
+
var partitionByLength = (arr, length) => {
|
|
52
|
+
if (!arr.length) return [];
|
|
53
|
+
const head = arr.slice(0, length);
|
|
54
|
+
const tail = arr.slice(length);
|
|
55
|
+
return [head, ...partitionByLength(tail, length)];
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// src/PersistenceRedis.ts
|
|
49
59
|
var DELIMITER = ":::";
|
|
50
60
|
var HASH_TAG = "{PluvPersistenceRedis}";
|
|
61
|
+
var GET_USERS_CONCURRENCY = 4;
|
|
51
62
|
var PersistenceRedis = class extends import_io.AbstractPersistence {
|
|
52
63
|
constructor(options) {
|
|
53
64
|
super();
|
|
65
|
+
this._initialized = null;
|
|
54
66
|
const { client } = options;
|
|
55
67
|
this._client = client;
|
|
56
68
|
}
|
|
57
69
|
addUser(room, connectionId, user) {
|
|
58
70
|
return __async(this, null, function* () {
|
|
71
|
+
if (!this._initialized) return;
|
|
72
|
+
yield this._initialized;
|
|
59
73
|
yield this._client.multi().sadd(this._getRoomUsersKey(room), connectionId).set(this._getRoomUsersUserKey(room, connectionId), JSON.stringify(user)).exec();
|
|
60
74
|
});
|
|
61
75
|
}
|
|
62
76
|
deleteStorageState(room) {
|
|
63
77
|
return __async(this, null, function* () {
|
|
78
|
+
if (!this._initialized) return;
|
|
79
|
+
yield this._initialized;
|
|
64
80
|
yield this._client.del(this._getRoomStorageKey(room));
|
|
65
81
|
});
|
|
66
82
|
}
|
|
67
83
|
deleteUser(room, connectionId) {
|
|
68
84
|
return __async(this, null, function* () {
|
|
85
|
+
if (!this._initialized) return;
|
|
86
|
+
yield this._initialized;
|
|
69
87
|
const size = yield this.getUsersSize(room);
|
|
70
88
|
let multi = this._client.multi().srem(this._getRoomUsersKey(room), connectionId).del(this._getRoomUsersUserKey(room, connectionId));
|
|
71
89
|
if (size === 1) {
|
|
@@ -76,6 +94,8 @@ var PersistenceRedis = class extends import_io.AbstractPersistence {
|
|
|
76
94
|
}
|
|
77
95
|
deleteUsers(room) {
|
|
78
96
|
return __async(this, null, function* () {
|
|
97
|
+
if (!this._initialized) return;
|
|
98
|
+
yield this._initialized;
|
|
79
99
|
const members = yield this._client.smembers(this._getRoomUsersKey(room));
|
|
80
100
|
yield members.reduce(
|
|
81
101
|
(commands, connectionId) => {
|
|
@@ -87,31 +107,53 @@ var PersistenceRedis = class extends import_io.AbstractPersistence {
|
|
|
87
107
|
}
|
|
88
108
|
getStorageState(room) {
|
|
89
109
|
return __async(this, null, function* () {
|
|
110
|
+
if (!this._initialized) return null;
|
|
111
|
+
yield this._initialized;
|
|
90
112
|
return yield this._client.get(this._getRoomStorageKey(room));
|
|
91
113
|
});
|
|
92
114
|
}
|
|
93
115
|
setStorageState(room, state) {
|
|
94
116
|
return __async(this, null, function* () {
|
|
117
|
+
if (!this._initialized) return;
|
|
118
|
+
yield this._initialized;
|
|
95
119
|
yield this._client.set(this._getRoomStorageKey(room), state);
|
|
96
120
|
});
|
|
97
121
|
}
|
|
98
122
|
getUser(room, connectionId) {
|
|
99
123
|
return __async(this, null, function* () {
|
|
124
|
+
if (!this._initialized) return null;
|
|
125
|
+
yield this._initialized;
|
|
100
126
|
const data = yield this._client.get(this._getRoomUsersUserKey(room, connectionId));
|
|
101
127
|
return !data ? null : JSON.parse(data);
|
|
102
128
|
});
|
|
103
129
|
}
|
|
104
130
|
getUsers(room) {
|
|
105
131
|
return __async(this, null, function* () {
|
|
132
|
+
if (!this._initialized) return /* @__PURE__ */ new Map();
|
|
133
|
+
yield this._initialized;
|
|
106
134
|
const members = yield this._client.smembers(this._getRoomUsersKey(room));
|
|
107
|
-
|
|
135
|
+
const partitions = partitionByLength(members, GET_USERS_CONCURRENCY);
|
|
136
|
+
return yield partitions.reduce((promise, partition) => __async(this, null, function* () {
|
|
137
|
+
const map = yield promise;
|
|
138
|
+
const promises = partition.map((connectionId) => __async(this, null, function* () {
|
|
139
|
+
map.set(connectionId, yield this.getUser(room, connectionId));
|
|
140
|
+
}));
|
|
141
|
+
yield Promise.all(promises);
|
|
142
|
+
return map;
|
|
143
|
+
}), Promise.resolve(/* @__PURE__ */ new Map()));
|
|
108
144
|
});
|
|
109
145
|
}
|
|
110
146
|
getUsersSize(room) {
|
|
111
147
|
return __async(this, null, function* () {
|
|
148
|
+
if (!this._initialized) return 0;
|
|
149
|
+
yield this._initialized;
|
|
112
150
|
return yield this._client.scard(this._getRoomUsersKey(room));
|
|
113
151
|
});
|
|
114
152
|
}
|
|
153
|
+
initialize(roomContext) {
|
|
154
|
+
this._initialized = Promise.resolve(true);
|
|
155
|
+
return this;
|
|
156
|
+
}
|
|
115
157
|
_getClusterKey(key) {
|
|
116
158
|
return `${HASH_TAG}${key}`;
|
|
117
159
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -21,26 +21,44 @@ var __async = (__this, __arguments, generator) => {
|
|
|
21
21
|
|
|
22
22
|
// src/PersistenceRedis.ts
|
|
23
23
|
import { AbstractPersistence } from "@pluv/io";
|
|
24
|
+
|
|
25
|
+
// src/utils/partitionByLength.ts
|
|
26
|
+
var partitionByLength = (arr, length) => {
|
|
27
|
+
if (!arr.length) return [];
|
|
28
|
+
const head = arr.slice(0, length);
|
|
29
|
+
const tail = arr.slice(length);
|
|
30
|
+
return [head, ...partitionByLength(tail, length)];
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// src/PersistenceRedis.ts
|
|
24
34
|
var DELIMITER = ":::";
|
|
25
35
|
var HASH_TAG = "{PluvPersistenceRedis}";
|
|
36
|
+
var GET_USERS_CONCURRENCY = 4;
|
|
26
37
|
var PersistenceRedis = class extends AbstractPersistence {
|
|
27
38
|
constructor(options) {
|
|
28
39
|
super();
|
|
40
|
+
this._initialized = null;
|
|
29
41
|
const { client } = options;
|
|
30
42
|
this._client = client;
|
|
31
43
|
}
|
|
32
44
|
addUser(room, connectionId, user) {
|
|
33
45
|
return __async(this, null, function* () {
|
|
46
|
+
if (!this._initialized) return;
|
|
47
|
+
yield this._initialized;
|
|
34
48
|
yield this._client.multi().sadd(this._getRoomUsersKey(room), connectionId).set(this._getRoomUsersUserKey(room, connectionId), JSON.stringify(user)).exec();
|
|
35
49
|
});
|
|
36
50
|
}
|
|
37
51
|
deleteStorageState(room) {
|
|
38
52
|
return __async(this, null, function* () {
|
|
53
|
+
if (!this._initialized) return;
|
|
54
|
+
yield this._initialized;
|
|
39
55
|
yield this._client.del(this._getRoomStorageKey(room));
|
|
40
56
|
});
|
|
41
57
|
}
|
|
42
58
|
deleteUser(room, connectionId) {
|
|
43
59
|
return __async(this, null, function* () {
|
|
60
|
+
if (!this._initialized) return;
|
|
61
|
+
yield this._initialized;
|
|
44
62
|
const size = yield this.getUsersSize(room);
|
|
45
63
|
let multi = this._client.multi().srem(this._getRoomUsersKey(room), connectionId).del(this._getRoomUsersUserKey(room, connectionId));
|
|
46
64
|
if (size === 1) {
|
|
@@ -51,6 +69,8 @@ var PersistenceRedis = class extends AbstractPersistence {
|
|
|
51
69
|
}
|
|
52
70
|
deleteUsers(room) {
|
|
53
71
|
return __async(this, null, function* () {
|
|
72
|
+
if (!this._initialized) return;
|
|
73
|
+
yield this._initialized;
|
|
54
74
|
const members = yield this._client.smembers(this._getRoomUsersKey(room));
|
|
55
75
|
yield members.reduce(
|
|
56
76
|
(commands, connectionId) => {
|
|
@@ -62,31 +82,53 @@ var PersistenceRedis = class extends AbstractPersistence {
|
|
|
62
82
|
}
|
|
63
83
|
getStorageState(room) {
|
|
64
84
|
return __async(this, null, function* () {
|
|
85
|
+
if (!this._initialized) return null;
|
|
86
|
+
yield this._initialized;
|
|
65
87
|
return yield this._client.get(this._getRoomStorageKey(room));
|
|
66
88
|
});
|
|
67
89
|
}
|
|
68
90
|
setStorageState(room, state) {
|
|
69
91
|
return __async(this, null, function* () {
|
|
92
|
+
if (!this._initialized) return;
|
|
93
|
+
yield this._initialized;
|
|
70
94
|
yield this._client.set(this._getRoomStorageKey(room), state);
|
|
71
95
|
});
|
|
72
96
|
}
|
|
73
97
|
getUser(room, connectionId) {
|
|
74
98
|
return __async(this, null, function* () {
|
|
99
|
+
if (!this._initialized) return null;
|
|
100
|
+
yield this._initialized;
|
|
75
101
|
const data = yield this._client.get(this._getRoomUsersUserKey(room, connectionId));
|
|
76
102
|
return !data ? null : JSON.parse(data);
|
|
77
103
|
});
|
|
78
104
|
}
|
|
79
105
|
getUsers(room) {
|
|
80
106
|
return __async(this, null, function* () {
|
|
107
|
+
if (!this._initialized) return /* @__PURE__ */ new Map();
|
|
108
|
+
yield this._initialized;
|
|
81
109
|
const members = yield this._client.smembers(this._getRoomUsersKey(room));
|
|
82
|
-
|
|
110
|
+
const partitions = partitionByLength(members, GET_USERS_CONCURRENCY);
|
|
111
|
+
return yield partitions.reduce((promise, partition) => __async(this, null, function* () {
|
|
112
|
+
const map = yield promise;
|
|
113
|
+
const promises = partition.map((connectionId) => __async(this, null, function* () {
|
|
114
|
+
map.set(connectionId, yield this.getUser(room, connectionId));
|
|
115
|
+
}));
|
|
116
|
+
yield Promise.all(promises);
|
|
117
|
+
return map;
|
|
118
|
+
}), Promise.resolve(/* @__PURE__ */ new Map()));
|
|
83
119
|
});
|
|
84
120
|
}
|
|
85
121
|
getUsersSize(room) {
|
|
86
122
|
return __async(this, null, function* () {
|
|
123
|
+
if (!this._initialized) return 0;
|
|
124
|
+
yield this._initialized;
|
|
87
125
|
return yield this._client.scard(this._getRoomUsersKey(room));
|
|
88
126
|
});
|
|
89
127
|
}
|
|
128
|
+
initialize(roomContext) {
|
|
129
|
+
this._initialized = Promise.resolve(true);
|
|
130
|
+
return this;
|
|
131
|
+
}
|
|
90
132
|
_getClusterKey(key) {
|
|
91
133
|
return `${HASH_TAG}${key}`;
|
|
92
134
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pluv/persistence-redis",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.43.0",
|
|
4
4
|
"description": "@pluv/io crdt storage persistence for node.js",
|
|
5
5
|
"author": "leedavidcs",
|
|
6
6
|
"license": "MIT",
|
|
@@ -17,20 +17,20 @@
|
|
|
17
17
|
"access": "public"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@types/node": "^22.
|
|
21
|
-
"@pluv/io": "^0.
|
|
22
|
-
"@pluv/types": "^0.
|
|
20
|
+
"@types/node": "^22.15.3",
|
|
21
|
+
"@pluv/io": "^0.43.0",
|
|
22
|
+
"@pluv/types": "^0.43.0"
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|
|
25
25
|
"ioredis": "^5.0.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"eslint": "^9.25.
|
|
28
|
+
"eslint": "^9.25.1",
|
|
29
29
|
"ioredis": "^5.6.1",
|
|
30
30
|
"tsup": "^8.4.0",
|
|
31
31
|
"typescript": "^5.8.3",
|
|
32
|
-
"@pluv/tsconfig": "^0.
|
|
33
|
-
"eslint-config-pluv": "^0.
|
|
32
|
+
"@pluv/tsconfig": "^0.43.0",
|
|
33
|
+
"eslint-config-pluv": "^0.43.0"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
36
|
"build": "tsup src/index.ts --format esm,cjs --dts",
|
package/src/PersistenceRedis.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { AbstractPersistence } from "@pluv/io";
|
|
2
2
|
import type { JsonObject } from "@pluv/types";
|
|
3
3
|
import type { Cluster, Redis } from "ioredis";
|
|
4
|
+
import { partitionByLength } from "./utils";
|
|
4
5
|
|
|
5
6
|
const DELIMITER = ":::";
|
|
6
7
|
const HASH_TAG = "{PluvPersistenceRedis}";
|
|
7
8
|
|
|
9
|
+
const GET_USERS_CONCURRENCY = 4;
|
|
10
|
+
|
|
8
11
|
export type RedisClient = Cluster | Redis;
|
|
9
12
|
|
|
10
13
|
export interface PersistenceRedisOptions {
|
|
@@ -13,6 +16,7 @@ export interface PersistenceRedisOptions {
|
|
|
13
16
|
|
|
14
17
|
export class PersistenceRedis extends AbstractPersistence {
|
|
15
18
|
private _client: RedisClient;
|
|
19
|
+
private _initialized: Promise<true> | null = null;
|
|
16
20
|
|
|
17
21
|
constructor(options: PersistenceRedisOptions) {
|
|
18
22
|
super();
|
|
@@ -23,6 +27,10 @@ export class PersistenceRedis extends AbstractPersistence {
|
|
|
23
27
|
}
|
|
24
28
|
|
|
25
29
|
public async addUser(room: string, connectionId: string, user: JsonObject | null): Promise<void> {
|
|
30
|
+
if (!this._initialized) return;
|
|
31
|
+
|
|
32
|
+
await this._initialized;
|
|
33
|
+
|
|
26
34
|
await this._client
|
|
27
35
|
.multi()
|
|
28
36
|
.sadd(this._getRoomUsersKey(room), connectionId)
|
|
@@ -31,10 +39,18 @@ export class PersistenceRedis extends AbstractPersistence {
|
|
|
31
39
|
}
|
|
32
40
|
|
|
33
41
|
public async deleteStorageState(room: string): Promise<void> {
|
|
42
|
+
if (!this._initialized) return;
|
|
43
|
+
|
|
44
|
+
await this._initialized;
|
|
45
|
+
|
|
34
46
|
await this._client.del(this._getRoomStorageKey(room));
|
|
35
47
|
}
|
|
36
48
|
|
|
37
49
|
public async deleteUser(room: string, connectionId: string): Promise<void> {
|
|
50
|
+
if (!this._initialized) return;
|
|
51
|
+
|
|
52
|
+
await this._initialized;
|
|
53
|
+
|
|
38
54
|
const size = await this.getUsersSize(room);
|
|
39
55
|
|
|
40
56
|
let multi = this._client
|
|
@@ -50,6 +66,10 @@ export class PersistenceRedis extends AbstractPersistence {
|
|
|
50
66
|
}
|
|
51
67
|
|
|
52
68
|
public async deleteUsers(room: string): Promise<void> {
|
|
69
|
+
if (!this._initialized) return;
|
|
70
|
+
|
|
71
|
+
await this._initialized;
|
|
72
|
+
|
|
53
73
|
const members = await this._client.smembers(this._getRoomUsersKey(room));
|
|
54
74
|
|
|
55
75
|
await members
|
|
@@ -63,29 +83,66 @@ export class PersistenceRedis extends AbstractPersistence {
|
|
|
63
83
|
}
|
|
64
84
|
|
|
65
85
|
public async getStorageState(room: string): Promise<string | null> {
|
|
86
|
+
if (!this._initialized) return null;
|
|
87
|
+
|
|
88
|
+
await this._initialized;
|
|
89
|
+
|
|
66
90
|
return await this._client.get(this._getRoomStorageKey(room));
|
|
67
91
|
}
|
|
68
92
|
|
|
69
93
|
public async setStorageState(room: string, state: string): Promise<void> {
|
|
94
|
+
if (!this._initialized) return;
|
|
95
|
+
|
|
96
|
+
await this._initialized;
|
|
97
|
+
|
|
70
98
|
await this._client.set(this._getRoomStorageKey(room), state);
|
|
71
99
|
}
|
|
72
100
|
|
|
73
101
|
public async getUser(room: string, connectionId: string): Promise<JsonObject | null> {
|
|
102
|
+
if (!this._initialized) return null;
|
|
103
|
+
|
|
104
|
+
await this._initialized;
|
|
105
|
+
|
|
74
106
|
const data = await this._client.get(this._getRoomUsersUserKey(room, connectionId));
|
|
75
107
|
|
|
76
108
|
return !data ? null : JSON.parse(data);
|
|
77
109
|
}
|
|
78
110
|
|
|
79
|
-
public async getUsers(room: string): Promise<
|
|
111
|
+
public async getUsers(room: string): Promise<Map<[connectionId: string][0], JsonObject | null>> {
|
|
112
|
+
if (!this._initialized) return new Map();
|
|
113
|
+
|
|
114
|
+
await this._initialized;
|
|
115
|
+
|
|
80
116
|
const members = await this._client.smembers(this._getRoomUsersKey(room));
|
|
117
|
+
const partitions = partitionByLength(members, GET_USERS_CONCURRENCY);
|
|
118
|
+
|
|
119
|
+
return await partitions.reduce(async (promise, partition) => {
|
|
120
|
+
const map = await promise;
|
|
121
|
+
|
|
122
|
+
const promises = partition.map(async (connectionId) => {
|
|
123
|
+
map.set(connectionId, await this.getUser(room, connectionId));
|
|
124
|
+
});
|
|
81
125
|
|
|
82
|
-
|
|
126
|
+
await Promise.all(promises);
|
|
127
|
+
|
|
128
|
+
return map;
|
|
129
|
+
}, Promise.resolve(new Map<string, JsonObject | null>()));
|
|
83
130
|
}
|
|
84
131
|
|
|
85
132
|
public async getUsersSize(room: string): Promise<number> {
|
|
133
|
+
if (!this._initialized) return 0;
|
|
134
|
+
|
|
135
|
+
await this._initialized;
|
|
136
|
+
|
|
86
137
|
return await this._client.scard(this._getRoomUsersKey(room));
|
|
87
138
|
}
|
|
88
139
|
|
|
140
|
+
public initialize(roomContext: {}): this {
|
|
141
|
+
this._initialized = Promise.resolve(true as const);
|
|
142
|
+
|
|
143
|
+
return this;
|
|
144
|
+
}
|
|
145
|
+
|
|
89
146
|
private _getClusterKey(key: string): string {
|
|
90
147
|
return `${HASH_TAG}${key}`;
|
|
91
148
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { partitionByLength } from "./partitionByLength";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const partitionByLength = <T>(arr: readonly T[] | T[], length: number): readonly (readonly T[])[] => {
|
|
2
|
+
if (!arr.length) return [];
|
|
3
|
+
|
|
4
|
+
const head = arr.slice(0, length);
|
|
5
|
+
const tail = arr.slice(length);
|
|
6
|
+
|
|
7
|
+
return [head, ...partitionByLength(tail, length)];
|
|
8
|
+
};
|