@mulingai-npm/redis 3.40.44 → 3.40.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/managers/aggregated-content-manager.d.ts +5 -1
- package/dist/managers/aggregated-content-manager.js +11 -4
- package/dist/managers/mulingstream-listener-manager.d.ts +15 -0
- package/dist/managers/mulingstream-listener-manager.js +18 -0
- package/dist/managers/page-content-manager.d.ts +19 -1
- package/dist/managers/page-content-manager.js +22 -6
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { RedisClient } from '../redis-client';
|
|
2
|
+
import type { CacheVersionResolver } from './page-content-manager';
|
|
2
3
|
export interface CachedAggregatedContent {
|
|
3
4
|
id: string;
|
|
4
5
|
locale: string;
|
|
@@ -10,8 +11,11 @@ export interface CachedAggregatedContent {
|
|
|
10
11
|
}
|
|
11
12
|
export declare class AggregatedContentManager {
|
|
12
13
|
private redis;
|
|
14
|
+
private resolveVersion?;
|
|
13
15
|
private static DEFAULT_TTL;
|
|
14
|
-
constructor(redis: RedisClient);
|
|
16
|
+
constructor(redis: RedisClient, resolveVersion?: CacheVersionResolver);
|
|
17
|
+
/** `v<version>--`, or empty when no resolver was supplied. See PageContentManager. */
|
|
18
|
+
private versionSegment;
|
|
15
19
|
private key;
|
|
16
20
|
private build;
|
|
17
21
|
private scan;
|
|
@@ -2,11 +2,18 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AggregatedContentManager = void 0;
|
|
4
4
|
class AggregatedContentManager {
|
|
5
|
-
constructor(redis) {
|
|
5
|
+
constructor(redis, resolveVersion) {
|
|
6
6
|
this.redis = redis;
|
|
7
|
+
this.resolveVersion = resolveVersion;
|
|
8
|
+
}
|
|
9
|
+
/** `v<version>--`, or empty when no resolver was supplied. See PageContentManager. */
|
|
10
|
+
versionSegment() {
|
|
11
|
+
var _a;
|
|
12
|
+
const version = (_a = this.resolveVersion) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
13
|
+
return version ? `v${version}--` : '';
|
|
7
14
|
}
|
|
8
15
|
key(locale, domain) {
|
|
9
|
-
return `aggregated-content
|
|
16
|
+
return `aggregated-content--${this.versionSegment()}[${locale.toLowerCase()}]-[${domain.toLowerCase()}]`;
|
|
10
17
|
}
|
|
11
18
|
build(locale, domain, payload) {
|
|
12
19
|
const id = this.key(locale, domain);
|
|
@@ -41,7 +48,7 @@ class AggregatedContentManager {
|
|
|
41
48
|
return raw ? JSON.parse(raw) : null;
|
|
42
49
|
}
|
|
43
50
|
async getAllAggregatedContents() {
|
|
44
|
-
const keys = await this.scan('aggregated-content
|
|
51
|
+
const keys = await this.scan('aggregated-content--*[');
|
|
45
52
|
if (!keys.length)
|
|
46
53
|
return [];
|
|
47
54
|
const p = this.redis.pipeline();
|
|
@@ -53,7 +60,7 @@ class AggregatedContentManager {
|
|
|
53
60
|
await this.redis.unlink(this.key(locale, domain));
|
|
54
61
|
}
|
|
55
62
|
async clearAllAggregatedContents() {
|
|
56
|
-
const keys = await this.scan('aggregated-content
|
|
63
|
+
const keys = await this.scan('aggregated-content--*[');
|
|
57
64
|
if (keys.length)
|
|
58
65
|
await this.redis.unlink(...keys);
|
|
59
66
|
}
|
|
@@ -36,6 +36,21 @@ export declare class MulingstreamListenerManager {
|
|
|
36
36
|
totalListeners: number;
|
|
37
37
|
languageBreakdown: Record<string, number>;
|
|
38
38
|
}>;
|
|
39
|
+
/**
|
|
40
|
+
* How many people in this room are ACTUALLY RECEIVING translation right now.
|
|
41
|
+
*
|
|
42
|
+
* Church passes turn on this number rather than on how many people joined. A
|
|
43
|
+
* pass is spent only when translation reached a human being, so somebody
|
|
44
|
+
* sitting on the join screen, or with the tab open and audio stopped, must
|
|
45
|
+
* not burn a church's pass.
|
|
46
|
+
*
|
|
47
|
+
* `isListening` is already maintained by setListeningState, so this is the
|
|
48
|
+
* honest count rather than a proxy for it. Falls back to counting a listener
|
|
49
|
+
* whose flag has never been written, because the flag arrived after some
|
|
50
|
+
* clients shipped and an older client that is genuinely playing audio should
|
|
51
|
+
* still count.
|
|
52
|
+
*/
|
|
53
|
+
getReceivingCount(roomId: string): Promise<number>;
|
|
39
54
|
private capKey;
|
|
40
55
|
/**
|
|
41
56
|
* Cache the room's listener cap. Called by the speaker service at go-live and
|
|
@@ -239,6 +239,24 @@ class MulingstreamListenerManager {
|
|
|
239
239
|
languageBreakdown
|
|
240
240
|
};
|
|
241
241
|
}
|
|
242
|
+
/**
|
|
243
|
+
* How many people in this room are ACTUALLY RECEIVING translation right now.
|
|
244
|
+
*
|
|
245
|
+
* Church passes turn on this number rather than on how many people joined. A
|
|
246
|
+
* pass is spent only when translation reached a human being, so somebody
|
|
247
|
+
* sitting on the join screen, or with the tab open and audio stopped, must
|
|
248
|
+
* not burn a church's pass.
|
|
249
|
+
*
|
|
250
|
+
* `isListening` is already maintained by setListeningState, so this is the
|
|
251
|
+
* honest count rather than a proxy for it. Falls back to counting a listener
|
|
252
|
+
* whose flag has never been written, because the flag arrived after some
|
|
253
|
+
* clients shipped and an older client that is genuinely playing audio should
|
|
254
|
+
* still count.
|
|
255
|
+
*/
|
|
256
|
+
async getReceivingCount(roomId) {
|
|
257
|
+
const listeners = await this.getListenersByRoom(roomId);
|
|
258
|
+
return listeners.filter((l) => l.isListening !== false).length;
|
|
259
|
+
}
|
|
242
260
|
// ─── Per-room listener capacity (design B, 2026-07-09) ────────────────────
|
|
243
261
|
// The cap value is the room owner's plan `max_audience`, resolved ONCE by the
|
|
244
262
|
// speaker service when it goes live (it already fetches the plan entitlements)
|
|
@@ -10,10 +10,28 @@ export interface CachedPageContent {
|
|
|
10
10
|
lastUsedAt: number | null;
|
|
11
11
|
totalUsage: number;
|
|
12
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Returns the namespace the cache should currently write under. Called per
|
|
15
|
+
* operation rather than captured once, so a caller can change it at runtime
|
|
16
|
+
* (local development, where content is edited under a running process).
|
|
17
|
+
*/
|
|
18
|
+
export type CacheVersionResolver = () => string;
|
|
13
19
|
export declare class PageContentManager {
|
|
14
20
|
private redis;
|
|
21
|
+
private resolveVersion?;
|
|
15
22
|
private static DEFAULT_TTL;
|
|
16
|
-
|
|
23
|
+
/**
|
|
24
|
+
* `resolveVersion` namespaces every key by the content it was built from.
|
|
25
|
+
* Content ships inside the service image, so nothing else invalidates this
|
|
26
|
+
* cache on deploy: without the namespace a new build keeps serving the
|
|
27
|
+
* previous build's content until the 30-day TTL expires.
|
|
28
|
+
*
|
|
29
|
+
* Omit it and keys keep their original un-namespaced shape, so an existing
|
|
30
|
+
* deployment behaves exactly as before.
|
|
31
|
+
*/
|
|
32
|
+
constructor(redis: RedisClient, resolveVersion?: CacheVersionResolver);
|
|
33
|
+
/** `v<version>--`, or empty when no resolver was supplied. */
|
|
34
|
+
private versionSegment;
|
|
17
35
|
private key;
|
|
18
36
|
private build;
|
|
19
37
|
private scan;
|
|
@@ -2,11 +2,27 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PageContentManager = void 0;
|
|
4
4
|
class PageContentManager {
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* `resolveVersion` namespaces every key by the content it was built from.
|
|
7
|
+
* Content ships inside the service image, so nothing else invalidates this
|
|
8
|
+
* cache on deploy: without the namespace a new build keeps serving the
|
|
9
|
+
* previous build's content until the 30-day TTL expires.
|
|
10
|
+
*
|
|
11
|
+
* Omit it and keys keep their original un-namespaced shape, so an existing
|
|
12
|
+
* deployment behaves exactly as before.
|
|
13
|
+
*/
|
|
14
|
+
constructor(redis, resolveVersion) {
|
|
6
15
|
this.redis = redis;
|
|
16
|
+
this.resolveVersion = resolveVersion;
|
|
17
|
+
}
|
|
18
|
+
/** `v<version>--`, or empty when no resolver was supplied. */
|
|
19
|
+
versionSegment() {
|
|
20
|
+
var _a;
|
|
21
|
+
const version = (_a = this.resolveVersion) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
22
|
+
return version ? `v${version}--` : '';
|
|
7
23
|
}
|
|
8
24
|
key(locale, route, domain) {
|
|
9
|
-
return `page-content
|
|
25
|
+
return `page-content--${this.versionSegment()}[${locale.toLowerCase()}]-[${route.toLowerCase()}]-[${domain.toLowerCase()}]`;
|
|
10
26
|
}
|
|
11
27
|
build(locale, route, domain, payload) {
|
|
12
28
|
const id = this.key(locale, route, domain);
|
|
@@ -43,7 +59,7 @@ class PageContentManager {
|
|
|
43
59
|
return raw ? JSON.parse(raw) : null;
|
|
44
60
|
}
|
|
45
61
|
async getAllPageContents() {
|
|
46
|
-
const keys = await this.scan('page-content
|
|
62
|
+
const keys = await this.scan('page-content--*[');
|
|
47
63
|
if (!keys.length)
|
|
48
64
|
return [];
|
|
49
65
|
const p = this.redis.pipeline();
|
|
@@ -52,7 +68,7 @@ class PageContentManager {
|
|
|
52
68
|
return res.flatMap(([_, v]) => (v ? [JSON.parse(v)] : []));
|
|
53
69
|
}
|
|
54
70
|
async getAllPageContentsByLocale(locale) {
|
|
55
|
-
const keys = await this.scan(`page-content
|
|
71
|
+
const keys = await this.scan(`page-content--*[${locale.toLowerCase()}]-[*`);
|
|
56
72
|
if (!keys.length)
|
|
57
73
|
return [];
|
|
58
74
|
const p = this.redis.pipeline();
|
|
@@ -64,12 +80,12 @@ class PageContentManager {
|
|
|
64
80
|
await this.redis.unlink(this.key(locale, route, domain));
|
|
65
81
|
}
|
|
66
82
|
async clearAllPageContents() {
|
|
67
|
-
const keys = await this.scan('page-content
|
|
83
|
+
const keys = await this.scan('page-content--*[');
|
|
68
84
|
if (keys.length)
|
|
69
85
|
await this.redis.unlink(...keys);
|
|
70
86
|
}
|
|
71
87
|
async clearAllPageContentsByLocale(locale) {
|
|
72
|
-
const keys = await this.scan(`page-content
|
|
88
|
+
const keys = await this.scan(`page-content--*[${locale.toLowerCase()}]-[*`);
|
|
73
89
|
if (keys.length)
|
|
74
90
|
await this.redis.unlink(...keys);
|
|
75
91
|
}
|