Socket
Socket
Sign inDemoInstall

@growthbook/proxy

Package Overview
Dependencies
Maintainers
1
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@growthbook/proxy - npm Package Compare versions

Comparing version 1.0.3 to 1.0.4

.github/workflows/ci.yml

1

dist/app.js

@@ -87,2 +87,3 @@ "use strict";

enableEventStream: true,
enableEventStreamHeaders: true,
proxyAllRequests: false,

@@ -89,0 +90,0 @@ };

7

dist/init.js

@@ -43,3 +43,3 @@ "use strict";

exports.default = () => __awaiter(void 0, void 0, void 0, function* () {
var _a, _b;
var _a, _b, _c, _d, _e;
const context = {

@@ -49,2 +49,4 @@ growthbookApiHost: process.env.GROWTHBOOK_API_HOST,

enableAdmin: ["true", "1"].includes((_a = process.env.ENABLE_ADMIN) !== null && _a !== void 0 ? _a : "0"),
enableEventStream: ["true", "1"].includes((_b = process.env.ENABLE_EVENT_STREAM) !== null && _b !== void 0 ? _b : "1"),
enableEventStreamHeaders: ["true", "1"].includes((_c = process.env.ENABLE_EVENT_STREAM_HEADERS) !== null && _c !== void 0 ? _c : "1"),
adminKey: process.env.ADMIN_KEY,

@@ -57,4 +59,5 @@ environment: process.env.NODE_ENV,

expiresTTL: parseInt(process.env.CACHE_EXPIRES_TTL || "600"),
allowStale: ["true", "1"].includes((_b = process.env.CACHE_ALLOW_STALE) !== null && _b !== void 0 ? _b : "1"),
allowStale: ["true", "1"].includes((_d = process.env.CACHE_ALLOW_STALE) !== null && _d !== void 0 ? _d : "1"),
useAdditionalMemoryCache: true,
publishPayloadToChannel: ["true", "1"].includes((_e = process.env.PUBLISH_PAYLOAD_TO_CHANNEL) !== null && _e !== void 0 ? _e : "0"),
},

@@ -61,0 +64,0 @@ };

@@ -15,3 +15,3 @@ "use strict";

var _a, _b;
if ((_b = (_a = req.app.locals) === null || _a === void 0 ? void 0 : _a.ctx) === null || _b === void 0 ? void 0 : _b.enableEventStream) {
if ((_b = (_a = req.app.locals) === null || _a === void 0 ? void 0 : _a.ctx) === null || _b === void 0 ? void 0 : _b.enableEventStreamHeaders) {
res.setHeader("x-sse-support", "enabled");

@@ -18,0 +18,0 @@ res.setHeader("Access-Control-Expose-Headers", "x-sse-support");

@@ -18,2 +18,3 @@ import { Context } from "../../types";

useAdditionalMemoryCache?: boolean;
publishPayloadToChannel?: boolean;
}

@@ -20,0 +21,0 @@ export declare type FeaturesCache = MemoryCache | RedisCache | MongoCache | null;

@@ -25,3 +25,3 @@ "use strict";

logger_1.default.info("using Redis cache");
exports.featuresCache = new RedisCache_1.RedisCache(context.cacheSettings);
exports.featuresCache = new RedisCache_1.RedisCache(context.cacheSettings, context);
yield exports.featuresCache.connect();

@@ -28,0 +28,0 @@ }

@@ -0,1 +1,2 @@

import { MongoClient } from "mongodb";
import { CacheEntry, CacheSettings } from "./index";

@@ -18,2 +19,3 @@ export declare class MongoCache {

set(key: string, payload: unknown): Promise<void>;
getClient(): MongoClient | undefined;
}

@@ -81,2 +81,5 @@ "use strict";

}
if (!entry) {
return undefined;
}
if (!this.allowStale && entry.staleOn < new Date()) {

@@ -115,4 +118,7 @@ return undefined;

}
getClient() {
return this.client;
}
}
exports.MongoCache = MongoCache;
//# sourceMappingURL=MongoCache.js.map

@@ -0,4 +1,8 @@

