hypertune
Version:
[Hypertune](https://www.hypertune.com/) is the most flexible platform for feature flags, A/B testing, analytics and app configuration. Built with full end-to-end type-safety, Git-style version control and local, synchronous, in-memory flag evaluation. Opt
177 lines • 8.51 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = create;
const shared_1 = require("../shared");
const types_1 = require("../shared/types");
const Context_1 = __importDefault(require("./Context"));
const Node_1 = __importDefault(require("./Node"));
const Logger_1 = __importDefault(require("./Logger"));
const environment_1 = require("./environment");
const getMetadata_1 = __importDefault(require("../shared/helpers/getMetadata"));
const HypertuneEdgeInitDataProvider_1 = __importDefault(require("./initDataProviders/HypertuneEdgeInitDataProvider"));
const VercelEdgeConfigInitDataProvider_1 = __importDefault(require("./initDataProviders/VercelEdgeConfigInitDataProvider"));
const defaultLocalLogger_1 = __importDefault(require("../shared/helpers/defaultLocalLogger"));
const minIntervalMs = 1000;
const defaultIntervalMs = 2000;
/**
* TODO
* - Remove `queryCode`; consolidate with `query`; benefit of having them
* separate was `queryCode` can be codegen'd differently, but this is not
* necessary
* - Add default values to arguments where possible
* - Move all arguments into `CreateOptions` with type parameters if they have
* generated types, then codegen concrete `CreateSourceOptions`
*/
function create({ NodeConstructor = Node_1.default, token, query = null, queryId, queryCode, variableValues = {}, override = null, options = {}, }) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
const traceId = (0, shared_1.uniqueId)();
const loggerId = (0, shared_1.uniqueId)();
const logsHandler = wrapLogsHandler(loggerId, options.logsHandler, options.localLogger);
const localLogger = wrapLocalLogger(loggerId, options.logsHandler, options.localLogger);
let logger;
const remoteLoggingMode = (_b = (_a = options.remoteLogging) === null || _a === void 0 ? void 0 : _a.mode) !== null && _b !== void 0 ? _b : (environment_1.isBrowser ? "session" : "normal");
try {
logger = new Logger_1.default({
id: loggerId,
traceId,
token,
remoteLoggingMode,
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,
logsHandler,
localLogger,
});
}
catch (error) {
localLogger(types_1.LogLevel.Error, "Pre-initialize error.", (0, getMetadata_1.default)(error));
return new NodeConstructor({
context: null,
logger: null,
parent: null,
step: null,
expression: null,
initDataHash: null,
});
}
const usesVercelEdgeConfig = options.initDataProvider &&
options.initDataProvider instanceof VercelEdgeConfigInitDataProvider_1.default;
logger.log(types_1.LogLevel.Debug, null, "Detected environment.", {
isBrowser: environment_1.isBrowser,
usesVercelEdgeConfig,
});
try {
const context = new Context_1.default({
traceId,
query,
initQuery: queryId
? { type: "StoredQuery", id: queryId }
: queryCode
? { type: "GraphqlQuery", code: queryCode }
: { type: "Query", query },
variableValues,
initData: (_f = options.initData) !== null && _f !== void 0 ? _f : null,
lastInitDataRefreshTime: (_h = (_g = options.lastInitDataRefreshTime) !== null && _g !== void 0 ? _g : options.lastDataProviderInitTime) !== null && _h !== void 0 ? _h : null,
initDataProvider: options.initDataProvider !== undefined
? options.initDataProvider
: new HypertuneEdgeInitDataProvider_1.default({
token,
baseUrl: shared_1.prodEdgeCdnBaseUrl,
branchName: options.branchName,
localLogger,
}),
initDataRefreshIntervalMs:
// Prioritize the new option else use the old option if it's not set to
// 0 else use the default interval. In all cases, force the value to be
// at least the minimum interval.
clampInterval((_j = options.initDataRefreshIntervalMs) !== null && _j !== void 0 ? _j : (options.initIntervalMs || defaultIntervalMs)),
shouldRefreshInitData:
// Prioritize the new option else if the old option is set to 0,
// disable, else enable except when using Vercel Edge Config.
(_l = (_k = options.shouldRefreshInitData) !== null && _k !== void 0 ? _k : options.shouldCheckForUpdates) !== null && _l !== void 0 ? _l : (options.initIntervalMs === 0 ? false : !usesVercelEdgeConfig),
shouldRefreshInitDataOnCreate: (_m = options.shouldRefreshInitDataOnCreate) !== null && _m !== void 0 ? _m : !usesVercelEdgeConfig,
shouldSkipInitDataUpdateOnRefresh: (_o = options.shouldSkipInitDataUpdateOnRefresh) !== null && _o !== void 0 ? _o : false,
logger,
cacheSize: (_p = options.cacheSize) !== null && _p !== void 0 ? _p : shared_1.defaultCacheSize,
override: override !== null && override !== void 0 ? override : null,
});
return new NodeConstructor({
context,
logger,
parent: null,
step: null,
expression: (_r = (_q = context.initData) === null || _q === void 0 ? void 0 : _q.reducedExpression) !== null && _r !== void 0 ? _r : null,
initDataHash: (_t = (_s = context.initData) === null || _s === void 0 ? void 0 : _s.hash) !== null && _t !== void 0 ? _t : null,
});
}
catch (error) {
logger.log(types_1.LogLevel.Error,
/* commitId */ null, "Initialize error.", (0, getMetadata_1.default)(error));
return new NodeConstructor({
context: null,
logger,
parent: null,
step: null,
expression: null,
initDataHash: null,
});
}
}
function clampInterval(intervalMs) {
return Math.max(intervalMs, minIntervalMs);
}
function wrapLogsHandler(loggerId, logsHandler, localLogger) {
if (!localLogger && !logsHandler) {
return (reductionLogs) => {
reductionLogs.messageList.forEach(({ level, message, metadata }) => (0, defaultLocalLogger_1.default)(level, message, metadata));
};
}
return (reductionLogs) => {
const messages = !logsHandler && !localLogger
? reductionLogs.messageList
: reductionLogs.messageList.map(({ level, message, metadata }) => ({
level,
message,
metadata: Object.assign({ sdkVersion: shared_1.sdkVersion,
loggerId }, metadata),
}));
if (logsHandler) {
logsHandler(Object.assign(Object.assign({}, reductionLogs), { messageList: messages }));
return;
}
if (localLogger) {
messages.forEach(({ level, message, metadata }) => {
localLogger(level, message, metadata);
});
}
};
}
function wrapLocalLogger(loggerId, logsHandler, localLogger) {
if (!localLogger && !logsHandler) {
return defaultLocalLogger_1.default;
}
return (level, message, baseMetadata) => {
const metadata = Object.assign({ sdkVersion: shared_1.sdkVersion,
loggerId }, baseMetadata);
if (logsHandler) {
logsHandler({
messageList: [{ level, message, metadata }],
eventList: [],
exposureList: [],
evaluationList: [],
});
return;
}
if (localLogger) {
localLogger(level, message, metadata);
}
};
}
//# sourceMappingURL=create.js.map