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

hypertune

Package Overview
Dependencies
Maintainers
3
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 1.7.23 to 1.8.0

dist/shared/helpers/LRUCache.d.ts

4

CHANGELOG.md
# Changelog
## 1.8.0
- Performance improvements.
## 1.7.23

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

36

dist/generated/graphql.d.ts

@@ -22,5 +22,2 @@ export type Maybe<T> = T | null;

};
export type AcceptInviteInput = {
inviteToken: Scalars['String'];
};
export type AddVercelAuthInput = {

@@ -46,2 +43,3 @@ businessId: Scalars['ID'];

id: Scalars['ID'];
inviteToken?: Maybe<Scalars['String']>;
invites: Array<Invite>;

@@ -52,3 +50,2 @@ memberCount: Scalars['Int'];

projects: Array<Project>;
publicToken: Scalars['String'];
type: BusinessType;

@@ -85,4 +82,7 @@ users: Array<User>;

export type CreateBusinessInput = {
inviteEmails: Array<Scalars['String']>;
inviteToken?: InputMaybe<Scalars['String']>;
name: Scalars['String'];
skipSwitch: Scalars['Boolean'];
transferProjectIds: Array<Scalars['ID']>;
};

@@ -273,3 +273,2 @@ export type CreateCommitInput = {

__typename?: 'Mutation';
acceptInvite: Scalars['ID'];
addVercelAuth: Scalars['ID'];

@@ -289,2 +288,3 @@ cloneProject: Scalars['ID'];

revokeInvite: Scalars['ID'];
sendVerifyAndInviteEmail: Scalars['ID'];
updateAnalyticsView: Scalars['ID'];

@@ -295,6 +295,4 @@ updateBusiness: Scalars['ID'];

updateWebhook: Scalars['ID'];
verifyEmailAndAcceptInvite: VerifyEmailAndAcceptInviteResponse;
};
export type MutationAcceptInviteArgs = {
input: AcceptInviteInput;
};
export type MutationAddVercelAuthArgs = {

@@ -339,2 +337,5 @@ input: AddVercelAuthInput;

};
export type MutationSendVerifyAndInviteEmailArgs = {
input: SendVerifyAndInviteEmailInput;
};
export type MutationUpdateAnalyticsViewArgs = {

@@ -355,2 +356,5 @@ input: UpdateAnalyticsViewInput;

};
export type MutationVerifyEmailAndAcceptInviteArgs = {
input: VerifyEmailAndAcceptInviteInput;
};
export type MutationResponseMessage = {

@@ -376,2 +380,3 @@ __typename?: 'MutationResponseMessage';

name: Scalars['String'];
setupCompleted: Scalars['Boolean'];
showOnboarding: Scalars['Boolean'];

@@ -422,2 +427,5 @@ token: Scalars['String'];

};
export type SendVerifyAndInviteEmailInput = {
verifyEmailAndInviteToken?: InputMaybe<Scalars['String']>;
};
export type UpdateAnalyticsViewInput = {

@@ -431,2 +439,3 @@ funnelStepsJson?: InputMaybe<Scalars['String']>;

id: Scalars['ID'];
inviteToken?: InputMaybe<Scalars['String']>;
name?: InputMaybe<Scalars['String']>;

@@ -457,2 +466,3 @@ vercelEdgeConfigConnectionsJson?: InputMaybe<Scalars['String']>;

email: Scalars['String'];
emailVerified: Scalars['Boolean'];
id: Scalars['ID'];

@@ -462,2 +472,12 @@ imageUrl: Scalars['String'];

};
export type VerifyEmailAndAcceptInviteInput = {
businessInviteToken?: InputMaybe<Scalars['String']>;
inviteToken?: InputMaybe<Scalars['String']>;
verifyEmailAndInviteToken?: InputMaybe<Scalars['String']>;
};
export type VerifyEmailAndAcceptInviteResponse = {
__typename?: 'VerifyEmailAndAcceptInviteResponse';
joinedBusinessesCount: Scalars['Int'];
verifiedEmail: Scalars['Boolean'];
};
export type Webhook = {

@@ -464,0 +484,0 @@ __typename?: 'Webhook';

import { InitResponseBody, Expression, Query, Value, ObjectValueWithVariables, InitSource, VercelEdgeConfigClient, Endpoints, UpdateListener, Fetch } from "../shared";
import Logger from "./Logger";
import LRUCache from "../shared/helpers/LRUCache";
/** @internal: Not part of the Hypertune public API */

@@ -23,6 +24,9 @@ export default class Context {

lastServerInitTime: number | null;
readonly getFieldCache: LRUCache<Expression> | null;
readonly getItemsCache: LRUCache<Expression[]> | null;
readonly evaluateCache: LRUCache<Value> | null;
readonly updateListeners: Map<UpdateListener, boolean>;
constructor(token: string, queryCode: string, variableValues: {
[variableName: string]: Value;
}, schemaVersion: string | null, shouldInitializeFromServer: boolean, shouldStartIntervals: boolean, shouldGetUpdatesFromServer: boolean, logger: Logger, fetchFunction: Fetch, vercelEdgeConfigClient: VercelEdgeConfigClient | null, vercelEdgeConfigItemKey: string | null, endpoints: Endpoints, query: Query<ObjectValueWithVariables>, fallbackInitData: InitResponseBody | null);
}, schemaVersion: string | null, shouldInitializeFromServer: boolean, shouldStartIntervals: boolean, shouldGetUpdatesFromServer: boolean, logger: Logger, fetchFunction: Fetch, vercelEdgeConfigClient: VercelEdgeConfigClient | null, vercelEdgeConfigItemKey: string | null, cacheSize: number, endpoints: Endpoints, query: Query<ObjectValueWithVariables>, fallbackInitData: InitResponseBody | null);
initFromData(initData: InitResponseBody | null): void;

@@ -29,0 +33,0 @@ private init;

@@ -21,6 +21,7 @@ "use strict";

const environment_1 = require("./environment");
const LRUCache_1 = __importDefault(require("../shared/helpers/LRUCache"));
/** @internal: Not part of the Hypertune public API */
class Context {
// eslint-disable-next-line max-params
constructor(token, queryCode, variableValues, schemaVersion, shouldInitializeFromServer, shouldStartIntervals, shouldGetUpdatesFromServer, logger, fetchFunction, vercelEdgeConfigClient, vercelEdgeConfigItemKey, endpoints, query, fallbackInitData) {
constructor(token, queryCode, variableValues, schemaVersion, shouldInitializeFromServer, shouldStartIntervals, shouldGetUpdatesFromServer, logger, fetchFunction, vercelEdgeConfigClient, vercelEdgeConfigItemKey, cacheSize, endpoints, query, fallbackInitData) {
this.shouldClose = false;

@@ -42,3 +43,11 @@ this.token = token;

this.lastServerInitTime = null;
this.getFieldCache = null;
this.getItemsCache = null;
this.evaluateCache = null;
this.updateListeners = new Map();
if (cacheSize > 0) {
this.getFieldCache = new LRUCache_1.default(cacheSize);
this.getItemsCache = new LRUCache_1.default(cacheSize);
this.evaluateCache = new LRUCache_1.default(cacheSize);
}
if (fallbackInitData) {

@@ -79,3 +88,3 @@ this.initFromData(fallbackInitData);

init(initSource, newInitData) {
var _a, _b;
var _a, _b, _c, _d, _e;
const initSourceName = (0, getInitSourceName_1.default)(initSource);

@@ -99,2 +108,5 @@ try {

this.logger.info(`Initialized successfully from ${initSourceName}.`);
(_c = this.getFieldCache) === null || _c === void 0 ? void 0 : _c.purge();
(_d = this.getItemsCache) === null || _d === void 0 ? void 0 : _d.purge();
(_e = this.evaluateCache) === null || _e === void 0 ? void 0 : _e.purge();
this.updateListeners.forEach((_, listener) => {

@@ -101,0 +113,0 @@ listener(newInitData.commitHash);

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

function initialize(NodeConstructor, 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;
let token;

@@ -61,3 +61,3 @@ let endpoints;

// native apps
((0, environment_1.isNextJsServer)() || environment_1.isBackendServer || environment_1.isReactNative), logger, fetchFunction, (_g = options.vercelEdgeConfigClient) !== null && _g !== void 0 ? _g : null, (_h = options.vercelEdgeConfigItemKey) !== null && _h !== void 0 ? _h : null, endpoints, options.query, (_j = options.fallbackInitData) !== null && _j !== void 0 ? _j : null);
((0, environment_1.isNextJsServer)() || environment_1.isBackendServer || environment_1.isReactNative), logger, fetchFunction, (_g = options.vercelEdgeConfigClient) !== null && _g !== void 0 ? _g : null, (_h = options.vercelEdgeConfigItemKey) !== null && _h !== void 0 ? _h : null, (_j = options.cacheSize) !== null && _j !== void 0 ? _j : shared_1.defaultCacheSize, endpoints, options.query, (_k = options.fallbackInitData) !== null && _k !== void 0 ? _k : null);
return new NodeConstructor({

@@ -68,3 +68,3 @@ context,

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,
});

@@ -71,0 +71,0 @@ }

@@ -18,6 +18,9 @@ import { Expression, ObjectValue, Query, Step, Value, InitResponseBody, UpdateListener } from "../shared";

protected getField(fieldName: string, fieldArguments: ObjectValue): Props;
private getFieldFallback;
private getReducedFieldExpression;
_getItems(fallbackLength: number): Props[];
private _getItemsFallback;
private _getItemExpressions;
protected evaluate(query: Query<ObjectValue> | null, fallback: Value): Value;
private getValue;
private createProps;
private createPropsArray;
_logUnexpectedTypeError(): void;

@@ -29,3 +32,2 @@ protected logUnexpectedValueError(value: Value): void;

private nodeError;
private getPath;
getCommitHash(): string | null;

@@ -32,0 +34,0 @@ addUpdateListener(listener: UpdateListener): void;

@@ -61,2 +61,25 @@ "use strict";

getField(fieldName, fieldArguments) {
var _a;
const step = { type: "GetFieldStep", fieldName, fieldArguments };
const { context } = this.props;
const commitHash = (_a = context === null || context === void 0 ? void 0 : context.initData) === null || _a === void 0 ? void 0 : _a.commitHash;
if (!commitHash || !context.getFieldCache) {
// No caching if the sdk hasn't been initialized or there is no cache.
return this.createProps(step, this.getReducedFieldExpression(fieldName, fieldArguments));
}
const cacheKey = getCacheKey(commitHash,
/* parent */ this, step,
/* suffix */ "");
const cachedReducedFieldExpression = context.getFieldCache.get(cacheKey);
if (cachedReducedFieldExpression) {
return this.createProps(step, cachedReducedFieldExpression);
}
const reducedFieldExpression = this.getReducedFieldExpression(fieldName, fieldArguments);
if (reducedFieldExpression) {
context.getFieldCache.set(cacheKey, reducedFieldExpression);
}
return this.createProps(step, reducedFieldExpression);
}
// @internal
getReducedFieldExpression(fieldName, fieldArguments) {
try {

@@ -71,6 +94,6 @@ // As fieldArguments are passed in by users, perform extra validation to

this.updateIfNeeded();
const { logger, expression } = this.props;
const { expression } = this.props;
if (!expression) {
this.debug(`Using fallback for field "${fieldName}" as expression is null. This is expected while initializing.`);
return this.getFieldFallback(fieldName, fieldArguments);
return null;
}

@@ -93,32 +116,37 @@ if (expression.type !== "ObjectExpression") {

reducedFieldExpression.logs = (0, shared_1.mergeLogs)(reducedObjectExpression.logs, (0, shared_1.getEvaluationLogs)(reducedObjectExpression), reducedFieldExpression.logs);
return {
context,
parent: this,
step: { type: "GetFieldStep", fieldName, fieldArguments },
expression: reducedFieldExpression,
logger,
};
return reducedFieldExpression;
}
catch (error) {
this.nodeError({ type: "GetField", fieldName, fieldArguments }, error);
return this.getFieldFallback(fieldName, fieldArguments);
return null;
}
}
getFieldFallback(fieldName, fieldArguments) {
const { logger, context } = this.props;
return {
context,
parent: this,
step: { type: "GetFieldStep", fieldName, fieldArguments },
expression: null,
logger,
};
_getItems(fallbackLength) {
var _a;
const { context } = this.props;
const commitHash = (_a = context === null || context === void 0 ? void 0 : context.initData) === null || _a === void 0 ? void 0 : _a.commitHash;
if (!commitHash || !context.getItemsCache) {
// No caching if the sdk hasn't been initialized or there is no cache.
return this.createPropsArray(this._getItemExpressions(), fallbackLength);
}
const cacheKey = getCacheKey(commitHash, this.props.parent, this.props.step,
/* suffix */ "");
const cachedItemExpressions = context.getItemsCache.get(cacheKey);
if (cachedItemExpressions) {
return this.createPropsArray(cachedItemExpressions, fallbackLength);
}
const itemExpressions = this._getItemExpressions();
if (itemExpressions) {
context.getItemsCache.set(cacheKey, itemExpressions);
}
return this.createPropsArray(itemExpressions, fallbackLength);
}
_getItems(fallbackLength) {
// @internal
_getItemExpressions() {
try {
this.updateIfNeeded();
const { context, logger, expression } = this.props;
const { expression } = this.props;
if (!expression) {
this.debug("Using fallback for array items as expression is null. This is expected while initializing.");
return this._getItemsFallback(fallbackLength);
return null;
}

@@ -132,9 +160,3 @@ if (expression.type !== "ListExpression") {

itemExpression.logs = (0, shared_1.mergeLogs)(listLogs, itemExpression.logs);
return {
context,
parent: this,
step: { type: "GetItemStep", index, fallbackLength },
expression: itemExpression,
logger,
};
return itemExpression;
});

@@ -145,18 +167,27 @@ return result;

this.nodeError({ type: "GetItems" }, error);
return this._getItemsFallback(fallbackLength);
return null;
}
}
_getItemsFallback(fallbackLength) {
const { context, logger } = this.props;
return Array(fallbackLength)
.fill(0)
.map((_, index) => ({
context,
parent: this,
step: { type: "GetItemStep", index, fallbackLength },
expression: null,
logger,
}));
evaluate(query, fallback) {
var _a, _b;
const { context } = this.props;
const commitHash = (_a = context === null || context === void 0 ? void 0 : context.initData) === null || _a === void 0 ? void 0 : _a.commitHash;
if (!commitHash || !context.evaluateCache) {
// No caching if the sdk hasn't been initialized or there is no cache.
return (_b = this.getValue(query)) !== null && _b !== void 0 ? _b : fallback;
}
const cacheKey = getCacheKey(commitHash, this.props.parent, this.props.step,
/* suffix */ JSON.stringify(query));
const cachedValue = context.evaluateCache.get(cacheKey);
if (cachedValue !== null && cachedValue !== undefined) {
return cachedValue;
}
const value = this.getValue(query);
if (value !== null && value !== undefined) {
context.evaluateCache.set(cacheKey, value);
}
return value !== null && value !== void 0 ? value : fallback;
}
evaluate(query, fallback) {
// @internal
getValue(query) {
try {

@@ -167,3 +198,3 @@ this.updateIfNeeded();

this.debug(`Using fallback while evaluating as expression is null. This is expected while initializing.`);
return fallback;
return null;
}

@@ -174,3 +205,4 @@ const context = (0, shared_1.nullThrows)(this.props.context, "Cannot evaluate as context is null.");

const { value, logs } = (0, shared_1.prefixError)(() => (0, shared_1.evaluate)(reducedExpression), "Evaluation error: ");
context.logger.nodeEvaluation(this.getPath(), { type: "Evaluate", query }, commitHash, this.typeName, logs, expression, value);
const { parent, step } = this.props;
context.logger.nodeEvaluation(getPath(parent, step), { type: "Evaluate", query }, commitHash, this.typeName, logs, expression, value);
return value;

@@ -180,5 +212,14 @@ }

this.nodeError({ type: "Evaluate", query }, error);
return fallback;
return null;
}
}
// @internal
createProps(step, expression) {
const { context, logger } = this.props;
return { step, parent: this, context, expression, logger };
}
// @internal
createPropsArray(itemExpressions, fallbackLength) {
return (itemExpressions || Array(fallbackLength).fill(null)).map((expression, index) => this.createProps({ type: "GetItemStep", index, fallbackLength }, expression));
}
_logUnexpectedTypeError() {

@@ -227,19 +268,10 @@ if (!this.props.expression) {

var _a;
const { logger, expression } = this.props;
const { parent, step, logger, expression } = this.props;
if (!logger) {
// eslint-disable-next-line no-console
console.error(`Logger is null so cannot remote log error for ${this.typeName} node at ${this.getPath()}`, error);
console.error(`Logger is null so cannot remote log error for ${this.typeName} node at ${getPath(parent, step)}`, error);
return;
}
logger.nodeError(this.getPath(), nodeOp, this.commitHash, this.typeName, expression, error instanceof Error ? error.message : JSON.stringify(error), error instanceof Error ? (_a = error.stack) !== null && _a !== void 0 ? _a : null : null);
logger.nodeError(getPath(parent, step), nodeOp, this.commitHash, this.typeName, expression, error instanceof Error ? error.message : JSON.stringify(error), error instanceof Error ? (_a = error.stack) !== null && _a !== void 0 ? _a : null : null);
}
// @internal
getPath() {
const { parent, step } = this.props;
return `${parent ? `${parent.getPath()} > ` : ""}${!step
? "{}"
: step.type === "GetFieldStep"
? `${step.fieldName}(${JSON.stringify(step.fieldArguments)})`
: `[${step.index}]`}`;
}
getCommitHash() {

@@ -332,2 +364,13 @@ var _a, _b;

exports.default = Node;
function getCacheKey(commitHash, parent, step, suffix) {
return (0, shared_1.hash)(`${commitHash}/${getPath(parent, step)}/${suffix}
)}`).toString();
}
function getPath(parent, step) {
return `${parent ? `${getPath(parent.props.parent, parent.props.step)} > ` : ""}${!step
? "{}"
: step.type === "GetFieldStep"
? `${step.fieldName}(${JSON.stringify(step.fieldArguments)})`
: `[${step.index}]`}`;
}
//# sourceMappingURL=Node.js.map

@@ -19,3 +19,4 @@ export declare const localBackendBaseUrl = "http://localhost:3001";

export declare const defaultArmKey = "default";
export declare const defaultCacheSize = 250;
export declare const breakingSchemaChangesError = "If you've made breaking changes to your schema like adding a new field argument, you may need to re-run code generation and fix the type errors.";
//# sourceMappingURL=constants.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.breakingSchemaChangesError = exports.defaultArmKey = exports.numHashBuckets = exports.fieldPathSeparator = exports.isQueryVariableKey = exports.isPartialObjectKey = exports.graphqlTypeNameKey = exports.tokenEnvironmentVariableName = exports.configFileName = exports.backendGraphqlEndpoint = exports.prodLogsBaseUrl = exports.prodEdgeBaseUrl = exports.prodBackendBaseUrl = exports.stagingLogsBaseUrl = exports.stagingEdgeBaseUrl = exports.stagingBackendBaseUrl = exports.localLogsBaseUrl = exports.localEdgeBaseUrl = exports.localBackendBaseUrl = void 0;
exports.breakingSchemaChangesError = exports.defaultCacheSize = exports.defaultArmKey = exports.numHashBuckets = exports.fieldPathSeparator = exports.isQueryVariableKey = exports.isPartialObjectKey = exports.graphqlTypeNameKey = exports.tokenEnvironmentVariableName = exports.configFileName = exports.backendGraphqlEndpoint = exports.prodLogsBaseUrl = exports.prodEdgeBaseUrl = exports.prodBackendBaseUrl = exports.stagingLogsBaseUrl = exports.stagingEdgeBaseUrl = exports.stagingBackendBaseUrl = exports.localLogsBaseUrl = exports.localEdgeBaseUrl = exports.localBackendBaseUrl = void 0;
exports.localBackendBaseUrl = "http://localhost:3001";

@@ -22,3 +22,4 @@ exports.localEdgeBaseUrl = "http://[::1]:3002";

exports.defaultArmKey = "default";
exports.defaultCacheSize = 250;
exports.breakingSchemaChangesError = "If you've made breaking changes to your schema like adding a new field argument, you may need to re-run code generation and fix the type errors.";
//# sourceMappingURL=constants.js.map

@@ -920,14 +920,12 @@ "use strict";

}
function getField(object, fieldPath) {
if (object.type !== "ObjectExpression") {
return null;
function getField(startObject, fieldPath) {
const fieldPathParts = fieldPath.split(constants_1.fieldPathSeparator);
let field = startObject;
for (let i = 0; i < fieldPathParts.length; i += 1) {
if (!field || field.type !== "ObjectExpression") {
return null;
}
const fieldName = fieldPathParts[i];
field = field.fields[fieldName] || null;
}
const [fieldName, ...rest] = fieldPath.split(constants_1.fieldPathSeparator);
const field = object.fields[fieldName];
if (!field) {
return null;
}
if (rest.length > 0) {
return getField(field, rest.join(constants_1.fieldPathSeparator));
}
return field;

@@ -934,0 +932,0 @@ }

@@ -47,12 +47,12 @@ "use strict";

return {
evaluations: mergeCountMaps(a.evaluations, bs.map((b) => b.evaluations)),
events: mergeCountMaps(a.events, bs.map((b) => b.events)),
exposures: mergeCountMaps(a.exposures, bs.map((b) => b.exposures)),
evaluations: mergeCountMapsFromLogs("evaluations", a, bs),
events: mergeCountMapsFromLogs("events", a, bs),
exposures: mergeCountMapsFromLogs("exposures", a, bs),
};
}
exports.mergeLogs = mergeLogs;
function mergeCountMaps(a, bs) {
const result = Object.assign({}, a);
function mergeCountMapsFromLogs(countMapKey, a, bs) {
const result = Object.assign({}, a[countMapKey]);
bs.forEach((b) => {
Object.entries(b).forEach(([key, value]) => {
Object.entries(b[countMapKey]).forEach(([key, value]) => {
result[key] = (result[key] || 0) + value;

@@ -59,0 +59,0 @@ });

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

@@ -609,2 +609,3 @@ import { z } from "zod";

vercelEdgeConfigItemKey?: string;
cacheSize?: number;
/** Hypertune internal use only */

@@ -611,0 +612,0 @@ _endpoints?: EndpointsPreset | Endpoints;

{
"name": "hypertune",
"version": "1.7.23",
"version": "1.8.0",
"private": false,

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

@@ -8,3 +8,3 @@ /* eslint-disable no-underscore-dangle */

Options extends object = object,
OptionsInput extends object = object
OptionsInput extends object = object,
> = z.ZodObject<z.ZodRawShape, "strip", z.ZodTypeAny, Options, OptionsInput>;

@@ -56,3 +56,3 @@

OptionsInput extends object,
Result
Result,
>(

@@ -181,3 +181,3 @@ handler: Handler<Options, Result>,

OptionsInput extends object,
HandlerResult
HandlerResult,
>(

@@ -184,0 +184,0 @@ schema: Schema<Options, OptionsInput>,

@@ -15,6 +15,2 @@ export type Maybe<T> = T | null;

export type AcceptInviteInput = {
inviteToken: Scalars['String'];
};
export type AddVercelAuthInput = {

@@ -43,2 +39,3 @@ businessId: Scalars['ID'];

id: Scalars['ID'];
inviteToken?: Maybe<Scalars['String']>;
invites: Array<Invite>;

@@ -49,3 +46,2 @@ memberCount: Scalars['Int'];

projects: Array<Project>;
publicToken: Scalars['String'];
type: BusinessType;

@@ -87,4 +83,7 @@ users: Array<User>;

export type CreateBusinessInput = {
inviteEmails: Array<Scalars['String']>;
inviteToken?: InputMaybe<Scalars['String']>;
name: Scalars['String'];
skipSwitch: Scalars['Boolean'];
transferProjectIds: Array<Scalars['ID']>;
};

@@ -304,3 +303,2 @@

__typename?: 'Mutation';
acceptInvite: Scalars['ID'];
addVercelAuth: Scalars['ID'];

@@ -320,2 +318,3 @@ cloneProject: Scalars['ID'];

revokeInvite: Scalars['ID'];
sendVerifyAndInviteEmail: Scalars['ID'];
updateAnalyticsView: Scalars['ID'];

@@ -326,10 +325,6 @@ updateBusiness: Scalars['ID'];

updateWebhook: Scalars['ID'];
verifyEmailAndAcceptInvite: VerifyEmailAndAcceptInviteResponse;
};
export type MutationAcceptInviteArgs = {
input: AcceptInviteInput;
};
export type MutationAddVercelAuthArgs = {

@@ -400,2 +395,7 @@ input: AddVercelAuthInput;

export type MutationSendVerifyAndInviteEmailArgs = {
input: SendVerifyAndInviteEmailInput;
};
export type MutationUpdateAnalyticsViewArgs = {

@@ -425,2 +425,7 @@ input: UpdateAnalyticsViewInput;

export type MutationVerifyEmailAndAcceptInviteArgs = {
input: VerifyEmailAndAcceptInviteInput;
};
export type MutationResponseMessage = {

@@ -448,2 +453,3 @@ __typename?: 'MutationResponseMessage';

name: Scalars['String'];
setupCompleted: Scalars['Boolean'];
showOnboarding: Scalars['Boolean'];

@@ -510,2 +516,6 @@ token: Scalars['String'];

export type SendVerifyAndInviteEmailInput = {
verifyEmailAndInviteToken?: InputMaybe<Scalars['String']>;
};
export type UpdateAnalyticsViewInput = {

@@ -520,2 +530,3 @@ funnelStepsJson?: InputMaybe<Scalars['String']>;

id: Scalars['ID'];
inviteToken?: InputMaybe<Scalars['String']>;
name?: InputMaybe<Scalars['String']>;

@@ -550,2 +561,3 @@ vercelEdgeConfigConnectionsJson?: InputMaybe<Scalars['String']>;

email: Scalars['String'];
emailVerified: Scalars['Boolean'];
id: Scalars['ID'];

@@ -556,2 +568,14 @@ imageUrl: Scalars['String'];

export type VerifyEmailAndAcceptInviteInput = {
businessInviteToken?: InputMaybe<Scalars['String']>;
inviteToken?: InputMaybe<Scalars['String']>;
verifyEmailAndInviteToken?: InputMaybe<Scalars['String']>;
};
export type VerifyEmailAndAcceptInviteResponse = {
__typename?: 'VerifyEmailAndAcceptInviteResponse';
joinedBusinessesCount: Scalars['Int'];
verifiedEmail: Scalars['Boolean'];
};
export type Webhook = {

@@ -558,0 +582,0 @@ __typename?: 'Webhook';

@@ -23,2 +23,3 @@ import pRetry from "p-retry";

import { isBrowser } from "./environment";
import LRUCache from "../shared/helpers/LRUCache";

@@ -43,2 +44,5 @@ /** @internal: Not part of the Hypertune public API */

public lastServerInitTime: number | null;
public readonly getFieldCache: LRUCache<Expression> | null;
public readonly getItemsCache: LRUCache<Expression[]> | null;
public readonly evaluateCache: LRUCache<Value> | null;
public readonly updateListeners: Map<UpdateListener, boolean>;

@@ -59,2 +63,3 @@

vercelEdgeConfigItemKey: string | null,
cacheSize: number,
endpoints: Endpoints,

@@ -80,4 +85,13 @@ query: Query<ObjectValueWithVariables>,

this.lastServerInitTime = null;
this.getFieldCache = null;
this.getItemsCache = null;
this.evaluateCache = null;
this.updateListeners = new Map();
if (cacheSize > 0) {
this.getFieldCache = new LRUCache(cacheSize);
this.getItemsCache = new LRUCache(cacheSize);
this.evaluateCache = new LRUCache(cacheSize);
}
if (fallbackInitData) {

@@ -162,2 +176,5 @@ this.initFromData(fallbackInitData);

this.getFieldCache?.purge();
this.getItemsCache?.purge();
this.evaluateCache?.purge();
this.updateListeners.forEach((_, listener) => {

@@ -387,12 +404,15 @@ listener(newInitData.commitHash);

const flushLogQueue = (): void => {
setTimeout(async () => {
if (this.shouldClose) {
this.logger.debug("Stopped flushing log queue.");
return;
}
setTimeout(
async () => {
if (this.shouldClose) {
this.logger.debug("Stopped flushing log queue.");
return;
}
await this.logger.flush();
await this.logger.flush();
flushLogQueue();
}, this.initData?.sdkConfig.flushLogsInterval ?? 1000);
flushLogQueue();
},
this.initData?.sdkConfig.flushLogsInterval ?? 1000
);
};

@@ -422,2 +442,3 @@ flushLogQueue();

);
return prefixError(

@@ -424,0 +445,0 @@ () =>

@@ -8,2 +8,3 @@ import { fetch } from "cross-fetch";

Fetch,
defaultCacheSize,
} from "../shared";

@@ -90,2 +91,3 @@ import { InternalInitializeOptions, LogLevel } from "..";

options.vercelEdgeConfigItemKey ?? null,
options.cacheSize ?? defaultCacheSize,
endpoints,

@@ -92,0 +94,0 @@ options.query,

@@ -20,2 +20,3 @@ /* eslint-disable no-underscore-dangle */

UpdateListener,
hash,
} from "../shared";

@@ -108,2 +109,40 @@ import getDeepestZodIssue from "../shared/helpers/getDeepestZodIssue";

protected getField(fieldName: string, fieldArguments: ObjectValue): Props {
const step: Step = { type: "GetFieldStep", fieldName, fieldArguments };
const { context } = this.props;
const commitHash = context?.initData?.commitHash;
if (!commitHash || !context.getFieldCache) {
// No caching if the sdk hasn't been initialized or there is no cache.
return this.createProps(
step,
this.getReducedFieldExpression(fieldName, fieldArguments)
);
}
const cacheKey = getCacheKey(
commitHash,
/* parent */ this,
step,
/* suffix */ ""
);
const cachedReducedFieldExpression = context.getFieldCache.get(cacheKey);
if (cachedReducedFieldExpression) {
return this.createProps(step, cachedReducedFieldExpression);
}
const reducedFieldExpression = this.getReducedFieldExpression(
fieldName,
fieldArguments
);
if (reducedFieldExpression) {
context.getFieldCache.set(cacheKey, reducedFieldExpression);
}
return this.createProps(step, reducedFieldExpression);
}
// @internal
private getReducedFieldExpression(
fieldName: string,
fieldArguments: ObjectValue
): Expression | null {
try {

@@ -122,3 +161,3 @@ // As fieldArguments are passed in by users, perform extra validation to

const { logger, expression } = this.props;
const { expression } = this.props;

@@ -129,3 +168,3 @@ if (!expression) {

);
return this.getFieldFallback(fieldName, fieldArguments);
return null;
}

@@ -168,35 +207,42 @@

return {
context,
parent: this,
step: { type: "GetFieldStep", fieldName, fieldArguments },
expression: reducedFieldExpression,
logger,
};
return reducedFieldExpression;
} catch (error) {
this.nodeError({ type: "GetField", fieldName, fieldArguments }, error);
return this.getFieldFallback(fieldName, fieldArguments);
return null;
}
}
private getFieldFallback(
fieldName: string,
fieldArguments: ObjectValue
): Props {
const { logger, context } = this.props;
_getItems(fallbackLength: number): Props[] {
const { context } = this.props;
const commitHash = context?.initData?.commitHash;
return {
context,
parent: this,
step: { type: "GetFieldStep", fieldName, fieldArguments },
expression: null,
logger,
};
if (!commitHash || !context.getItemsCache) {
// No caching if the sdk hasn't been initialized or there is no cache.
return this.createPropsArray(this._getItemExpressions(), fallbackLength);
}
const cacheKey = getCacheKey(
commitHash,
this.props.parent,
this.props.step,
/* suffix */ ""
);
const cachedItemExpressions = context.getItemsCache.get(cacheKey);
if (cachedItemExpressions) {
return this.createPropsArray(cachedItemExpressions, fallbackLength);
}
const itemExpressions = this._getItemExpressions();
if (itemExpressions) {
context.getItemsCache.set(cacheKey, itemExpressions);
}
return this.createPropsArray(itemExpressions, fallbackLength);
}
_getItems(fallbackLength: number): Props[] {
// @internal
private _getItemExpressions(): Expression[] | null {
try {
this.updateIfNeeded();
const { context, logger, expression } = this.props;
const { expression } = this.props;

@@ -207,3 +253,3 @@ if (!expression) {

);
return this._getItemsFallback(fallbackLength);
return null;
}

@@ -222,3 +268,3 @@

const result: Props[] = expression.items.map((item, index) => {
const result: Expression[] = expression.items.map((item, index) => {
const itemExpression = nullThrows(

@@ -230,9 +276,3 @@ item,

return {
context,
parent: this,
step: { type: "GetItemStep", index, fallbackLength },
expression: itemExpression,
logger,
};
return itemExpression;
});

@@ -243,23 +283,35 @@

this.nodeError({ type: "GetItems" }, error);
return this._getItemsFallback(fallbackLength);
return null;
}
}
private _getItemsFallback(fallbackLength: number): Props[] {
const { context, logger } = this.props;
protected evaluate(query: Query<ObjectValue> | null, fallback: Value): Value {
const { context } = this.props;
const commitHash = context?.initData?.commitHash;
return Array(fallbackLength)
.fill(0)
.map(
(_, index): Props => ({
context,
parent: this,
step: { type: "GetItemStep", index, fallbackLength },
expression: null,
logger,
})
);
if (!commitHash || !context.evaluateCache) {
// No caching if the sdk hasn't been initialized or there is no cache.
return this.getValue(query) ?? fallback;
}
const cacheKey = getCacheKey(
commitHash,
this.props.parent,
this.props.step,
/* suffix */ JSON.stringify(query)
);
const cachedValue = context.evaluateCache.get(cacheKey);
if (cachedValue !== null && cachedValue !== undefined) {
return cachedValue;
}
const value = this.getValue(query);
if (value !== null && value !== undefined) {
context.evaluateCache.set(cacheKey, value);
}
return value ?? fallback;
}
protected evaluate(query: Query<ObjectValue> | null, fallback: Value): Value {
// @internal
private getValue(query: Query<ObjectValue> | null): Value | null {
try {

@@ -273,3 +325,3 @@ this.updateIfNeeded();

);
return fallback;
return null;
}

@@ -294,4 +346,5 @@

const { parent, step } = this.props;
context.logger.nodeEvaluation(
this.getPath(),
getPath(parent, step),
{ type: "Evaluate", query },

@@ -309,6 +362,26 @@ commitHash,

return fallback;
return null;
}
}
// @internal
private createProps(step: Step, expression: Expression | null): Props {
const { context, logger } = this.props;
return { step, parent: this, context, expression, logger };
}
// @internal
private createPropsArray(
itemExpressions: Expression[] | null,
fallbackLength: number
): Props[] {
return (itemExpressions || Array(fallbackLength).fill(null)).map(
(expression, index) =>
this.createProps(
{ type: "GetItemStep", index, fallbackLength },
expression
)
);
}
_logUnexpectedTypeError(): void {

@@ -370,3 +443,3 @@ if (!this.props.expression) {

private nodeError(nodeOp: DbNodeOp | null, error: unknown): void {
const { logger, expression } = this.props;
const { parent, step, logger, expression } = this.props;
if (!logger) {

@@ -377,3 +450,3 @@ // eslint-disable-next-line no-console

this.typeName
} node at ${this.getPath()}`,
} node at ${getPath(parent, step)}`,
error

@@ -385,3 +458,3 @@ );

logger.nodeError(
this.getPath(),
getPath(parent, step),
nodeOp,

@@ -396,14 +469,2 @@ this.commitHash,

// @internal
private getPath(): string {
const { parent, step } = this.props;
return `${parent ? `${parent.getPath()} > ` : ""}${
!step
? "{}"
: step.type === "GetFieldStep"
? `${step.fieldName}(${JSON.stringify(step.fieldArguments)})`
: `[${step.index}]`
}`;
}
getCommitHash(): string | null {

@@ -505,1 +566,25 @@ const { context } = this.props;

}
function getCacheKey(
commitHash: string,
parent: Node | null,
step: Step | null,
suffix: string
): string {
return hash(
`${commitHash}/${getPath(parent, step)}/${suffix}
)}`
).toString();
}
function getPath(parent: Node | null, step: Step | null): string {
return `${
parent ? `${getPath(parent.props.parent, parent.props.step)} > ` : ""
}${
!step
? "{}"
: step.type === "GetFieldStep"
? `${step.fieldName}(${JSON.stringify(step.fieldArguments)})`
: `[${step.index}]`
}`;
}

@@ -26,3 +26,5 @@ export const localBackendBaseUrl = "http://localhost:3001";

export const defaultCacheSize = 250;
export const breakingSchemaChangesError =
"If you've made breaking changes to your schema like adding a new field argument, you may need to re-run code generation and fix the type errors.";

@@ -448,4 +448,4 @@ /* eslint-disable capitalized-comments */

: innerQuery[objectTypeName]
? innerQuery[objectTypeName].selection
: {};
? innerQuery[objectTypeName].selection
: {};

@@ -1700,14 +1700,16 @@ Object.keys(expression.updates).forEach((fieldName) => {

function getField(object: Expression, fieldPath: string): Expression | null {
if (object.type !== "ObjectExpression") {
return null;
function getField(
startObject: Expression,
fieldPath: string
): Expression | null {
const fieldPathParts = fieldPath.split(fieldPathSeparator);
let field: Expression | null = startObject;
for (let i = 0; i < fieldPathParts.length; i += 1) {
if (!field || field.type !== "ObjectExpression") {
return null;
}
const fieldName = fieldPathParts[i];
field = field.fields[fieldName] || null;
}
const [fieldName, ...rest] = fieldPath.split(fieldPathSeparator);
const field = object.fields[fieldName];
if (!field) {
return null;
}
if (rest.length > 0) {
return getField(field, rest.join(fieldPathSeparator));
}
return field;

@@ -1714,0 +1716,0 @@ }

@@ -46,21 +46,16 @@ import stableStringify from "./stableStringify";

return {
evaluations: mergeCountMaps(
a.evaluations,
bs.map((b) => b.evaluations)
),
events: mergeCountMaps(
a.events,
bs.map((b) => b.events)
),
exposures: mergeCountMaps(
a.exposures,
bs.map((b) => b.exposures)
),
evaluations: mergeCountMapsFromLogs("evaluations", a, bs),
events: mergeCountMapsFromLogs("events", a, bs),
exposures: mergeCountMapsFromLogs("exposures", a, bs),
};
}
function mergeCountMaps(a: CountMap, bs: CountMap[]): CountMap {
const result: CountMap = { ...a };
function mergeCountMapsFromLogs<K extends keyof ReductionLogs>(
countMapKey: K,
a: ReductionLogs,
bs: ReductionLogs[]
): CountMap {
const result: CountMap = { ...a[countMapKey] };
bs.forEach((b) => {
Object.entries(b).forEach(([key, value]) => {
Object.entries(b[countMapKey]).forEach(([key, value]) => {
result[key] = (result[key] || 0) + value;

@@ -67,0 +62,0 @@ });

@@ -565,3 +565,3 @@ /* eslint-disable capitalized-comments */

export type Query<
TFieldArguments extends ObjectValueWithVariables | ObjectExpression
TFieldArguments extends ObjectValueWithVariables | ObjectExpression,
> = {

@@ -572,3 +572,3 @@ [objectTypeName: string]: Fragment<TFieldArguments>;

export type Fragment<
TFieldArguments extends ObjectValueWithVariables | ObjectExpression
TFieldArguments extends ObjectValueWithVariables | ObjectExpression,
> = {

@@ -580,3 +580,3 @@ objectTypeName: string;

export type Selection<
TFieldArguments extends ObjectValueWithVariables | ObjectExpression
TFieldArguments extends ObjectValueWithVariables | ObjectExpression,
> = {

@@ -769,2 +769,3 @@ [fieldName: string]: {

vercelEdgeConfigItemKey?: string;
cacheSize?: number; // Defaults to 250. Setting it to 0 disables caching.

@@ -771,0 +772,0 @@ /** Hypertune internal use only */

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