import { Context } from "../../types";
import { CacheEntry, CacheSettings } from "./index";
export declare class RedisCache {
private client;
private clientUUID;
private readonly publishPayloadToChannel;
private subscriberClient;
private readonly memoryCacheClient;

@@ -9,8 +13,574 @@ private readonly connectionUrl;

readonly allowStale: boolean;
private readonly appContext?;
constructor({ staleTTL, // 1 minute
expiresTTL, // 10 minutes
allowStale, connectionUrl, useAdditionalMemoryCache, }?: CacheSettings);
allowStale, connectionUrl, useAdditionalMemoryCache, publishPayloadToChannel, }?: CacheSettings, appContext?: Context);
connect(): Promise<void>;
get(key: string): Promise<CacheEntry | undefined>;
set(key: string, payload: unknown): Promise<void>;
private subscribe;
getClient(): import("@redis/client").RedisClientType<{
graph: {
CONFIG_GET: typeof import("@redis/graph/dist/commands/CONFIG_GET");
configGet: typeof import("@redis/graph/dist/commands/CONFIG_GET");
CONFIG_SET: typeof import("@redis/graph/dist/commands/CONFIG_SET");
configSet: typeof import("@redis/graph/dist/commands/CONFIG_SET");
DELETE: typeof import("@redis/graph/dist/commands/DELETE");
delete: typeof import("@redis/graph/dist/commands/DELETE");
EXPLAIN: typeof import("@redis/graph/dist/commands/EXPLAIN");
explain: typeof import("@redis/graph/dist/commands/EXPLAIN");
LIST: typeof import("@redis/graph/dist/commands/LIST");
list: typeof import("@redis/graph/dist/commands/LIST");
PROFILE: typeof import("@redis/graph/dist/commands/PROFILE");
profile: typeof import("@redis/graph/dist/commands/PROFILE");
QUERY: typeof import("@redis/graph/dist/commands/QUERY");
query: typeof import("@redis/graph/dist/commands/QUERY");
RO_QUERY: typeof import("@redis/graph/dist/commands/RO_QUERY");
roQuery: typeof import("@redis/graph/dist/commands/RO_QUERY");
SLOWLOG: typeof import("@redis/graph/dist/commands/SLOWLOG");
slowLog: typeof import("@redis/graph/dist/commands/SLOWLOG");
};
json: {
ARRAPPEND: typeof import("@redis/json/dist/commands/ARRAPPEND");
arrAppend: typeof import("@redis/json/dist/commands/ARRAPPEND");
ARRINDEX: typeof import("@redis/json/dist/commands/ARRINDEX");
arrIndex: typeof import("@redis/json/dist/commands/ARRINDEX");
ARRINSERT: typeof import("@redis/json/dist/commands/ARRINSERT");
arrInsert: typeof import("@redis/json/dist/commands/ARRINSERT");
ARRLEN: typeof import("@redis/json/dist/commands/ARRLEN");
arrLen: typeof import("@redis/json/dist/commands/ARRLEN");
ARRPOP: typeof import("@redis/json/dist/commands/ARRPOP");
arrPop: typeof import("@redis/json/dist/commands/ARRPOP");
ARRTRIM: typeof import("@redis/json/dist/commands/ARRTRIM");
arrTrim: typeof import("@redis/json/dist/commands/ARRTRIM");
DEBUG_MEMORY: typeof import("@redis/json/dist/commands/DEBUG_MEMORY");
debugMemory: typeof import("@redis/json/dist/commands/DEBUG_MEMORY");
DEL: typeof import("@redis/json/dist/commands/DEL");
del: typeof import("@redis/json/dist/commands/DEL");
FORGET: typeof import("@redis/json/dist/commands/FORGET");
forget: typeof import("@redis/json/dist/commands/FORGET");
GET: typeof import("@redis/json/dist/commands/GET");
get: typeof import("@redis/json/dist/commands/GET");
MGET: typeof import("@redis/json/dist/commands/MGET");
mGet: typeof import("@redis/json/dist/commands/MGET");
NUMINCRBY: typeof import("@redis/json/dist/commands/NUMINCRBY");
numIncrBy: typeof import("@redis/json/dist/commands/NUMINCRBY");
NUMMULTBY: typeof import("@redis/json/dist/commands/NUMMULTBY");
numMultBy: typeof import("@redis/json/dist/commands/NUMMULTBY");
OBJKEYS: typeof import("@redis/json/dist/commands/OBJKEYS");
objKeys: typeof import("@redis/json/dist/commands/OBJKEYS");
OBJLEN: typeof import("@redis/json/dist/commands/OBJLEN");
objLen: typeof import("@redis/json/dist/commands/OBJLEN");
RESP: typeof import("@redis/json/dist/commands/RESP");
resp: typeof import("@redis/json/dist/commands/RESP");
SET: typeof import("@redis/json/dist/commands/SET");
set: typeof import("@redis/json/dist/commands/SET");
STRAPPEND: typeof import("@redis/json/dist/commands/STRAPPEND");
strAppend: typeof import("@redis/json/dist/commands/STRAPPEND");
STRLEN: typeof import("@redis/json/dist/commands/STRLEN");
strLen: typeof import("@redis/json/dist/commands/STRLEN");
TYPE: typeof import("@redis/json/dist/commands/TYPE");
type: typeof import("@redis/json/dist/commands/TYPE");
};
ft: {
_LIST: typeof import("@redis/search/dist/commands/_LIST");
_list: typeof import("@redis/search/dist/commands/_LIST");
ALTER: typeof import("@redis/search/dist/commands/ALTER");
alter: typeof import("@redis/search/dist/commands/ALTER");
AGGREGATE_WITHCURSOR: typeof import("@redis/search/dist/commands/AGGREGATE_WITHCURSOR");
aggregateWithCursor: typeof import("@redis/search/dist/commands/AGGREGATE_WITHCURSOR");
AGGREGATE: typeof import("@redis/search/dist/commands/AGGREGATE");
aggregate: typeof import("@redis/search/dist/commands/AGGREGATE");
ALIASADD: typeof import("@redis/search/dist/commands/ALIASADD");
aliasAdd: typeof import("@redis/search/dist/commands/ALIASADD");
ALIASDEL: typeof import("@redis/search/dist/commands/ALIASDEL");
aliasDel: typeof import("@redis/search/dist/commands/ALIASDEL");
ALIASUPDATE: typeof import("@redis/search/dist/commands/ALIASUPDATE");
aliasUpdate: typeof import("@redis/search/dist/commands/ALIASUPDATE");
CONFIG_GET: typeof import("@redis/search/dist/commands/CONFIG_GET");
configGet: typeof import("@redis/search/dist/commands/CONFIG_GET");
CONFIG_SET: typeof import("@redis/search/dist/commands/CONFIG_SET");
configSet: typeof import("@redis/search/dist/commands/CONFIG_SET");
CREATE: typeof import("@redis/search/dist/commands/CREATE");
create: typeof import("@redis/search/dist/commands/CREATE");
CURSOR_DEL: typeof import("@redis/search/dist/commands/CURSOR_DEL");
cursorDel: typeof import("@redis/search/dist/commands/CURSOR_DEL");
CURSOR_READ: typeof import("@redis/search/dist/commands/CURSOR_READ");
cursorRead: typeof import("@redis/search/dist/commands/CURSOR_READ");
DICTADD: typeof import("@redis/search/dist/commands/DICTADD");
dictAdd: typeof import("@redis/search/dist/commands/DICTADD");
DICTDEL: typeof import("@redis/search/dist/commands/DICTDEL");
dictDel: typeof import("@redis/search/dist/commands/DICTDEL");
DICTDUMP: typeof import("@redis/search/dist/commands/DICTDUMP");
dictDump: typeof import("@redis/search/dist/commands/DICTDUMP");
DROPINDEX: typeof import("@redis/search/dist/commands/DROPINDEX");
dropIndex: typeof import("@redis/search/dist/commands/DROPINDEX");
EXPLAIN: typeof import("@redis/search/dist/commands/EXPLAIN");
explain: typeof import("@redis/search/dist/commands/EXPLAIN");
EXPLAINCLI: typeof import("@redis/search/dist/commands/EXPLAINCLI");
explainCli: typeof import("@redis/search/dist/commands/EXPLAINCLI");
INFO: typeof import("@redis/search/dist/commands/INFO");
info: typeof import("@redis/search/dist/commands/INFO");
PROFILESEARCH: typeof import("@redis/search/dist/commands/PROFILE_SEARCH");
profileSearch: typeof import("@redis/search/dist/commands/PROFILE_SEARCH");
PROFILEAGGREGATE: typeof import("@redis/search/dist/commands/PROFILE_AGGREGATE");
profileAggregate: typeof import("@redis/search/dist/commands/PROFILE_AGGREGATE");
SEARCH: typeof import("@redis/search/dist/commands/SEARCH");
search: typeof import("@redis/search/dist/commands/SEARCH");
SPELLCHECK: typeof import("@redis/search/dist/commands/SPELLCHECK");
spellCheck: typeof import("@redis/search/dist/commands/SPELLCHECK");
SUGADD: typeof import("@redis/search/dist/commands/SUGADD");
sugAdd: typeof import("@redis/search/dist/commands/SUGADD");
SUGDEL: typeof import("@redis/search/dist/commands/SUGDEL");
sugDel: typeof import("@redis/search/dist/commands/SUGDEL");
SUGGET_WITHPAYLOADS: typeof import("@redis/search/dist/commands/SUGGET_WITHPAYLOADS");
sugGetWithPayloads: typeof import("@redis/search/dist/commands/SUGGET_WITHPAYLOADS");
SUGGET_WITHSCORES_WITHPAYLOADS: typeof import("@redis/search/dist/commands/SUGGET_WITHSCORES_WITHPAYLOADS");
sugGetWithScoresWithPayloads: typeof import("@redis/search/dist/commands/SUGGET_WITHSCORES_WITHPAYLOADS");
SUGGET_WITHSCORES: typeof import("@redis/search/dist/commands/SUGGET_WITHSCORES");
sugGetWithScores: typeof import("@redis/search/dist/commands/SUGGET_WITHSCORES");
SUGGET: typeof import("@redis/search/dist/commands/SUGGET");
sugGet: typeof import("@redis/search/dist/commands/SUGGET");
SUGLEN: typeof import("@redis/search/dist/commands/SUGLEN");
sugLen: typeof import("@redis/search/dist/commands/SUGLEN");
SYNDUMP: typeof import("@redis/search/dist/commands/SYNDUMP");
synDump: typeof import("@redis/search/dist/commands/SYNDUMP");
SYNUPDATE: typeof import("@redis/search/dist/commands/SYNUPDATE");
synUpdate: typeof import("@redis/search/dist/commands/SYNUPDATE");
TAGVALS: typeof import("@redis/search/dist/commands/TAGVALS");
tagVals: typeof import("@redis/search/dist/commands/TAGVALS");
};
ts: {
ADD: typeof import("@redis/time-series/dist/commands/ADD");
add: typeof import("@redis/time-series/dist/commands/ADD");
ALTER: typeof import("@redis/time-series/dist/commands/ALTER");
alter: typeof import("@redis/time-series/dist/commands/ALTER");
CREATE: typeof import("@redis/time-series/dist/commands/CREATE");
create: typeof import("@redis/time-series/dist/commands/CREATE");
CREATERULE: typeof import("@redis/time-series/dist/commands/CREATERULE");
createRule: typeof import("@redis/time-series/dist/commands/CREATERULE");
DECRBY: typeof import("@redis/time-series/dist/commands/DECRBY");
decrBy: typeof import("@redis/time-series/dist/commands/DECRBY");
DEL: typeof import("@redis/time-series/dist/commands/DEL");
del: typeof import("@redis/time-series/dist/commands/DEL");
DELETERULE: typeof import("@redis/time-series/dist/commands/DELETERULE");
deleteRule: typeof import("@redis/time-series/dist/commands/DELETERULE");
GET: typeof import("@redis/time-series/dist/commands/GET");
get: typeof import("@redis/time-series/dist/commands/GET");
INCRBY: typeof import("@redis/time-series/dist/commands/INCRBY");
incrBy: typeof import("@redis/time-series/dist/commands/INCRBY");
INFO_DEBUG: typeof import("@redis/time-series/dist/commands/INFO_DEBUG");
infoDebug: typeof import("@redis/time-series/dist/commands/INFO_DEBUG");
INFO: typeof import("@redis/time-series/dist/commands/INFO");
info: typeof import("@redis/time-series/dist/commands/INFO");
MADD: typeof import("@redis/time-series/dist/commands/MADD");
mAdd: typeof import("@redis/time-series/dist/commands/MADD");
MGET: typeof import("@redis/time-series/dist/commands/MGET");
mGet: typeof import("@redis/time-series/dist/commands/MGET");
MGET_WITHLABELS: typeof import("@redis/time-series/dist/commands/MGET_WITHLABELS");
mGetWithLabels: typeof import("@redis/time-series/dist/commands/MGET_WITHLABELS");
QUERYINDEX: typeof import("@redis/time-series/dist/commands/QUERYINDEX");
queryIndex: typeof import("@redis/time-series/dist/commands/QUERYINDEX");
RANGE: typeof import("@redis/time-series/dist/commands/RANGE");
range: typeof import("@redis/time-series/dist/commands/RANGE");
REVRANGE: typeof import("@redis/time-series/dist/commands/REVRANGE");
revRange: typeof import("@redis/time-series/dist/commands/REVRANGE");
MRANGE: typeof import("@redis/time-series/dist/commands/MRANGE");
mRange: typeof import("@redis/time-series/dist/commands/MRANGE");
MRANGE_WITHLABELS: typeof import("@redis/time-series/dist/commands/MRANGE_WITHLABELS");
mRangeWithLabels: typeof import("@redis/time-series/dist/commands/MRANGE_WITHLABELS");
MREVRANGE: typeof import("@redis/time-series/dist/commands/MREVRANGE");
mRevRange: typeof import("@redis/time-series/dist/commands/MREVRANGE");
MREVRANGE_WITHLABELS: typeof import("@redis/time-series/dist/commands/MREVRANGE_WITHLABELS");
mRevRangeWithLabels: typeof import("@redis/time-series/dist/commands/MREVRANGE_WITHLABELS");
};
bf: {
ADD: typeof import("@redis/bloom/dist/commands/bloom/ADD");
add: typeof import("@redis/bloom/dist/commands/bloom/ADD");
EXISTS: typeof import("@redis/bloom/dist/commands/bloom/EXISTS");
exists: typeof import("@redis/bloom/dist/commands/bloom/EXISTS");
INFO: typeof import("@redis/bloom/dist/commands/bloom/INFO");
info: typeof import("@redis/bloom/dist/commands/bloom/INFO");
INSERT: typeof import("@redis/bloom/dist/commands/bloom/INSERT");
insert: typeof import("@redis/bloom/dist/commands/bloom/INSERT");
LOADCHUNK: typeof import("@redis/bloom/dist/commands/bloom/LOADCHUNK");
loadChunk: typeof import("@redis/bloom/dist/commands/bloom/LOADCHUNK");
MADD: typeof import("@redis/bloom/dist/commands/bloom/MADD");
mAdd: typeof import("@redis/bloom/dist/commands/bloom/MADD");
MEXISTS: typeof import("@redis/bloom/dist/commands/bloom/MEXISTS");
mExists: typeof import("@redis/bloom/dist/commands/bloom/MEXISTS");
RESERVE: typeof import("@redis/bloom/dist/commands/bloom/RESERVE");
reserve: typeof import("@redis/bloom/dist/commands/bloom/RESERVE");
SCANDUMP: typeof import("@redis/bloom/dist/commands/bloom/SCANDUMP");
scanDump: typeof import("@redis/bloom/dist/commands/bloom/SCANDUMP");
};
cms: {
INCRBY: typeof import("@redis/bloom/dist/commands/count-min-sketch/INCRBY");
incrBy: typeof import("@redis/bloom/dist/commands/count-min-sketch/INCRBY");
INFO: typeof import("@redis/bloom/dist/commands/count-min-sketch/INFO");
info: typeof import("@redis/bloom/dist/commands/count-min-sketch/INFO");
INITBYDIM: typeof import("@redis/bloom/dist/commands/count-min-sketch/INITBYDIM");
initByDim: typeof import("@redis/bloom/dist/commands/count-min-sketch/INITBYDIM");
INITBYPROB: typeof import("@redis/bloom/dist/commands/count-min-sketch/INITBYPROB");
initByProb: typeof import("@redis/bloom/dist/commands/count-min-sketch/INITBYPROB");
MERGE: typeof import("@redis/bloom/dist/commands/count-min-sketch/MERGE");
merge: typeof import("@redis/bloom/dist/commands/count-min-sketch/MERGE");
QUERY: typeof import("@redis/bloom/dist/commands/count-min-sketch/QUERY");
query: typeof import("@redis/bloom/dist/commands/count-min-sketch/QUERY");
};
cf: {
ADD: typeof import("@redis/bloom/dist/commands/cuckoo/ADD");
add: typeof import("@redis/bloom/dist/commands/cuckoo/ADD");
ADDNX: typeof import("@redis/bloom/dist/commands/cuckoo/ADDNX");
addNX: typeof import("@redis/bloom/dist/commands/cuckoo/ADDNX");
COUNT: typeof import("@redis/bloom/dist/commands/cuckoo/COUNT");
count: typeof import("@redis/bloom/dist/commands/cuckoo/COUNT");
DEL: typeof import("@redis/bloom/dist/commands/cuckoo/DEL");
del: typeof import("@redis/bloom/dist/commands/cuckoo/DEL");
EXISTS: typeof import("@redis/bloom/dist/commands/cuckoo/EXISTS");
exists: typeof import("@redis/bloom/dist/commands/cuckoo/EXISTS");
INFO: typeof import("@redis/bloom/dist/commands/cuckoo/INFO");
info: typeof import("@redis/bloom/dist/commands/cuckoo/INFO");
INSERT: typeof import("@redis/bloom/dist/commands/cuckoo/INSERT");
insert: typeof import("@redis/bloom/dist/commands/cuckoo/INSERT");
INSERTNX: typeof import("@redis/bloom/dist/commands/cuckoo/INSERTNX");
insertNX: typeof import("@redis/bloom/dist/commands/cuckoo/INSERTNX");
LOADCHUNK: typeof import("@redis/bloom/dist/commands/cuckoo/LOADCHUNK");
loadChunk: typeof import("@redis/bloom/dist/commands/cuckoo/LOADCHUNK");
RESERVE: typeof import("@redis/bloom/dist/commands/cuckoo/RESERVE");
reserve: typeof import("@redis/bloom/dist/commands/cuckoo/RESERVE");
SCANDUMP: typeof import("@redis/bloom/dist/commands/cuckoo/SCANDUMP");
scanDump: typeof import("@redis/bloom/dist/commands/cuckoo/SCANDUMP");
};
tDigest: {
ADD: typeof import("@redis/bloom/dist/commands/t-digest/ADD");
add: typeof import("@redis/bloom/dist/commands/t-digest/ADD");
BYRANK: typeof import("@redis/bloom/dist/commands/t-digest/BYRANK");
byRank: typeof import("@redis/bloom/dist/commands/t-digest/BYRANK");
BYREVRANK: typeof import("@redis/bloom/dist/commands/t-digest/BYREVRANK");
byRevRank: typeof import("@redis/bloom/dist/commands/t-digest/BYREVRANK");
CDF: typeof import("@redis/bloom/dist/commands/t-digest/CDF");
cdf: typeof import("@redis/bloom/dist/commands/t-digest/CDF");
CREATE: typeof import("@redis/bloom/dist/commands/t-digest/CREATE");
create: typeof import("@redis/bloom/dist/commands/t-digest/CREATE");
INFO: typeof import("@redis/bloom/dist/commands/t-digest/INFO");
info: typeof import("@redis/bloom/dist/commands/t-digest/INFO");
MAX: typeof import("@redis/bloom/dist/commands/t-digest/MAX");
max: typeof import("@redis/bloom/dist/commands/t-digest/MAX");
MERGE: typeof import("@redis/bloom/dist/commands/t-digest/MERGE");
merge: typeof import("@redis/bloom/dist/commands/t-digest/MERGE");
MIN: typeof import("@redis/bloom/dist/commands/t-digest/MIN");
min: typeof import("@redis/bloom/dist/commands/t-digest/MIN");
QUANTILE: typeof import("@redis/bloom/dist/commands/t-digest/QUANTILE");
quantile: typeof import("@redis/bloom/dist/commands/t-digest/QUANTILE");
RANK: typeof import("@redis/bloom/dist/commands/t-digest/RANK");
rank: typeof import("@redis/bloom/dist/commands/t-digest/RANK");
RESET: typeof import("@redis/bloom/dist/commands/t-digest/RESET");
reset: typeof import("@redis/bloom/dist/commands/t-digest/RESET");
REVRANK: typeof import("@redis/bloom/dist/commands/t-digest/REVRANK");
revRank: typeof import("@redis/bloom/dist/commands/t-digest/REVRANK");
TRIMMED_MEAN: typeof import("@redis/bloom/dist/commands/t-digest/TRIMMED_MEAN");
trimmedMean: typeof import("@redis/bloom/dist/commands/t-digest/TRIMMED_MEAN");
};
topK: {
ADD: typeof import("@redis/bloom/dist/commands/top-k/ADD");
add: typeof import("@redis/bloom/dist/commands/top-k/ADD");
COUNT: typeof import("@redis/bloom/dist/commands/top-k/COUNT");
count: typeof import("@redis/bloom/dist/commands/top-k/COUNT");
INCRBY: typeof import("@redis/bloom/dist/commands/top-k/INCRBY");
incrBy: typeof import("@redis/bloom/dist/commands/top-k/INCRBY");
INFO: typeof import("@redis/bloom/dist/commands/top-k/INFO");
info: typeof import("@redis/bloom/dist/commands/top-k/INFO");
LIST_WITHCOUNT: typeof import("@redis/bloom/dist/commands/top-k/LIST_WITHCOUNT");
listWithCount: typeof import("@redis/bloom/dist/commands/top-k/LIST_WITHCOUNT");
LIST: typeof import("@redis/bloom/dist/commands/top-k/LIST");
list: typeof import("@redis/bloom/dist/commands/top-k/LIST");
QUERY: typeof import("@redis/bloom/dist/commands/top-k/QUERY");
query: typeof import("@redis/bloom/dist/commands/top-k/QUERY");
RESERVE: typeof import("@redis/bloom/dist/commands/top-k/RESERVE");
reserve: typeof import("@redis/bloom/dist/commands/top-k/RESERVE");
};
} & import("redis").RedisModules, import("redis").RedisFunctions, import("redis").RedisScripts> | undefined;
getsubscriberClient(): import("@redis/client").RedisClientType<{
graph: {
CONFIG_GET: typeof import("@redis/graph/dist/commands/CONFIG_GET");
configGet: typeof import("@redis/graph/dist/commands/CONFIG_GET");
CONFIG_SET: typeof import("@redis/graph/dist/commands/CONFIG_SET");
configSet: typeof import("@redis/graph/dist/commands/CONFIG_SET");
DELETE: typeof import("@redis/graph/dist/commands/DELETE");
delete: typeof import("@redis/graph/dist/commands/DELETE");
EXPLAIN: typeof import("@redis/graph/dist/commands/EXPLAIN");
explain: typeof import("@redis/graph/dist/commands/EXPLAIN");
LIST: typeof import("@redis/graph/dist/commands/LIST");
list: typeof import("@redis/graph/dist/commands/LIST");
PROFILE: typeof import("@redis/graph/dist/commands/PROFILE");
profile: typeof import("@redis/graph/dist/commands/PROFILE");
QUERY: typeof import("@redis/graph/dist/commands/QUERY");
query: typeof import("@redis/graph/dist/commands/QUERY");
RO_QUERY: typeof import("@redis/graph/dist/commands/RO_QUERY");
roQuery: typeof import("@redis/graph/dist/commands/RO_QUERY");
SLOWLOG: typeof import("@redis/graph/dist/commands/SLOWLOG");
slowLog: typeof import("@redis/graph/dist/commands/SLOWLOG");
};
json: {
ARRAPPEND: typeof import("@redis/json/dist/commands/ARRAPPEND");
arrAppend: typeof import("@redis/json/dist/commands/ARRAPPEND");
ARRINDEX: typeof import("@redis/json/dist/commands/ARRINDEX");
arrIndex: typeof import("@redis/json/dist/commands/ARRINDEX");
ARRINSERT: typeof import("@redis/json/dist/commands/ARRINSERT");
arrInsert: typeof import("@redis/json/dist/commands/ARRINSERT");
ARRLEN: typeof import("@redis/json/dist/commands/ARRLEN");
arrLen: typeof import("@redis/json/dist/commands/ARRLEN");
ARRPOP: typeof import("@redis/json/dist/commands/ARRPOP");
arrPop: typeof import("@redis/json/dist/commands/ARRPOP");
ARRTRIM: typeof import("@redis/json/dist/commands/ARRTRIM");
arrTrim: typeof import("@redis/json/dist/commands/ARRTRIM");
DEBUG_MEMORY: typeof import("@redis/json/dist/commands/DEBUG_MEMORY");
debugMemory: typeof import("@redis/json/dist/commands/DEBUG_MEMORY");
DEL: typeof import("@redis/json/dist/commands/DEL");
del: typeof import("@redis/json/dist/commands/DEL");
FORGET: typeof import("@redis/json/dist/commands/FORGET");
forget: typeof import("@redis/json/dist/commands/FORGET");
GET: typeof import("@redis/json/dist/commands/GET");
get: typeof import("@redis/json/dist/commands/GET");
MGET: typeof import("@redis/json/dist/commands/MGET");
mGet: typeof import("@redis/json/dist/commands/MGET");
NUMINCRBY: typeof import("@redis/json/dist/commands/NUMINCRBY");
numIncrBy: typeof import("@redis/json/dist/commands/NUMINCRBY");
NUMMULTBY: typeof import("@redis/json/dist/commands/NUMMULTBY");
numMultBy: typeof import("@redis/json/dist/commands/NUMMULTBY");
OBJKEYS: typeof import("@redis/json/dist/commands/OBJKEYS");
objKeys: typeof import("@redis/json/dist/commands/OBJKEYS");
OBJLEN: typeof import("@redis/json/dist/commands/OBJLEN");
objLen: typeof import("@redis/json/dist/commands/OBJLEN");
RESP: typeof import("@redis/json/dist/commands/RESP");
resp: typeof import("@redis/json/dist/commands/RESP");
SET: typeof import("@redis/json/dist/commands/SET");
set: typeof import("@redis/json/dist/commands/SET");
STRAPPEND: typeof import("@redis/json/dist/commands/STRAPPEND");
strAppend: typeof import("@redis/json/dist/commands/STRAPPEND");
STRLEN: typeof import("@redis/json/dist/commands/STRLEN");
strLen: typeof import("@redis/json/dist/commands/STRLEN");
TYPE: typeof import("@redis/json/dist/commands/TYPE");
type: typeof import("@redis/json/dist/commands/TYPE");
};
ft: {
_LIST: typeof import("@redis/search/dist/commands/_LIST");
_list: typeof import("@redis/search/dist/commands/_LIST");
ALTER: typeof import("@redis/search/dist/commands/ALTER");
alter: typeof import("@redis/search/dist/commands/ALTER");
AGGREGATE_WITHCURSOR: typeof import("@redis/search/dist/commands/AGGREGATE_WITHCURSOR");
aggregateWithCursor: typeof import("@redis/search/dist/commands/AGGREGATE_WITHCURSOR");
AGGREGATE: typeof import("@redis/search/dist/commands/AGGREGATE");
aggregate: typeof import("@redis/search/dist/commands/AGGREGATE");
ALIASADD: typeof import("@redis/search/dist/commands/ALIASADD");
aliasAdd: typeof import("@redis/search/dist/commands/ALIASADD");
ALIASDEL: typeof import("@redis/search/dist/commands/ALIASDEL");
aliasDel: typeof import("@redis/search/dist/commands/ALIASDEL");
ALIASUPDATE: typeof import("@redis/search/dist/commands/ALIASUPDATE");
aliasUpdate: typeof import("@redis/search/dist/commands/ALIASUPDATE");
CONFIG_GET: typeof import("@redis/search/dist/commands/CONFIG_GET");
configGet: typeof import("@redis/search/dist/commands/CONFIG_GET");
CONFIG_SET: typeof import("@redis/search/dist/commands/CONFIG_SET");
configSet: typeof import("@redis/search/dist/commands/CONFIG_SET");
CREATE: typeof import("@redis/search/dist/commands/CREATE");
create: typeof import("@redis/search/dist/commands/CREATE");
CURSOR_DEL: typeof import("@redis/search/dist/commands/CURSOR_DEL");
cursorDel: typeof import("@redis/search/dist/commands/CURSOR_DEL");
CURSOR_READ: typeof import("@redis/search/dist/commands/CURSOR_READ");
cursorRead: typeof import("@redis/search/dist/commands/CURSOR_READ");
DICTADD: typeof import("@redis/search/dist/commands/DICTADD");
dictAdd: typeof import("@redis/search/dist/commands/DICTADD");
DICTDEL: typeof import("@redis/search/dist/commands/DICTDEL");
dictDel: typeof import("@redis/search/dist/commands/DICTDEL");
DICTDUMP: typeof import("@redis/search/dist/commands/DICTDUMP");
dictDump: typeof import("@redis/search/dist/commands/DICTDUMP");
DROPINDEX: typeof import("@redis/search/dist/commands/DROPINDEX");
dropIndex: typeof import("@redis/search/dist/commands/DROPINDEX");
EXPLAIN: typeof import("@redis/search/dist/commands/EXPLAIN");
explain: typeof import("@redis/search/dist/commands/EXPLAIN");
EXPLAINCLI: typeof import("@redis/search/dist/commands/EXPLAINCLI");
explainCli: typeof import("@redis/search/dist/commands/EXPLAINCLI");
INFO: typeof import("@redis/search/dist/commands/INFO");
info: typeof import("@redis/search/dist/commands/INFO");
PROFILESEARCH: typeof import("@redis/search/dist/commands/PROFILE_SEARCH");
profileSearch: typeof import("@redis/search/dist/commands/PROFILE_SEARCH");
PROFILEAGGREGATE: typeof import("@redis/search/dist/commands/PROFILE_AGGREGATE");
profileAggregate: typeof import("@redis/search/dist/commands/PROFILE_AGGREGATE");
SEARCH: typeof import("@redis/search/dist/commands/SEARCH");
search: typeof import("@redis/search/dist/commands/SEARCH");
SPELLCHECK: typeof import("@redis/search/dist/commands/SPELLCHECK");
spellCheck: typeof import("@redis/search/dist/commands/SPELLCHECK");
SUGADD: typeof import("@redis/search/dist/commands/SUGADD");
sugAdd: typeof import("@redis/search/dist/commands/SUGADD");
SUGDEL: typeof import("@redis/search/dist/commands/SUGDEL");
sugDel: typeof import("@redis/search/dist/commands/SUGDEL");
SUGGET_WITHPAYLOADS: typeof import("@redis/search/dist/commands/SUGGET_WITHPAYLOADS");
sugGetWithPayloads: typeof import("@redis/search/dist/commands/SUGGET_WITHPAYLOADS");
SUGGET_WITHSCORES_WITHPAYLOADS: typeof import("@redis/search/dist/commands/SUGGET_WITHSCORES_WITHPAYLOADS");
sugGetWithScoresWithPayloads: typeof import("@redis/search/dist/commands/SUGGET_WITHSCORES_WITHPAYLOADS");
SUGGET_WITHSCORES: typeof import("@redis/search/dist/commands/SUGGET_WITHSCORES");
sugGetWithScores: typeof import("@redis/search/dist/commands/SUGGET_WITHSCORES");
SUGGET: typeof import("@redis/search/dist/commands/SUGGET");
sugGet: typeof import("@redis/search/dist/commands/SUGGET");
SUGLEN: typeof import("@redis/search/dist/commands/SUGLEN");
sugLen: typeof import("@redis/search/dist/commands/SUGLEN");
SYNDUMP: typeof import("@redis/search/dist/commands/SYNDUMP");
synDump: typeof import("@redis/search/dist/commands/SYNDUMP");
SYNUPDATE: typeof import("@redis/search/dist/commands/SYNUPDATE");
synUpdate: typeof import("@redis/search/dist/commands/SYNUPDATE");
TAGVALS: typeof import("@redis/search/dist/commands/TAGVALS");
tagVals: typeof import("@redis/search/dist/commands/TAGVALS");
};
ts: {
ADD: typeof import("@redis/time-series/dist/commands/ADD");
add: typeof import("@redis/time-series/dist/commands/ADD");
ALTER: typeof import("@redis/time-series/dist/commands/ALTER");
alter: typeof import("@redis/time-series/dist/commands/ALTER");
CREATE: typeof import("@redis/time-series/dist/commands/CREATE");
create: typeof import("@redis/time-series/dist/commands/CREATE");
CREATERULE: typeof import("@redis/time-series/dist/commands/CREATERULE");
createRule: typeof import("@redis/time-series/dist/commands/CREATERULE");
DECRBY: typeof import("@redis/time-series/dist/commands/DECRBY");
decrBy: typeof import("@redis/time-series/dist/commands/DECRBY");
DEL: typeof import("@redis/time-series/dist/commands/DEL");
del: typeof import("@redis/time-series/dist/commands/DEL");
DELETERULE: typeof import("@redis/time-series/dist/commands/DELETERULE");
deleteRule: typeof import("@redis/time-series/dist/commands/DELETERULE");
GET: typeof import("@redis/time-series/dist/commands/GET");
get: typeof import("@redis/time-series/dist/commands/GET");
INCRBY: typeof import("@redis/time-series/dist/commands/INCRBY");
incrBy: typeof import("@redis/time-series/dist/commands/INCRBY");
INFO_DEBUG: typeof import("@redis/time-series/dist/commands/INFO_DEBUG");
infoDebug: typeof import("@redis/time-series/dist/commands/INFO_DEBUG");
INFO: typeof import("@redis/time-series/dist/commands/INFO");
info: typeof import("@redis/time-series/dist/commands/INFO");
MADD: typeof import("@redis/time-series/dist/commands/MADD");
mAdd: typeof import("@redis/time-series/dist/commands/MADD");
MGET: typeof import("@redis/time-series/dist/commands/MGET");
mGet: typeof import("@redis/time-series/dist/commands/MGET");
MGET_WITHLABELS: typeof import("@redis/time-series/dist/commands/MGET_WITHLABELS");
mGetWithLabels: typeof import("@redis/time-series/dist/commands/MGET_WITHLABELS");
QUERYINDEX: typeof import("@redis/time-series/dist/commands/QUERYINDEX");
queryIndex: typeof import("@redis/time-series/dist/commands/QUERYINDEX");
RANGE: typeof import("@redis/time-series/dist/commands/RANGE");
range: typeof import("@redis/time-series/dist/commands/RANGE");
REVRANGE: typeof import("@redis/time-series/dist/commands/REVRANGE");
revRange: typeof import("@redis/time-series/dist/commands/REVRANGE");
MRANGE: typeof import("@redis/time-series/dist/commands/MRANGE");
mRange: typeof import("@redis/time-series/dist/commands/MRANGE");
MRANGE_WITHLABELS: typeof import("@redis/time-series/dist/commands/MRANGE_WITHLABELS");
mRangeWithLabels: typeof import("@redis/time-series/dist/commands/MRANGE_WITHLABELS");
MREVRANGE: typeof import("@redis/time-series/dist/commands/MREVRANGE");
mRevRange: typeof import("@redis/time-series/dist/commands/MREVRANGE");
MREVRANGE_WITHLABELS: typeof import("@redis/time-series/dist/commands/MREVRANGE_WITHLABELS");
mRevRangeWithLabels: typeof import("@redis/time-series/dist/commands/MREVRANGE_WITHLABELS");
};
bf: {
ADD: typeof import("@redis/bloom/dist/commands/bloom/ADD");
add: typeof import("@redis/bloom/dist/commands/bloom/ADD");
EXISTS: typeof import("@redis/bloom/dist/commands/bloom/EXISTS");
exists: typeof import("@redis/bloom/dist/commands/bloom/EXISTS");
INFO: typeof import("@redis/bloom/dist/commands/bloom/INFO");
info: typeof import("@redis/bloom/dist/commands/bloom/INFO");
INSERT: typeof import("@redis/bloom/dist/commands/bloom/INSERT");
insert: typeof import("@redis/bloom/dist/commands/bloom/INSERT");
LOADCHUNK: typeof import("@redis/bloom/dist/commands/bloom/LOADCHUNK");
loadChunk: typeof import("@redis/bloom/dist/commands/bloom/LOADCHUNK");
MADD: typeof import("@redis/bloom/dist/commands/bloom/MADD");
mAdd: typeof import("@redis/bloom/dist/commands/bloom/MADD");
MEXISTS: typeof import("@redis/bloom/dist/commands/bloom/MEXISTS");
mExists: typeof import("@redis/bloom/dist/commands/bloom/MEXISTS");
RESERVE: typeof import("@redis/bloom/dist/commands/bloom/RESERVE");
reserve: typeof import("@redis/bloom/dist/commands/bloom/RESERVE");
SCANDUMP: typeof import("@redis/bloom/dist/commands/bloom/SCANDUMP");
scanDump: typeof import("@redis/bloom/dist/commands/bloom/SCANDUMP");
};
cms: {
INCRBY: typeof import("@redis/bloom/dist/commands/count-min-sketch/INCRBY");
incrBy: typeof import("@redis/bloom/dist/commands/count-min-sketch/INCRBY");
INFO: typeof import("@redis/bloom/dist/commands/count-min-sketch/INFO");
info: typeof import("@redis/bloom/dist/commands/count-min-sketch/INFO");
INITBYDIM: typeof import("@redis/bloom/dist/commands/count-min-sketch/INITBYDIM");
initByDim: typeof import("@redis/bloom/dist/commands/count-min-sketch/INITBYDIM");
INITBYPROB: typeof import("@redis/bloom/dist/commands/count-min-sketch/INITBYPROB");
initByProb: typeof import("@redis/bloom/dist/commands/count-min-sketch/INITBYPROB");
MERGE: typeof import("@redis/bloom/dist/commands/count-min-sketch/MERGE");
merge: typeof import("@redis/bloom/dist/commands/count-min-sketch/MERGE");
QUERY: typeof import("@redis/bloom/dist/commands/count-min-sketch/QUERY");
query: typeof import("@redis/bloom/dist/commands/count-min-sketch/QUERY");
};
cf: {
ADD: typeof import("@redis/bloom/dist/commands/cuckoo/ADD");
add: typeof import("@redis/bloom/dist/commands/cuckoo/ADD");
ADDNX: typeof import("@redis/bloom/dist/commands/cuckoo/ADDNX");
addNX: typeof import("@redis/bloom/dist/commands/cuckoo/ADDNX");
COUNT: typeof import("@redis/bloom/dist/commands/cuckoo/COUNT");
count: typeof import("@redis/bloom/dist/commands/cuckoo/COUNT");
DEL: typeof import("@redis/bloom/dist/commands/cuckoo/DEL");
del: typeof import("@redis/bloom/dist/commands/cuckoo/DEL");
EXISTS: typeof import("@redis/bloom/dist/commands/cuckoo/EXISTS");
exists: typeof import("@redis/bloom/dist/commands/cuckoo/EXISTS");
INFO: typeof import("@redis/bloom/dist/commands/cuckoo/INFO");
info: typeof import("@redis/bloom/dist/commands/cuckoo/INFO");
INSERT: typeof import("@redis/bloom/dist/commands/cuckoo/INSERT");
insert: typeof import("@redis/bloom/dist/commands/cuckoo/INSERT");
INSERTNX: typeof import("@redis/bloom/dist/commands/cuckoo/INSERTNX");
insertNX: typeof import("@redis/bloom/dist/commands/cuckoo/INSERTNX");
LOADCHUNK: typeof import("@redis/bloom/dist/commands/cuckoo/LOADCHUNK");
loadChunk: typeof import("@redis/bloom/dist/commands/cuckoo/LOADCHUNK");
RESERVE: typeof import("@redis/bloom/dist/commands/cuckoo/RESERVE");
reserve: typeof import("@redis/bloom/dist/commands/cuckoo/RESERVE");
SCANDUMP: typeof import("@redis/bloom/dist/commands/cuckoo/SCANDUMP");
scanDump: typeof import("@redis/bloom/dist/commands/cuckoo/SCANDUMP");
};
tDigest: {
ADD: typeof import("@redis/bloom/dist/commands/t-digest/ADD");
add: typeof import("@redis/bloom/dist/commands/t-digest/ADD");
BYRANK: typeof import("@redis/bloom/dist/commands/t-digest/BYRANK");
byRank: typeof import("@redis/bloom/dist/commands/t-digest/BYRANK");
BYREVRANK: typeof import("@redis/bloom/dist/commands/t-digest/BYREVRANK");
byRevRank: typeof import("@redis/bloom/dist/commands/t-digest/BYREVRANK");
CDF: typeof import("@redis/bloom/dist/commands/t-digest/CDF");
cdf: typeof import("@redis/bloom/dist/commands/t-digest/CDF");
CREATE: typeof import("@redis/bloom/dist/commands/t-digest/CREATE");
create: typeof import("@redis/bloom/dist/commands/t-digest/CREATE");
INFO: typeof import("@redis/bloom/dist/commands/t-digest/INFO");
info: typeof import("@redis/bloom/dist/commands/t-digest/INFO");
MAX: typeof import("@redis/bloom/dist/commands/t-digest/MAX");
max: typeof import("@redis/bloom/dist/commands/t-digest/MAX");
MERGE: typeof import("@redis/bloom/dist/commands/t-digest/MERGE");
merge: typeof import("@redis/bloom/dist/commands/t-digest/MERGE");
MIN: typeof import("@redis/bloom/dist/commands/t-digest/MIN");
min: typeof import("@redis/bloom/dist/commands/t-digest/MIN");
QUANTILE: typeof import("@redis/bloom/dist/commands/t-digest/QUANTILE");
quantile: typeof import("@redis/bloom/dist/commands/t-digest/QUANTILE");
RANK: typeof import("@redis/bloom/dist/commands/t-digest/RANK");
rank: typeof import("@redis/bloom/dist/commands/t-digest/RANK");
RESET: typeof import("@redis/bloom/dist/commands/t-digest/RESET");
reset: typeof import("@redis/bloom/dist/commands/t-digest/RESET");
REVRANK: typeof import("@redis/bloom/dist/commands/t-digest/REVRANK");
revRank: typeof import("@redis/bloom/dist/commands/t-digest/REVRANK");
TRIMMED_MEAN: typeof import("@redis/bloom/dist/commands/t-digest/TRIMMED_MEAN");
trimmedMean: typeof import("@redis/bloom/dist/commands/t-digest/TRIMMED_MEAN");
};
topK: {
ADD: typeof import("@redis/bloom/dist/commands/top-k/ADD");
add: typeof import("@redis/bloom/dist/commands/top-k/ADD");
COUNT: typeof import("@redis/bloom/dist/commands/top-k/COUNT");
count: typeof import("@redis/bloom/dist/commands/top-k/COUNT");
INCRBY: typeof import("@redis/bloom/dist/commands/top-k/INCRBY");
incrBy: typeof import("@redis/bloom/dist/commands/top-k/INCRBY");
INFO: typeof import("@redis/bloom/dist/commands/top-k/INFO");
info: typeof import("@redis/bloom/dist/commands/top-k/INFO");
LIST_WITHCOUNT: typeof import("@redis/bloom/dist/commands/top-k/LIST_WITHCOUNT");
listWithCount: typeof import("@redis/bloom/dist/commands/top-k/LIST_WITHCOUNT");
LIST: typeof import("@redis/bloom/dist/commands/top-k/LIST");
list: typeof import("@redis/bloom/dist/commands/top-k/LIST");
QUERY: typeof import("@redis/bloom/dist/commands/top-k/QUERY");
query: typeof import("@redis/bloom/dist/commands/top-k/QUERY");
RESERVE: typeof import("@redis/bloom/dist/commands/top-k/RESERVE");
reserve: typeof import("@redis/bloom/dist/commands/top-k/RESERVE");
};
} & import("redis").RedisModules, import("redis").RedisFunctions, import("redis").RedisScripts> | undefined;
}

