Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

hypertune

Package Overview
Dependencies
Maintainers
2
Versions
156
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hypertune - npm Package Compare versions

Comparing version 2.2.5 to 2.3.0-alpha.0

dist/shared/helpers/RemoteLogger.d.ts

4

CHANGELOG.md
# Changelog
## 2.3.0
- Traceability and shutdown behavior improvements.
## 2.2.5

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

2

dist/cli/generate/index.js

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

})
.option("--framework [value]", "Framework (nextApp, nextAppFlags, nextPages, react, remix or gatsby)")
.option("--framework [value]", "Framework (nextApp, nextPages, react, remix or gatsby)")
.option("--platform [value]", "Platform (vercel)")

@@ -71,0 +71,0 @@ .option("--getHypertuneImportPath [value]", "Relative import path for a file with a default export of the `getHypertune` function, which takes a single object argument containing readonly `headers` and `cookies`; only used for the nextApp framework and vercel platform");

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

/// <reference types="node" />
import { InitData, Expression, Query, Value, ObjectValueWithVariables, UpdateListener, ReductionLogs, DehydratedState, DeepPartial, InitDataProvider, ObjectValue } from "../shared";

@@ -12,4 +13,5 @@ import Logger from "./Logger";

protected readonly updateListeners: Map<UpdateListener, boolean>;
protected shouldClose: boolean;
protected updateTimeout: NodeJS.Timeout | null;
readonly logger: Logger;
shouldClose: boolean;
initData: InitData | null;

@@ -24,4 +26,6 @@ lastDataProviderInitTime: number | null;

override: DeepPartial<ObjectValue> | null;
constructor({ initData, initDataProvider, initDataRefreshIntervalMs, shouldCheckForUpdates, query, queryCode, variableValues, logger, loggerFlushIntervalMs, cacheSize, override, }: {
constructor({ traceId, initData, lastDataProviderInitTime, initDataProvider, initDataRefreshIntervalMs, shouldCheckForUpdates, query, queryCode, variableValues, logger, cacheSize, override, }: {
traceId: string;
initData: InitData | null;
lastDataProviderInitTime: number | null;
initDataProvider: InitDataProvider | null;

@@ -34,3 +38,2 @@ initDataRefreshIntervalMs: number;

logger: Logger;
loggerFlushIntervalMs: number | null;
cacheSize: number;

@@ -47,2 +50,3 @@ override: object | null;

isReady(): boolean;
close(traceId: string): Promise<void>;
getStateHash(): string;

@@ -55,2 +59,3 @@ addUpdateListener(listener: UpdateListener): void;

hydrate<TOverride extends ObjectValue, TVariableValues extends ObjectValue>(traceId: string, dehydratedState: DehydratedState<TOverride, TVariableValues>): void;
private setLastDataProviderInitTime;
reduce(query: Query<ObjectValueWithVariables> | null, expression: Expression): Expression;

@@ -57,0 +62,0 @@ private log;

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

// eslint-disable-next-line max-params
constructor({ initData, initDataProvider, initDataRefreshIntervalMs, shouldCheckForUpdates, query, queryCode, variableValues, logger, loggerFlushIntervalMs, cacheSize, override, }) {
constructor({ traceId, initData, lastDataProviderInitTime, initDataProvider, initDataRefreshIntervalMs, shouldCheckForUpdates, query, queryCode, variableValues, logger, cacheSize, override, }) {
this.shouldClose = false;
this.updateTimeout = null;
// @internal
this.shouldClose = false;
this.initData = null;
// @internal
this.lastDataProviderInitTime = null;
// @internal
this.getFieldCache = null;
// @internal
this.getItemsCache = null;
// @internal
this.evaluateCache = null;
// @internal
this.override = null;
this.initDataProvider = initDataProvider;

@@ -34,7 +46,2 @@ this.initDataRefreshIntervalMs = initDataRefreshIntervalMs;

this.logger = logger;
this.initData = null;
this.lastDataProviderInitTime = null;
this.getFieldCache = null;
this.getItemsCache = null;
this.evaluateCache = null;
this.override = override;

@@ -46,7 +53,7 @@ if (cacheSize > 0) {

}
const traceId = (0, shared_1.uniqueId)();
if (initData) {
this.initFromData(traceId, initData);
this.setLastDataProviderInitTime(lastDataProviderInitTime);
}
this.initAndStartIntervals(shouldCheckForUpdates, loggerFlushIntervalMs);
this.initAndStartIntervals(traceId, shouldCheckForUpdates);
if (environment_1.isBrowser) {

@@ -57,3 +64,3 @@ window.addEventListener("beforeunload", () => __awaiter(this, void 0, void 0, function* () {

}
yield this.logger.flush(/* traceId */ (0, shared_1.uniqueId)());
yield this.close(/* traceId */ (0, shared_1.uniqueId)());
}));

@@ -201,5 +208,5 @@ }

}
initAndStartIntervals(shouldCheckForUpdates, loggerFlushIntervalMs) {
initAndStartIntervals(initTraceId, shouldCheckForUpdates) {
if (!this.initDataProvider || !shouldCheckForUpdates) {
this.log(/* traceId */ "", shared_1.LogLevel.Info, "Not polling for updates.");
this.log(initTraceId, shared_1.LogLevel.Info, "Not polling for updates.");
}

@@ -210,2 +217,8 @@ if (this.initDataProvider) {

const traceId = (0, shared_1.uniqueId)();
if (this.shouldClose) {
// No need to get updates when the SDK is shutting down.
this.updateTimeout = null;
this.log(traceId, shared_1.LogLevel.Debug, "Stopped getting updates from the data provider.");
return;
}
this.initIfNeeded(traceId, shared_1.defaultRetries)

@@ -215,8 +228,8 @@ .catch((error) => this.log(traceId, shared_1.LogLevel.Error, "Error updating from data provider.", (0, getMetadata_1.default)(error)))

if (this.shouldClose) {
this.log(
/* traceId */ "", shared_1.LogLevel.Debug, "Stopped getting updates from the data provider.");
this.updateTimeout = null;
this.log(traceId, shared_1.LogLevel.Debug, "Stopped getting updates from the data provider.");
return;
}
if (shouldCheckForUpdates) {
setTimeout(update, this.initDataRefreshIntervalMs);
this.updateTimeout = setTimeout(update, this.initDataRefreshIntervalMs);
}

@@ -227,22 +240,2 @@ });

}
// eslint-disable-next-line @hypertune/prefer-early-returns
if (loggerFlushIntervalMs !== null) {
// eslint-disable-next-line func-style
const flushLogQueue = () => {
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
if (this.shouldClose) {
this.log(
/* traceId */ "", shared_1.LogLevel.Debug, "Stopped flushing log queue.");
return;
}
yield this.logger.flush(/* traceId */ (0, shared_1.uniqueId)());
flushLogQueue();
}), loggerFlushIntervalMs);
};
flushLogQueue();
}
else {
this.log(
/* traceId */ "", shared_1.LogLevel.Info, "Not automatically flushing logs.");
}
}

