@growthbook/proxy
Advanced tools
Comparing version 1.0.8 to 1.0.9
@@ -50,2 +50,3 @@ "use strict"; | ||
enableEventStreamHeaders: ["true", "1"].includes((_c = process.env.ENABLE_EVENT_STREAM_HEADERS) !== null && _c !== void 0 ? _c : "1"), | ||
eventStreamMaxDurationMs: 30000, | ||
adminKey: process.env.ADMIN_KEY, | ||
@@ -52,0 +53,0 @@ environment: process.env.NODE_ENV, |
@@ -122,2 +122,3 @@ "use strict"; | ||
if (hasChanges) { | ||
logger_1.default.debug({ payload }, "RedisCache.set: publish to Redis subscribers"); | ||
this.client.publish("set", JSON.stringify({ | ||
@@ -128,3 +129,5 @@ uuid: this.clientUUID, | ||
})); | ||
return; | ||
} | ||
logger_1.default.debug({ payload, oldPayload: oldEntry === null || oldEntry === void 0 ? void 0 : oldEntry.payload }, "RedisCache.set: do not publish to Redis subscribers (no changes)"); | ||
} | ||
@@ -134,5 +137,7 @@ }); | ||
subscribe() { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (!this.publishPayloadToChannel) | ||
return; | ||
((_a = this.appContext) === null || _a === void 0 ? void 0 : _a.verboseDebugging) && logger_1.default.debug("RedisCache.subscribe"); | ||
if (!this.client) { | ||
@@ -148,3 +153,3 @@ throw new Error("No redis client"); | ||
this.subscriberClient.subscribe("set", (message, channel) => __awaiter(this, void 0, void 0, function* () { | ||
var _a; | ||
var _b, _c, _d; | ||
if (channel === "set") { | ||
@@ -156,5 +161,9 @@ try { | ||
return; | ||
((_b = this.appContext) === null || _b === void 0 ? void 0 : _b.verboseDebugging) && | ||
logger_1.default.debug({ payload }, "RedisCache.subscribe: got 'set' message"); | ||
// 1. emit SSE to SDK clients (if new payload !== old payload) | ||
if (((_a = this.appContext) === null || _a === void 0 ? void 0 : _a.enableEventStream) && eventStreamManager_1.eventStreamManager) { | ||
if (((_c = this.appContext) === null || _c === void 0 ? void 0 : _c.enableEventStream) && eventStreamManager_1.eventStreamManager) { | ||
const oldEntry = yield this.get(key); | ||
((_d = this.appContext) === null || _d === void 0 ? void 0 : _d.verboseDebugging) && | ||
logger_1.default.debug({ payload }, "RedisCache.subscribe: publish SSE"); | ||
eventStreamManager_1.eventStreamManager.publish(key, "features", payload, oldEntry === null || oldEntry === void 0 ? void 0 : oldEntry.payload); | ||
@@ -161,0 +170,0 @@ } |
@@ -9,5 +9,2 @@ "use strict"; | ||
const ssePubsub_1 = require("./ssePubsub"); | ||
const defaultOptions = { | ||
historySize: 1, | ||
}; | ||
class SSEManager { | ||
@@ -19,2 +16,5 @@ constructor(appContext) { | ||
subscribe(req, res) { | ||
var _a; | ||
((_a = this.appContext) === null || _a === void 0 ? void 0 : _a.verboseDebugging) && | ||
logger_1.default.info("EventStreamManager.subscribe"); | ||
const apiKey = res.locals.apiKey; | ||
@@ -92,3 +92,3 @@ if (apiKey) { | ||
apiKey, | ||
channel: new ssePubsub_1.SSEChannel(defaultOptions, this.appContext), | ||
channel: new ssePubsub_1.SSEChannel({ maxStreamDuration: this.appContext.eventStreamMaxDurationMs }, this.appContext), | ||
}); | ||
@@ -95,0 +95,0 @@ scopedChannel = this.scopedChannels.get(apiKey); |
@@ -9,3 +9,3 @@ "use strict"; | ||
class SSEChannel { | ||
constructor({ pingInterval = 3000, maxStreamDuration = 30000, clientRetryInterval = 1000, startId = 1, historySize = 100, rewind = 0, }, ctx) { | ||
constructor({ pingInterval = 3000, maxStreamDuration = 30000, clientRetryInterval = 1000, startId = 1, historySize = 1, rewind = 0, }, ctx) { | ||
this.nextID = 1; | ||
@@ -32,2 +32,5 @@ this.clients = new Set(); | ||
publish(data, eventName) { | ||
var _a; | ||
((_a = this.ctx) === null || _a === void 0 ? void 0 : _a.verboseDebugging) && | ||
logger_1.default.info({ clients: this.clients.size }, "ssePubsub.subscribe: publish"); | ||
if (!this.active) { | ||
@@ -73,2 +76,4 @@ logger_1.default.warn("ssePubsub.publish: Channel closed"); | ||
subscribe(req, res, events) { | ||
var _a; | ||
((_a = this.ctx) === null || _a === void 0 ? void 0 : _a.verboseDebugging) && logger_1.default.info("ssePubsub.subscribe: subscribe"); | ||
if (!this.active) { | ||
@@ -103,10 +108,12 @@ logger_1.default.warn("ssePubsub.subscribe: Channel closed"); | ||
this.clients.add(c); | ||
setTimeout(() => { | ||
var _a; | ||
if (!c.res.finished) { | ||
((_a = this.ctx) === null || _a === void 0 ? void 0 : _a.verboseDebugging) && | ||
logger_1.default.info("ssePubsub.subscribe: unsubscribe via timeout"); | ||
this.unsubscribe(c); | ||
} | ||
}, this.options.maxStreamDuration); | ||
if (this.options.maxStreamDuration) { | ||
setTimeout(() => { | ||
var _a; | ||
if (!c.res.finished) { | ||
((_a = this.ctx) === null || _a === void 0 ? void 0 : _a.verboseDebugging) && | ||
logger_1.default.info("ssePubsub.subscribe: unsubscribe via timeout"); | ||
this.unsubscribe(c); | ||
} | ||
}, this.options.maxStreamDuration); | ||
} | ||
c.res.on("close", () => { | ||
@@ -113,0 +120,0 @@ var _a; |
@@ -34,2 +34,3 @@ import { Express } from "express"; | ||
enableEventStreamHeaders?: boolean; | ||
eventStreamMaxDurationMs?: number; | ||
proxyAllRequests?: boolean; | ||
@@ -36,0 +37,0 @@ environment?: "development" | "production"; |
@@ -7,3 +7,3 @@ { | ||
"description": "GrowthBook proxy server for caching, realtime updates, telemetry, etc", | ||
"version": "1.0.8", | ||
"version": "1.0.9", | ||
"main": "dist/app.js", | ||
@@ -10,0 +10,0 @@ "license": "MIT", |
@@ -18,2 +18,3 @@ import express from "express"; | ||
), | ||
eventStreamMaxDurationMs: 30000, | ||
adminKey: process.env.ADMIN_KEY, | ||
@@ -20,0 +21,0 @@ environment: process.env.NODE_ENV as Context["environment"], |
@@ -138,2 +138,7 @@ import { createClient } from "redis"; | ||
if (hasChanges) { | ||
logger.debug( | ||
{ payload }, | ||
"RedisCache.set: publish to Redis subscribers" | ||
); | ||
this.client.publish( | ||
@@ -147,3 +152,9 @@ "set", | ||
); | ||
return; | ||
} | ||
logger.debug( | ||
{ payload, oldPayload: oldEntry?.payload }, | ||
"RedisCache.set: do not publish to Redis subscribers (no changes)" | ||
); | ||
} | ||
@@ -154,2 +165,4 @@ } | ||
if (!this.publishPayloadToChannel) return; | ||
this.appContext?.verboseDebugging && logger.debug("RedisCache.subscribe"); | ||
if (!this.client) { | ||
@@ -173,2 +186,7 @@ throw new Error("No redis client"); | ||
if (uuid === this.clientUUID) return; | ||
this.appContext?.verboseDebugging && | ||
logger.debug( | ||
{ payload }, | ||
"RedisCache.subscribe: got 'set' message" | ||
); | ||
@@ -178,2 +196,5 @@ // 1. emit SSE to SDK clients (if new payload !== old payload) | ||
const oldEntry = await this.get(key); | ||
this.appContext?.verboseDebugging && | ||
logger.debug({ payload }, "RedisCache.subscribe: publish SSE"); | ||
eventStreamManager.publish( | ||
@@ -180,0 +201,0 @@ key, |
import { Request, Response } from "express"; | ||
import logger from "../logger"; | ||
import { Context } from "../../types"; | ||
import { SSEChannel, Options } from "./ssePubsub"; | ||
import { SSEChannel } from "./ssePubsub"; | ||
const defaultOptions: Partial<Options> = { | ||
historySize: 1, | ||
}; | ||
interface ScopedChannel { | ||
@@ -25,2 +21,4 @@ apiKey: string; | ||
public subscribe(req: Request, res: Response) { | ||
this.appContext?.verboseDebugging && | ||
logger.info("EventStreamManager.subscribe"); | ||
const apiKey = res.locals.apiKey; | ||
@@ -108,3 +106,6 @@ if (apiKey) { | ||
apiKey, | ||
channel: new SSEChannel(defaultOptions, this.appContext), | ||
channel: new SSEChannel( | ||
{ maxStreamDuration: this.appContext.eventStreamMaxDurationMs }, | ||
this.appContext | ||
), | ||
}); | ||
@@ -111,0 +112,0 @@ scopedChannel = this.scopedChannels.get(apiKey); |
@@ -49,3 +49,3 @@ import { Request, Response } from "express"; | ||
startId = 1, | ||
historySize = 100, | ||
historySize = 1, | ||
rewind = 0, | ||
@@ -77,2 +77,7 @@ }: Partial<Options>, | ||
publish(data?: any, eventName?: string) { | ||
this.ctx?.verboseDebugging && | ||
logger.info( | ||
{ clients: this.clients.size }, | ||
"ssePubsub.subscribe: publish" | ||
); | ||
if (!this.active) { | ||
@@ -125,2 +130,3 @@ logger.warn("ssePubsub.publish: Channel closed"); | ||
subscribe(req: Request, res: Response, events?: (string | RegExp)[]) { | ||
this.ctx?.verboseDebugging && logger.info("ssePubsub.subscribe: subscribe"); | ||
if (!this.active) { | ||
@@ -161,9 +167,11 @@ logger.warn("ssePubsub.subscribe: Channel closed"); | ||
setTimeout(() => { | ||
if (!c.res.finished) { | ||
this.ctx?.verboseDebugging && | ||
logger.info("ssePubsub.subscribe: unsubscribe via timeout"); | ||
this.unsubscribe(c); | ||
} | ||
}, this.options.maxStreamDuration); | ||
if (this.options.maxStreamDuration) { | ||
setTimeout(() => { | ||
if (!c.res.finished) { | ||
this.ctx?.verboseDebugging && | ||
logger.info("ssePubsub.subscribe: unsubscribe via timeout"); | ||
this.unsubscribe(c); | ||
} | ||
}, this.options.maxStreamDuration); | ||
} | ||
@@ -170,0 +178,0 @@ c.res.on("close", () => { |
@@ -36,2 +36,3 @@ import { Express } from "express"; | ||
enableEventStreamHeaders?: boolean; | ||
eventStreamMaxDurationMs?: number; | ||
proxyAllRequests?: boolean; | ||
@@ -38,0 +39,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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
247604
4181