@@ -17,3 +17,5 @@ "use strict";

const redis_1 = require("redis");
const uuid_1 = require("uuid");
const logger_1 = __importDefault(require("../logger"));
const eventStreamManager_1 = require("../eventStreamManager");
const MemoryCache_1 = require("./MemoryCache");

@@ -23,3 +25,4 @@ class RedisCache {

expiresTTL = 10 * 60, // 10 minutes
allowStale = true, connectionUrl, useAdditionalMemoryCache, } = {}) {
allowStale = true, connectionUrl, useAdditionalMemoryCache, publishPayloadToChannel = false, } = {}, appContext) {
this.clientUUID = (0, uuid_1.v4)();
this.connectionUrl = connectionUrl;

@@ -29,2 +32,4 @@ this.staleTTL = staleTTL * 1000;

this.allowStale = allowStale;
this.publishPayloadToChannel = publishPayloadToChannel;
this.appContext = appContext;
// wrap the RedisCache in a MemoryCache to avoid hitting Redis on every request

@@ -48,2 +53,3 @@ if (useAdditionalMemoryCache) {

yield this.client.connect();
yield this.subscribe();
}

@@ -79,2 +85,5 @@ });

}
if (!entry) {
return undefined;
}
if (!this.allowStale && entry.staleOn < new Date()) {

@@ -110,6 +119,70 @@ return undefined;

}
// Publish with Redis pub/sub so that other proxy nodes can
// 1. emit SSE to SDK subscribers
// 2. update their MemoryCache
if (this.publishPayloadToChannel && this.subscriberClient) {
// publish to Redis subscribers if new payload !== old payload
const oldEntry = yield this.get(key);
const hasChanges = JSON.stringify(oldEntry === null || oldEntry === void 0 ? void 0 : oldEntry.payload) !== JSON.stringify(payload);
if (hasChanges) {
this.client.publish("set", JSON.stringify({
uuid: this.clientUUID,
key,
payload,
}));
}
}
});
}
subscribe() {
return __awaiter(this, void 0, void 0, function* () {
if (!this.publishPayloadToChannel)
return;
if (!this.client) {
throw new Error("No redis client");
}
// Redis requires that subscribers use a separate client
this.subscriberClient = this.client.duplicate();
yield this.subscriberClient.connect();
// Subscribe to Redis pub/sub so that this proxy node can:
// 1. emit SSE to SDK subscribers
// 2. update its MemoryCache
this.subscriberClient.subscribe("set", (message, channel) => __awaiter(this, void 0, void 0, function* () {
var _a;
if (channel === "set") {
try {
const { uuid, key, payload } = JSON.parse(message);
// ignore messages published from this node (shouldn't subscribe to ourselves)
if (uuid === this.clientUUID)
return;
// 1. emit SSE to SDK clients (if new payload !== old payload)
if ((_a = this.appContext) === null || _a === void 0 ? void 0 : _a.enableEventStream) {
const oldEntry = yield this.get(key);
eventStreamManager_1.eventStreamManager.publish(key, "features", payload, oldEntry === null || oldEntry === void 0 ? void 0 : oldEntry.payload);
}
// 2. update MemoryCache
if (this.memoryCacheClient) {
const entry = {
payload,
staleOn: new Date(Date.now() + this.staleTTL),
expiresOn: new Date(Date.now() + this.expiresTTL),
};
yield this.memoryCacheClient.set(key, entry);
}
}
catch (e) {
logger_1.default.error(e, "Error parsing message from Redis pub/sub");
}
}
}));
});
}
getClient() {
return this.client;
}
getsubscriberClient() {
return this.subscriberClient;
}
}
exports.RedisCache = RedisCache;
//# sourceMappingURL=RedisCache.js.map