@@ -256,2 +249,15 @@ // @internal

// @internal
close(traceId) {
return __awaiter(this, void 0, void 0, function* () {
this.log(traceId, shared_1.LogLevel.Info, "Closing...");
this.shouldClose = true;
if (this.updateTimeout) {
clearTimeout(this.updateTimeout);
this.updateTimeout = null;
}
yield this.logger.close(traceId);
this.log(traceId, shared_1.LogLevel.Info, "Closed.");
});
}
// @internal
getStateHash() {

@@ -294,3 +300,3 @@ var _a, _b;

}
const { override } = this;
const { lastDataProviderInitTime, override } = this;
const dehydrateQuery = query !== null && query !== void 0 ? query : this.query;

@@ -305,2 +311,3 @@ const dehydrateQueryVariableValues = variableValues !== null && variableValues !== void 0 ? variableValues : this.variableValues;

initData,
lastDataProviderInitTime,
override: override,

@@ -313,3 +320,3 @@ variableValues: dehydrateQueryVariableValues,

this.log(traceId, shared_1.LogLevel.Info, "Hydrating...");
const { initData, override, variableValues } = dehydratedState;
const { initData, override, variableValues, lastDataProviderInitTime } = dehydratedState;
if (initData && variableValues) {

@@ -319,9 +326,13 @@ this.variableValues = variableValues;

this.initFromData(traceId, initData);
if (this.initDataProvider) {
// Set the last initialization time as hydration should only be used with
// the latest available data.
this.lastDataProviderInitTime = Date.now();
}
this.setLastDataProviderInitTime(lastDataProviderInitTime);
this.setOverride(traceId, override);
}
setLastDataProviderInitTime(newTime) {
if (!this.initDataProvider || !newTime) {
return;
}
// Don't set the time to a future value.
const now = Date.now();
this.lastDataProviderInitTime = newTime > now ? now : newTime;
}
// @internal

