@spotify-confidence/openfeature-server-provider-local 0.10.1 → 0.11.0
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/CHANGELOG.md +16 -0
- package/dist/client.d.ts +1 -1
- package/dist/client.js +10 -0
- package/dist/confidence_resolver.wasm +0 -0
- package/dist/index.fetch.d.ts +25 -2
- package/dist/index.fetch.js +218 -3
- package/dist/index.inlined.d.ts +25 -2
- package/dist/index.inlined.js +219 -4
- package/dist/index.node.d.ts +25 -2
- package/dist/index.node.js +218 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.11.0](https://github.com/spotify/confidence-resolver/compare/openfeature-provider-js-v0.10.1...openfeature-provider-js-v0.11.0) (2026-03-24)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add register_resolve WASM export for SDK-side telemetry ([#354](https://github.com/spotify/confidence-resolver/issues/354)) ([31499bc](https://github.com/spotify/confidence-resolver/commit/31499bc911942ecd751b4a4a702f35ded41e9776))
|
|
9
|
+
* add resolver_version field to TelemetryData ([#346](https://github.com/spotify/confidence-resolver/issues/346)) ([10ab1c6](https://github.com/spotify/confidence-resolver/commit/10ab1c657cb830dc36f433d1dca0af73beecaa27))
|
|
10
|
+
* local prometheus sdk metrics ([#322](https://github.com/spotify/confidence-resolver/issues/322)) ([8b18119](https://github.com/spotify/confidence-resolver/commit/8b18119eae449afbe4a0815e8aab5f82888a8621))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Dependencies
|
|
14
|
+
|
|
15
|
+
* The following workspace dependencies were updated
|
|
16
|
+
* dependencies
|
|
17
|
+
* rust-guest bumped from 0.1.19 to 0.1.20
|
|
18
|
+
|
|
3
19
|
## [0.10.1](https://github.com/spotify/confidence-resolver/compare/openfeature-provider-js-v0.10.0...openfeature-provider-js-v0.10.1) (2026-03-12)
|
|
4
20
|
|
|
5
21
|
|
package/dist/client.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EvaluationDetails, FlagValue } from "@openfeature/core";
|
|
2
2
|
|
|
3
3
|
//#region src/types.d.ts
|
|
4
|
-
type ResolutionReason = "ERROR" | "FLAG_ARCHIVED" | "MATCH" | "NO_SEGMENT_MATCH" | "TARGETING_KEY_ERROR" | "NO_TREATMENT_MATCH" | "UNSPECIFIED";
|
|
4
|
+
type ResolutionReason = "ERROR" | "FLAG_ARCHIVED" | "MATCH" | "NO_SEGMENT_MATCH" | "TARGETING_KEY_ERROR" | "NO_TREATMENT_MATCH" | "MATERIALIZATION_NOT_SUPPORTED" | "UNSPECIFIED";
|
|
5
5
|
declare enum ErrorCode {
|
|
6
6
|
PROVIDER_NOT_READY = "PROVIDER_NOT_READY",
|
|
7
7
|
PROVIDER_FATAL = "PROVIDER_FATAL",
|
package/dist/client.js
CHANGED
|
@@ -92,6 +92,16 @@ function resolve(bundle, flagKey, defaultValue, logger$1) {
|
|
|
92
92
|
shouldApply: false
|
|
93
93
|
};
|
|
94
94
|
}
|
|
95
|
+
if (flag.reason === "MATERIALIZATION_NOT_SUPPORTED") {
|
|
96
|
+
logger$1?.warn("Flag '%s' requires materializations but no materialization store is configured. Pass a MaterializationStore implementation or: 'CONFIDENCE_REMOTE_STORE' to createConfidenceServerProvider()", flagName);
|
|
97
|
+
return {
|
|
98
|
+
reason: "ERROR",
|
|
99
|
+
errorCode: ErrorCode.GENERAL,
|
|
100
|
+
errorMessage: `Flag '${flagName}' requires materializations. Configure a materialization store.`,
|
|
101
|
+
value: defaultValue,
|
|
102
|
+
shouldApply: false
|
|
103
|
+
};
|
|
104
|
+
}
|
|
95
105
|
let value = flag.value;
|
|
96
106
|
for (let i = 0; i < path.length; i++) {
|
|
97
107
|
if (value === null || typeof value !== "object" || Array.isArray(value)) return {
|
|
Binary file
|
package/dist/index.fetch.d.ts
CHANGED
|
@@ -82,6 +82,10 @@ declare enum ResolveReason {
|
|
|
82
82
|
RESOLVE_REASON_UNRECOGNIZED_TARGETING_RULE = 7,
|
|
83
83
|
/** RESOLVE_REASON_MATERIALIZATION_NOT_SUPPORTED - The flag could not be resolved because a rule is using materialization */
|
|
84
84
|
RESOLVE_REASON_MATERIALIZATION_NOT_SUPPORTED = 8,
|
|
85
|
+
/** RESOLVE_REASON_TYPE_MISMATCH - The resolved value type does not match the type requested by the SDK */
|
|
86
|
+
RESOLVE_REASON_TYPE_MISMATCH = 9,
|
|
87
|
+
/** RESOLVE_REASON_FLAG_NOT_FOUND - The flag was not found in the resolve response */
|
|
88
|
+
RESOLVE_REASON_FLAG_NOT_FOUND = 10,
|
|
85
89
|
UNRECOGNIZED = -1,
|
|
86
90
|
}
|
|
87
91
|
declare enum SdkId {
|
|
@@ -273,6 +277,10 @@ interface MaterializationRecord {
|
|
|
273
277
|
rule: string;
|
|
274
278
|
variant: string;
|
|
275
279
|
}
|
|
280
|
+
interface RegisterResolveRequest {
|
|
281
|
+
reason: ResolveReason;
|
|
282
|
+
latencyUs: number;
|
|
283
|
+
}
|
|
276
284
|
declare const ResolveProcessRequest: MessageFns$2<ResolveProcessRequest>;
|
|
277
285
|
declare const ResolveProcessRequest_StaticMaterializations: MessageFns$2<ResolveProcessRequest_StaticMaterializations>;
|
|
278
286
|
declare const ResolveProcessRequest_Resume: MessageFns$2<ResolveProcessRequest_Resume>;
|
|
@@ -280,6 +288,7 @@ declare const ResolveProcessResponse: MessageFns$2<ResolveProcessResponse>;
|
|
|
280
288
|
declare const ResolveProcessResponse_Resolved: MessageFns$2<ResolveProcessResponse_Resolved>;
|
|
281
289
|
declare const ResolveProcessResponse_Suspended: MessageFns$2<ResolveProcessResponse_Suspended>;
|
|
282
290
|
declare const MaterializationRecord: MessageFns$2<MaterializationRecord>;
|
|
291
|
+
declare const RegisterResolveRequest: MessageFns$2<RegisterResolveRequest>;
|
|
283
292
|
type Builtin$2 = Date | Function | Uint8Array | string | number | boolean | undefined;
|
|
284
293
|
type DeepPartial$2<T> = T extends Builtin$2 ? T : T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial$2<U>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial$2<U>> : T extends {} ? { [K in keyof T]?: DeepPartial$2<T[K]> } : Partial<T>;
|
|
285
294
|
type KeysOfUnion$2<T> = T extends T ? keyof T : never;
|
|
@@ -316,10 +325,12 @@ interface MessageFns$1<T> {
|
|
|
316
325
|
//#region src/LocalResolver.d.ts
|
|
317
326
|
interface LocalResolver {
|
|
318
327
|
resolveProcess(request: ResolveProcessRequest): ResolveProcessResponse;
|
|
328
|
+
registerResolve(request: RegisterResolveRequest): void;
|
|
319
329
|
setResolverState(request: SetResolverStateRequest): void;
|
|
320
330
|
flushLogs(): Uint8Array;
|
|
321
331
|
flushAssigned(): Uint8Array;
|
|
322
332
|
applyFlags(request: ApplyFlagsRequest): void;
|
|
333
|
+
prometheusSnapshot(instance: string): string;
|
|
323
334
|
}
|
|
324
335
|
//#endregion
|
|
325
336
|
//#region src/proto/confidence/flags/resolver/v1/internal_api.d.ts
|
|
@@ -429,7 +440,7 @@ interface MaterializationStore {
|
|
|
429
440
|
}
|
|
430
441
|
//#endregion
|
|
431
442
|
//#region src/types.d.ts
|
|
432
|
-
type ResolutionReason = "ERROR" | "FLAG_ARCHIVED" | "MATCH" | "NO_SEGMENT_MATCH" | "TARGETING_KEY_ERROR" | "NO_TREATMENT_MATCH" | "UNSPECIFIED";
|
|
443
|
+
type ResolutionReason = "ERROR" | "FLAG_ARCHIVED" | "MATCH" | "NO_SEGMENT_MATCH" | "TARGETING_KEY_ERROR" | "NO_TREATMENT_MATCH" | "MATERIALIZATION_NOT_SUPPORTED" | "UNSPECIFIED";
|
|
433
444
|
declare enum ErrorCode {
|
|
434
445
|
PROVIDER_NOT_READY = "PROVIDER_NOT_READY",
|
|
435
446
|
PROVIDER_FATAL = "PROVIDER_FATAL",
|
|
@@ -462,6 +473,12 @@ interface FlagBundle {
|
|
|
462
473
|
//#endregion
|
|
463
474
|
//#region src/ConfidenceServerProviderLocal.d.ts
|
|
464
475
|
type FlagBundle$1 = FlagBundle;
|
|
476
|
+
/**
|
|
477
|
+
* Configuration for {@link ConfidenceServerProviderLocal.getPrometheusMetrics}.
|
|
478
|
+
*
|
|
479
|
+
* @experimental This API is subject to change.
|
|
480
|
+
*/
|
|
481
|
+
interface SnapshotConfig {}
|
|
465
482
|
interface ProviderOptions {
|
|
466
483
|
flagClientSecret: string;
|
|
467
484
|
initializeTimeout?: number;
|
|
@@ -513,6 +530,12 @@ declare class ConfidenceServerProviderLocal implements Provider {
|
|
|
513
530
|
/** Resolves with an evaluation of a String flag */
|
|
514
531
|
resolveStringEvaluation(flagKey: string, defaultValue: string, context: EvaluationContext): Promise<ResolutionDetails<string>>;
|
|
515
532
|
/**
|
|
533
|
+
* Returns a Prometheus metrics snapshot from the WASM resolver.
|
|
534
|
+
*
|
|
535
|
+
* @experimental This API is subject to change.
|
|
536
|
+
*/
|
|
537
|
+
getPrometheusMetrics(_request?: SnapshotConfig): string;
|
|
538
|
+
/**
|
|
516
539
|
* Applies a previously resolved flag, logging that it was used/exposed.
|
|
517
540
|
* Call this when a flag value is actually rendered or used in the client.
|
|
518
541
|
* @param resolveToken - Base64-encoded resolve token from the flag bundle
|
|
@@ -530,4 +553,4 @@ declare function createConfidenceServerProvider({
|
|
|
530
553
|
...options
|
|
531
554
|
}: ProviderOptionsExt): ConfidenceServerProviderLocal;
|
|
532
555
|
//#endregion
|
|
533
|
-
export { type MaterializationStore, ProviderOptionsExt, createConfidenceServerProvider };
|
|
556
|
+
export { type MaterializationStore, ProviderOptionsExt, type SnapshotConfig, createConfidenceServerProvider };
|
package/dist/index.fetch.js
CHANGED
|
@@ -774,6 +774,8 @@ let ResolveReason = /* @__PURE__ */ function(ResolveReason$1) {
|
|
|
774
774
|
ResolveReason$1[ResolveReason$1["RESOLVE_REASON_ERROR"] = 6] = "RESOLVE_REASON_ERROR";
|
|
775
775
|
ResolveReason$1[ResolveReason$1["RESOLVE_REASON_UNRECOGNIZED_TARGETING_RULE"] = 7] = "RESOLVE_REASON_UNRECOGNIZED_TARGETING_RULE";
|
|
776
776
|
ResolveReason$1[ResolveReason$1["RESOLVE_REASON_MATERIALIZATION_NOT_SUPPORTED"] = 8] = "RESOLVE_REASON_MATERIALIZATION_NOT_SUPPORTED";
|
|
777
|
+
ResolveReason$1[ResolveReason$1["RESOLVE_REASON_TYPE_MISMATCH"] = 9] = "RESOLVE_REASON_TYPE_MISMATCH";
|
|
778
|
+
ResolveReason$1[ResolveReason$1["RESOLVE_REASON_FLAG_NOT_FOUND"] = 10] = "RESOLVE_REASON_FLAG_NOT_FOUND";
|
|
777
779
|
ResolveReason$1[ResolveReason$1["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
|
|
778
780
|
return ResolveReason$1;
|
|
779
781
|
}({});
|
|
@@ -797,6 +799,10 @@ function resolveReasonFromJSON(object) {
|
|
|
797
799
|
case "RESOLVE_REASON_UNRECOGNIZED_TARGETING_RULE": return ResolveReason.RESOLVE_REASON_UNRECOGNIZED_TARGETING_RULE;
|
|
798
800
|
case 8:
|
|
799
801
|
case "RESOLVE_REASON_MATERIALIZATION_NOT_SUPPORTED": return ResolveReason.RESOLVE_REASON_MATERIALIZATION_NOT_SUPPORTED;
|
|
802
|
+
case 9:
|
|
803
|
+
case "RESOLVE_REASON_TYPE_MISMATCH": return ResolveReason.RESOLVE_REASON_TYPE_MISMATCH;
|
|
804
|
+
case 10:
|
|
805
|
+
case "RESOLVE_REASON_FLAG_NOT_FOUND": return ResolveReason.RESOLVE_REASON_FLAG_NOT_FOUND;
|
|
800
806
|
case -1:
|
|
801
807
|
case "UNRECOGNIZED":
|
|
802
808
|
default: return ResolveReason.UNRECOGNIZED;
|
|
@@ -813,6 +819,8 @@ function resolveReasonToJSON(object) {
|
|
|
813
819
|
case ResolveReason.RESOLVE_REASON_ERROR: return "RESOLVE_REASON_ERROR";
|
|
814
820
|
case ResolveReason.RESOLVE_REASON_UNRECOGNIZED_TARGETING_RULE: return "RESOLVE_REASON_UNRECOGNIZED_TARGETING_RULE";
|
|
815
821
|
case ResolveReason.RESOLVE_REASON_MATERIALIZATION_NOT_SUPPORTED: return "RESOLVE_REASON_MATERIALIZATION_NOT_SUPPORTED";
|
|
822
|
+
case ResolveReason.RESOLVE_REASON_TYPE_MISMATCH: return "RESOLVE_REASON_TYPE_MISMATCH";
|
|
823
|
+
case ResolveReason.RESOLVE_REASON_FLAG_NOT_FOUND: return "RESOLVE_REASON_FLAG_NOT_FOUND";
|
|
816
824
|
case ResolveReason.UNRECOGNIZED:
|
|
817
825
|
default: return "UNRECOGNIZED";
|
|
818
826
|
}
|
|
@@ -1410,7 +1418,7 @@ function isObject(value) {
|
|
|
1410
1418
|
function isSet$3(value) {
|
|
1411
1419
|
return value !== null && value !== void 0;
|
|
1412
1420
|
}
|
|
1413
|
-
const VERSION = "0.
|
|
1421
|
+
const VERSION = "0.11.0";
|
|
1414
1422
|
const NOOP_LOG_FN = Object.assign(() => {}, { enabled: false });
|
|
1415
1423
|
const debugBackend = loadDebug();
|
|
1416
1424
|
const logger$2 = new class LoggerImpl {
|
|
@@ -2550,6 +2558,90 @@ const Response$1 = {
|
|
|
2550
2558
|
return message;
|
|
2551
2559
|
}
|
|
2552
2560
|
};
|
|
2561
|
+
function createBasePrometheusSnapshotRequest() {
|
|
2562
|
+
return { instance: "" };
|
|
2563
|
+
}
|
|
2564
|
+
const PrometheusSnapshotRequest = {
|
|
2565
|
+
encode(message, writer = new BinaryWriter()) {
|
|
2566
|
+
if (message.instance !== "") writer.uint32(10).string(message.instance);
|
|
2567
|
+
return writer;
|
|
2568
|
+
},
|
|
2569
|
+
decode(input, length) {
|
|
2570
|
+
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
|
2571
|
+
const end = length === void 0 ? reader.len : reader.pos + length;
|
|
2572
|
+
const message = createBasePrometheusSnapshotRequest();
|
|
2573
|
+
while (reader.pos < end) {
|
|
2574
|
+
const tag = reader.uint32();
|
|
2575
|
+
switch (tag >>> 3) {
|
|
2576
|
+
case 1:
|
|
2577
|
+
if (tag !== 10) break;
|
|
2578
|
+
message.instance = reader.string();
|
|
2579
|
+
continue;
|
|
2580
|
+
}
|
|
2581
|
+
if ((tag & 7) === 4 || tag === 0) break;
|
|
2582
|
+
reader.skip(tag & 7);
|
|
2583
|
+
}
|
|
2584
|
+
return message;
|
|
2585
|
+
},
|
|
2586
|
+
fromJSON(object) {
|
|
2587
|
+
return { instance: isSet$1(object.instance) ? globalThis.String(object.instance) : "" };
|
|
2588
|
+
},
|
|
2589
|
+
toJSON(message) {
|
|
2590
|
+
const obj = {};
|
|
2591
|
+
if (message.instance !== "") obj.instance = message.instance;
|
|
2592
|
+
return obj;
|
|
2593
|
+
},
|
|
2594
|
+
create(base) {
|
|
2595
|
+
return PrometheusSnapshotRequest.fromPartial(base ?? {});
|
|
2596
|
+
},
|
|
2597
|
+
fromPartial(object) {
|
|
2598
|
+
const message = createBasePrometheusSnapshotRequest();
|
|
2599
|
+
message.instance = object.instance ?? "";
|
|
2600
|
+
return message;
|
|
2601
|
+
}
|
|
2602
|
+
};
|
|
2603
|
+
function createBasePrometheusSnapshotResponse() {
|
|
2604
|
+
return { text: "" };
|
|
2605
|
+
}
|
|
2606
|
+
const PrometheusSnapshotResponse = {
|
|
2607
|
+
encode(message, writer = new BinaryWriter()) {
|
|
2608
|
+
if (message.text !== "") writer.uint32(10).string(message.text);
|
|
2609
|
+
return writer;
|
|
2610
|
+
},
|
|
2611
|
+
decode(input, length) {
|
|
2612
|
+
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
|
2613
|
+
const end = length === void 0 ? reader.len : reader.pos + length;
|
|
2614
|
+
const message = createBasePrometheusSnapshotResponse();
|
|
2615
|
+
while (reader.pos < end) {
|
|
2616
|
+
const tag = reader.uint32();
|
|
2617
|
+
switch (tag >>> 3) {
|
|
2618
|
+
case 1:
|
|
2619
|
+
if (tag !== 10) break;
|
|
2620
|
+
message.text = reader.string();
|
|
2621
|
+
continue;
|
|
2622
|
+
}
|
|
2623
|
+
if ((tag & 7) === 4 || tag === 0) break;
|
|
2624
|
+
reader.skip(tag & 7);
|
|
2625
|
+
}
|
|
2626
|
+
return message;
|
|
2627
|
+
},
|
|
2628
|
+
fromJSON(object) {
|
|
2629
|
+
return { text: isSet$1(object.text) ? globalThis.String(object.text) : "" };
|
|
2630
|
+
},
|
|
2631
|
+
toJSON(message) {
|
|
2632
|
+
const obj = {};
|
|
2633
|
+
if (message.text !== "") obj.text = message.text;
|
|
2634
|
+
return obj;
|
|
2635
|
+
},
|
|
2636
|
+
create(base) {
|
|
2637
|
+
return PrometheusSnapshotResponse.fromPartial(base ?? {});
|
|
2638
|
+
},
|
|
2639
|
+
fromPartial(object) {
|
|
2640
|
+
const message = createBasePrometheusSnapshotResponse();
|
|
2641
|
+
message.text = object.text ?? "";
|
|
2642
|
+
return message;
|
|
2643
|
+
}
|
|
2644
|
+
};
|
|
2553
2645
|
function bytesFromBase64$2(b64) {
|
|
2554
2646
|
if (globalThis.Buffer) return Uint8Array.from(globalThis.Buffer.from(b64, "base64"));
|
|
2555
2647
|
else {
|
|
@@ -2629,6 +2721,16 @@ function resolve(bundle, flagKey, defaultValue, logger$4) {
|
|
|
2629
2721
|
shouldApply: false
|
|
2630
2722
|
};
|
|
2631
2723
|
}
|
|
2724
|
+
if (flag.reason === "MATERIALIZATION_NOT_SUPPORTED") {
|
|
2725
|
+
logger$4?.warn("Flag '%s' requires materializations but no materialization store is configured. Pass a MaterializationStore implementation or: 'CONFIDENCE_REMOTE_STORE' to createConfidenceServerProvider()", flagName);
|
|
2726
|
+
return {
|
|
2727
|
+
reason: "ERROR",
|
|
2728
|
+
errorCode: ErrorCode.GENERAL,
|
|
2729
|
+
errorMessage: `Flag '${flagName}' requires materializations. Configure a materialization store.`,
|
|
2730
|
+
value: defaultValue,
|
|
2731
|
+
shouldApply: false
|
|
2732
|
+
};
|
|
2733
|
+
}
|
|
2632
2734
|
let value = flag.value;
|
|
2633
2735
|
for (let i = 0; i < path.length; i++) {
|
|
2634
2736
|
if (value === null || typeof value !== "object" || Array.isArray(value)) return {
|
|
@@ -2682,6 +2784,7 @@ function convertReason(reason) {
|
|
|
2682
2784
|
case ResolveReason.RESOLVE_REASON_TARGETING_KEY_ERROR: return "TARGETING_KEY_ERROR";
|
|
2683
2785
|
case ResolveReason.RESOLVE_REASON_NO_TREATMENT_MATCH: return "NO_TREATMENT_MATCH";
|
|
2684
2786
|
case ResolveReason.RESOLVE_REASON_UNRECOGNIZED_TARGETING_RULE: return "ERROR";
|
|
2787
|
+
case ResolveReason.RESOLVE_REASON_MATERIALIZATION_NOT_SUPPORTED: return "MATERIALIZATION_NOT_SUPPORTED";
|
|
2685
2788
|
default: return "UNSPECIFIED";
|
|
2686
2789
|
}
|
|
2687
2790
|
}
|
|
@@ -2777,10 +2880,28 @@ var ConfidenceServerProviderLocal = class ConfidenceServerProviderLocal {
|
|
|
2777
2880
|
}
|
|
2778
2881
|
}
|
|
2779
2882
|
async evaluate(flagKey, defaultValue, context) {
|
|
2883
|
+
const startMs = performance.now();
|
|
2780
2884
|
try {
|
|
2781
2885
|
const [flagName] = flagKey.split(".", 1);
|
|
2782
2886
|
const resolution = await this.resolve(context, [flagName], true);
|
|
2783
|
-
|
|
2887
|
+
const result = resolve(resolution, flagKey, defaultValue, logger$1);
|
|
2888
|
+
const latencyUs = Math.round((performance.now() - startMs) * 1e3);
|
|
2889
|
+
let reason;
|
|
2890
|
+
if (resolution.errorCode) reason = ResolveReason.RESOLVE_REASON_ERROR;
|
|
2891
|
+
else {
|
|
2892
|
+
const [flagNameForTelemetry] = flagKey.split(".", 1);
|
|
2893
|
+
if (resolution.flags[flagNameForTelemetry]?.reason === "MATERIALIZATION_NOT_SUPPORTED") reason = ResolveReason.RESOLVE_REASON_MATERIALIZATION_NOT_SUPPORTED;
|
|
2894
|
+
else if (result.errorCode === ErrorCode.FLAG_NOT_FOUND) reason = ResolveReason.RESOLVE_REASON_FLAG_NOT_FOUND;
|
|
2895
|
+
else if (result.errorCode === ErrorCode.TYPE_MISMATCH) reason = ResolveReason.RESOLVE_REASON_TYPE_MISMATCH;
|
|
2896
|
+
else reason = reasonStringToEnum(result.reason);
|
|
2897
|
+
}
|
|
2898
|
+
try {
|
|
2899
|
+
this.resolver.registerResolve({
|
|
2900
|
+
reason,
|
|
2901
|
+
latencyUs
|
|
2902
|
+
});
|
|
2903
|
+
} catch {}
|
|
2904
|
+
return result;
|
|
2784
2905
|
} finally {
|
|
2785
2906
|
this.flushAssigned();
|
|
2786
2907
|
}
|
|
@@ -2887,6 +3008,9 @@ var ConfidenceServerProviderLocal = class ConfidenceServerProviderLocal {
|
|
|
2887
3008
|
resolveStringEvaluation(flagKey, defaultValue, context) {
|
|
2888
3009
|
return Promise.resolve(this.evaluate(flagKey, defaultValue, context));
|
|
2889
3010
|
}
|
|
3011
|
+
getPrometheusMetrics(_request) {
|
|
3012
|
+
return this.resolver.prometheusSnapshot("0");
|
|
3013
|
+
}
|
|
2890
3014
|
applyFlag(resolveToken, flagName) {
|
|
2891
3015
|
const request = {
|
|
2892
3016
|
flags: [{
|
|
@@ -2904,6 +3028,17 @@ var ConfidenceServerProviderLocal = class ConfidenceServerProviderLocal {
|
|
|
2904
3028
|
this.resolver.applyFlags(request);
|
|
2905
3029
|
}
|
|
2906
3030
|
};
|
|
3031
|
+
function reasonStringToEnum(reason) {
|
|
3032
|
+
switch (reason) {
|
|
3033
|
+
case "MATCH": return ResolveReason.RESOLVE_REASON_MATCH;
|
|
3034
|
+
case "NO_SEGMENT_MATCH": return ResolveReason.RESOLVE_REASON_NO_SEGMENT_MATCH;
|
|
3035
|
+
case "NO_TREATMENT_MATCH": return ResolveReason.RESOLVE_REASON_NO_TREATMENT_MATCH;
|
|
3036
|
+
case "FLAG_ARCHIVED": return ResolveReason.RESOLVE_REASON_FLAG_ARCHIVED;
|
|
3037
|
+
case "TARGETING_KEY_ERROR": return ResolveReason.RESOLVE_REASON_TARGETING_KEY_ERROR;
|
|
3038
|
+
case "ERROR": return ResolveReason.RESOLVE_REASON_ERROR;
|
|
3039
|
+
default: return ResolveReason.RESOLVE_REASON_UNSPECIFIED;
|
|
3040
|
+
}
|
|
3041
|
+
}
|
|
2907
3042
|
function createBaseResolveProcessRequest() {
|
|
2908
3043
|
return {
|
|
2909
3044
|
deferredMaterializations: void 0,
|
|
@@ -3325,6 +3460,61 @@ const MaterializationRecord = {
|
|
|
3325
3460
|
return message;
|
|
3326
3461
|
}
|
|
3327
3462
|
};
|
|
3463
|
+
function createBaseRegisterResolveRequest() {
|
|
3464
|
+
return {
|
|
3465
|
+
reason: 0,
|
|
3466
|
+
latencyUs: 0
|
|
3467
|
+
};
|
|
3468
|
+
}
|
|
3469
|
+
const RegisterResolveRequest = {
|
|
3470
|
+
encode(message, writer = new BinaryWriter()) {
|
|
3471
|
+
if (message.reason !== 0) writer.uint32(8).int32(message.reason);
|
|
3472
|
+
if (message.latencyUs !== 0) writer.uint32(16).uint32(message.latencyUs);
|
|
3473
|
+
return writer;
|
|
3474
|
+
},
|
|
3475
|
+
decode(input, length) {
|
|
3476
|
+
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
|
3477
|
+
const end = length === void 0 ? reader.len : reader.pos + length;
|
|
3478
|
+
const message = createBaseRegisterResolveRequest();
|
|
3479
|
+
while (reader.pos < end) {
|
|
3480
|
+
const tag = reader.uint32();
|
|
3481
|
+
switch (tag >>> 3) {
|
|
3482
|
+
case 1:
|
|
3483
|
+
if (tag !== 8) break;
|
|
3484
|
+
message.reason = reader.int32();
|
|
3485
|
+
continue;
|
|
3486
|
+
case 2:
|
|
3487
|
+
if (tag !== 16) break;
|
|
3488
|
+
message.latencyUs = reader.uint32();
|
|
3489
|
+
continue;
|
|
3490
|
+
}
|
|
3491
|
+
if ((tag & 7) === 4 || tag === 0) break;
|
|
3492
|
+
reader.skip(tag & 7);
|
|
3493
|
+
}
|
|
3494
|
+
return message;
|
|
3495
|
+
},
|
|
3496
|
+
fromJSON(object) {
|
|
3497
|
+
return {
|
|
3498
|
+
reason: isSet(object.reason) ? resolveReasonFromJSON(object.reason) : 0,
|
|
3499
|
+
latencyUs: isSet(object.latencyUs) ? globalThis.Number(object.latencyUs) : 0
|
|
3500
|
+
};
|
|
3501
|
+
},
|
|
3502
|
+
toJSON(message) {
|
|
3503
|
+
const obj = {};
|
|
3504
|
+
if (message.reason !== 0) obj.reason = resolveReasonToJSON(message.reason);
|
|
3505
|
+
if (message.latencyUs !== 0) obj.latencyUs = Math.round(message.latencyUs);
|
|
3506
|
+
return obj;
|
|
3507
|
+
},
|
|
3508
|
+
create(base) {
|
|
3509
|
+
return RegisterResolveRequest.fromPartial(base ?? {});
|
|
3510
|
+
},
|
|
3511
|
+
fromPartial(object) {
|
|
3512
|
+
const message = createBaseRegisterResolveRequest();
|
|
3513
|
+
message.reason = object.reason ?? 0;
|
|
3514
|
+
message.latencyUs = object.latencyUs ?? 0;
|
|
3515
|
+
return message;
|
|
3516
|
+
}
|
|
3517
|
+
};
|
|
3328
3518
|
function bytesFromBase64(b64) {
|
|
3329
3519
|
if (globalThis.Buffer) return Uint8Array.from(globalThis.Buffer.from(b64, "base64"));
|
|
3330
3520
|
else {
|
|
@@ -3352,10 +3542,12 @@ const EXPORT_FN_NAMES = [
|
|
|
3352
3542
|
"wasm_msg_alloc",
|
|
3353
3543
|
"wasm_msg_free",
|
|
3354
3544
|
"wasm_msg_guest_resolve_flags",
|
|
3545
|
+
"wasm_msg_guest_register_resolve",
|
|
3355
3546
|
"wasm_msg_guest_set_resolver_state",
|
|
3356
3547
|
"wasm_msg_guest_bounded_flush_logs",
|
|
3357
3548
|
"wasm_msg_guest_bounded_flush_assign",
|
|
3358
|
-
"wasm_msg_guest_apply_flags"
|
|
3549
|
+
"wasm_msg_guest_apply_flags",
|
|
3550
|
+
"wasm_msg_guest_prometheus_snapshot"
|
|
3359
3551
|
];
|
|
3360
3552
|
function verifyExports(exports) {
|
|
3361
3553
|
for (const fnName of EXPORT_FN_NAMES) if (typeof exports[fnName] !== "function") throw new Error(`Expected Function export "${fnName}" found ${exports[fnName]}`);
|
|
@@ -3382,6 +3574,11 @@ var UnsafeWasmResolver = class {
|
|
|
3382
3574
|
const resPtr = this.exports.wasm_msg_guest_resolve_flags(reqPtr);
|
|
3383
3575
|
return this.consumeResponse(resPtr, ResolveProcessResponse);
|
|
3384
3576
|
}
|
|
3577
|
+
registerResolve(request) {
|
|
3578
|
+
const reqPtr = this.transferRequest(request, RegisterResolveRequest);
|
|
3579
|
+
const resPtr = this.exports.wasm_msg_guest_register_resolve(reqPtr);
|
|
3580
|
+
this.consumeResponse(resPtr, Void);
|
|
3581
|
+
}
|
|
3385
3582
|
setResolverState(request) {
|
|
3386
3583
|
const reqPtr = this.transferRequest(request, SetResolverStateRequest);
|
|
3387
3584
|
const resPtr = this.exports.wasm_msg_guest_set_resolver_state(reqPtr);
|
|
@@ -3404,6 +3601,11 @@ var UnsafeWasmResolver = class {
|
|
|
3404
3601
|
const resPtr = this.exports.wasm_msg_guest_apply_flags(reqPtr);
|
|
3405
3602
|
this.consumeResponse(resPtr, Void);
|
|
3406
3603
|
}
|
|
3604
|
+
prometheusSnapshot(instance) {
|
|
3605
|
+
const reqPtr = this.transferRequest({ instance }, PrometheusSnapshotRequest);
|
|
3606
|
+
const resPtr = this.exports.wasm_msg_guest_prometheus_snapshot(reqPtr);
|
|
3607
|
+
return this.consumeResponse(resPtr, PrometheusSnapshotResponse).text;
|
|
3608
|
+
}
|
|
3407
3609
|
transferRequest(value, codec) {
|
|
3408
3610
|
const data = codec.encode(value).finish();
|
|
3409
3611
|
return this.transfer({ data }, Request);
|
|
@@ -3461,6 +3663,11 @@ var WasmResolver = class {
|
|
|
3461
3663
|
throw error$1;
|
|
3462
3664
|
}
|
|
3463
3665
|
}
|
|
3666
|
+
registerResolve(request) {
|
|
3667
|
+
try {
|
|
3668
|
+
this.delegate.registerResolve(request);
|
|
3669
|
+
} catch {}
|
|
3670
|
+
}
|
|
3464
3671
|
setResolverState(request) {
|
|
3465
3672
|
this.currentState = request;
|
|
3466
3673
|
try {
|
|
@@ -3498,6 +3705,14 @@ var WasmResolver = class {
|
|
|
3498
3705
|
throw error$1;
|
|
3499
3706
|
}
|
|
3500
3707
|
}
|
|
3708
|
+
prometheusSnapshot(instance) {
|
|
3709
|
+
try {
|
|
3710
|
+
return this.delegate.prometheusSnapshot(instance);
|
|
3711
|
+
} catch (error$1) {
|
|
3712
|
+
logger.error("prometheus snapshot failed:", error$1);
|
|
3713
|
+
return "";
|
|
3714
|
+
}
|
|
3715
|
+
}
|
|
3501
3716
|
};
|
|
3502
3717
|
let resolver = null;
|
|
3503
3718
|
function createConfidenceServerProvider({ wasmUrl,...options }) {
|
package/dist/index.inlined.d.ts
CHANGED
|
@@ -82,6 +82,10 @@ declare enum ResolveReason {
|
|
|
82
82
|
RESOLVE_REASON_UNRECOGNIZED_TARGETING_RULE = 7,
|
|
83
83
|
/** RESOLVE_REASON_MATERIALIZATION_NOT_SUPPORTED - The flag could not be resolved because a rule is using materialization */
|
|
84
84
|
RESOLVE_REASON_MATERIALIZATION_NOT_SUPPORTED = 8,
|
|
85
|
+
/** RESOLVE_REASON_TYPE_MISMATCH - The resolved value type does not match the type requested by the SDK */
|
|
86
|
+
RESOLVE_REASON_TYPE_MISMATCH = 9,
|
|
87
|
+
/** RESOLVE_REASON_FLAG_NOT_FOUND - The flag was not found in the resolve response */
|
|
88
|
+
RESOLVE_REASON_FLAG_NOT_FOUND = 10,
|
|
85
89
|
UNRECOGNIZED = -1,
|
|
86
90
|
}
|
|
87
91
|
declare enum SdkId {
|
|
@@ -273,6 +277,10 @@ interface MaterializationRecord {
|
|
|
273
277
|
rule: string;
|
|
274
278
|
variant: string;
|
|
275
279
|
}
|
|
280
|
+
interface RegisterResolveRequest {
|
|
281
|
+
reason: ResolveReason;
|
|
282
|
+
latencyUs: number;
|
|
283
|
+
}
|
|
276
284
|
declare const ResolveProcessRequest: MessageFns$2<ResolveProcessRequest>;
|
|
277
285
|
declare const ResolveProcessRequest_StaticMaterializations: MessageFns$2<ResolveProcessRequest_StaticMaterializations>;
|
|
278
286
|
declare const ResolveProcessRequest_Resume: MessageFns$2<ResolveProcessRequest_Resume>;
|
|
@@ -280,6 +288,7 @@ declare const ResolveProcessResponse: MessageFns$2<ResolveProcessResponse>;
|
|
|
280
288
|
declare const ResolveProcessResponse_Resolved: MessageFns$2<ResolveProcessResponse_Resolved>;
|
|
281
289
|
declare const ResolveProcessResponse_Suspended: MessageFns$2<ResolveProcessResponse_Suspended>;
|
|
282
290
|
declare const MaterializationRecord: MessageFns$2<MaterializationRecord>;
|
|
291
|
+
declare const RegisterResolveRequest: MessageFns$2<RegisterResolveRequest>;
|
|
283
292
|
type Builtin$2 = Date | Function | Uint8Array | string | number | boolean | undefined;
|
|
284
293
|
type DeepPartial$2<T> = T extends Builtin$2 ? T : T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial$2<U>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial$2<U>> : T extends {} ? { [K in keyof T]?: DeepPartial$2<T[K]> } : Partial<T>;
|
|
285
294
|
type KeysOfUnion$2<T> = T extends T ? keyof T : never;
|
|
@@ -316,10 +325,12 @@ interface MessageFns$1<T> {
|
|
|
316
325
|
//#region src/LocalResolver.d.ts
|
|
317
326
|
interface LocalResolver {
|
|
318
327
|
resolveProcess(request: ResolveProcessRequest): ResolveProcessResponse;
|
|
328
|
+
registerResolve(request: RegisterResolveRequest): void;
|
|
319
329
|
setResolverState(request: SetResolverStateRequest): void;
|
|
320
330
|
flushLogs(): Uint8Array;
|
|
321
331
|
flushAssigned(): Uint8Array;
|
|
322
332
|
applyFlags(request: ApplyFlagsRequest): void;
|
|
333
|
+
prometheusSnapshot(instance: string): string;
|
|
323
334
|
}
|
|
324
335
|
//#endregion
|
|
325
336
|
//#region src/proto/confidence/flags/resolver/v1/internal_api.d.ts
|
|
@@ -429,7 +440,7 @@ interface MaterializationStore {
|
|
|
429
440
|
}
|
|
430
441
|
//#endregion
|
|
431
442
|
//#region src/types.d.ts
|
|
432
|
-
type ResolutionReason = "ERROR" | "FLAG_ARCHIVED" | "MATCH" | "NO_SEGMENT_MATCH" | "TARGETING_KEY_ERROR" | "NO_TREATMENT_MATCH" | "UNSPECIFIED";
|
|
443
|
+
type ResolutionReason = "ERROR" | "FLAG_ARCHIVED" | "MATCH" | "NO_SEGMENT_MATCH" | "TARGETING_KEY_ERROR" | "NO_TREATMENT_MATCH" | "MATERIALIZATION_NOT_SUPPORTED" | "UNSPECIFIED";
|
|
433
444
|
declare enum ErrorCode {
|
|
434
445
|
PROVIDER_NOT_READY = "PROVIDER_NOT_READY",
|
|
435
446
|
PROVIDER_FATAL = "PROVIDER_FATAL",
|
|
@@ -462,6 +473,12 @@ interface FlagBundle {
|
|
|
462
473
|
//#endregion
|
|
463
474
|
//#region src/ConfidenceServerProviderLocal.d.ts
|
|
464
475
|
type FlagBundle$1 = FlagBundle;
|
|
476
|
+
/**
|
|
477
|
+
* Configuration for {@link ConfidenceServerProviderLocal.getPrometheusMetrics}.
|
|
478
|
+
*
|
|
479
|
+
* @experimental This API is subject to change.
|
|
480
|
+
*/
|
|
481
|
+
interface SnapshotConfig {}
|
|
465
482
|
interface ProviderOptions {
|
|
466
483
|
flagClientSecret: string;
|
|
467
484
|
initializeTimeout?: number;
|
|
@@ -513,6 +530,12 @@ declare class ConfidenceServerProviderLocal implements Provider {
|
|
|
513
530
|
/** Resolves with an evaluation of a String flag */
|
|
514
531
|
resolveStringEvaluation(flagKey: string, defaultValue: string, context: EvaluationContext): Promise<ResolutionDetails<string>>;
|
|
515
532
|
/**
|
|
533
|
+
* Returns a Prometheus metrics snapshot from the WASM resolver.
|
|
534
|
+
*
|
|
535
|
+
* @experimental This API is subject to change.
|
|
536
|
+
*/
|
|
537
|
+
getPrometheusMetrics(_request?: SnapshotConfig): string;
|
|
538
|
+
/**
|
|
516
539
|
* Applies a previously resolved flag, logging that it was used/exposed.
|
|
517
540
|
* Call this when a flag value is actually rendered or used in the client.
|
|
518
541
|
* @param resolveToken - Base64-encoded resolve token from the flag bundle
|
|
@@ -525,4 +548,4 @@ declare class ConfidenceServerProviderLocal implements Provider {
|
|
|
525
548
|
type ProviderOptionsExt = ProviderOptions;
|
|
526
549
|
declare function createConfidenceServerProvider(options: ProviderOptions): ConfidenceServerProviderLocal;
|
|
527
550
|
//#endregion
|
|
528
|
-
export { type MaterializationStore, ProviderOptionsExt, createConfidenceServerProvider };
|
|
551
|
+
export { type MaterializationStore, ProviderOptionsExt, type SnapshotConfig, createConfidenceServerProvider };
|