@spotify-confidence/openfeature-server-provider-local 0.10.0 → 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.
@@ -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;
@@ -297,6 +306,7 @@ interface MessageFns$2<T> {
297
306
  interface SetResolverStateRequest {
298
307
  state: Uint8Array;
299
308
  accountId: string;
309
+ sdk?: Sdk | undefined;
300
310
  }
301
311
  declare const SetResolverStateRequest: MessageFns$1<SetResolverStateRequest>;
302
312
  type Builtin$1 = Date | Function | Uint8Array | string | number | boolean | undefined;
@@ -315,10 +325,12 @@ interface MessageFns$1<T> {
315
325
  //#region src/LocalResolver.d.ts
316
326
  interface LocalResolver {
317
327
  resolveProcess(request: ResolveProcessRequest): ResolveProcessResponse;
328
+ registerResolve(request: RegisterResolveRequest): void;
318
329
  setResolverState(request: SetResolverStateRequest): void;
319
330
  flushLogs(): Uint8Array;
320
331
  flushAssigned(): Uint8Array;
321
332
  applyFlags(request: ApplyFlagsRequest): void;
333
+ prometheusSnapshot(instance: string): string;
322
334
  }
323
335
  //#endregion
324
336
  //#region src/proto/confidence/flags/resolver/v1/internal_api.d.ts
@@ -428,7 +440,7 @@ interface MaterializationStore {
428
440
  }
429
441
  //#endregion
430
442
  //#region src/types.d.ts
431
- 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";
432
444
  declare enum ErrorCode {
433
445
  PROVIDER_NOT_READY = "PROVIDER_NOT_READY",
434
446
  PROVIDER_FATAL = "PROVIDER_FATAL",
@@ -461,6 +473,12 @@ interface FlagBundle {
461
473
  //#endregion
462
474
  //#region src/ConfidenceServerProviderLocal.d.ts
463
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 {}
464
482
  interface ProviderOptions {
465
483
  flagClientSecret: string;
466
484
  initializeTimeout?: number;
@@ -512,6 +530,12 @@ declare class ConfidenceServerProviderLocal implements Provider {
512
530
  /** Resolves with an evaluation of a String flag */
513
531
  resolveStringEvaluation(flagKey: string, defaultValue: string, context: EvaluationContext): Promise<ResolutionDetails<string>>;
514
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
+ /**
515
539
  * Applies a previously resolved flag, logging that it was used/exposed.
516
540
  * Call this when a flag value is actually rendered or used in the client.
517
541
  * @param resolveToken - Base64-encoded resolve token from the flag bundle
@@ -529,4 +553,4 @@ declare function createConfidenceServerProvider({
529
553
  ...options
530
554
  }: ProviderOptionsExt): ConfidenceServerProviderLocal;
531
555
  //#endregion
532
- export { type MaterializationStore, ProviderOptionsExt, createConfidenceServerProvider };
556
+ export { type MaterializationStore, ProviderOptionsExt, type SnapshotConfig, createConfidenceServerProvider };
@@ -777,6 +777,8 @@ let ResolveReason = /* @__PURE__ */ function(ResolveReason$1) {
777
777
  ResolveReason$1[ResolveReason$1["RESOLVE_REASON_ERROR"] = 6] = "RESOLVE_REASON_ERROR";
778
778
  ResolveReason$1[ResolveReason$1["RESOLVE_REASON_UNRECOGNIZED_TARGETING_RULE"] = 7] = "RESOLVE_REASON_UNRECOGNIZED_TARGETING_RULE";
779
779
  ResolveReason$1[ResolveReason$1["RESOLVE_REASON_MATERIALIZATION_NOT_SUPPORTED"] = 8] = "RESOLVE_REASON_MATERIALIZATION_NOT_SUPPORTED";
780
+ ResolveReason$1[ResolveReason$1["RESOLVE_REASON_TYPE_MISMATCH"] = 9] = "RESOLVE_REASON_TYPE_MISMATCH";
781
+ ResolveReason$1[ResolveReason$1["RESOLVE_REASON_FLAG_NOT_FOUND"] = 10] = "RESOLVE_REASON_FLAG_NOT_FOUND";
780
782
  ResolveReason$1[ResolveReason$1["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
781
783
  return ResolveReason$1;
782
784
  }({});
@@ -800,6 +802,10 @@ function resolveReasonFromJSON(object) {
800
802
  case "RESOLVE_REASON_UNRECOGNIZED_TARGETING_RULE": return ResolveReason.RESOLVE_REASON_UNRECOGNIZED_TARGETING_RULE;
801
803
  case 8:
802
804
  case "RESOLVE_REASON_MATERIALIZATION_NOT_SUPPORTED": return ResolveReason.RESOLVE_REASON_MATERIALIZATION_NOT_SUPPORTED;
805
+ case 9:
806
+ case "RESOLVE_REASON_TYPE_MISMATCH": return ResolveReason.RESOLVE_REASON_TYPE_MISMATCH;
807
+ case 10:
808
+ case "RESOLVE_REASON_FLAG_NOT_FOUND": return ResolveReason.RESOLVE_REASON_FLAG_NOT_FOUND;
803
809
  case -1:
804
810
  case "UNRECOGNIZED":
805
811
  default: return ResolveReason.UNRECOGNIZED;
@@ -816,6 +822,8 @@ function resolveReasonToJSON(object) {
816
822
  case ResolveReason.RESOLVE_REASON_ERROR: return "RESOLVE_REASON_ERROR";
817
823
  case ResolveReason.RESOLVE_REASON_UNRECOGNIZED_TARGETING_RULE: return "RESOLVE_REASON_UNRECOGNIZED_TARGETING_RULE";
818
824
  case ResolveReason.RESOLVE_REASON_MATERIALIZATION_NOT_SUPPORTED: return "RESOLVE_REASON_MATERIALIZATION_NOT_SUPPORTED";
825
+ case ResolveReason.RESOLVE_REASON_TYPE_MISMATCH: return "RESOLVE_REASON_TYPE_MISMATCH";
826
+ case ResolveReason.RESOLVE_REASON_FLAG_NOT_FOUND: return "RESOLVE_REASON_FLAG_NOT_FOUND";
819
827
  case ResolveReason.UNRECOGNIZED:
820
828
  default: return "UNRECOGNIZED";
821
829
  }
@@ -1413,7 +1421,7 @@ function isObject(value) {
1413
1421
  function isSet$3(value) {
1414
1422
  return value !== null && value !== void 0;
1415
1423
  }
1416
- const VERSION = "0.10.0";
1424
+ const VERSION = "0.11.0";
1417
1425
  const NOOP_LOG_FN = Object.assign(() => {}, { enabled: false });
1418
1426
  const debugBackend = loadDebug();
1419
1427
  const logger$2 = new class LoggerImpl {
@@ -2395,13 +2403,15 @@ const Void = {
2395
2403
  function createBaseSetResolverStateRequest() {
2396
2404
  return {
2397
2405
  state: new Uint8Array(0),
2398
- accountId: ""
2406
+ accountId: "",
2407
+ sdk: void 0
2399
2408
  };
2400
2409
  }
2401
2410
  const SetResolverStateRequest = {
2402
2411
  encode(message, writer = new BinaryWriter()) {
2403
2412
  if (message.state.length !== 0) writer.uint32(10).bytes(message.state);
2404
2413
  if (message.accountId !== "") writer.uint32(18).string(message.accountId);
2414
+ if (message.sdk !== void 0) Sdk.encode(message.sdk, writer.uint32(26).fork()).join();
2405
2415
  return writer;
2406
2416
  },
2407
2417
  decode(input, length) {
@@ -2419,6 +2429,10 @@ const SetResolverStateRequest = {
2419
2429
  if (tag !== 18) break;
2420
2430
  message.accountId = reader.string();
2421
2431
  continue;
2432
+ case 3:
2433
+ if (tag !== 26) break;
2434
+ message.sdk = Sdk.decode(reader, reader.uint32());
2435
+ continue;
2422
2436
  }
2423
2437
  if ((tag & 7) === 4 || tag === 0) break;
2424
2438
  reader.skip(tag & 7);
@@ -2428,13 +2442,15 @@ const SetResolverStateRequest = {
2428
2442
  fromJSON(object) {
2429
2443
  return {
2430
2444
  state: isSet$1(object.state) ? bytesFromBase64$2(object.state) : new Uint8Array(0),
2431
- accountId: isSet$1(object.accountId) ? globalThis.String(object.accountId) : ""
2445
+ accountId: isSet$1(object.accountId) ? globalThis.String(object.accountId) : "",
2446
+ sdk: isSet$1(object.sdk) ? Sdk.fromJSON(object.sdk) : void 0
2432
2447
  };
2433
2448
  },
2434
2449
  toJSON(message) {
2435
2450
  const obj = {};
2436
2451
  if (message.state.length !== 0) obj.state = base64FromBytes$2(message.state);
2437
2452
  if (message.accountId !== "") obj.accountId = message.accountId;
2453
+ if (message.sdk !== void 0) obj.sdk = Sdk.toJSON(message.sdk);
2438
2454
  return obj;
2439
2455
  },
2440
2456
  create(base) {
@@ -2444,6 +2460,7 @@ const SetResolverStateRequest = {
2444
2460
  const message = createBaseSetResolverStateRequest();
2445
2461
  message.state = object.state ?? new Uint8Array(0);
2446
2462
  message.accountId = object.accountId ?? "";
2463
+ message.sdk = object.sdk !== void 0 && object.sdk !== null ? Sdk.fromPartial(object.sdk) : void 0;
2447
2464
  return message;
2448
2465
  }
2449
2466
  };
@@ -2544,6 +2561,90 @@ const Response$1 = {
2544
2561
  return message;
2545
2562
  }
2546
2563
  };
2564
+ function createBasePrometheusSnapshotRequest() {
2565
+ return { instance: "" };
2566
+ }
2567
+ const PrometheusSnapshotRequest = {
2568
+ encode(message, writer = new BinaryWriter()) {
2569
+ if (message.instance !== "") writer.uint32(10).string(message.instance);
2570
+ return writer;
2571
+ },
2572
+ decode(input, length) {
2573
+ const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
2574
+ const end = length === void 0 ? reader.len : reader.pos + length;
2575
+ const message = createBasePrometheusSnapshotRequest();
2576
+ while (reader.pos < end) {
2577
+ const tag = reader.uint32();
2578
+ switch (tag >>> 3) {
2579
+ case 1:
2580
+ if (tag !== 10) break;
2581
+ message.instance = reader.string();
2582
+ continue;
2583
+ }
2584
+ if ((tag & 7) === 4 || tag === 0) break;
2585
+ reader.skip(tag & 7);
2586
+ }
2587
+ return message;
2588
+ },
2589
+ fromJSON(object) {
2590
+ return { instance: isSet$1(object.instance) ? globalThis.String(object.instance) : "" };
2591
+ },
2592
+ toJSON(message) {
2593
+ const obj = {};
2594
+ if (message.instance !== "") obj.instance = message.instance;
2595
+ return obj;
2596
+ },
2597
+ create(base) {
2598
+ return PrometheusSnapshotRequest.fromPartial(base ?? {});
2599
+ },
2600
+ fromPartial(object) {
2601
+ const message = createBasePrometheusSnapshotRequest();
2602
+ message.instance = object.instance ?? "";
2603
+ return message;
2604
+ }
2605
+ };
2606
+ function createBasePrometheusSnapshotResponse() {
2607
+ return { text: "" };
2608
+ }
2609
+ const PrometheusSnapshotResponse = {
2610
+ encode(message, writer = new BinaryWriter()) {
2611
+ if (message.text !== "") writer.uint32(10).string(message.text);
2612
+ return writer;
2613
+ },
2614
+ decode(input, length) {
2615
+ const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
2616
+ const end = length === void 0 ? reader.len : reader.pos + length;
2617
+ const message = createBasePrometheusSnapshotResponse();
2618
+ while (reader.pos < end) {
2619
+ const tag = reader.uint32();
2620
+ switch (tag >>> 3) {
2621
+ case 1:
2622
+ if (tag !== 10) break;
2623
+ message.text = reader.string();
2624
+ continue;
2625
+ }
2626
+ if ((tag & 7) === 4 || tag === 0) break;
2627
+ reader.skip(tag & 7);
2628
+ }
2629
+ return message;
2630
+ },
2631
+ fromJSON(object) {
2632
+ return { text: isSet$1(object.text) ? globalThis.String(object.text) : "" };
2633
+ },
2634
+ toJSON(message) {
2635
+ const obj = {};
2636
+ if (message.text !== "") obj.text = message.text;
2637
+ return obj;
2638
+ },
2639
+ create(base) {
2640
+ return PrometheusSnapshotResponse.fromPartial(base ?? {});
2641
+ },
2642
+ fromPartial(object) {
2643
+ const message = createBasePrometheusSnapshotResponse();
2644
+ message.text = object.text ?? "";
2645
+ return message;
2646
+ }
2647
+ };
2547
2648
  function bytesFromBase64$2(b64) {
2548
2649
  if (globalThis.Buffer) return Uint8Array.from(globalThis.Buffer.from(b64, "base64"));
2549
2650
  else {
@@ -2623,6 +2724,16 @@ function resolve(bundle, flagKey, defaultValue, logger$4) {
2623
2724
  shouldApply: false
2624
2725
  };
2625
2726
  }
2727
+ if (flag.reason === "MATERIALIZATION_NOT_SUPPORTED") {
2728
+ logger$4?.warn("Flag '%s' requires materializations but no materialization store is configured. Pass a MaterializationStore implementation or: 'CONFIDENCE_REMOTE_STORE' to createConfidenceServerProvider()", flagName);
2729
+ return {
2730
+ reason: "ERROR",
2731
+ errorCode: ErrorCode.GENERAL,
2732
+ errorMessage: `Flag '${flagName}' requires materializations. Configure a materialization store.`,
2733
+ value: defaultValue,
2734
+ shouldApply: false
2735
+ };
2736
+ }
2626
2737
  let value = flag.value;
2627
2738
  for (let i = 0; i < path.length; i++) {
2628
2739
  if (value === null || typeof value !== "object" || Array.isArray(value)) return {
@@ -2676,6 +2787,7 @@ function convertReason(reason) {
2676
2787
  case ResolveReason.RESOLVE_REASON_TARGETING_KEY_ERROR: return "TARGETING_KEY_ERROR";
2677
2788
  case ResolveReason.RESOLVE_REASON_NO_TREATMENT_MATCH: return "NO_TREATMENT_MATCH";
2678
2789
  case ResolveReason.RESOLVE_REASON_UNRECOGNIZED_TARGETING_RULE: return "ERROR";
2790
+ case ResolveReason.RESOLVE_REASON_MATERIALIZATION_NOT_SUPPORTED: return "MATERIALIZATION_NOT_SUPPORTED";
2679
2791
  default: return "UNSPECIFIED";
2680
2792
  }
2681
2793
  }
@@ -2771,10 +2883,28 @@ var ConfidenceServerProviderLocal = class ConfidenceServerProviderLocal {
2771
2883
  }
2772
2884
  }
2773
2885
  async evaluate(flagKey, defaultValue, context) {
2886
+ const startMs = performance.now();
2774
2887
  try {
2775
2888
  const [flagName] = flagKey.split(".", 1);
2776
2889
  const resolution = await this.resolve(context, [flagName], true);
2777
- return resolve(resolution, flagKey, defaultValue, logger$1);
2890
+ const result = resolve(resolution, flagKey, defaultValue, logger$1);
2891
+ const latencyUs = Math.round((performance.now() - startMs) * 1e3);
2892
+ let reason;
2893
+ if (resolution.errorCode) reason = ResolveReason.RESOLVE_REASON_ERROR;
2894
+ else {
2895
+ const [flagNameForTelemetry] = flagKey.split(".", 1);
2896
+ if (resolution.flags[flagNameForTelemetry]?.reason === "MATERIALIZATION_NOT_SUPPORTED") reason = ResolveReason.RESOLVE_REASON_MATERIALIZATION_NOT_SUPPORTED;
2897
+ else if (result.errorCode === ErrorCode.FLAG_NOT_FOUND) reason = ResolveReason.RESOLVE_REASON_FLAG_NOT_FOUND;
2898
+ else if (result.errorCode === ErrorCode.TYPE_MISMATCH) reason = ResolveReason.RESOLVE_REASON_TYPE_MISMATCH;
2899
+ else reason = reasonStringToEnum(result.reason);
2900
+ }
2901
+ try {
2902
+ this.resolver.registerResolve({
2903
+ reason,
2904
+ latencyUs
2905
+ });
2906
+ } catch {}
2907
+ return result;
2778
2908
  } finally {
2779
2909
  this.flushAssigned();
2780
2910
  }
@@ -2816,7 +2946,12 @@ var ConfidenceServerProviderLocal = class ConfidenceServerProviderLocal {
2816
2946
  if (!resp.ok) throw new Error(`Failed to fetch state: ${resp.status} ${resp.statusText}`);
2817
2947
  this.stateEtag = resp.headers.get("etag");
2818
2948
  const bytes = new Uint8Array(await resp.arrayBuffer());
2819
- this.resolver.setResolverState(SetResolverStateRequest.decode(bytes));
2949
+ const stateRequest = SetResolverStateRequest.decode(bytes);
2950
+ stateRequest.sdk = {
2951
+ id: SdkId.SDK_ID_JS_LOCAL_SERVER_PROVIDER,
2952
+ version: VERSION
2953
+ };
2954
+ this.resolver.setResolverState(stateRequest);
2820
2955
  }
2821
2956
  async flush(signal) {
2822
2957
  const writeFlagLogRequest = this.resolver.flushLogs();
@@ -2876,6 +3011,9 @@ var ConfidenceServerProviderLocal = class ConfidenceServerProviderLocal {
2876
3011
  resolveStringEvaluation(flagKey, defaultValue, context) {
2877
3012
  return Promise.resolve(this.evaluate(flagKey, defaultValue, context));
2878
3013
  }
3014
+ getPrometheusMetrics(_request) {
3015
+ return this.resolver.prometheusSnapshot("0");
3016
+ }
2879
3017
  applyFlag(resolveToken, flagName) {
2880
3018
  const request = {
2881
3019
  flags: [{
@@ -2893,6 +3031,17 @@ var ConfidenceServerProviderLocal = class ConfidenceServerProviderLocal {
2893
3031
  this.resolver.applyFlags(request);
2894
3032
  }
2895
3033
  };
3034
+ function reasonStringToEnum(reason) {
3035
+ switch (reason) {
3036
+ case "MATCH": return ResolveReason.RESOLVE_REASON_MATCH;
3037
+ case "NO_SEGMENT_MATCH": return ResolveReason.RESOLVE_REASON_NO_SEGMENT_MATCH;
3038
+ case "NO_TREATMENT_MATCH": return ResolveReason.RESOLVE_REASON_NO_TREATMENT_MATCH;
3039
+ case "FLAG_ARCHIVED": return ResolveReason.RESOLVE_REASON_FLAG_ARCHIVED;
3040
+ case "TARGETING_KEY_ERROR": return ResolveReason.RESOLVE_REASON_TARGETING_KEY_ERROR;
3041
+ case "ERROR": return ResolveReason.RESOLVE_REASON_ERROR;
3042
+ default: return ResolveReason.RESOLVE_REASON_UNSPECIFIED;
3043
+ }
3044
+ }
2896
3045
  function createBaseResolveProcessRequest() {
2897
3046
  return {
2898
3047
  deferredMaterializations: void 0,
@@ -3314,6 +3463,61 @@ const MaterializationRecord = {
3314
3463
  return message;
3315
3464
  }
3316
3465
  };
3466
+ function createBaseRegisterResolveRequest() {
3467
+ return {
3468
+ reason: 0,
3469
+ latencyUs: 0
3470
+ };
3471
+ }
3472
+ const RegisterResolveRequest = {
3473
+ encode(message, writer = new BinaryWriter()) {
3474
+ if (message.reason !== 0) writer.uint32(8).int32(message.reason);
3475
+ if (message.latencyUs !== 0) writer.uint32(16).uint32(message.latencyUs);
3476
+ return writer;
3477
+ },
3478
+ decode(input, length) {
3479
+ const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
3480
+ const end = length === void 0 ? reader.len : reader.pos + length;
3481
+ const message = createBaseRegisterResolveRequest();
3482
+ while (reader.pos < end) {
3483
+ const tag = reader.uint32();
3484
+ switch (tag >>> 3) {
3485
+ case 1:
3486
+ if (tag !== 8) break;
3487
+ message.reason = reader.int32();
3488
+ continue;
3489
+ case 2:
3490
+ if (tag !== 16) break;
3491
+ message.latencyUs = reader.uint32();
3492
+ continue;
3493
+ }
3494
+ if ((tag & 7) === 4 || tag === 0) break;
3495
+ reader.skip(tag & 7);
3496
+ }
3497
+ return message;
3498
+ },
3499
+ fromJSON(object) {
3500
+ return {
3501
+ reason: isSet(object.reason) ? resolveReasonFromJSON(object.reason) : 0,
3502
+ latencyUs: isSet(object.latencyUs) ? globalThis.Number(object.latencyUs) : 0
3503
+ };
3504
+ },
3505
+ toJSON(message) {
3506
+ const obj = {};
3507
+ if (message.reason !== 0) obj.reason = resolveReasonToJSON(message.reason);
3508
+ if (message.latencyUs !== 0) obj.latencyUs = Math.round(message.latencyUs);
3509
+ return obj;
3510
+ },
3511
+ create(base) {
3512
+ return RegisterResolveRequest.fromPartial(base ?? {});
3513
+ },
3514
+ fromPartial(object) {
3515
+ const message = createBaseRegisterResolveRequest();
3516
+ message.reason = object.reason ?? 0;
3517
+ message.latencyUs = object.latencyUs ?? 0;
3518
+ return message;
3519
+ }
3520
+ };
3317
3521
  function bytesFromBase64(b64) {
3318
3522
  if (globalThis.Buffer) return Uint8Array.from(globalThis.Buffer.from(b64, "base64"));
3319
3523
  else {
@@ -3341,10 +3545,12 @@ const EXPORT_FN_NAMES = [
3341
3545
  "wasm_msg_alloc",
3342
3546
  "wasm_msg_free",
3343
3547
  "wasm_msg_guest_resolve_flags",
3548
+ "wasm_msg_guest_register_resolve",
3344
3549
  "wasm_msg_guest_set_resolver_state",
3345
3550
  "wasm_msg_guest_bounded_flush_logs",
3346
3551
  "wasm_msg_guest_bounded_flush_assign",
3347
- "wasm_msg_guest_apply_flags"
3552
+ "wasm_msg_guest_apply_flags",
3553
+ "wasm_msg_guest_prometheus_snapshot"
3348
3554
  ];
3349
3555
  function verifyExports(exports) {
3350
3556
  for (const fnName of EXPORT_FN_NAMES) if (typeof exports[fnName] !== "function") throw new Error(`Expected Function export "${fnName}" found ${exports[fnName]}`);
@@ -3371,6 +3577,11 @@ var UnsafeWasmResolver = class {
3371
3577
  const resPtr = this.exports.wasm_msg_guest_resolve_flags(reqPtr);
3372
3578
  return this.consumeResponse(resPtr, ResolveProcessResponse);
3373
3579
  }
3580
+ registerResolve(request) {
3581
+ const reqPtr = this.transferRequest(request, RegisterResolveRequest);
3582
+ const resPtr = this.exports.wasm_msg_guest_register_resolve(reqPtr);
3583
+ this.consumeResponse(resPtr, Void);
3584
+ }
3374
3585
  setResolverState(request) {
3375
3586
  const reqPtr = this.transferRequest(request, SetResolverStateRequest);
3376
3587
  const resPtr = this.exports.wasm_msg_guest_set_resolver_state(reqPtr);
@@ -3393,6 +3604,11 @@ var UnsafeWasmResolver = class {
3393
3604
  const resPtr = this.exports.wasm_msg_guest_apply_flags(reqPtr);
3394
3605
  this.consumeResponse(resPtr, Void);
3395
3606
  }
3607
+ prometheusSnapshot(instance) {
3608
+ const reqPtr = this.transferRequest({ instance }, PrometheusSnapshotRequest);
3609
+ const resPtr = this.exports.wasm_msg_guest_prometheus_snapshot(reqPtr);
3610
+ return this.consumeResponse(resPtr, PrometheusSnapshotResponse).text;
3611
+ }
3396
3612
  transferRequest(value, codec) {
3397
3613
  const data = codec.encode(value).finish();
3398
3614
  return this.transfer({ data }, Request);
@@ -3450,6 +3666,11 @@ var WasmResolver = class {
3450
3666
  throw error$1;
3451
3667
  }
3452
3668
  }
3669
+ registerResolve(request) {
3670
+ try {
3671
+ this.delegate.registerResolve(request);
3672
+ } catch {}
3673
+ }
3453
3674
  setResolverState(request) {
3454
3675
  this.currentState = request;
3455
3676
  try {
@@ -3487,6 +3708,14 @@ var WasmResolver = class {
3487
3708
  throw error$1;
3488
3709
  }
3489
3710
  }
3711
+ prometheusSnapshot(instance) {
3712
+ try {
3713
+ return this.delegate.prometheusSnapshot(instance);
3714
+ } catch (error$1) {
3715
+ logger.error("prometheus snapshot failed:", error$1);
3716
+ return "";
3717
+ }
3718
+ }
3490
3719
  };
3491
3720
  let resolver = null;
3492
3721
  function createConfidenceServerProvider({ wasmPath,...options }) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spotify-confidence/openfeature-server-provider-local",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "Spotify Confidence Open Feature provider",
5
5
  "type": "module",
6
6
  "files": [