@@ -33,2 +33,3 @@ import { Express } from "express";

enableEventStream?: boolean;
enableEventStreamHeaders?: boolean;
proxyAllRequests?: boolean;

@@ -35,0 +36,0 @@ environment?: "development" | "production";

@@ -7,3 +7,3 @@ {

"description": "GrowthBook proxy server for caching, realtime updates, telemetry, etc",
"version": "1.0.3",
"version": "1.0.4",
"main": "dist/app.js",

@@ -21,3 +21,3 @@ "license": "MIT",

"type-check": "tsc --pretty --noEmit",
"start": "node dist/src/index.js",
"start": "node dist/index.js",
"dev": "concurrently 'tsc --watch' 'nodemon -q dist/index.js | yarn pino-pretty'"

@@ -35,3 +35,4 @@ },

"spdy": "^4.0.2",
"sse-pubsub": "^1.4.1"
"sse-pubsub": "^1.4.1",
"uuid": "^9.0.0"
},

@@ -45,2 +46,3 @@ "devDependencies": {

"@types/spdy": "^3.4.5",
"@types/uuid": "^9.0.1",
"@typescript-eslint/eslint-plugin": "^5.48.0",

@@ -47,0 +49,0 @@ "@typescript-eslint/parser": "^5.48.0",

@@ -36,3 +36,13 @@ # GrowthBook Proxy

You will also need to ensure that your self-hosted GrowthBook instance is configured to use the proxy server. This includes setting environment variables:
```
PROXY_ENABLED=1
PROXY_HOST_PUBLIC=https://proxy.example.com
## Optional; you may also use the GrowthBook UI to set this:
SECRET_API_KEY=something_secret
```
See GrowthBook's [Proxy documentation](https://docs.growthbook.io/self-host/proxy#standalone) for more information.
## Configuration

@@ -39,0 +49,0 @@

@@ -55,2 +55,3 @@ import fs from "fs";

enableEventStream: true,
enableEventStreamHeaders: true,
proxyAllRequests: false,

@@ -104,2 +105,2 @@ };

};
};
};