@@ -328,0 +339,0 @@ reduce(query, expression) {

@@ -16,3 +16,4 @@ "use strict";

function create({ NodeConstructor, token, query, queryCode, variableValues, override, options, }) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
const traceId = (0, shared_1.uniqueId)();
let logger;

@@ -22,5 +23,12 @@ const remoteLoggingMode = (_b = (_a = options.remoteLogging) === null || _a === void 0 ? void 0 : _a.mode) !== null && _b !== void 0 ? _b : (environment_1.isBrowser ? "session" : "normal");

logger = new Logger_1.default({
traceId,
token,
remoteLoggingMode,
remoteLoggingEndpointUrl: (_d = (_c = options.remoteLogging) === null || _c === void 0 ? void 0 : _c.endpointUrl) !== null && _d !== void 0 ? _d : shared_1.prodLogsEndpointUrl,
remoteFlushIntervalMs: ((_c = options.remoteLogging) === null || _c === void 0 ? void 0 : _c.flushIntervalMs) !== undefined
? options.remoteLogging.flushIntervalMs === null ||
options.remoteLogging.flushIntervalMs === 0 // TODO: Deprecate
? null
: clampInterval(options.remoteLogging.flushIntervalMs)
: defaultIntervalMs,
remoteLoggingEndpointUrl: (_e = (_d = options.remoteLogging) === null || _d === void 0 ? void 0 : _d.endpointUrl) !== null && _e !== void 0 ? _e : shared_1.prodLogsEndpointUrl,
localLogger: options.localLogger,

@@ -48,6 +56,8 @@ });

const context = new Context_1.default({
traceId,
query,
queryCode,
variableValues,
initData: (_e = options.initData) !== null && _e !== void 0 ? _e : null,
initData: (_f = options.initData) !== null && _f !== void 0 ? _f : null,
lastDataProviderInitTime: (_g = options.lastDataProviderInitTime) !== null && _g !== void 0 ? _g : null,
initDataProvider: options.initDataProvider !== undefined

@@ -65,20 +75,9 @@ ? options.initDataProvider

// at least the minimum interval.
clampInterval((_f = options.initDataRefreshIntervalMs) !== null && _f !== void 0 ? _f : (options.initIntervalMs || defaultIntervalMs)),
clampInterval((_h = options.initDataRefreshIntervalMs) !== null && _h !== void 0 ? _h : (options.initIntervalMs || defaultIntervalMs)),
shouldCheckForUpdates:
// Prioritize the new option else if the old option is set to 0,
// disable, else enable except for Next.js servers.
(_g = options.shouldCheckForUpdates) !== null && _g !== void 0 ? _g : (options.initIntervalMs === 0 ? false : !isNextJsBuildOrServer),
(_j = options.shouldCheckForUpdates) !== null && _j !== void 0 ? _j : (options.initIntervalMs === 0 ? false : !isNextJsBuildOrServer),
logger,
loggerFlushIntervalMs:
// Use the provided option else use the default interval but disable
// flushing by default if remote logging mode is set to off.
remoteLoggingMode === "off"
? null
: ((_h = options.remoteLogging) === null || _h === void 0 ? void 0 : _h.flushIntervalMs) !== undefined
? options.remoteLogging.flushIntervalMs === null ||
options.remoteLogging.flushIntervalMs === 0 // TODO: Deprecate
? null
: clampInterval(options.remoteLogging.flushIntervalMs)
: defaultIntervalMs,
cacheSize: (_j = options.cacheSize) !== null && _j !== void 0 ? _j : shared_1.defaultCacheSize,
cacheSize: (_k = options.cacheSize) !== null && _k !== void 0 ? _k : shared_1.defaultCacheSize,
override: override !== null && override !== void 0 ? override : null,

@@ -91,3 +90,3 @@ });

step: null,
expression: (_l = (_k = context.initData) === null || _k === void 0 ? void 0 : _k.reducedExpression) !== null && _l !== void 0 ? _l : null,
expression: (_m = (_l = context.initData) === null || _l === void 0 ? void 0 : _l.reducedExpression) !== null && _m !== void 0 ? _m : null,
});

@@ -94,0 +93,0 @@ }

import { ReductionLogs, Expression, LocalLogger, LogLevel } from "../shared";
import { RemoteLoggingMode } from "../shared/types";
/**
* Logger provides a high level API for Node and generic SDK logs. It emits
* these logs using the local logger and it also forwards them to the
* `RemoteLogger` based on the selected `RemoteLoggingMode`.
*/
export default class Logger {

@@ -9,5 +14,7 @@ readonly id: string;

private readonly localLogger;
constructor({ token, remoteLoggingMode, remoteLoggingEndpointUrl, localLogger, }: {
constructor({ traceId, token, remoteLoggingMode, remoteFlushIntervalMs, remoteLoggingEndpointUrl, localLogger, }: {
traceId: string;
token: string;
remoteLoggingMode: RemoteLoggingMode;
remoteFlushIntervalMs: number | null;
remoteLoggingEndpointUrl: string;

@@ -27,6 +34,7 @@ localLogger?: LocalLogger;

}): void;
private shouldRemoteLog;
private shouldRemoteNodeLog;
log(level: LogLevel, commitId: string | null, message: string, metadata: object): void;
flush(traceId: string): Promise<void>;
close(traceId: string): Promise<void>;
}
//# sourceMappingURL=Logger.d.ts.map

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

const shared_1 = require("../shared");
const BackendRemoteLogger_1 = __importDefault(require("../shared/helpers/BackendRemoteLogger"));
const RemoteLogger_1 = __importDefault(require("../shared/helpers/RemoteLogger"));
const toConsoleFunction_1 = __importDefault(require("../shared/helpers/toConsoleFunction"));

@@ -23,15 +23,19 @@ const LRUCache_1 = __importDefault(require("../shared/helpers/LRUCache"));

const newTracedFetch_1 = __importDefault(require("../shared/helpers/newTracedFetch"));
const NoopRemoteLogger_1 = __importDefault(require("../shared/helpers/NoopRemoteLogger"));
const fetchMaxKeepAliveRequestSizeBytes = 64000;
/**
* Logger provides a high level API for Node and generic SDK logs. It emits
* these logs using the local logger and it also forwards them to the
* `RemoteLogger` based on the selected `RemoteLoggingMode`.
*/
class Logger {
constructor({ token, remoteLoggingMode, remoteLoggingEndpointUrl, localLogger, }) {
constructor({ traceId, token, remoteLoggingMode, remoteFlushIntervalMs, remoteLoggingEndpointUrl, localLogger, }) {
this.remoteLogCache = new LRUCache_1.default(10000);
this.id = (0, shared_1.uniqueId)();
this.remoteLoggingMode =
remoteLoggingMode === "off" ? "normal" : remoteLoggingMode;
this.remoteLoggingMode = remoteLoggingMode;
this.localLogger = wrapLocalLogger(this.id, localLogger);
this.remoteLogger =
remoteLoggingMode === "off"
? (0, NoopRemoteLogger_1.default)()
: new BackendRemoteLogger_1.default({
? null
: new RemoteLogger_1.default({
traceId,
token,

@@ -43,5 +47,7 @@ createLogs: getCreateLogsFunction((0, newTracedFetch_1.default)({

localLogger: this.localLogger,
flushIntervalMs: remoteFlushIntervalMs,
});
}
nodeLog({ commitId, initDataHash, nodeTypeName, nodePath, nodeExpression, level, message, metadata, reductionLogs, }) {
var _a, _b, _c, _d, _e;
const logMessage = `${nodeTypeName}Node at ${nodePath}: ${message}`;

@@ -55,4 +61,4 @@ const logMetadata = Object.assign({ sdkVersion: shared_1.sdkVersion,

if ((level === shared_1.LogLevel.Warn || level === shared_1.LogLevel.Error) &&
this.shouldRemoteLog(initDataHash, nodePath, message)) {
this.remoteLogger.log(shared_1.LogType.SdkNode, level, commitId, logMessage, logMetadata);
this.shouldRemoteNodeLog(initDataHash, nodePath, message)) {
(_a = this.remoteLogger) === null || _a === void 0 ? void 0 : _a.log(shared_1.LogType.SdkNode, level, commitId, logMessage, logMetadata);
}

@@ -63,18 +69,18 @@ if (reductionLogs) {

this.localLogger(shared_1.LogLevel.Error, errorMessage, logMetadata);
if (this.shouldRemoteLog(initDataHash, nodePath, message)) {
this.remoteLogger.log(shared_1.LogType.SdkNode, level, commitId, errorMessage, logMetadata);
if (this.shouldRemoteNodeLog(initDataHash, nodePath, message)) {
(_b = this.remoteLogger) === null || _b === void 0 ? void 0 : _b.log(shared_1.LogType.SdkNode, level, commitId, errorMessage, logMetadata);
}
return;
}
if (this.shouldRemoteLog(initDataHash, nodePath, "evaluations")) {
this.remoteLogger.evaluations(commitId, reductionLogs.evaluations);
if (this.shouldRemoteNodeLog(initDataHash, nodePath, "evaluations")) {
(_c = this.remoteLogger) === null || _c === void 0 ? void 0 : _c.evaluations(commitId, reductionLogs.evaluations);
}
// We always log events to the backend
this.remoteLogger.events(commitId, reductionLogs.events);
if (this.shouldRemoteLog(initDataHash, nodePath, "exposures")) {
this.remoteLogger.exposures(commitId, reductionLogs.exposures);
(_d = this.remoteLogger) === null || _d === void 0 ? void 0 : _d.events(commitId, reductionLogs.events);
if (this.shouldRemoteNodeLog(initDataHash, nodePath, "exposures")) {
(_e = this.remoteLogger) === null || _e === void 0 ? void 0 : _e.exposures(commitId, reductionLogs.exposures);
}
}
}
shouldRemoteLog(initDataHash, nodePath, cacheKeySuffix) {
shouldRemoteNodeLog(initDataHash, nodePath, cacheKeySuffix) {
switch (this.remoteLoggingMode) {

@@ -94,2 +100,5 @@ case "session": {

}
case "off": {
return false;
}
default: {

@@ -102,10 +111,19 @@ const neverLoggingMode = this.remoteLoggingMode;

log(level, commitId, message, metadata) {
var _a;
this.localLogger(level, message, metadata);
if (level === shared_1.LogLevel.Warn || level === shared_1.LogLevel.Error) {
this.remoteLogger.log(shared_1.LogType.SdkMessage, level, commitId, message, Object.assign(Object.assign({}, metadata), { sdkVersion: shared_1.sdkVersion }));
if (this.remoteLoggingMode !== "off" &&
(level === shared_1.LogLevel.Warn || level === shared_1.LogLevel.Error)) {
(_a = this.remoteLogger) === null || _a === void 0 ? void 0 : _a.log(shared_1.LogType.SdkMessage, level, commitId, message, Object.assign(Object.assign({}, metadata), { sdkVersion: shared_1.sdkVersion }));
}
}
flush(traceId) {
return this.remoteLogger.flush(traceId);
return this.remoteLogger
? this.remoteLogger.flush(traceId)
: Promise.resolve();
}
close(traceId) {
return this.remoteLogger
? this.remoteLogger.close(traceId)
: Promise.resolve();
}
}

@@ -112,0 +130,0 @@ exports.default = Logger;

@@ -40,7 +40,11 @@ "use strict";

function mergeObjectSource(value, override) {
return Object.fromEntries(Object.entries(value).map(([fieldName, field]) => [
return Object.fromEntries(Object.entries(value)
.map(([fieldName, field]) => [
fieldName,
mergeSource(field, override[fieldName]),
]));
])
.concat(
// Add any additional fields from the override to the object.
Object.entries(override).filter(([fieldName]) => !(fieldName in value))));
}
//# sourceMappingURL=merge.js.map

@@ -63,3 +63,4 @@ "use strict";

});
(0, vitest_1.expect)((0, merge_1.default)({ a: 1, b: "str" }, { c: "val" })).toEqual({ a: 1, b: "str", c: "val" });
});
//# sourceMappingURL=merge.test.js.map

@@ -53,4 +53,8 @@ import { Expression, ObjectValue, Query, Step, Value, UpdateListener, ReductionLogs, DehydratedState, DeepPartial, ObjectValueWithVariables } from "../shared";

hydrate<TOverride extends ObjectValue, TVariableValues extends ObjectValue>(dehydratedState: DehydratedState<TOverride, TVariableValues>, traceId?: string): void;
close(): void;
/**
* Close flushes any remaining logs and stops all background processes
* ensuring clean shutdown.
*/
close(traceId?: string): Promise<void>;
}
//# sourceMappingURL=Node.d.ts.map

@@ -369,9 +369,13 @@ "use strict";

}
close() {
/**
* Close flushes any remaining logs and stops all background processes
* ensuring clean shutdown.
*/
close(traceId = (0, shared_1.uniqueId)()) {
const { context } = this.props;
if (!context) {
this.log(shared_1.LogLevel.Error, "No context so cannot close.");
return;
return Promise.resolve();
}
context.shouldClose = true;
return context.close(traceId);
}

@@ -378,0 +382,0 @@ }

export { default as asError } from "./asError";
export { default as BackendRemoteLogger } from "./BackendRemoteLogger";
export { default as RemoteLogger } from "./RemoteLogger";
export { default as emptyThrows } from "./emptyThrows";

@@ -4,0 +4,0 @@ export { default as evaluate, complexFormExpressionEvaluationError, } from "./evaluate";

@@ -20,7 +20,7 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.getSplitsAndCommitConfigForExpression = exports.uniqueId = exports.toWords = exports.toStartCaseWords = exports.toStartCase = exports.toInt = exports.toDimensionTypeEnum = exports.throws = exports.stableStringify = exports.reduce = exports.prefixError = exports.nullThrows = exports.nanThrows = exports.mapExpressionWithResult = exports.mapExpression = exports.fold = exports.getNextName = exports.hash = exports.complexFormExpressionEvaluationError = exports.evaluate = exports.emptyThrows = exports.BackendRemoteLogger = exports.asError = void 0;
exports.getSplitsAndCommitConfigForExpression = exports.uniqueId = exports.toWords = exports.toStartCaseWords = exports.toStartCase = exports.toInt = exports.toDimensionTypeEnum = exports.throws = exports.stableStringify = exports.reduce = exports.prefixError = exports.nullThrows = exports.nanThrows = exports.mapExpressionWithResult = exports.mapExpression = exports.fold = exports.getNextName = exports.hash = exports.complexFormExpressionEvaluationError = exports.evaluate = exports.emptyThrows = exports.RemoteLogger = exports.asError = void 0;
var asError_1 = require("./asError");
Object.defineProperty(exports, "asError", { enumerable: true, get: function () { return __importDefault(asError_1).default; } });
var BackendRemoteLogger_1 = require("./BackendRemoteLogger");
Object.defineProperty(exports, "BackendRemoteLogger", { enumerable: true, get: function () { return __importDefault(BackendRemoteLogger_1).default; } });
var RemoteLogger_1 = require("./RemoteLogger");
Object.defineProperty(exports, "RemoteLogger", { enumerable: true, get: function () { return __importDefault(RemoteLogger_1).default; } });
var emptyThrows_1 = require("./emptyThrows");

@@ -27,0 +27,0 @@ Object.defineProperty(exports, "emptyThrows", { enumerable: true, get: function () { return __importDefault(emptyThrows_1).default; } });

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/** Replaced by the value in package.json on build */
exports.default = "2.2.5";
exports.default = "2.3.0-alpha.0";
//# sourceMappingURL=sdkVersion.js.map

@@ -545,9 +545,2 @@ import { isQueryVariableKey } from "./constants";

export type UpdateListener = (newStateHash: string) => void;
export type RemoteLogger = {
log(type: LogType, level: LogLevel, commitId: string | null, message: string, metadata: object): void;
evaluations(commitId: string, evaluations: CountMap): void;
events(commitId: string, events: CountMap): void;
exposures(commitId: string, exposures: CountMap): void;
flush(traceId: string): Promise<void>;
};
export type TracedFetch = (traceId: string, url: string, requestInit: Omit<RequestInit, "headers"> & {

@@ -603,2 +596,8 @@ headers: Record<string, string>;

/**
* `lastDataProviderInitTime` is a timestamp specifying the last time
* the provided `initData` was last checked for freshness using an
* `InitDataProvider`. It is ignored when no `initData` was provided.
*/
lastDataProviderInitTime?: number | null;
/**
* `initDataRefreshIntervalMs` specifies the interval, in milliseconds, at

@@ -689,2 +688,3 @@ * which the SDK checks for updates. The minimum allowed value is 1000ms.

initData: InitData;
lastDataProviderInitTime: number | null;
override: DeepPartial<TOverride> | null;

@@ -691,0 +691,0 @@ variableValues: TVariableValues;

{
"name": "hypertune",
"version": "2.2.5",
"version": "2.3.0-alpha.0",
"private": false,

@@ -5,0 +5,0 @@ "main": "./dist/index.js",

@@ -103,3 +103,3 @@ import { CAC } from "cac";

"--framework [value]",
"Framework (nextApp, nextAppFlags, nextPages, react, remix or gatsby)"
"Framework (nextApp, nextPages, react, remix or gatsby)"
)

@@ -106,0 +106,0 @@ .option("--platform [value]", "Platform (vercel)")

@@ -39,25 +39,27 @@ import pRetry from "p-retry";

protected readonly updateListeners: Map<UpdateListener, boolean>;
protected shouldClose = false;
protected updateTimeout: NodeJS.Timeout | null = null;
// @internal
public readonly logger: Logger;
// @internal
public shouldClose = false;
public initData: InitData | null = null;
// @internal
public initData: InitData | null;
public lastDataProviderInitTime: number | null = null;
// @internal
public lastDataProviderInitTime: number | null;
public readonly getFieldCache: LRUCache<Expression> | null = null;
// @internal
public readonly getFieldCache: LRUCache<Expression> | null;
public readonly getItemsCache: LRUCache<Expression[]> | null = null;
// @internal
public readonly getItemsCache: LRUCache<Expression[]> | null;
// @internal
public readonly evaluateCache: LRUCache<{
value: Value;
logs: ReductionLogs;
}> | null;
}> | null = null;
// @internal
public override: DeepPartial<ObjectValue> | null;
public override: DeepPartial<ObjectValue> | null = null;
// eslint-disable-next-line max-params
constructor({
traceId,
initData,
lastDataProviderInitTime,
initDataProvider,

@@ -70,7 +72,8 @@ initDataRefreshIntervalMs,

logger,
loggerFlushIntervalMs,
cacheSize,
override,
}: {
traceId: string;
initData: InitData | null;
lastDataProviderInitTime: number | null;
initDataProvider: InitDataProvider | null;

@@ -83,3 +86,2 @@ initDataRefreshIntervalMs: number;

logger: Logger;
loggerFlushIntervalMs: number | null;
cacheSize: number;

@@ -94,9 +96,3 @@ override: object | null;

this.updateListeners = new Map();
this.logger = logger;
this.initData = null;
this.lastDataProviderInitTime = null;
this.getFieldCache = null;
this.getItemsCache = null;
this.evaluateCache = null;
this.override = override;

@@ -109,8 +105,8 @@

}
const traceId = uniqueId();
if (initData) {
this.initFromData(traceId, initData);
this.setLastDataProviderInitTime(lastDataProviderInitTime);
}
this.initAndStartIntervals(shouldCheckForUpdates, loggerFlushIntervalMs);
this.initAndStartIntervals(traceId, shouldCheckForUpdates);

@@ -122,3 +118,3 @@ if (isBrowser) {

}
await this.logger.flush(/* traceId */ uniqueId());
await this.close(/* traceId */ uniqueId());
});

@@ -395,7 +391,7 @@ }

private initAndStartIntervals(
shouldCheckForUpdates: boolean,
loggerFlushIntervalMs: number | null
initTraceId: string,
shouldCheckForUpdates: boolean
): void {
if (!this.initDataProvider || !shouldCheckForUpdates) {
this.log(/* traceId */ "", LogLevel.Info, "Not polling for updates.");
this.log(initTraceId, LogLevel.Info, "Not polling for updates.");
}

@@ -407,2 +403,13 @@ if (this.initDataProvider) {

if (this.shouldClose) {
// No need to get updates when the SDK is shutting down.
this.updateTimeout = null;
this.log(
traceId,
LogLevel.Debug,
"Stopped getting updates from the data provider."
);
return;
}
this.initIfNeeded(traceId, defaultRetries)

@@ -419,4 +426,5 @@ .catch((error) =>

if (this.shouldClose) {
this.updateTimeout = null;
this.log(
/* traceId */ "",
traceId,
LogLevel.Debug,

@@ -428,3 +436,6 @@ "Stopped getting updates from the data provider."

if (shouldCheckForUpdates) {
setTimeout(update, this.initDataRefreshIntervalMs);
this.updateTimeout = setTimeout(
update,
this.initDataRefreshIntervalMs
);
}

@@ -435,30 +446,2 @@ });

}
// eslint-disable-next-line @hypertune/prefer-early-returns
if (loggerFlushIntervalMs !== null) {
// eslint-disable-next-line func-style
const flushLogQueue = (): void => {
setTimeout(async () => {
if (this.shouldClose) {
this.log(
/* traceId */ "",
LogLevel.Debug,
"Stopped flushing log queue."
);
return;
}
await this.logger.flush(/* traceId */ uniqueId());
flushLogQueue();
}, loggerFlushIntervalMs);
};
flushLogQueue();
} else {
this.log(
/* traceId */ "",
LogLevel.Info,
"Not automatically flushing logs."
);
}
}

@@ -474,2 +457,16 @@

// @internal
async close(traceId: string): Promise<void> {
this.log(traceId, LogLevel.Info, "Closing...");
this.shouldClose = true;
if (this.updateTimeout) {
clearTimeout(this.updateTimeout);
this.updateTimeout = null;
}
await this.logger.close(traceId);
this.log(traceId, LogLevel.Info, "Closed.");
}
// @internal
getStateHash(): string {

@@ -527,3 +524,3 @@ const initDataHash = this.initData?.hash ?? null;

}
const { override } = this;
const { lastDataProviderInitTime, override } = this;

@@ -556,2 +553,3 @@ const dehydrateQuery = query ?? this.query;

initData,
lastDataProviderInitTime,
override: override as DeepPartial<TOverride> | null,

@@ -568,3 +566,4 @@ variableValues: dehydrateQueryVariableValues,

this.log(traceId, LogLevel.Info, "Hydrating...");
const { initData, override, variableValues } = dehydratedState;
const { initData, override, variableValues, lastDataProviderInitTime } =
dehydratedState;

@@ -575,10 +574,15 @@ if (initData && variableValues) {

this.initFromData(traceId, initData);
if (this.initDataProvider) {
// Set the last initialization time as hydration should only be used with
// the latest available data.
this.lastDataProviderInitTime = Date.now();
}
this.setLastDataProviderInitTime(lastDataProviderInitTime);
this.setOverride<TOverride>(traceId, override);
}
private setLastDataProviderInitTime(newTime: number | null): void {
if (!this.initDataProvider || !newTime) {
return;
}
// Don't set the time to a future value.
const now = Date.now();
this.lastDataProviderInitTime = newTime > now ? now : newTime;
}
// @internal

@@ -585,0 +589,0 @@ reduce(

@@ -5,2 +5,3 @@ import {

prodEdgeCdnBaseUrl,
uniqueId,
} from "../shared";

@@ -41,2 +42,3 @@ import {

}): T {
const traceId = uniqueId();
let logger: Logger;

@@ -48,4 +50,12 @@ const remoteLoggingMode =

logger = new Logger({
traceId,
token,
remoteLoggingMode,
remoteFlushIntervalMs:
options.remoteLogging?.flushIntervalMs !== undefined
? options.remoteLogging.flushIntervalMs === null ||
options.remoteLogging.flushIntervalMs === 0 // TODO: Deprecate
? null
: clampInterval(options.remoteLogging.flushIntervalMs)
: defaultIntervalMs,
remoteLoggingEndpointUrl:

@@ -78,2 +88,3 @@ options.remoteLogging?.endpointUrl ?? prodLogsEndpointUrl,

const context = new Context({
traceId,
query,

@@ -83,2 +94,3 @@ queryCode,

initData: options.initData ?? null,
lastDataProviderInitTime: options.lastDataProviderInitTime ?? null,
initDataProvider:

@@ -107,13 +119,2 @@ options.initDataProvider !== undefined

logger,
loggerFlushIntervalMs:
// Use the provided option else use the default interval but disable
// flushing by default if remote logging mode is set to off.
remoteLoggingMode === "off"
? null
: options.remoteLogging?.flushIntervalMs !== undefined
? options.remoteLogging.flushIntervalMs === null ||
options.remoteLogging.flushIntervalMs === 0 // TODO: Deprecate
? null
: clampInterval(options.remoteLogging.flushIntervalMs)
: defaultIntervalMs,
cacheSize: options.cacheSize ?? defaultCacheSize,

@@ -120,0 +121,0 @@ override: override ?? null,

@@ -12,4 +12,4 @@ import {

} from "../shared";
import { RemoteLogger, RemoteLoggingMode } from "../shared/types";
import BackendRemoteLogger from "../shared/helpers/BackendRemoteLogger";
import { RemoteLoggingMode } from "../shared/types";
import RemoteLogger from "../shared/helpers/RemoteLogger";
import toConsoleFunction from "../shared/helpers/toConsoleFunction";

@@ -20,21 +20,29 @@ import LRUCache from "../shared/helpers/LRUCache";

import newTracedFetch from "../shared/helpers/newTracedFetch";
import NoopRemoteLogger from "../shared/helpers/NoopRemoteLogger";
const fetchMaxKeepAliveRequestSizeBytes = 64_000;
/**
* Logger provides a high level API for Node and generic SDK logs. It emits
* these logs using the local logger and it also forwards them to the
* `RemoteLogger` based on the selected `RemoteLoggingMode`.
*/
export default class Logger {
public readonly id: string;
private readonly remoteLoggingMode: "normal" | "session";
private readonly remoteLoggingMode: RemoteLoggingMode;
private readonly remoteLogCache: LRUCache<boolean> = new LRUCache(10_000);
private readonly remoteLogger: RemoteLogger;
private readonly remoteLogger: RemoteLogger | null;
private readonly localLogger: LocalLogger;
constructor({
traceId,
token,
remoteLoggingMode,
remoteFlushIntervalMs,
remoteLoggingEndpointUrl,
localLogger,
}: {
traceId: string;
token: string;
remoteLoggingMode: RemoteLoggingMode;
remoteFlushIntervalMs: number | null;
remoteLoggingEndpointUrl: string;

@@ -44,4 +52,3 @@ localLogger?: LocalLogger;

this.id = uniqueId();
this.remoteLoggingMode =
remoteLoggingMode === "off" ? "normal" : remoteLoggingMode;
this.remoteLoggingMode = remoteLoggingMode;

@@ -52,4 +59,5 @@ this.localLogger = wrapLocalLogger(this.id, localLogger);

remoteLoggingMode === "off"
? NoopRemoteLogger()
: new BackendRemoteLogger({
? null
: new RemoteLogger({
traceId,
token,

@@ -64,2 +72,3 @@ createLogs: getCreateLogsFunction(

localLogger: this.localLogger,
flushIntervalMs: remoteFlushIntervalMs,
});

@@ -102,5 +111,5 @@ }

(level === LogLevel.Warn || level === LogLevel.Error) &&
this.shouldRemoteLog(initDataHash, nodePath, message)
this.shouldRemoteNodeLog(initDataHash, nodePath, message)
) {
this.remoteLogger.log(
this.remoteLogger?.log(
LogType.SdkNode,

@@ -118,4 +127,4 @@ level,

this.localLogger(LogLevel.Error, errorMessage, logMetadata);
if (this.shouldRemoteLog(initDataHash, nodePath, message)) {
this.remoteLogger.log(
if (this.shouldRemoteNodeLog(initDataHash, nodePath, message)) {
this.remoteLogger?.log(
LogType.SdkNode,

@@ -130,11 +139,11 @@ level,

}
if (this.shouldRemoteLog(initDataHash, nodePath, "evaluations")) {
this.remoteLogger.evaluations(commitId, reductionLogs.evaluations);
if (this.shouldRemoteNodeLog(initDataHash, nodePath, "evaluations")) {
this.remoteLogger?.evaluations(commitId, reductionLogs.evaluations);
}
// We always log events to the backend
this.remoteLogger.events(commitId, reductionLogs.events);
this.remoteLogger?.events(commitId, reductionLogs.events);
if (this.shouldRemoteLog(initDataHash, nodePath, "exposures")) {
this.remoteLogger.exposures(commitId, reductionLogs.exposures);
if (this.shouldRemoteNodeLog(initDataHash, nodePath, "exposures")) {
this.remoteLogger?.exposures(commitId, reductionLogs.exposures);
}

@@ -144,3 +153,3 @@ }

private shouldRemoteLog(
private shouldRemoteNodeLog(
initDataHash: string | null,

@@ -175,2 +184,6 @@ nodePath: string,

case "off": {
return false;
}
default: {

@@ -190,4 +203,7 @@ const neverLoggingMode: never = this.remoteLoggingMode;

this.localLogger(level, message, metadata);
if (level === LogLevel.Warn || level === LogLevel.Error) {
this.remoteLogger.log(LogType.SdkMessage, level, commitId, message, {
if (
this.remoteLoggingMode !== "off" &&
(level === LogLevel.Warn || level === LogLevel.Error)
) {
this.remoteLogger?.log(LogType.SdkMessage, level, commitId, message, {
...metadata,

@@ -200,4 +216,12 @@ sdkVersion,

public flush(traceId: string): Promise<void> {
return this.remoteLogger.flush(traceId);
return this.remoteLogger
? this.remoteLogger.flush(traceId)
: Promise.resolve();
}
public close(traceId: string): Promise<void> {
return this.remoteLogger
? this.remoteLogger.close(traceId)
: Promise.resolve();
}
}

@@ -204,0 +228,0 @@

@@ -74,2 +74,8 @@ import { expect, test } from "vitest";

});
expect(
merge<{ a: number; b: string; c?: string }>(
{ a: 1, b: "str" },
{ c: "val" }
)
).toEqual({ a: 1, b: "str", c: "val" });
});

@@ -60,7 +60,14 @@ import { DeepPartial, ObjectValue, Value } from "../shared/types";

return Object.fromEntries(
Object.entries(value).map(([fieldName, field]) => [
fieldName,
mergeSource(field, (override as T)[fieldName]),
])
Object.entries(value)
.map(([fieldName, field]) => [
fieldName,
mergeSource(field, (override as T)[fieldName]),
])
.concat(
// Add any additional fields from the override to the object.
Object.entries(override as ObjectValue).filter(
([fieldName]) => !(fieldName in value)
)
)
) as T;
}

@@ -594,10 +594,14 @@ /* eslint-disable no-underscore-dangle */

close(): void {
/**
* Close flushes any remaining logs and stops all background processes
* ensuring clean shutdown.
*/
close(traceId = uniqueId()): Promise<void> {
const { context } = this.props;
if (!context) {
this.log(LogLevel.Error, "No context so cannot close.");
return;
return Promise.resolve();
}
context.shouldClose = true;
return context.close(traceId);
}
}
export { default as asError } from "./asError";
export { default as BackendRemoteLogger } from "./BackendRemoteLogger";
export { default as RemoteLogger } from "./RemoteLogger";
export { default as emptyThrows } from "./emptyThrows";

@@ -4,0 +4,0 @@ export {

@@ -760,16 +760,2 @@ /* eslint-disable capitalized-comments */

export type RemoteLogger = {
log(
type: LogType,
level: LogLevel,
commitId: string | null,
message: string,
metadata: object
): void;
evaluations(commitId: string, evaluations: CountMap): void;
events(commitId: string, events: CountMap): void;
exposures(commitId: string, exposures: CountMap): void;
flush(traceId: string): Promise<void>;
};
export type TracedFetch = (

@@ -833,3 +819,10 @@ traceId: string,

initDataProvider?: InitDataProvider | null;
/**
* `lastDataProviderInitTime` is a timestamp specifying the last time
* the provided `initData` was last checked for freshness using an
* `InitDataProvider`. It is ignored when no `initData` was provided.
*/
lastDataProviderInitTime?: number | null;
/**
* `initDataRefreshIntervalMs` specifies the interval, in milliseconds, at

@@ -931,2 +924,3 @@ * which the SDK checks for updates. The minimum allowed value is 1000ms.

initData: InitData;
lastDataProviderInitTime: number | null;
override: DeepPartial<TOverride> | null;

@@ -933,0 +927,0 @@ variableValues: TVariableValues;

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

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

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