superposition-provider 0.93.1 → 0.93.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/experimentation-client.d.ts +5 -1
- package/dist/index.esm.js +73 -32
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +73 -32
- package/dist/index.js.map +1 -1
- package/dist/native-lib/libsuperposition_core-aarch64-apple-darwin.dylib +0 -0
- package/dist/native-lib/libsuperposition_core-x86_64-apple-darwin.dylib +0 -0
- package/dist/native-lib/libsuperposition_core-x86_64-pc-windows-msvc.dll +0 -0
- package/dist/native-lib/libsuperposition_core-x86_64-unknown-linux-gnu.so +0 -0
- package/dist/superposition-provider.d.ts +3 -3
- package/dist/types.d.ts +13 -0
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GroupType,
|
|
1
|
+
import { GroupType, VariantType } from "superposition-sdk";
|
|
2
2
|
import { SuperpositionOptions, ExperimentationOptions } from "./types";
|
|
3
3
|
export interface Variant {
|
|
4
4
|
id: string;
|
|
@@ -13,6 +13,10 @@ export interface Experiment {
|
|
|
13
13
|
variants: Variant[];
|
|
14
14
|
traffic_percentage: number;
|
|
15
15
|
}
|
|
16
|
+
export interface Bucket {
|
|
17
|
+
variant_id: string;
|
|
18
|
+
experiment_id: string;
|
|
19
|
+
}
|
|
16
20
|
export interface ExperimentGroup {
|
|
17
21
|
id: string;
|
|
18
22
|
context: Record<string, string>;
|
package/dist/index.esm.js
CHANGED
|
@@ -9900,6 +9900,7 @@ function requireAws_restJson1 () {
|
|
|
9900
9900
|
[_v]: [, input[_v]],
|
|
9901
9901
|
[_sr]: [() => input.show_reasoning !== void 0, () => (input[_sr].toString())],
|
|
9902
9902
|
[_ci]: [, input[_ci]],
|
|
9903
|
+
[_rr]: [() => input.resolve_remote !== void 0, () => (input[_rr].toString())],
|
|
9903
9904
|
});
|
|
9904
9905
|
let body;
|
|
9905
9906
|
body = JSON.stringify((0, smithy_client_1.take)(input, {
|
|
@@ -12617,6 +12618,7 @@ function requireAws_restJson1 () {
|
|
|
12617
12618
|
};
|
|
12618
12619
|
const de_DimensionInfo = (output, context) => {
|
|
12619
12620
|
return (0, smithy_client_1.take)(output, {
|
|
12621
|
+
'autocomplete_function_name': smithy_client_1.expectString,
|
|
12620
12622
|
'dependency_graph': smithy_client_1._json,
|
|
12621
12623
|
'dimension_type': (_) => (0, smithy_client_1._json)((0, core_1.awsExpectUnion)(_)),
|
|
12622
12624
|
'position': smithy_client_1.expectInt32,
|
|
@@ -12933,6 +12935,7 @@ function requireAws_restJson1 () {
|
|
|
12933
12935
|
const _p = "prefix";
|
|
12934
12936
|
const _pa = "page";
|
|
12935
12937
|
const _pl = "plaintext";
|
|
12938
|
+
const _rr = "resolve_remote";
|
|
12936
12939
|
const _s = "status";
|
|
12937
12940
|
const _sb = "sort_by";
|
|
12938
12941
|
const _so = "sort_on";
|
|
@@ -15596,7 +15599,10 @@ class ExperimentationClient {
|
|
|
15596
15599
|
member_experiment_ids: exp_group.member_experiment_ids || [],
|
|
15597
15600
|
group_type: exp_group.group_type ||
|
|
15598
15601
|
superpositionSdk.GroupType.USER_CREATED,
|
|
15599
|
-
buckets: exp_group.buckets
|
|
15602
|
+
buckets: exp_group.buckets?.map((bucket) => ({
|
|
15603
|
+
variant_id: bucket.variant_id || "",
|
|
15604
|
+
experiment_id: bucket.experiment_id || "",
|
|
15605
|
+
})) || [],
|
|
15600
15606
|
});
|
|
15601
15607
|
}
|
|
15602
15608
|
return experimentGroups;
|
|
@@ -15741,10 +15747,10 @@ class ConfigurationClient {
|
|
|
15741
15747
|
console.error("Failed to refresh configuration. Will continue to use the last known good configuration.", error);
|
|
15742
15748
|
}
|
|
15743
15749
|
}, strategy.interval);
|
|
15744
|
-
|
|
15745
|
-
|
|
15746
|
-
|
|
15747
|
-
|
|
15750
|
+
}
|
|
15751
|
+
if (experimentationOptions) {
|
|
15752
|
+
this.experimentationOptions = experimentationOptions;
|
|
15753
|
+
this.experimentationClient = new ExperimentationClient(config, experimentationOptions);
|
|
15748
15754
|
}
|
|
15749
15755
|
this.smithyClient = new superpositionSdk.SuperpositionClient({
|
|
15750
15756
|
endpoint: this.config.endpoint,
|
|
@@ -15763,8 +15769,10 @@ class ConfigurationClient {
|
|
|
15763
15769
|
let experimentationArgs;
|
|
15764
15770
|
if (this.experimentationClient && targetingKey) {
|
|
15765
15771
|
const experiments = await this.experimentationClient.getExperiments();
|
|
15772
|
+
const experiment_groups = await this.experimentationClient.getExperimentGroups();
|
|
15766
15773
|
experimentationArgs = {
|
|
15767
15774
|
experiments,
|
|
15775
|
+
experiment_groups,
|
|
15768
15776
|
targeting_key: targetingKey,
|
|
15769
15777
|
};
|
|
15770
15778
|
}
|
|
@@ -15806,6 +15814,7 @@ class ConfigurationClient {
|
|
|
15806
15814
|
}
|
|
15807
15815
|
}
|
|
15808
15816
|
// TODO: defaultValue is taken but not used. Should it be used as a fallback?
|
|
15817
|
+
// TODO: Remove this function all together and use eval for getAllConfigValue as well
|
|
15809
15818
|
async getAllConfigValue(defaultValue, context, targetingKey) {
|
|
15810
15819
|
try {
|
|
15811
15820
|
const configData = await this.fetchConfigData();
|
|
@@ -15953,7 +15962,9 @@ class NativeResolver {
|
|
|
15953
15962
|
console.log(" queryData :", queryDataJson);
|
|
15954
15963
|
console.log(" mergeStrategy:", mergeStrategy);
|
|
15955
15964
|
console.log(" filterPrefixes:", filterPrefixes);
|
|
15956
|
-
console.log("
|
|
15965
|
+
console.log(" experiment:", experimentation?.experiments?.length);
|
|
15966
|
+
console.log(" experiment groups:", experimentation?.experiment_groups?.length);
|
|
15967
|
+
console.log(" targetingKey:", experimentation?.targetingKey);
|
|
15957
15968
|
if (!defaultConfigsJson ||
|
|
15958
15969
|
defaultConfigsJson === "null" ||
|
|
15959
15970
|
defaultConfigsJson === "undefined") {
|
|
@@ -16165,13 +16176,14 @@ class SuperpositionProvider {
|
|
|
16165
16176
|
constructor(config) {
|
|
16166
16177
|
this.config = config;
|
|
16167
16178
|
this.metadata = {
|
|
16168
|
-
name:
|
|
16169
|
-
slug:
|
|
16179
|
+
name: "SuperpositionProvider",
|
|
16180
|
+
slug: "superposition-provider",
|
|
16170
16181
|
};
|
|
16171
16182
|
this.events = new OpenFeatureEventEmitter();
|
|
16172
16183
|
this.hooks = [];
|
|
16173
16184
|
this.status = ProviderStatus.NOT_READY;
|
|
16174
16185
|
// Cache for processed contexts
|
|
16186
|
+
// TODO: verify if this is at all needed
|
|
16175
16187
|
this.processedContextCache = new WeakMap();
|
|
16176
16188
|
this.client = new ConfigurationClient({
|
|
16177
16189
|
endpoint: config.endpoint,
|
|
@@ -16188,14 +16200,22 @@ class SuperpositionProvider {
|
|
|
16188
16200
|
this.status = ProviderStatus.NOT_READY;
|
|
16189
16201
|
try {
|
|
16190
16202
|
await this.client.initialize();
|
|
16203
|
+
// TODO: find why is this needed?
|
|
16191
16204
|
await this.client.eval(context || {});
|
|
16192
16205
|
this.status = ProviderStatus.READY;
|
|
16193
|
-
this.events.emit(ProviderEvents.Ready, {
|
|
16206
|
+
this.events.emit(ProviderEvents.Ready, {
|
|
16207
|
+
message: "Provider ready",
|
|
16208
|
+
});
|
|
16194
16209
|
}
|
|
16195
16210
|
catch (error) {
|
|
16196
16211
|
this.status = ProviderStatus.ERROR;
|
|
16197
|
-
const message = error instanceof Error
|
|
16198
|
-
|
|
16212
|
+
const message = error instanceof Error
|
|
16213
|
+
? error.message
|
|
16214
|
+
: "Initialization failed";
|
|
16215
|
+
this.events.emit(ProviderEvents.Error, {
|
|
16216
|
+
message,
|
|
16217
|
+
errorCode: ErrorCode.PROVIDER_NOT_READY,
|
|
16218
|
+
});
|
|
16199
16219
|
throw error;
|
|
16200
16220
|
}
|
|
16201
16221
|
}
|
|
@@ -16210,7 +16230,7 @@ class SuperpositionProvider {
|
|
|
16210
16230
|
processedContext = this.filterContext(context);
|
|
16211
16231
|
this.processedContextCache.set(context, processedContext);
|
|
16212
16232
|
}
|
|
16213
|
-
const config = await this.client.eval(processedContext);
|
|
16233
|
+
const config = await this.client.eval(processedContext, undefined, context.targetingKey);
|
|
16214
16234
|
const value = getNestedValue(config, flagKey);
|
|
16215
16235
|
const converter = TYPE_CONVERTERS[type];
|
|
16216
16236
|
return converter(value, defaultValue);
|
|
@@ -16218,17 +16238,24 @@ class SuperpositionProvider {
|
|
|
16218
16238
|
filterContext(context) {
|
|
16219
16239
|
const filtered = {};
|
|
16220
16240
|
for (const [key, value] of Object.entries(context)) {
|
|
16221
|
-
if (key.startsWith(
|
|
16241
|
+
if (key.startsWith("__") ||
|
|
16242
|
+
key === "targetingKey" ||
|
|
16243
|
+
key === "timestamp") {
|
|
16222
16244
|
continue;
|
|
16223
16245
|
}
|
|
16224
16246
|
// Only include simple, serializable types
|
|
16225
|
-
if (typeof value ===
|
|
16247
|
+
if (typeof value === "string" ||
|
|
16248
|
+
typeof value === "number" ||
|
|
16249
|
+
typeof value === "boolean") {
|
|
16226
16250
|
filtered[key] = value;
|
|
16227
16251
|
}
|
|
16228
|
-
else if (typeof value ===
|
|
16252
|
+
else if (typeof value === "object" &&
|
|
16253
|
+
value !== null &&
|
|
16254
|
+
!Array.isArray(value)) {
|
|
16229
16255
|
try {
|
|
16230
16256
|
const serialized = JSON.stringify(value);
|
|
16231
|
-
if (serialized.length < 1000 &&
|
|
16257
|
+
if (serialized.length < 1000 &&
|
|
16258
|
+
Object.keys(value).length < 10) {
|
|
16232
16259
|
filtered[key] = value;
|
|
16233
16260
|
}
|
|
16234
16261
|
}
|
|
@@ -16241,62 +16268,76 @@ class SuperpositionProvider {
|
|
|
16241
16268
|
}
|
|
16242
16269
|
createResolver(type) {
|
|
16243
16270
|
return async (flagKey, defaultValue, context) => {
|
|
16244
|
-
if (this.status !== ProviderStatus.READY &&
|
|
16271
|
+
if (this.status !== ProviderStatus.READY &&
|
|
16272
|
+
this.status !== ProviderStatus.STALE) {
|
|
16245
16273
|
return {
|
|
16246
16274
|
value: defaultValue,
|
|
16247
|
-
reason:
|
|
16248
|
-
errorCode: this.status === ProviderStatus.FATAL
|
|
16249
|
-
|
|
16275
|
+
reason: "ERROR",
|
|
16276
|
+
errorCode: this.status === ProviderStatus.FATAL
|
|
16277
|
+
? ErrorCode.PROVIDER_FATAL
|
|
16278
|
+
: ErrorCode.PROVIDER_NOT_READY,
|
|
16279
|
+
errorMessage: `Provider status: ${this.status}`,
|
|
16250
16280
|
};
|
|
16251
16281
|
}
|
|
16252
16282
|
try {
|
|
16253
16283
|
const value = await this.evaluateFlag(flagKey, defaultValue, context, type);
|
|
16254
16284
|
return {
|
|
16255
16285
|
value,
|
|
16256
|
-
reason: this.status === ProviderStatus.STALE
|
|
16286
|
+
reason: this.status === ProviderStatus.STALE
|
|
16287
|
+
? "STALE"
|
|
16288
|
+
: "TARGETING_MATCH",
|
|
16257
16289
|
};
|
|
16258
16290
|
}
|
|
16259
16291
|
catch (error) {
|
|
16260
16292
|
return {
|
|
16261
16293
|
value: defaultValue,
|
|
16262
|
-
reason:
|
|
16294
|
+
reason: "ERROR",
|
|
16263
16295
|
errorCode: ErrorCode.GENERAL,
|
|
16264
|
-
errorMessage: error instanceof Error
|
|
16296
|
+
errorMessage: error instanceof Error
|
|
16297
|
+
? error.message
|
|
16298
|
+
: "Evaluation failed",
|
|
16265
16299
|
};
|
|
16266
16300
|
}
|
|
16267
16301
|
};
|
|
16268
16302
|
}
|
|
16269
16303
|
async resolveBooleanEvaluation(flagKey, defaultValue, context) {
|
|
16270
|
-
return this.createResolver(
|
|
16304
|
+
return this.createResolver("boolean")(flagKey, defaultValue, context);
|
|
16271
16305
|
}
|
|
16272
16306
|
async resolveStringEvaluation(flagKey, defaultValue, context) {
|
|
16273
|
-
return this.createResolver(
|
|
16307
|
+
return this.createResolver("string")(flagKey, defaultValue, context);
|
|
16274
16308
|
}
|
|
16275
16309
|
async resolveNumberEvaluation(flagKey, defaultValue, context) {
|
|
16276
|
-
return this.createResolver(
|
|
16310
|
+
return this.createResolver("number")(flagKey, defaultValue, context);
|
|
16277
16311
|
}
|
|
16278
16312
|
async resolveObjectEvaluation(flagKey, defaultValue, context, logger) {
|
|
16279
|
-
return this.createResolver(
|
|
16313
|
+
return this.createResolver("object")(flagKey, defaultValue, context);
|
|
16280
16314
|
}
|
|
16281
16315
|
async resolveAllConfigDetails(defaultValue, context) {
|
|
16282
|
-
if (this.status !== ProviderStatus.READY &&
|
|
16316
|
+
if (this.status !== ProviderStatus.READY &&
|
|
16317
|
+
this.status !== ProviderStatus.STALE) {
|
|
16283
16318
|
return defaultValue;
|
|
16284
16319
|
}
|
|
16285
16320
|
try {
|
|
16286
|
-
const processedContext = this.processedContextCache.get(context) ||
|
|
16321
|
+
const processedContext = this.processedContextCache.get(context) ||
|
|
16322
|
+
this.filterContext(context);
|
|
16287
16323
|
if (!this.processedContextCache.has(context)) {
|
|
16288
16324
|
this.processedContextCache.set(context, processedContext);
|
|
16289
16325
|
}
|
|
16290
16326
|
const targetingKey = context.targetingKey;
|
|
16327
|
+
// TODO: remove this function and use eval for getAllConfigValue as well
|
|
16291
16328
|
return await this.client.getAllConfigValue(defaultValue, processedContext, targetingKey);
|
|
16292
16329
|
}
|
|
16293
16330
|
catch (error) {
|
|
16294
|
-
console.error(
|
|
16331
|
+
console.error("Error resolving all config details:", error);
|
|
16295
16332
|
return defaultValue;
|
|
16296
16333
|
}
|
|
16297
16334
|
}
|
|
16298
|
-
getStatus() {
|
|
16299
|
-
|
|
16335
|
+
getStatus() {
|
|
16336
|
+
return this.status;
|
|
16337
|
+
}
|
|
16338
|
+
getConfigurationClient() {
|
|
16339
|
+
return this.client;
|
|
16340
|
+
}
|
|
16300
16341
|
}
|
|
16301
16342
|
|
|
16302
16343
|
function httpRequest(options) {
|