@@ -12,2 +12,8 @@ import express from "express";

enableAdmin: ["true", "1"].includes(process.env.ENABLE_ADMIN ?? "0"),
enableEventStream: ["true", "1"].includes(
process.env.ENABLE_EVENT_STREAM ?? "1"
),
enableEventStreamHeaders: ["true", "1"].includes(
process.env.ENABLE_EVENT_STREAM_HEADERS ?? "1"
),
adminKey: process.env.ADMIN_KEY,

@@ -22,2 +28,5 @@ environment: process.env.NODE_ENV as Context["environment"],

useAdditionalMemoryCache: true,
publishPayloadToChannel: ["true", "1"].includes(
process.env.PUBLISH_PAYLOAD_TO_CHANNEL ?? "0"
),
},

@@ -24,0 +33,0 @@ };

@@ -8,3 +8,3 @@ import { NextFunction, Request, Response } from "express";

) => {
if (req.app.locals?.ctx?.enableEventStream) {
if (req.app.locals?.ctx?.enableEventStreamHeaders) {
res.setHeader("x-sse-support", "enabled");

@@ -11,0 +11,0 @@ res.setHeader("Access-Control-Expose-Headers", "x-sse-support");

@@ -21,2 +21,3 @@ import { Context } from "../../types";

useAdditionalMemoryCache?: boolean;
publishPayloadToChannel?: boolean; // for RedisCache pub/sub
}

@@ -32,3 +33,3 @@

logger.info("using Redis cache");
featuresCache = new RedisCache(context.cacheSettings);
featuresCache = new RedisCache(context.cacheSettings, context);
await featuresCache.connect();

@@ -35,0 +36,0 @@ } else if (context.cacheSettings.cacheEngine === "mongo") {

@@ -89,2 +89,5 @@ import { Collection, MongoClient } from "mongodb";

if (!entry) {
return undefined;
}
if (!this.allowStale && entry.staleOn < new Date()) {

@@ -123,2 +126,6 @@ return undefined;

}
public getClient() {
return this.client;
}
}
import { createClient } from "redis";
import { v4 as uuidv4 } from "uuid";
import logger from "../logger";
import { eventStreamManager } from "../eventStreamManager";
import { Context } from "../../types";
import { MemoryCache } from "./MemoryCache";

@@ -8,2 +11,7 @@ import { CacheEntry, CacheSettings } from "./index";

private client: ReturnType<typeof createClient> | undefined;
private clientUUID: string = uuidv4();
private readonly publishPayloadToChannel: boolean;
private subscriberClient: ReturnType<typeof createClient> | undefined;
private readonly memoryCacheClient: MemoryCache | undefined;

@@ -15,9 +23,15 @@ private readonly connectionUrl: string | undefined;

public constructor({
staleTTL = 60, // 1 minute
expiresTTL = 10 * 60, // 10 minutes
allowStale = true,
connectionUrl,
useAdditionalMemoryCache,
}: CacheSettings = {}) {
private readonly appContext?: Context;
public constructor(
{
staleTTL = 60, // 1 minute
expiresTTL = 10 * 60, // 10 minutes
allowStale = true,
connectionUrl,
useAdditionalMemoryCache,
publishPayloadToChannel = false,
}: CacheSettings = {},
appContext?: Context
) {
this.connectionUrl = connectionUrl;

@@ -27,3 +41,6 @@ this.staleTTL = staleTTL * 1000;

this.allowStale = allowStale;
this.publishPayloadToChannel = publishPayloadToChannel;
this.appContext = appContext;
// wrap the RedisCache in a MemoryCache to avoid hitting Redis on every request

@@ -47,2 +64,4 @@ if (useAdditionalMemoryCache) {

await this.client.connect();
await this.subscribe();
}

@@ -79,2 +98,5 @@ }

if (!entry) {
return undefined;
}
if (!this.allowStale && entry.staleOn < new Date()) {

@@ -111,3 +133,79 @@ return undefined;

}
// Publish with Redis pub/sub so that other proxy nodes can
// 1. emit SSE to SDK subscribers
// 2. update their MemoryCache
if (this.publishPayloadToChannel && this.subscriberClient) {
// publish to Redis subscribers if new payload !== old payload
const oldEntry = await this.get(key);
const hasChanges =
JSON.stringify(oldEntry?.payload) !== JSON.stringify(payload);
if (hasChanges) {
this.client.publish(
"set",
JSON.stringify({
uuid: this.clientUUID,
key,
payload,
})
);
}
}
}
private async subscribe() {
if (!this.publishPayloadToChannel) return;
if (!this.client) {
throw new Error("No redis client");
}
// Redis requires that subscribers use a separate client
this.subscriberClient = this.client.duplicate();
await this.subscriberClient.connect();
// Subscribe to Redis pub/sub so that this proxy node can:
// 1. emit SSE to SDK subscribers
// 2. update its MemoryCache
this.subscriberClient.subscribe("set", async (message, channel) => {
if (channel === "set") {
try {
const { uuid, key, payload } = JSON.parse(message);
// ignore messages published from this node (shouldn't subscribe to ourselves)
if (uuid === this.clientUUID) return;
// 1. emit SSE to SDK clients (if new payload !== old payload)
if (this.appContext?.enableEventStream) {
const oldEntry = await this.get(key);
eventStreamManager.publish(
key,
"features",
payload,
oldEntry?.payload
);
}
// 2. update MemoryCache
if (this.memoryCacheClient) {
const entry = {
payload,
staleOn: new Date(Date.now() + this.staleTTL),
expiresOn: new Date(Date.now() + this.expiresTTL),
};
await this.memoryCacheClient.set(key, entry);
}
} catch (e) {
logger.error(e, "Error parsing message from Redis pub/sub");
}
}
});
}
public getClient() {
return this.client;
}
public getsubscriberClient() {
return this.subscriberClient;
}
}

@@ -35,2 +35,3 @@ import { Express } from "express";

enableEventStream?: boolean;
enableEventStreamHeaders?: boolean;
proxyAllRequests?: boolean;

@@ -37,0 +38,0 @@ environment?: "development" | "production";

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc