@spotify-confidence/openfeature-server-provider-local 0.1.0 → 0.2.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 +21 -0
- package/README.md +16 -3
- package/dist/confidence_resolver.wasm +0 -0
- package/dist/index.browser.d.ts +34 -0
- package/dist/index.browser.js +277 -26
- package/dist/index.node.d.ts +34 -0
- package/dist/index.node.js +277 -26
- package/package.json +9 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.2.0](https://github.com/spotify/confidence-resolver/compare/openfeature-provider-js-v0.1.1...openfeature-provider-js-v0.2.0) (2025-11-24)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* send js sdk info in resolve request ([#161](https://github.com/spotify/confidence-resolver/issues/161)) ([5cbc7d9](https://github.com/spotify/confidence-resolver/commit/5cbc7d9e2ada26c52298d74faaba50ec6cb4c3e7))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Dependencies
|
|
12
|
+
|
|
13
|
+
* The following workspace dependencies were updated
|
|
14
|
+
* dependencies
|
|
15
|
+
* rust-guest bumped from 0.1.9 to 0.1.10
|
|
16
|
+
|
|
17
|
+
## [0.1.1](https://github.com/spotify/confidence-resolver-rust/compare/openfeature-provider-js-v0.1.0...openfeature-provider-js-v0.1.1) (2025-11-03)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* handle panics ([#76](https://github.com/spotify/confidence-resolver-rust/issues/76)) ([1ea86ea](https://github.com/spotify/confidence-resolver-rust/commit/1ea86eaa3e64aea5a64086534fe94a155828ef80))
|
|
23
|
+
|
|
3
24
|
## 0.1.0 (2025-10-24)
|
|
4
25
|
|
|
5
26
|
|
package/README.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
# @spotify-confidence/openfeature-server-provider-local
|
|
2
2
|
|
|
3
3
|
OpenFeature provider for the Spotify Confidence resolver (local mode, powered by WebAssembly). It periodically fetches resolver state, evaluates flags locally, and flushes evaluation logs to the Confidence backend.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Features
|
|
6
6
|
- Local flag evaluation via WASM (no per-eval network calls)
|
|
7
7
|
- Automatic state refresh and batched flag log flushing
|
|
8
8
|
- Pluggable `fetch` with retries, timeouts and routing
|
|
9
9
|
- Optional logging using `debug`
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
## Requirements
|
|
12
12
|
- Node.js 18+ (built-in `fetch`) or provide a compatible `fetch`
|
|
13
13
|
- WebAssembly support (Node 18+/modern browsers)
|
|
14
14
|
|
|
@@ -78,6 +78,11 @@ The provider periodically:
|
|
|
78
78
|
|
|
79
79
|
---
|
|
80
80
|
|
|
81
|
+
## Migration from online resolver
|
|
82
|
+
If you're currently using the ["online resolver"](https://github.com/spotify/confidence-sdk-js/tree/main/packages/openfeature-server-provider) and wants to improve the resolve latency, [migration](MIGRATION.md) is easy!
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
81
86
|
## Sticky Assignments
|
|
82
87
|
|
|
83
88
|
Confidence supports "sticky" flag assignments to ensure users receive consistent variant assignments even when their context changes or flag configurations are updated. This SDK falls back to a cloud resolve in these cases.
|
|
@@ -182,3 +187,11 @@ The package exports a browser ESM build that compiles the WASM via streaming and
|
|
|
182
187
|
## License
|
|
183
188
|
|
|
184
189
|
See the root `LICENSE`.
|
|
190
|
+
|
|
191
|
+
## Formatting
|
|
192
|
+
|
|
193
|
+
Code is formatted using prettier, you can format all files by running
|
|
194
|
+
|
|
195
|
+
```sh
|
|
196
|
+
yarn format
|
|
197
|
+
```
|
|
Binary file
|
package/dist/index.browser.d.ts
CHANGED
|
@@ -2,6 +2,32 @@ import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
|
|
2
2
|
import { EvaluationContext, JsonValue, Provider, ProviderMetadata, ProviderStatus, ResolutionDetails } from "@openfeature/server-sdk";
|
|
3
3
|
|
|
4
4
|
//#region src/proto/api.d.ts
|
|
5
|
+
declare enum SdkId {
|
|
6
|
+
SDK_ID_UNSPECIFIED = 0,
|
|
7
|
+
SDK_ID_JAVA_PROVIDER = 1,
|
|
8
|
+
SDK_ID_KOTLIN_PROVIDER = 2,
|
|
9
|
+
SDK_ID_SWIFT_PROVIDER = 3,
|
|
10
|
+
SDK_ID_JS_WEB_PROVIDER = 4,
|
|
11
|
+
SDK_ID_JS_SERVER_PROVIDER = 5,
|
|
12
|
+
SDK_ID_PYTHON_PROVIDER = 6,
|
|
13
|
+
SDK_ID_GO_PROVIDER = 7,
|
|
14
|
+
SDK_ID_RUBY_PROVIDER = 8,
|
|
15
|
+
SDK_ID_RUST_PROVIDER = 9,
|
|
16
|
+
SDK_ID_JAVA_CONFIDENCE = 10,
|
|
17
|
+
SDK_ID_KOTLIN_CONFIDENCE = 11,
|
|
18
|
+
SDK_ID_SWIFT_CONFIDENCE = 12,
|
|
19
|
+
SDK_ID_JS_CONFIDENCE = 13,
|
|
20
|
+
SDK_ID_PYTHON_CONFIDENCE = 14,
|
|
21
|
+
SDK_ID_GO_CONFIDENCE = 15,
|
|
22
|
+
SDK_ID_RUST_CONFIDENCE = 16,
|
|
23
|
+
SDK_ID_FLUTTER_IOS_CONFIDENCE = 17,
|
|
24
|
+
SDK_ID_FLUTTER_ANDROID_CONFIDENCE = 18,
|
|
25
|
+
SDK_ID_DOTNET_CONFIDENCE = 19,
|
|
26
|
+
SDK_ID_GO_LOCAL_PROVIDER = 20,
|
|
27
|
+
SDK_ID_JAVA_LOCAL_PROVIDER = 21,
|
|
28
|
+
SDK_ID_JS_LOCAL_SERVER_PROVIDER = 22,
|
|
29
|
+
UNRECOGNIZED = -1,
|
|
30
|
+
}
|
|
5
31
|
declare enum ResolveReason {
|
|
6
32
|
/** RESOLVE_REASON_UNSPECIFIED - Unspecified enum. */
|
|
7
33
|
RESOLVE_REASON_UNSPECIFIED = 0,
|
|
@@ -24,6 +50,11 @@ declare enum ResolveReason {
|
|
|
24
50
|
RESOLVE_REASON_ERROR = 6,
|
|
25
51
|
UNRECOGNIZED = -1,
|
|
26
52
|
}
|
|
53
|
+
interface Sdk {
|
|
54
|
+
id?: SdkId | undefined;
|
|
55
|
+
customId?: string | undefined;
|
|
56
|
+
version: string;
|
|
57
|
+
}
|
|
27
58
|
interface ResolveFlagsRequest {
|
|
28
59
|
/**
|
|
29
60
|
* If non-empty, the specific flags are resolved, otherwise all flags
|
|
@@ -50,6 +81,8 @@ interface ResolveFlagsRequest {
|
|
|
50
81
|
* `apply` should likely be set to false.
|
|
51
82
|
*/
|
|
52
83
|
apply: boolean;
|
|
84
|
+
/** Information about the SDK used to initiate the request. */
|
|
85
|
+
sdk?: Sdk | undefined;
|
|
53
86
|
}
|
|
54
87
|
interface ResolveFlagsResponse {
|
|
55
88
|
/**
|
|
@@ -143,6 +176,7 @@ interface ResolveWithStickyResponse_MaterializationUpdate {
|
|
|
143
176
|
rule: string;
|
|
144
177
|
variant: string;
|
|
145
178
|
}
|
|
179
|
+
declare const Sdk: MessageFns<Sdk>;
|
|
146
180
|
declare const ResolveFlagsRequest: MessageFns<ResolveFlagsRequest>;
|
|
147
181
|
declare const ResolveFlagsResponse: MessageFns<ResolveFlagsResponse>;
|
|
148
182
|
declare const ResolvedFlag: MessageFns<ResolvedFlag>;
|
package/dist/index.browser.js
CHANGED
|
@@ -315,6 +315,115 @@ function isObject$1(value) {
|
|
|
315
315
|
function isSet$3(value) {
|
|
316
316
|
return value !== null && value !== void 0;
|
|
317
317
|
}
|
|
318
|
+
let SdkId = /* @__PURE__ */ function(SdkId$1) {
|
|
319
|
+
SdkId$1[SdkId$1["SDK_ID_UNSPECIFIED"] = 0] = "SDK_ID_UNSPECIFIED";
|
|
320
|
+
SdkId$1[SdkId$1["SDK_ID_JAVA_PROVIDER"] = 1] = "SDK_ID_JAVA_PROVIDER";
|
|
321
|
+
SdkId$1[SdkId$1["SDK_ID_KOTLIN_PROVIDER"] = 2] = "SDK_ID_KOTLIN_PROVIDER";
|
|
322
|
+
SdkId$1[SdkId$1["SDK_ID_SWIFT_PROVIDER"] = 3] = "SDK_ID_SWIFT_PROVIDER";
|
|
323
|
+
SdkId$1[SdkId$1["SDK_ID_JS_WEB_PROVIDER"] = 4] = "SDK_ID_JS_WEB_PROVIDER";
|
|
324
|
+
SdkId$1[SdkId$1["SDK_ID_JS_SERVER_PROVIDER"] = 5] = "SDK_ID_JS_SERVER_PROVIDER";
|
|
325
|
+
SdkId$1[SdkId$1["SDK_ID_PYTHON_PROVIDER"] = 6] = "SDK_ID_PYTHON_PROVIDER";
|
|
326
|
+
SdkId$1[SdkId$1["SDK_ID_GO_PROVIDER"] = 7] = "SDK_ID_GO_PROVIDER";
|
|
327
|
+
SdkId$1[SdkId$1["SDK_ID_RUBY_PROVIDER"] = 8] = "SDK_ID_RUBY_PROVIDER";
|
|
328
|
+
SdkId$1[SdkId$1["SDK_ID_RUST_PROVIDER"] = 9] = "SDK_ID_RUST_PROVIDER";
|
|
329
|
+
SdkId$1[SdkId$1["SDK_ID_JAVA_CONFIDENCE"] = 10] = "SDK_ID_JAVA_CONFIDENCE";
|
|
330
|
+
SdkId$1[SdkId$1["SDK_ID_KOTLIN_CONFIDENCE"] = 11] = "SDK_ID_KOTLIN_CONFIDENCE";
|
|
331
|
+
SdkId$1[SdkId$1["SDK_ID_SWIFT_CONFIDENCE"] = 12] = "SDK_ID_SWIFT_CONFIDENCE";
|
|
332
|
+
SdkId$1[SdkId$1["SDK_ID_JS_CONFIDENCE"] = 13] = "SDK_ID_JS_CONFIDENCE";
|
|
333
|
+
SdkId$1[SdkId$1["SDK_ID_PYTHON_CONFIDENCE"] = 14] = "SDK_ID_PYTHON_CONFIDENCE";
|
|
334
|
+
SdkId$1[SdkId$1["SDK_ID_GO_CONFIDENCE"] = 15] = "SDK_ID_GO_CONFIDENCE";
|
|
335
|
+
SdkId$1[SdkId$1["SDK_ID_RUST_CONFIDENCE"] = 16] = "SDK_ID_RUST_CONFIDENCE";
|
|
336
|
+
SdkId$1[SdkId$1["SDK_ID_FLUTTER_IOS_CONFIDENCE"] = 17] = "SDK_ID_FLUTTER_IOS_CONFIDENCE";
|
|
337
|
+
SdkId$1[SdkId$1["SDK_ID_FLUTTER_ANDROID_CONFIDENCE"] = 18] = "SDK_ID_FLUTTER_ANDROID_CONFIDENCE";
|
|
338
|
+
SdkId$1[SdkId$1["SDK_ID_DOTNET_CONFIDENCE"] = 19] = "SDK_ID_DOTNET_CONFIDENCE";
|
|
339
|
+
SdkId$1[SdkId$1["SDK_ID_GO_LOCAL_PROVIDER"] = 20] = "SDK_ID_GO_LOCAL_PROVIDER";
|
|
340
|
+
SdkId$1[SdkId$1["SDK_ID_JAVA_LOCAL_PROVIDER"] = 21] = "SDK_ID_JAVA_LOCAL_PROVIDER";
|
|
341
|
+
SdkId$1[SdkId$1["SDK_ID_JS_LOCAL_SERVER_PROVIDER"] = 22] = "SDK_ID_JS_LOCAL_SERVER_PROVIDER";
|
|
342
|
+
SdkId$1[SdkId$1["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
|
|
343
|
+
return SdkId$1;
|
|
344
|
+
}({});
|
|
345
|
+
function sdkIdFromJSON(object) {
|
|
346
|
+
switch (object) {
|
|
347
|
+
case 0:
|
|
348
|
+
case "SDK_ID_UNSPECIFIED": return SdkId.SDK_ID_UNSPECIFIED;
|
|
349
|
+
case 1:
|
|
350
|
+
case "SDK_ID_JAVA_PROVIDER": return SdkId.SDK_ID_JAVA_PROVIDER;
|
|
351
|
+
case 2:
|
|
352
|
+
case "SDK_ID_KOTLIN_PROVIDER": return SdkId.SDK_ID_KOTLIN_PROVIDER;
|
|
353
|
+
case 3:
|
|
354
|
+
case "SDK_ID_SWIFT_PROVIDER": return SdkId.SDK_ID_SWIFT_PROVIDER;
|
|
355
|
+
case 4:
|
|
356
|
+
case "SDK_ID_JS_WEB_PROVIDER": return SdkId.SDK_ID_JS_WEB_PROVIDER;
|
|
357
|
+
case 5:
|
|
358
|
+
case "SDK_ID_JS_SERVER_PROVIDER": return SdkId.SDK_ID_JS_SERVER_PROVIDER;
|
|
359
|
+
case 6:
|
|
360
|
+
case "SDK_ID_PYTHON_PROVIDER": return SdkId.SDK_ID_PYTHON_PROVIDER;
|
|
361
|
+
case 7:
|
|
362
|
+
case "SDK_ID_GO_PROVIDER": return SdkId.SDK_ID_GO_PROVIDER;
|
|
363
|
+
case 8:
|
|
364
|
+
case "SDK_ID_RUBY_PROVIDER": return SdkId.SDK_ID_RUBY_PROVIDER;
|
|
365
|
+
case 9:
|
|
366
|
+
case "SDK_ID_RUST_PROVIDER": return SdkId.SDK_ID_RUST_PROVIDER;
|
|
367
|
+
case 10:
|
|
368
|
+
case "SDK_ID_JAVA_CONFIDENCE": return SdkId.SDK_ID_JAVA_CONFIDENCE;
|
|
369
|
+
case 11:
|
|
370
|
+
case "SDK_ID_KOTLIN_CONFIDENCE": return SdkId.SDK_ID_KOTLIN_CONFIDENCE;
|
|
371
|
+
case 12:
|
|
372
|
+
case "SDK_ID_SWIFT_CONFIDENCE": return SdkId.SDK_ID_SWIFT_CONFIDENCE;
|
|
373
|
+
case 13:
|
|
374
|
+
case "SDK_ID_JS_CONFIDENCE": return SdkId.SDK_ID_JS_CONFIDENCE;
|
|
375
|
+
case 14:
|
|
376
|
+
case "SDK_ID_PYTHON_CONFIDENCE": return SdkId.SDK_ID_PYTHON_CONFIDENCE;
|
|
377
|
+
case 15:
|
|
378
|
+
case "SDK_ID_GO_CONFIDENCE": return SdkId.SDK_ID_GO_CONFIDENCE;
|
|
379
|
+
case 16:
|
|
380
|
+
case "SDK_ID_RUST_CONFIDENCE": return SdkId.SDK_ID_RUST_CONFIDENCE;
|
|
381
|
+
case 17:
|
|
382
|
+
case "SDK_ID_FLUTTER_IOS_CONFIDENCE": return SdkId.SDK_ID_FLUTTER_IOS_CONFIDENCE;
|
|
383
|
+
case 18:
|
|
384
|
+
case "SDK_ID_FLUTTER_ANDROID_CONFIDENCE": return SdkId.SDK_ID_FLUTTER_ANDROID_CONFIDENCE;
|
|
385
|
+
case 19:
|
|
386
|
+
case "SDK_ID_DOTNET_CONFIDENCE": return SdkId.SDK_ID_DOTNET_CONFIDENCE;
|
|
387
|
+
case 20:
|
|
388
|
+
case "SDK_ID_GO_LOCAL_PROVIDER": return SdkId.SDK_ID_GO_LOCAL_PROVIDER;
|
|
389
|
+
case 21:
|
|
390
|
+
case "SDK_ID_JAVA_LOCAL_PROVIDER": return SdkId.SDK_ID_JAVA_LOCAL_PROVIDER;
|
|
391
|
+
case 22:
|
|
392
|
+
case "SDK_ID_JS_LOCAL_SERVER_PROVIDER": return SdkId.SDK_ID_JS_LOCAL_SERVER_PROVIDER;
|
|
393
|
+
case -1:
|
|
394
|
+
case "UNRECOGNIZED":
|
|
395
|
+
default: return SdkId.UNRECOGNIZED;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
function sdkIdToJSON(object) {
|
|
399
|
+
switch (object) {
|
|
400
|
+
case SdkId.SDK_ID_UNSPECIFIED: return "SDK_ID_UNSPECIFIED";
|
|
401
|
+
case SdkId.SDK_ID_JAVA_PROVIDER: return "SDK_ID_JAVA_PROVIDER";
|
|
402
|
+
case SdkId.SDK_ID_KOTLIN_PROVIDER: return "SDK_ID_KOTLIN_PROVIDER";
|
|
403
|
+
case SdkId.SDK_ID_SWIFT_PROVIDER: return "SDK_ID_SWIFT_PROVIDER";
|
|
404
|
+
case SdkId.SDK_ID_JS_WEB_PROVIDER: return "SDK_ID_JS_WEB_PROVIDER";
|
|
405
|
+
case SdkId.SDK_ID_JS_SERVER_PROVIDER: return "SDK_ID_JS_SERVER_PROVIDER";
|
|
406
|
+
case SdkId.SDK_ID_PYTHON_PROVIDER: return "SDK_ID_PYTHON_PROVIDER";
|
|
407
|
+
case SdkId.SDK_ID_GO_PROVIDER: return "SDK_ID_GO_PROVIDER";
|
|
408
|
+
case SdkId.SDK_ID_RUBY_PROVIDER: return "SDK_ID_RUBY_PROVIDER";
|
|
409
|
+
case SdkId.SDK_ID_RUST_PROVIDER: return "SDK_ID_RUST_PROVIDER";
|
|
410
|
+
case SdkId.SDK_ID_JAVA_CONFIDENCE: return "SDK_ID_JAVA_CONFIDENCE";
|
|
411
|
+
case SdkId.SDK_ID_KOTLIN_CONFIDENCE: return "SDK_ID_KOTLIN_CONFIDENCE";
|
|
412
|
+
case SdkId.SDK_ID_SWIFT_CONFIDENCE: return "SDK_ID_SWIFT_CONFIDENCE";
|
|
413
|
+
case SdkId.SDK_ID_JS_CONFIDENCE: return "SDK_ID_JS_CONFIDENCE";
|
|
414
|
+
case SdkId.SDK_ID_PYTHON_CONFIDENCE: return "SDK_ID_PYTHON_CONFIDENCE";
|
|
415
|
+
case SdkId.SDK_ID_GO_CONFIDENCE: return "SDK_ID_GO_CONFIDENCE";
|
|
416
|
+
case SdkId.SDK_ID_RUST_CONFIDENCE: return "SDK_ID_RUST_CONFIDENCE";
|
|
417
|
+
case SdkId.SDK_ID_FLUTTER_IOS_CONFIDENCE: return "SDK_ID_FLUTTER_IOS_CONFIDENCE";
|
|
418
|
+
case SdkId.SDK_ID_FLUTTER_ANDROID_CONFIDENCE: return "SDK_ID_FLUTTER_ANDROID_CONFIDENCE";
|
|
419
|
+
case SdkId.SDK_ID_DOTNET_CONFIDENCE: return "SDK_ID_DOTNET_CONFIDENCE";
|
|
420
|
+
case SdkId.SDK_ID_GO_LOCAL_PROVIDER: return "SDK_ID_GO_LOCAL_PROVIDER";
|
|
421
|
+
case SdkId.SDK_ID_JAVA_LOCAL_PROVIDER: return "SDK_ID_JAVA_LOCAL_PROVIDER";
|
|
422
|
+
case SdkId.SDK_ID_JS_LOCAL_SERVER_PROVIDER: return "SDK_ID_JS_LOCAL_SERVER_PROVIDER";
|
|
423
|
+
case SdkId.UNRECOGNIZED:
|
|
424
|
+
default: return "UNRECOGNIZED";
|
|
425
|
+
}
|
|
426
|
+
}
|
|
318
427
|
let ResolveReason = /* @__PURE__ */ function(ResolveReason$1) {
|
|
319
428
|
ResolveReason$1[ResolveReason$1["RESOLVE_REASON_UNSPECIFIED"] = 0] = "RESOLVE_REASON_UNSPECIFIED";
|
|
320
429
|
ResolveReason$1[ResolveReason$1["RESOLVE_REASON_MATCH"] = 1] = "RESOLVE_REASON_MATCH";
|
|
@@ -360,12 +469,77 @@ function resolveReasonToJSON(object) {
|
|
|
360
469
|
default: return "UNRECOGNIZED";
|
|
361
470
|
}
|
|
362
471
|
}
|
|
472
|
+
function createBaseSdk() {
|
|
473
|
+
return {
|
|
474
|
+
id: void 0,
|
|
475
|
+
customId: void 0,
|
|
476
|
+
version: ""
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
const Sdk = {
|
|
480
|
+
encode(message, writer = new BinaryWriter()) {
|
|
481
|
+
if (message.id !== void 0) writer.uint32(8).int32(message.id);
|
|
482
|
+
if (message.customId !== void 0) writer.uint32(18).string(message.customId);
|
|
483
|
+
if (message.version !== "") writer.uint32(26).string(message.version);
|
|
484
|
+
return writer;
|
|
485
|
+
},
|
|
486
|
+
decode(input, length) {
|
|
487
|
+
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
|
488
|
+
const end = length === void 0 ? reader.len : reader.pos + length;
|
|
489
|
+
const message = createBaseSdk();
|
|
490
|
+
while (reader.pos < end) {
|
|
491
|
+
const tag = reader.uint32();
|
|
492
|
+
switch (tag >>> 3) {
|
|
493
|
+
case 1:
|
|
494
|
+
if (tag !== 8) break;
|
|
495
|
+
message.id = reader.int32();
|
|
496
|
+
continue;
|
|
497
|
+
case 2:
|
|
498
|
+
if (tag !== 18) break;
|
|
499
|
+
message.customId = reader.string();
|
|
500
|
+
continue;
|
|
501
|
+
case 3:
|
|
502
|
+
if (tag !== 26) break;
|
|
503
|
+
message.version = reader.string();
|
|
504
|
+
continue;
|
|
505
|
+
}
|
|
506
|
+
if ((tag & 7) === 4 || tag === 0) break;
|
|
507
|
+
reader.skip(tag & 7);
|
|
508
|
+
}
|
|
509
|
+
return message;
|
|
510
|
+
},
|
|
511
|
+
fromJSON(object) {
|
|
512
|
+
return {
|
|
513
|
+
id: isSet$2(object.id) ? sdkIdFromJSON(object.id) : void 0,
|
|
514
|
+
customId: isSet$2(object.customId) ? globalThis.String(object.customId) : void 0,
|
|
515
|
+
version: isSet$2(object.version) ? globalThis.String(object.version) : ""
|
|
516
|
+
};
|
|
517
|
+
},
|
|
518
|
+
toJSON(message) {
|
|
519
|
+
const obj = {};
|
|
520
|
+
if (message.id !== void 0) obj.id = sdkIdToJSON(message.id);
|
|
521
|
+
if (message.customId !== void 0) obj.customId = message.customId;
|
|
522
|
+
if (message.version !== "") obj.version = message.version;
|
|
523
|
+
return obj;
|
|
524
|
+
},
|
|
525
|
+
create(base) {
|
|
526
|
+
return Sdk.fromPartial(base ?? {});
|
|
527
|
+
},
|
|
528
|
+
fromPartial(object) {
|
|
529
|
+
const message = createBaseSdk();
|
|
530
|
+
message.id = object.id ?? void 0;
|
|
531
|
+
message.customId = object.customId ?? void 0;
|
|
532
|
+
message.version = object.version ?? "";
|
|
533
|
+
return message;
|
|
534
|
+
}
|
|
535
|
+
};
|
|
363
536
|
function createBaseResolveFlagsRequest() {
|
|
364
537
|
return {
|
|
365
538
|
flags: [],
|
|
366
539
|
evaluationContext: void 0,
|
|
367
540
|
clientSecret: "",
|
|
368
|
-
apply: false
|
|
541
|
+
apply: false,
|
|
542
|
+
sdk: void 0
|
|
369
543
|
};
|
|
370
544
|
}
|
|
371
545
|
const ResolveFlagsRequest = {
|
|
@@ -374,6 +548,7 @@ const ResolveFlagsRequest = {
|
|
|
374
548
|
if (message.evaluationContext !== void 0) Struct.encode(Struct.wrap(message.evaluationContext), writer.uint32(18).fork()).join();
|
|
375
549
|
if (message.clientSecret !== "") writer.uint32(26).string(message.clientSecret);
|
|
376
550
|
if (message.apply !== false) writer.uint32(32).bool(message.apply);
|
|
551
|
+
if (message.sdk !== void 0) Sdk.encode(message.sdk, writer.uint32(42).fork()).join();
|
|
377
552
|
return writer;
|
|
378
553
|
},
|
|
379
554
|
decode(input, length) {
|
|
@@ -399,6 +574,10 @@ const ResolveFlagsRequest = {
|
|
|
399
574
|
if (tag !== 32) break;
|
|
400
575
|
message.apply = reader.bool();
|
|
401
576
|
continue;
|
|
577
|
+
case 5:
|
|
578
|
+
if (tag !== 42) break;
|
|
579
|
+
message.sdk = Sdk.decode(reader, reader.uint32());
|
|
580
|
+
continue;
|
|
402
581
|
}
|
|
403
582
|
if ((tag & 7) === 4 || tag === 0) break;
|
|
404
583
|
reader.skip(tag & 7);
|
|
@@ -410,7 +589,8 @@ const ResolveFlagsRequest = {
|
|
|
410
589
|
flags: globalThis.Array.isArray(object?.flags) ? object.flags.map((e) => globalThis.String(e)) : [],
|
|
411
590
|
evaluationContext: isObject(object.evaluationContext) ? object.evaluationContext : void 0,
|
|
412
591
|
clientSecret: isSet$2(object.clientSecret) ? globalThis.String(object.clientSecret) : "",
|
|
413
|
-
apply: isSet$2(object.apply) ? globalThis.Boolean(object.apply) : false
|
|
592
|
+
apply: isSet$2(object.apply) ? globalThis.Boolean(object.apply) : false,
|
|
593
|
+
sdk: isSet$2(object.sdk) ? Sdk.fromJSON(object.sdk) : void 0
|
|
414
594
|
};
|
|
415
595
|
},
|
|
416
596
|
toJSON(message) {
|
|
@@ -419,6 +599,7 @@ const ResolveFlagsRequest = {
|
|
|
419
599
|
if (message.evaluationContext !== void 0) obj.evaluationContext = message.evaluationContext;
|
|
420
600
|
if (message.clientSecret !== "") obj.clientSecret = message.clientSecret;
|
|
421
601
|
if (message.apply !== false) obj.apply = message.apply;
|
|
602
|
+
if (message.sdk !== void 0) obj.sdk = Sdk.toJSON(message.sdk);
|
|
422
603
|
return obj;
|
|
423
604
|
},
|
|
424
605
|
create(base) {
|
|
@@ -430,6 +611,7 @@ const ResolveFlagsRequest = {
|
|
|
430
611
|
message.evaluationContext = object.evaluationContext ?? void 0;
|
|
431
612
|
message.clientSecret = object.clientSecret ?? "";
|
|
432
613
|
message.apply = object.apply ?? false;
|
|
614
|
+
message.sdk = object.sdk !== void 0 && object.sdk !== null ? Sdk.fromPartial(object.sdk) : void 0;
|
|
433
615
|
return message;
|
|
434
616
|
}
|
|
435
617
|
};
|
|
@@ -1328,9 +1510,10 @@ function isObject(value) {
|
|
|
1328
1510
|
function isSet$2(value) {
|
|
1329
1511
|
return value !== null && value !== void 0;
|
|
1330
1512
|
}
|
|
1513
|
+
const VERSION = "0.2.0";
|
|
1331
1514
|
const NOOP_LOG_FN = () => {};
|
|
1332
1515
|
const debugBackend = loadDebug();
|
|
1333
|
-
const logger = new class LoggerImpl {
|
|
1516
|
+
const logger$1 = new class LoggerImpl {
|
|
1334
1517
|
childLoggers = /* @__PURE__ */ new Map();
|
|
1335
1518
|
debug = NOOP_LOG_FN;
|
|
1336
1519
|
info = NOOP_LOG_FN;
|
|
@@ -1362,6 +1545,7 @@ const logger = new class LoggerImpl {
|
|
|
1362
1545
|
return child;
|
|
1363
1546
|
}
|
|
1364
1547
|
}("cnfd");
|
|
1548
|
+
const getLogger = logger$1.getLogger.bind(logger$1);
|
|
1365
1549
|
async function loadDebug() {
|
|
1366
1550
|
try {
|
|
1367
1551
|
const { default: debug } = await import("debug");
|
|
@@ -1391,7 +1575,7 @@ function scheduleWithFixedInterval(operation, intervalMs, opt = {}) {
|
|
|
1391
1575
|
try {
|
|
1392
1576
|
await operation(ac.signal);
|
|
1393
1577
|
} catch (e) {
|
|
1394
|
-
logger.warn("scheduleWithFixedInterval failure:", e);
|
|
1578
|
+
logger$1.warn("scheduleWithFixedInterval failure:", e);
|
|
1395
1579
|
}
|
|
1396
1580
|
concurrent--;
|
|
1397
1581
|
if (Date.now() - lastRunTime > intervalMs && nextRunTimeoutId != 0) {
|
|
@@ -1453,7 +1637,7 @@ function promiseSignal(signal) {
|
|
|
1453
1637
|
function abortablePromise(promise, signal) {
|
|
1454
1638
|
return signal ? Promise.race([promise, promiseSignal(signal)]) : promise;
|
|
1455
1639
|
}
|
|
1456
|
-
const logger$
|
|
1640
|
+
const logger$2 = logger$1.getLogger("fetch");
|
|
1457
1641
|
let Fetch;
|
|
1458
1642
|
(function(_Fetch) {
|
|
1459
1643
|
function create(middleware, sink = fetch) {
|
|
@@ -1524,13 +1708,13 @@ function withRetry(opts) {
|
|
|
1524
1708
|
const onSuccess = async (resp) => {
|
|
1525
1709
|
const { status, statusText } = resp;
|
|
1526
1710
|
if (status !== 408 && status !== 429 && status < 500 || attempts >= maxAttempts) return resp;
|
|
1527
|
-
logger$
|
|
1711
|
+
logger$2.debug("withRetry %s failed attempt %d with %d %s", url, attempts - 1, status, statusText);
|
|
1528
1712
|
const serverDelay = parseRetryAfter(resp.headers.get("Retry-After"), baseInterval, maxInterval);
|
|
1529
1713
|
await abortableSleep(serverDelay ?? deadline - Date.now(), signal);
|
|
1530
1714
|
return doTry();
|
|
1531
1715
|
};
|
|
1532
1716
|
const onError = async (error) => {
|
|
1533
|
-
logger$
|
|
1717
|
+
logger$2.debug("withRetry %s failed attempt %d with %s", url, attempts - 1, error);
|
|
1534
1718
|
if (signal?.aborted || attempts >= maxAttempts) throw error;
|
|
1535
1719
|
await abortableSleep(deadline - Date.now(), signal);
|
|
1536
1720
|
return doTry();
|
|
@@ -1556,10 +1740,10 @@ function withAuth(tokenProvider, signal) {
|
|
|
1556
1740
|
clearTimeout(renewTimeout);
|
|
1557
1741
|
});
|
|
1558
1742
|
const renewToken = () => {
|
|
1559
|
-
logger$
|
|
1743
|
+
logger$2.debug("withAuth renewing token");
|
|
1560
1744
|
clearTimeout(renewTimeout);
|
|
1561
1745
|
current = tokenProvider().then(([token, expiry]) => {
|
|
1562
|
-
logger$
|
|
1746
|
+
logger$2.debug("withAuth renew success %s", expiry && expiry.valueOf() - Date.now());
|
|
1563
1747
|
if (expiry) {
|
|
1564
1748
|
const ttl = expiry.valueOf() - Date.now();
|
|
1565
1749
|
renewTimeout = portableSetTimeout(renewToken, .8 * ttl);
|
|
@@ -1631,7 +1815,7 @@ function withRouter(routes) {
|
|
|
1631
1815
|
return async (url, init = {}) => {
|
|
1632
1816
|
const match = table.find(([pred]) => pred(url));
|
|
1633
1817
|
if (!match) {
|
|
1634
|
-
logger$
|
|
1818
|
+
logger$2.info("withRouter no route matched %s, falling through", url);
|
|
1635
1819
|
return next(url, init);
|
|
1636
1820
|
}
|
|
1637
1821
|
return match[1](url, init);
|
|
@@ -1641,13 +1825,13 @@ function withRouter(routes) {
|
|
|
1641
1825
|
function withResponse(factory) {
|
|
1642
1826
|
return (_next) => factory;
|
|
1643
1827
|
}
|
|
1644
|
-
const fetchLogger = logger$
|
|
1645
|
-
function withLogging(logger$
|
|
1828
|
+
const fetchLogger = logger$2;
|
|
1829
|
+
function withLogging(logger$3 = fetchLogger) {
|
|
1646
1830
|
return (next) => async (url, init) => {
|
|
1647
1831
|
const start = Date.now();
|
|
1648
1832
|
const resp = await next(url, init);
|
|
1649
1833
|
const duration = Date.now() - start;
|
|
1650
|
-
logger$
|
|
1834
|
+
logger$3.info("%s %s (%i) %dms", (init?.method ?? "get").toUpperCase(), url.split("?", 1)[0], resp.status, duration);
|
|
1651
1835
|
return resp;
|
|
1652
1836
|
};
|
|
1653
1837
|
}
|
|
@@ -1699,7 +1883,7 @@ var ConfidenceServerProviderLocal = class ConfidenceServerProviderLocal {
|
|
|
1699
1883
|
baseInterval: 500,
|
|
1700
1884
|
maxInterval: DEFAULT_STATE_INTERVAL
|
|
1701
1885
|
}), withStallTimeout(500)],
|
|
1702
|
-
"https://
|
|
1886
|
+
"https://resolver.confidence.dev/*": [withConfidenceAuth, withRouter({
|
|
1703
1887
|
"*/v1/resolverState:resolverStateUri": [withFastRetry],
|
|
1704
1888
|
"*/v1/flags:resolve": [withRetry({
|
|
1705
1889
|
maxAttempts: 3,
|
|
@@ -1742,7 +1926,11 @@ var ConfidenceServerProviderLocal = class ConfidenceServerProviderLocal {
|
|
|
1742
1926
|
flags: [`flags/${flagName}`],
|
|
1743
1927
|
evaluationContext: ConfidenceServerProviderLocal.convertEvaluationContext(context),
|
|
1744
1928
|
apply: true,
|
|
1745
|
-
clientSecret: this.options.flagClientSecret
|
|
1929
|
+
clientSecret: this.options.flagClientSecret,
|
|
1930
|
+
sdk: {
|
|
1931
|
+
id: SdkId.SDK_ID_JS_LOCAL_SERVER_PROVIDER,
|
|
1932
|
+
version: VERSION
|
|
1933
|
+
}
|
|
1746
1934
|
},
|
|
1747
1935
|
materializationsPerUnit: {},
|
|
1748
1936
|
failFastOnSticky: true
|
|
@@ -1827,7 +2015,7 @@ var ConfidenceServerProviderLocal = class ConfidenceServerProviderLocal {
|
|
|
1827
2015
|
});
|
|
1828
2016
|
}
|
|
1829
2017
|
async fetchResolveStateUri(signal) {
|
|
1830
|
-
const resp = await this.fetch("https://
|
|
2018
|
+
const resp = await this.fetch("https://resolver.confidence.dev/v1/resolverState:resolverStateUri", { signal });
|
|
1831
2019
|
if (!resp.ok) throw new Error("Failed to get resolve state url");
|
|
1832
2020
|
return resp.json();
|
|
1833
2021
|
}
|
|
@@ -2108,11 +2296,22 @@ function longToNumber(int64) {
|
|
|
2108
2296
|
function isSet(value) {
|
|
2109
2297
|
return value !== null && value !== void 0;
|
|
2110
2298
|
}
|
|
2111
|
-
|
|
2299
|
+
const logger = getLogger("wasm-resolver");
|
|
2300
|
+
const EXPORT_FN_NAMES = [
|
|
2301
|
+
"wasm_msg_alloc",
|
|
2302
|
+
"wasm_msg_free",
|
|
2303
|
+
"wasm_msg_guest_resolve_with_sticky",
|
|
2304
|
+
"wasm_msg_guest_set_resolver_state",
|
|
2305
|
+
"wasm_msg_guest_flush_logs"
|
|
2306
|
+
];
|
|
2307
|
+
function verifyExports(exports) {
|
|
2308
|
+
for (const fnName of EXPORT_FN_NAMES) if (typeof exports[fnName] !== "function") throw new Error(`Expected Function export "${fnName}" found ${exports[fnName]}`);
|
|
2309
|
+
if (!(exports.memory instanceof WebAssembly.Memory)) throw new Error(`Expected WebAssembly.Memory export "memory", found ${exports.memory}`);
|
|
2310
|
+
}
|
|
2311
|
+
var UnsafeWasmResolver = class {
|
|
2112
2312
|
exports;
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
this.imports = { wasm_msg: { wasm_msg_host_current_time: () => {
|
|
2313
|
+
constructor(module$1) {
|
|
2314
|
+
const { exports } = new WebAssembly.Instance(module$1, { wasm_msg: { wasm_msg_host_current_time: () => {
|
|
2116
2315
|
const epochMillisecond = Date.now();
|
|
2117
2316
|
const seconds = Math.floor(epochMillisecond / 1e3);
|
|
2118
2317
|
const nanos = (epochMillisecond - 1e3 * seconds) * 1e6;
|
|
@@ -2120,7 +2319,9 @@ var WasmResolver = class WasmResolver {
|
|
|
2120
2319
|
seconds,
|
|
2121
2320
|
nanos
|
|
2122
2321
|
}, Timestamp);
|
|
2123
|
-
} } };
|
|
2322
|
+
} } });
|
|
2323
|
+
verifyExports(exports);
|
|
2324
|
+
this.exports = exports;
|
|
2124
2325
|
}
|
|
2125
2326
|
resolveWithSticky(request) {
|
|
2126
2327
|
const reqPtr = this.transferRequest(request, ResolveWithStickyRequest);
|
|
@@ -2166,15 +2367,65 @@ var WasmResolver = class WasmResolver {
|
|
|
2166
2367
|
free(ptr) {
|
|
2167
2368
|
this.exports.wasm_msg_free(ptr);
|
|
2168
2369
|
}
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2370
|
+
};
|
|
2371
|
+
const DEFAULT_DELEGATE_FACTORY = (module$1) => new UnsafeWasmResolver(module$1);
|
|
2372
|
+
var WasmResolver = class {
|
|
2373
|
+
delegate;
|
|
2374
|
+
currentState;
|
|
2375
|
+
bufferedLogs = [];
|
|
2376
|
+
constructor(module$1, delegateFactory = DEFAULT_DELEGATE_FACTORY) {
|
|
2377
|
+
this.module = module$1;
|
|
2378
|
+
this.delegateFactory = delegateFactory;
|
|
2379
|
+
this.delegate = delegateFactory(module$1);
|
|
2380
|
+
}
|
|
2381
|
+
reloadInstance(error) {
|
|
2382
|
+
logger.error("Failure calling into wasm:", error);
|
|
2383
|
+
try {
|
|
2384
|
+
this.bufferedLogs.push(this.delegate.flushLogs());
|
|
2385
|
+
} catch (_) {
|
|
2386
|
+
logger.error("Failed to flushLogs on error");
|
|
2387
|
+
}
|
|
2388
|
+
this.delegate = this.delegateFactory(this.module);
|
|
2389
|
+
if (this.currentState) this.delegate.setResolverState(this.currentState);
|
|
2390
|
+
}
|
|
2391
|
+
resolveWithSticky(request) {
|
|
2392
|
+
try {
|
|
2393
|
+
return this.delegate.resolveWithSticky(request);
|
|
2394
|
+
} catch (error) {
|
|
2395
|
+
if (error instanceof WebAssembly.RuntimeError) this.reloadInstance(error);
|
|
2396
|
+
throw error;
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2399
|
+
setResolverState(request) {
|
|
2400
|
+
this.currentState = request;
|
|
2401
|
+
try {
|
|
2402
|
+
this.delegate.setResolverState(request);
|
|
2403
|
+
} catch (error) {
|
|
2404
|
+
if (error instanceof WebAssembly.RuntimeError) this.reloadInstance(error);
|
|
2405
|
+
throw error;
|
|
2406
|
+
}
|
|
2407
|
+
}
|
|
2408
|
+
flushLogs() {
|
|
2409
|
+
try {
|
|
2410
|
+
this.bufferedLogs.push(this.delegate.flushLogs());
|
|
2411
|
+
const len = this.bufferedLogs.reduce((sum, chunk) => sum + chunk.length, 0);
|
|
2412
|
+
const buffer = new Uint8Array(len);
|
|
2413
|
+
let offset = 0;
|
|
2414
|
+
for (const chunk of this.bufferedLogs) {
|
|
2415
|
+
buffer.set(chunk, offset);
|
|
2416
|
+
offset += chunk.length;
|
|
2417
|
+
}
|
|
2418
|
+
this.bufferedLogs.length = 0;
|
|
2419
|
+
return buffer;
|
|
2420
|
+
} catch (error) {
|
|
2421
|
+
if (error instanceof WebAssembly.RuntimeError) this.reloadInstance(error);
|
|
2422
|
+
throw error;
|
|
2423
|
+
}
|
|
2173
2424
|
}
|
|
2174
2425
|
};
|
|
2175
2426
|
const wasmUrl = new URL("confidence_resolver.wasm", import.meta.url);
|
|
2176
2427
|
const module = await WebAssembly.compileStreaming(fetch(wasmUrl));
|
|
2177
|
-
const resolver =
|
|
2428
|
+
const resolver = new WasmResolver(module);
|
|
2178
2429
|
function createConfidenceServerProvider(options) {
|
|
2179
2430
|
return new ConfidenceServerProviderLocal(resolver, options);
|
|
2180
2431
|
}
|
package/dist/index.node.d.ts
CHANGED
|
@@ -2,6 +2,32 @@ import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
|
|
2
2
|
import { EvaluationContext, JsonValue, Provider, ProviderMetadata, ProviderStatus, ResolutionDetails } from "@openfeature/server-sdk";
|
|
3
3
|
|
|
4
4
|
//#region src/proto/api.d.ts
|
|
5
|
+
declare enum SdkId {
|
|
6
|
+
SDK_ID_UNSPECIFIED = 0,
|
|
7
|
+
SDK_ID_JAVA_PROVIDER = 1,
|
|
8
|
+
SDK_ID_KOTLIN_PROVIDER = 2,
|
|
9
|
+
SDK_ID_SWIFT_PROVIDER = 3,
|
|
10
|
+
SDK_ID_JS_WEB_PROVIDER = 4,
|
|
11
|
+
SDK_ID_JS_SERVER_PROVIDER = 5,
|
|
12
|
+
SDK_ID_PYTHON_PROVIDER = 6,
|
|
13
|
+
SDK_ID_GO_PROVIDER = 7,
|
|
14
|
+
SDK_ID_RUBY_PROVIDER = 8,
|
|
15
|
+
SDK_ID_RUST_PROVIDER = 9,
|
|
16
|
+
SDK_ID_JAVA_CONFIDENCE = 10,
|
|
17
|
+
SDK_ID_KOTLIN_CONFIDENCE = 11,
|
|
18
|
+
SDK_ID_SWIFT_CONFIDENCE = 12,
|
|
19
|
+
SDK_ID_JS_CONFIDENCE = 13,
|
|
20
|
+
SDK_ID_PYTHON_CONFIDENCE = 14,
|
|
21
|
+
SDK_ID_GO_CONFIDENCE = 15,
|
|
22
|
+
SDK_ID_RUST_CONFIDENCE = 16,
|
|
23
|
+
SDK_ID_FLUTTER_IOS_CONFIDENCE = 17,
|
|
24
|
+
SDK_ID_FLUTTER_ANDROID_CONFIDENCE = 18,
|
|
25
|
+
SDK_ID_DOTNET_CONFIDENCE = 19,
|
|
26
|
+
SDK_ID_GO_LOCAL_PROVIDER = 20,
|
|
27
|
+
SDK_ID_JAVA_LOCAL_PROVIDER = 21,
|
|
28
|
+
SDK_ID_JS_LOCAL_SERVER_PROVIDER = 22,
|
|
29
|
+
UNRECOGNIZED = -1,
|
|
30
|
+
}
|
|
5
31
|
declare enum ResolveReason {
|
|
6
32
|
/** RESOLVE_REASON_UNSPECIFIED - Unspecified enum. */
|
|
7
33
|
RESOLVE_REASON_UNSPECIFIED = 0,
|
|
@@ -24,6 +50,11 @@ declare enum ResolveReason {
|
|
|
24
50
|
RESOLVE_REASON_ERROR = 6,
|
|
25
51
|
UNRECOGNIZED = -1,
|
|
26
52
|
}
|
|
53
|
+
interface Sdk {
|
|
54
|
+
id?: SdkId | undefined;
|
|
55
|
+
customId?: string | undefined;
|
|
56
|
+
version: string;
|
|
57
|
+
}
|
|
27
58
|
interface ResolveFlagsRequest {
|
|
28
59
|
/**
|
|
29
60
|
* If non-empty, the specific flags are resolved, otherwise all flags
|
|
@@ -50,6 +81,8 @@ interface ResolveFlagsRequest {
|
|
|
50
81
|
* `apply` should likely be set to false.
|
|
51
82
|
*/
|
|
52
83
|
apply: boolean;
|
|
84
|
+
/** Information about the SDK used to initiate the request. */
|
|
85
|
+
sdk?: Sdk | undefined;
|
|
53
86
|
}
|
|
54
87
|
interface ResolveFlagsResponse {
|
|
55
88
|
/**
|
|
@@ -143,6 +176,7 @@ interface ResolveWithStickyResponse_MaterializationUpdate {
|
|
|
143
176
|
rule: string;
|
|
144
177
|
variant: string;
|
|
145
178
|
}
|
|
179
|
+
declare const Sdk: MessageFns<Sdk>;
|
|
146
180
|
declare const ResolveFlagsRequest: MessageFns<ResolveFlagsRequest>;
|
|
147
181
|
declare const ResolveFlagsResponse: MessageFns<ResolveFlagsResponse>;
|
|
148
182
|
declare const ResolvedFlag: MessageFns<ResolvedFlag>;
|
package/dist/index.node.js
CHANGED
|
@@ -318,6 +318,115 @@ function isObject$1(value) {
|
|
|
318
318
|
function isSet$3(value) {
|
|
319
319
|
return value !== null && value !== void 0;
|
|
320
320
|
}
|
|
321
|
+
let SdkId = /* @__PURE__ */ function(SdkId$1) {
|
|
322
|
+
SdkId$1[SdkId$1["SDK_ID_UNSPECIFIED"] = 0] = "SDK_ID_UNSPECIFIED";
|
|
323
|
+
SdkId$1[SdkId$1["SDK_ID_JAVA_PROVIDER"] = 1] = "SDK_ID_JAVA_PROVIDER";
|
|
324
|
+
SdkId$1[SdkId$1["SDK_ID_KOTLIN_PROVIDER"] = 2] = "SDK_ID_KOTLIN_PROVIDER";
|
|
325
|
+
SdkId$1[SdkId$1["SDK_ID_SWIFT_PROVIDER"] = 3] = "SDK_ID_SWIFT_PROVIDER";
|
|
326
|
+
SdkId$1[SdkId$1["SDK_ID_JS_WEB_PROVIDER"] = 4] = "SDK_ID_JS_WEB_PROVIDER";
|
|
327
|
+
SdkId$1[SdkId$1["SDK_ID_JS_SERVER_PROVIDER"] = 5] = "SDK_ID_JS_SERVER_PROVIDER";
|
|
328
|
+
SdkId$1[SdkId$1["SDK_ID_PYTHON_PROVIDER"] = 6] = "SDK_ID_PYTHON_PROVIDER";
|
|
329
|
+
SdkId$1[SdkId$1["SDK_ID_GO_PROVIDER"] = 7] = "SDK_ID_GO_PROVIDER";
|
|
330
|
+
SdkId$1[SdkId$1["SDK_ID_RUBY_PROVIDER"] = 8] = "SDK_ID_RUBY_PROVIDER";
|
|
331
|
+
SdkId$1[SdkId$1["SDK_ID_RUST_PROVIDER"] = 9] = "SDK_ID_RUST_PROVIDER";
|
|
332
|
+
SdkId$1[SdkId$1["SDK_ID_JAVA_CONFIDENCE"] = 10] = "SDK_ID_JAVA_CONFIDENCE";
|
|
333
|
+
SdkId$1[SdkId$1["SDK_ID_KOTLIN_CONFIDENCE"] = 11] = "SDK_ID_KOTLIN_CONFIDENCE";
|
|
334
|
+
SdkId$1[SdkId$1["SDK_ID_SWIFT_CONFIDENCE"] = 12] = "SDK_ID_SWIFT_CONFIDENCE";
|
|
335
|
+
SdkId$1[SdkId$1["SDK_ID_JS_CONFIDENCE"] = 13] = "SDK_ID_JS_CONFIDENCE";
|
|
336
|
+
SdkId$1[SdkId$1["SDK_ID_PYTHON_CONFIDENCE"] = 14] = "SDK_ID_PYTHON_CONFIDENCE";
|
|
337
|
+
SdkId$1[SdkId$1["SDK_ID_GO_CONFIDENCE"] = 15] = "SDK_ID_GO_CONFIDENCE";
|
|
338
|
+
SdkId$1[SdkId$1["SDK_ID_RUST_CONFIDENCE"] = 16] = "SDK_ID_RUST_CONFIDENCE";
|
|
339
|
+
SdkId$1[SdkId$1["SDK_ID_FLUTTER_IOS_CONFIDENCE"] = 17] = "SDK_ID_FLUTTER_IOS_CONFIDENCE";
|
|
340
|
+
SdkId$1[SdkId$1["SDK_ID_FLUTTER_ANDROID_CONFIDENCE"] = 18] = "SDK_ID_FLUTTER_ANDROID_CONFIDENCE";
|
|
341
|
+
SdkId$1[SdkId$1["SDK_ID_DOTNET_CONFIDENCE"] = 19] = "SDK_ID_DOTNET_CONFIDENCE";
|
|
342
|
+
SdkId$1[SdkId$1["SDK_ID_GO_LOCAL_PROVIDER"] = 20] = "SDK_ID_GO_LOCAL_PROVIDER";
|
|
343
|
+
SdkId$1[SdkId$1["SDK_ID_JAVA_LOCAL_PROVIDER"] = 21] = "SDK_ID_JAVA_LOCAL_PROVIDER";
|
|
344
|
+
SdkId$1[SdkId$1["SDK_ID_JS_LOCAL_SERVER_PROVIDER"] = 22] = "SDK_ID_JS_LOCAL_SERVER_PROVIDER";
|
|
345
|
+
SdkId$1[SdkId$1["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
|
|
346
|
+
return SdkId$1;
|
|
347
|
+
}({});
|
|
348
|
+
function sdkIdFromJSON(object) {
|
|
349
|
+
switch (object) {
|
|
350
|
+
case 0:
|
|
351
|
+
case "SDK_ID_UNSPECIFIED": return SdkId.SDK_ID_UNSPECIFIED;
|
|
352
|
+
case 1:
|
|
353
|
+
case "SDK_ID_JAVA_PROVIDER": return SdkId.SDK_ID_JAVA_PROVIDER;
|
|
354
|
+
case 2:
|
|
355
|
+
case "SDK_ID_KOTLIN_PROVIDER": return SdkId.SDK_ID_KOTLIN_PROVIDER;
|
|
356
|
+
case 3:
|
|
357
|
+
case "SDK_ID_SWIFT_PROVIDER": return SdkId.SDK_ID_SWIFT_PROVIDER;
|
|
358
|
+
case 4:
|
|
359
|
+
case "SDK_ID_JS_WEB_PROVIDER": return SdkId.SDK_ID_JS_WEB_PROVIDER;
|
|
360
|
+
case 5:
|
|
361
|
+
case "SDK_ID_JS_SERVER_PROVIDER": return SdkId.SDK_ID_JS_SERVER_PROVIDER;
|
|
362
|
+
case 6:
|
|
363
|
+
case "SDK_ID_PYTHON_PROVIDER": return SdkId.SDK_ID_PYTHON_PROVIDER;
|
|
364
|
+
case 7:
|
|
365
|
+
case "SDK_ID_GO_PROVIDER": return SdkId.SDK_ID_GO_PROVIDER;
|
|
366
|
+
case 8:
|
|
367
|
+
case "SDK_ID_RUBY_PROVIDER": return SdkId.SDK_ID_RUBY_PROVIDER;
|
|
368
|
+
case 9:
|
|
369
|
+
case "SDK_ID_RUST_PROVIDER": return SdkId.SDK_ID_RUST_PROVIDER;
|
|
370
|
+
case 10:
|
|
371
|
+
case "SDK_ID_JAVA_CONFIDENCE": return SdkId.SDK_ID_JAVA_CONFIDENCE;
|
|
372
|
+
case 11:
|
|
373
|
+
case "SDK_ID_KOTLIN_CONFIDENCE": return SdkId.SDK_ID_KOTLIN_CONFIDENCE;
|
|
374
|
+
case 12:
|
|
375
|
+
case "SDK_ID_SWIFT_CONFIDENCE": return SdkId.SDK_ID_SWIFT_CONFIDENCE;
|
|
376
|
+
case 13:
|
|
377
|
+
case "SDK_ID_JS_CONFIDENCE": return SdkId.SDK_ID_JS_CONFIDENCE;
|
|
378
|
+
case 14:
|
|
379
|
+
case "SDK_ID_PYTHON_CONFIDENCE": return SdkId.SDK_ID_PYTHON_CONFIDENCE;
|
|
380
|
+
case 15:
|
|
381
|
+
case "SDK_ID_GO_CONFIDENCE": return SdkId.SDK_ID_GO_CONFIDENCE;
|
|
382
|
+
case 16:
|
|
383
|
+
case "SDK_ID_RUST_CONFIDENCE": return SdkId.SDK_ID_RUST_CONFIDENCE;
|
|
384
|
+
case 17:
|
|
385
|
+
case "SDK_ID_FLUTTER_IOS_CONFIDENCE": return SdkId.SDK_ID_FLUTTER_IOS_CONFIDENCE;
|
|
386
|
+
case 18:
|
|
387
|
+
case "SDK_ID_FLUTTER_ANDROID_CONFIDENCE": return SdkId.SDK_ID_FLUTTER_ANDROID_CONFIDENCE;
|
|
388
|
+
case 19:
|
|
389
|
+
case "SDK_ID_DOTNET_CONFIDENCE": return SdkId.SDK_ID_DOTNET_CONFIDENCE;
|
|
390
|
+
case 20:
|
|
391
|
+
case "SDK_ID_GO_LOCAL_PROVIDER": return SdkId.SDK_ID_GO_LOCAL_PROVIDER;
|
|
392
|
+
case 21:
|
|
393
|
+
case "SDK_ID_JAVA_LOCAL_PROVIDER": return SdkId.SDK_ID_JAVA_LOCAL_PROVIDER;
|
|
394
|
+
case 22:
|
|
395
|
+
case "SDK_ID_JS_LOCAL_SERVER_PROVIDER": return SdkId.SDK_ID_JS_LOCAL_SERVER_PROVIDER;
|
|
396
|
+
case -1:
|
|
397
|
+
case "UNRECOGNIZED":
|
|
398
|
+
default: return SdkId.UNRECOGNIZED;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
function sdkIdToJSON(object) {
|
|
402
|
+
switch (object) {
|
|
403
|
+
case SdkId.SDK_ID_UNSPECIFIED: return "SDK_ID_UNSPECIFIED";
|
|
404
|
+
case SdkId.SDK_ID_JAVA_PROVIDER: return "SDK_ID_JAVA_PROVIDER";
|
|
405
|
+
case SdkId.SDK_ID_KOTLIN_PROVIDER: return "SDK_ID_KOTLIN_PROVIDER";
|
|
406
|
+
case SdkId.SDK_ID_SWIFT_PROVIDER: return "SDK_ID_SWIFT_PROVIDER";
|
|
407
|
+
case SdkId.SDK_ID_JS_WEB_PROVIDER: return "SDK_ID_JS_WEB_PROVIDER";
|
|
408
|
+
case SdkId.SDK_ID_JS_SERVER_PROVIDER: return "SDK_ID_JS_SERVER_PROVIDER";
|
|
409
|
+
case SdkId.SDK_ID_PYTHON_PROVIDER: return "SDK_ID_PYTHON_PROVIDER";
|
|
410
|
+
case SdkId.SDK_ID_GO_PROVIDER: return "SDK_ID_GO_PROVIDER";
|
|
411
|
+
case SdkId.SDK_ID_RUBY_PROVIDER: return "SDK_ID_RUBY_PROVIDER";
|
|
412
|
+
case SdkId.SDK_ID_RUST_PROVIDER: return "SDK_ID_RUST_PROVIDER";
|
|
413
|
+
case SdkId.SDK_ID_JAVA_CONFIDENCE: return "SDK_ID_JAVA_CONFIDENCE";
|
|
414
|
+
case SdkId.SDK_ID_KOTLIN_CONFIDENCE: return "SDK_ID_KOTLIN_CONFIDENCE";
|
|
415
|
+
case SdkId.SDK_ID_SWIFT_CONFIDENCE: return "SDK_ID_SWIFT_CONFIDENCE";
|
|
416
|
+
case SdkId.SDK_ID_JS_CONFIDENCE: return "SDK_ID_JS_CONFIDENCE";
|
|
417
|
+
case SdkId.SDK_ID_PYTHON_CONFIDENCE: return "SDK_ID_PYTHON_CONFIDENCE";
|
|
418
|
+
case SdkId.SDK_ID_GO_CONFIDENCE: return "SDK_ID_GO_CONFIDENCE";
|
|
419
|
+
case SdkId.SDK_ID_RUST_CONFIDENCE: return "SDK_ID_RUST_CONFIDENCE";
|
|
420
|
+
case SdkId.SDK_ID_FLUTTER_IOS_CONFIDENCE: return "SDK_ID_FLUTTER_IOS_CONFIDENCE";
|
|
421
|
+
case SdkId.SDK_ID_FLUTTER_ANDROID_CONFIDENCE: return "SDK_ID_FLUTTER_ANDROID_CONFIDENCE";
|
|
422
|
+
case SdkId.SDK_ID_DOTNET_CONFIDENCE: return "SDK_ID_DOTNET_CONFIDENCE";
|
|
423
|
+
case SdkId.SDK_ID_GO_LOCAL_PROVIDER: return "SDK_ID_GO_LOCAL_PROVIDER";
|
|
424
|
+
case SdkId.SDK_ID_JAVA_LOCAL_PROVIDER: return "SDK_ID_JAVA_LOCAL_PROVIDER";
|
|
425
|
+
case SdkId.SDK_ID_JS_LOCAL_SERVER_PROVIDER: return "SDK_ID_JS_LOCAL_SERVER_PROVIDER";
|
|
426
|
+
case SdkId.UNRECOGNIZED:
|
|
427
|
+
default: return "UNRECOGNIZED";
|
|
428
|
+
}
|
|
429
|
+
}
|
|
321
430
|
let ResolveReason = /* @__PURE__ */ function(ResolveReason$1) {
|
|
322
431
|
ResolveReason$1[ResolveReason$1["RESOLVE_REASON_UNSPECIFIED"] = 0] = "RESOLVE_REASON_UNSPECIFIED";
|
|
323
432
|
ResolveReason$1[ResolveReason$1["RESOLVE_REASON_MATCH"] = 1] = "RESOLVE_REASON_MATCH";
|
|
@@ -363,12 +472,77 @@ function resolveReasonToJSON(object) {
|
|
|
363
472
|
default: return "UNRECOGNIZED";
|
|
364
473
|
}
|
|
365
474
|
}
|
|
475
|
+
function createBaseSdk() {
|
|
476
|
+
return {
|
|
477
|
+
id: void 0,
|
|
478
|
+
customId: void 0,
|
|
479
|
+
version: ""
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
const Sdk = {
|
|
483
|
+
encode(message, writer = new BinaryWriter()) {
|
|
484
|
+
if (message.id !== void 0) writer.uint32(8).int32(message.id);
|
|
485
|
+
if (message.customId !== void 0) writer.uint32(18).string(message.customId);
|
|
486
|
+
if (message.version !== "") writer.uint32(26).string(message.version);
|
|
487
|
+
return writer;
|
|
488
|
+
},
|
|
489
|
+
decode(input, length) {
|
|
490
|
+
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
|
491
|
+
const end = length === void 0 ? reader.len : reader.pos + length;
|
|
492
|
+
const message = createBaseSdk();
|
|
493
|
+
while (reader.pos < end) {
|
|
494
|
+
const tag = reader.uint32();
|
|
495
|
+
switch (tag >>> 3) {
|
|
496
|
+
case 1:
|
|
497
|
+
if (tag !== 8) break;
|
|
498
|
+
message.id = reader.int32();
|
|
499
|
+
continue;
|
|
500
|
+
case 2:
|
|
501
|
+
if (tag !== 18) break;
|
|
502
|
+
message.customId = reader.string();
|
|
503
|
+
continue;
|
|
504
|
+
case 3:
|
|
505
|
+
if (tag !== 26) break;
|
|
506
|
+
message.version = reader.string();
|
|
507
|
+
continue;
|
|
508
|
+
}
|
|
509
|
+
if ((tag & 7) === 4 || tag === 0) break;
|
|
510
|
+
reader.skip(tag & 7);
|
|
511
|
+
}
|
|
512
|
+
return message;
|
|
513
|
+
},
|
|
514
|
+
fromJSON(object) {
|
|
515
|
+
return {
|
|
516
|
+
id: isSet$2(object.id) ? sdkIdFromJSON(object.id) : void 0,
|
|
517
|
+
customId: isSet$2(object.customId) ? globalThis.String(object.customId) : void 0,
|
|
518
|
+
version: isSet$2(object.version) ? globalThis.String(object.version) : ""
|
|
519
|
+
};
|
|
520
|
+
},
|
|
521
|
+
toJSON(message) {
|
|
522
|
+
const obj = {};
|
|
523
|
+
if (message.id !== void 0) obj.id = sdkIdToJSON(message.id);
|
|
524
|
+
if (message.customId !== void 0) obj.customId = message.customId;
|
|
525
|
+
if (message.version !== "") obj.version = message.version;
|
|
526
|
+
return obj;
|
|
527
|
+
},
|
|
528
|
+
create(base) {
|
|
529
|
+
return Sdk.fromPartial(base ?? {});
|
|
530
|
+
},
|
|
531
|
+
fromPartial(object) {
|
|
532
|
+
const message = createBaseSdk();
|
|
533
|
+
message.id = object.id ?? void 0;
|
|
534
|
+
message.customId = object.customId ?? void 0;
|
|
535
|
+
message.version = object.version ?? "";
|
|
536
|
+
return message;
|
|
537
|
+
}
|
|
538
|
+
};
|
|
366
539
|
function createBaseResolveFlagsRequest() {
|
|
367
540
|
return {
|
|
368
541
|
flags: [],
|
|
369
542
|
evaluationContext: void 0,
|
|
370
543
|
clientSecret: "",
|
|
371
|
-
apply: false
|
|
544
|
+
apply: false,
|
|
545
|
+
sdk: void 0
|
|
372
546
|
};
|
|
373
547
|
}
|
|
374
548
|
const ResolveFlagsRequest = {
|
|
@@ -377,6 +551,7 @@ const ResolveFlagsRequest = {
|
|
|
377
551
|
if (message.evaluationContext !== void 0) Struct.encode(Struct.wrap(message.evaluationContext), writer.uint32(18).fork()).join();
|
|
378
552
|
if (message.clientSecret !== "") writer.uint32(26).string(message.clientSecret);
|
|
379
553
|
if (message.apply !== false) writer.uint32(32).bool(message.apply);
|
|
554
|
+
if (message.sdk !== void 0) Sdk.encode(message.sdk, writer.uint32(42).fork()).join();
|
|
380
555
|
return writer;
|
|
381
556
|
},
|
|
382
557
|
decode(input, length) {
|
|
@@ -402,6 +577,10 @@ const ResolveFlagsRequest = {
|
|
|
402
577
|
if (tag !== 32) break;
|
|
403
578
|
message.apply = reader.bool();
|
|
404
579
|
continue;
|
|
580
|
+
case 5:
|
|
581
|
+
if (tag !== 42) break;
|
|
582
|
+
message.sdk = Sdk.decode(reader, reader.uint32());
|
|
583
|
+
continue;
|
|
405
584
|
}
|
|
406
585
|
if ((tag & 7) === 4 || tag === 0) break;
|
|
407
586
|
reader.skip(tag & 7);
|
|
@@ -413,7 +592,8 @@ const ResolveFlagsRequest = {
|
|
|
413
592
|
flags: globalThis.Array.isArray(object?.flags) ? object.flags.map((e) => globalThis.String(e)) : [],
|
|
414
593
|
evaluationContext: isObject(object.evaluationContext) ? object.evaluationContext : void 0,
|
|
415
594
|
clientSecret: isSet$2(object.clientSecret) ? globalThis.String(object.clientSecret) : "",
|
|
416
|
-
apply: isSet$2(object.apply) ? globalThis.Boolean(object.apply) : false
|
|
595
|
+
apply: isSet$2(object.apply) ? globalThis.Boolean(object.apply) : false,
|
|
596
|
+
sdk: isSet$2(object.sdk) ? Sdk.fromJSON(object.sdk) : void 0
|
|
417
597
|
};
|
|
418
598
|
},
|
|
419
599
|
toJSON(message) {
|
|
@@ -422,6 +602,7 @@ const ResolveFlagsRequest = {
|
|
|
422
602
|
if (message.evaluationContext !== void 0) obj.evaluationContext = message.evaluationContext;
|
|
423
603
|
if (message.clientSecret !== "") obj.clientSecret = message.clientSecret;
|
|
424
604
|
if (message.apply !== false) obj.apply = message.apply;
|
|
605
|
+
if (message.sdk !== void 0) obj.sdk = Sdk.toJSON(message.sdk);
|
|
425
606
|
return obj;
|
|
426
607
|
},
|
|
427
608
|
create(base) {
|
|
@@ -433,6 +614,7 @@ const ResolveFlagsRequest = {
|
|
|
433
614
|
message.evaluationContext = object.evaluationContext ?? void 0;
|
|
434
615
|
message.clientSecret = object.clientSecret ?? "";
|
|
435
616
|
message.apply = object.apply ?? false;
|
|
617
|
+
message.sdk = object.sdk !== void 0 && object.sdk !== null ? Sdk.fromPartial(object.sdk) : void 0;
|
|
436
618
|
return message;
|
|
437
619
|
}
|
|
438
620
|
};
|
|
@@ -1331,9 +1513,10 @@ function isObject(value) {
|
|
|
1331
1513
|
function isSet$2(value) {
|
|
1332
1514
|
return value !== null && value !== void 0;
|
|
1333
1515
|
}
|
|
1516
|
+
const VERSION = "0.2.0";
|
|
1334
1517
|
const NOOP_LOG_FN = () => {};
|
|
1335
1518
|
const debugBackend = loadDebug();
|
|
1336
|
-
const logger = new class LoggerImpl {
|
|
1519
|
+
const logger$1 = new class LoggerImpl {
|
|
1337
1520
|
childLoggers = /* @__PURE__ */ new Map();
|
|
1338
1521
|
debug = NOOP_LOG_FN;
|
|
1339
1522
|
info = NOOP_LOG_FN;
|
|
@@ -1365,6 +1548,7 @@ const logger = new class LoggerImpl {
|
|
|
1365
1548
|
return child;
|
|
1366
1549
|
}
|
|
1367
1550
|
}("cnfd");
|
|
1551
|
+
const getLogger = logger$1.getLogger.bind(logger$1);
|
|
1368
1552
|
async function loadDebug() {
|
|
1369
1553
|
try {
|
|
1370
1554
|
const { default: debug } = await import("debug");
|
|
@@ -1394,7 +1578,7 @@ function scheduleWithFixedInterval(operation, intervalMs, opt = {}) {
|
|
|
1394
1578
|
try {
|
|
1395
1579
|
await operation(ac.signal);
|
|
1396
1580
|
} catch (e) {
|
|
1397
|
-
logger.warn("scheduleWithFixedInterval failure:", e);
|
|
1581
|
+
logger$1.warn("scheduleWithFixedInterval failure:", e);
|
|
1398
1582
|
}
|
|
1399
1583
|
concurrent--;
|
|
1400
1584
|
if (Date.now() - lastRunTime > intervalMs && nextRunTimeoutId != 0) {
|
|
@@ -1456,7 +1640,7 @@ function promiseSignal(signal) {
|
|
|
1456
1640
|
function abortablePromise(promise, signal) {
|
|
1457
1641
|
return signal ? Promise.race([promise, promiseSignal(signal)]) : promise;
|
|
1458
1642
|
}
|
|
1459
|
-
const logger$
|
|
1643
|
+
const logger$2 = logger$1.getLogger("fetch");
|
|
1460
1644
|
let Fetch;
|
|
1461
1645
|
(function(_Fetch) {
|
|
1462
1646
|
function create(middleware, sink = fetch) {
|
|
@@ -1527,13 +1711,13 @@ function withRetry(opts) {
|
|
|
1527
1711
|
const onSuccess = async (resp) => {
|
|
1528
1712
|
const { status, statusText } = resp;
|
|
1529
1713
|
if (status !== 408 && status !== 429 && status < 500 || attempts >= maxAttempts) return resp;
|
|
1530
|
-
logger$
|
|
1714
|
+
logger$2.debug("withRetry %s failed attempt %d with %d %s", url, attempts - 1, status, statusText);
|
|
1531
1715
|
const serverDelay = parseRetryAfter(resp.headers.get("Retry-After"), baseInterval, maxInterval);
|
|
1532
1716
|
await abortableSleep(serverDelay ?? deadline - Date.now(), signal);
|
|
1533
1717
|
return doTry();
|
|
1534
1718
|
};
|
|
1535
1719
|
const onError = async (error) => {
|
|
1536
|
-
logger$
|
|
1720
|
+
logger$2.debug("withRetry %s failed attempt %d with %s", url, attempts - 1, error);
|
|
1537
1721
|
if (signal?.aborted || attempts >= maxAttempts) throw error;
|
|
1538
1722
|
await abortableSleep(deadline - Date.now(), signal);
|
|
1539
1723
|
return doTry();
|
|
@@ -1559,10 +1743,10 @@ function withAuth(tokenProvider, signal) {
|
|
|
1559
1743
|
clearTimeout(renewTimeout);
|
|
1560
1744
|
});
|
|
1561
1745
|
const renewToken = () => {
|
|
1562
|
-
logger$
|
|
1746
|
+
logger$2.debug("withAuth renewing token");
|
|
1563
1747
|
clearTimeout(renewTimeout);
|
|
1564
1748
|
current = tokenProvider().then(([token, expiry]) => {
|
|
1565
|
-
logger$
|
|
1749
|
+
logger$2.debug("withAuth renew success %s", expiry && expiry.valueOf() - Date.now());
|
|
1566
1750
|
if (expiry) {
|
|
1567
1751
|
const ttl = expiry.valueOf() - Date.now();
|
|
1568
1752
|
renewTimeout = portableSetTimeout(renewToken, .8 * ttl);
|
|
@@ -1634,7 +1818,7 @@ function withRouter(routes) {
|
|
|
1634
1818
|
return async (url, init = {}) => {
|
|
1635
1819
|
const match = table.find(([pred]) => pred(url));
|
|
1636
1820
|
if (!match) {
|
|
1637
|
-
logger$
|
|
1821
|
+
logger$2.info("withRouter no route matched %s, falling through", url);
|
|
1638
1822
|
return next(url, init);
|
|
1639
1823
|
}
|
|
1640
1824
|
return match[1](url, init);
|
|
@@ -1644,13 +1828,13 @@ function withRouter(routes) {
|
|
|
1644
1828
|
function withResponse(factory) {
|
|
1645
1829
|
return (_next) => factory;
|
|
1646
1830
|
}
|
|
1647
|
-
const fetchLogger = logger$
|
|
1648
|
-
function withLogging(logger$
|
|
1831
|
+
const fetchLogger = logger$2;
|
|
1832
|
+
function withLogging(logger$3 = fetchLogger) {
|
|
1649
1833
|
return (next) => async (url, init) => {
|
|
1650
1834
|
const start = Date.now();
|
|
1651
1835
|
const resp = await next(url, init);
|
|
1652
1836
|
const duration = Date.now() - start;
|
|
1653
|
-
logger$
|
|
1837
|
+
logger$3.info("%s %s (%i) %dms", (init?.method ?? "get").toUpperCase(), url.split("?", 1)[0], resp.status, duration);
|
|
1654
1838
|
return resp;
|
|
1655
1839
|
};
|
|
1656
1840
|
}
|
|
@@ -1702,7 +1886,7 @@ var ConfidenceServerProviderLocal = class ConfidenceServerProviderLocal {
|
|
|
1702
1886
|
baseInterval: 500,
|
|
1703
1887
|
maxInterval: DEFAULT_STATE_INTERVAL
|
|
1704
1888
|
}), withStallTimeout(500)],
|
|
1705
|
-
"https://
|
|
1889
|
+
"https://resolver.confidence.dev/*": [withConfidenceAuth, withRouter({
|
|
1706
1890
|
"*/v1/resolverState:resolverStateUri": [withFastRetry],
|
|
1707
1891
|
"*/v1/flags:resolve": [withRetry({
|
|
1708
1892
|
maxAttempts: 3,
|
|
@@ -1745,7 +1929,11 @@ var ConfidenceServerProviderLocal = class ConfidenceServerProviderLocal {
|
|
|
1745
1929
|
flags: [`flags/${flagName}`],
|
|
1746
1930
|
evaluationContext: ConfidenceServerProviderLocal.convertEvaluationContext(context),
|
|
1747
1931
|
apply: true,
|
|
1748
|
-
clientSecret: this.options.flagClientSecret
|
|
1932
|
+
clientSecret: this.options.flagClientSecret,
|
|
1933
|
+
sdk: {
|
|
1934
|
+
id: SdkId.SDK_ID_JS_LOCAL_SERVER_PROVIDER,
|
|
1935
|
+
version: VERSION
|
|
1936
|
+
}
|
|
1749
1937
|
},
|
|
1750
1938
|
materializationsPerUnit: {},
|
|
1751
1939
|
failFastOnSticky: true
|
|
@@ -1830,7 +2018,7 @@ var ConfidenceServerProviderLocal = class ConfidenceServerProviderLocal {
|
|
|
1830
2018
|
});
|
|
1831
2019
|
}
|
|
1832
2020
|
async fetchResolveStateUri(signal) {
|
|
1833
|
-
const resp = await this.fetch("https://
|
|
2021
|
+
const resp = await this.fetch("https://resolver.confidence.dev/v1/resolverState:resolverStateUri", { signal });
|
|
1834
2022
|
if (!resp.ok) throw new Error("Failed to get resolve state url");
|
|
1835
2023
|
return resp.json();
|
|
1836
2024
|
}
|
|
@@ -2111,11 +2299,22 @@ function longToNumber(int64) {
|
|
|
2111
2299
|
function isSet(value) {
|
|
2112
2300
|
return value !== null && value !== void 0;
|
|
2113
2301
|
}
|
|
2114
|
-
|
|
2302
|
+
const logger = getLogger("wasm-resolver");
|
|
2303
|
+
const EXPORT_FN_NAMES = [
|
|
2304
|
+
"wasm_msg_alloc",
|
|
2305
|
+
"wasm_msg_free",
|
|
2306
|
+
"wasm_msg_guest_resolve_with_sticky",
|
|
2307
|
+
"wasm_msg_guest_set_resolver_state",
|
|
2308
|
+
"wasm_msg_guest_flush_logs"
|
|
2309
|
+
];
|
|
2310
|
+
function verifyExports(exports) {
|
|
2311
|
+
for (const fnName of EXPORT_FN_NAMES) if (typeof exports[fnName] !== "function") throw new Error(`Expected Function export "${fnName}" found ${exports[fnName]}`);
|
|
2312
|
+
if (!(exports.memory instanceof WebAssembly.Memory)) throw new Error(`Expected WebAssembly.Memory export "memory", found ${exports.memory}`);
|
|
2313
|
+
}
|
|
2314
|
+
var UnsafeWasmResolver = class {
|
|
2115
2315
|
exports;
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
this.imports = { wasm_msg: { wasm_msg_host_current_time: () => {
|
|
2316
|
+
constructor(module$1) {
|
|
2317
|
+
const { exports } = new WebAssembly.Instance(module$1, { wasm_msg: { wasm_msg_host_current_time: () => {
|
|
2119
2318
|
const epochMillisecond = Date.now();
|
|
2120
2319
|
const seconds = Math.floor(epochMillisecond / 1e3);
|
|
2121
2320
|
const nanos = (epochMillisecond - 1e3 * seconds) * 1e6;
|
|
@@ -2123,7 +2322,9 @@ var WasmResolver = class WasmResolver {
|
|
|
2123
2322
|
seconds,
|
|
2124
2323
|
nanos
|
|
2125
2324
|
}, Timestamp);
|
|
2126
|
-
} } };
|
|
2325
|
+
} } });
|
|
2326
|
+
verifyExports(exports);
|
|
2327
|
+
this.exports = exports;
|
|
2127
2328
|
}
|
|
2128
2329
|
resolveWithSticky(request) {
|
|
2129
2330
|
const reqPtr = this.transferRequest(request, ResolveWithStickyRequest);
|
|
@@ -2169,16 +2370,66 @@ var WasmResolver = class WasmResolver {
|
|
|
2169
2370
|
free(ptr) {
|
|
2170
2371
|
this.exports.wasm_msg_free(ptr);
|
|
2171
2372
|
}
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2373
|
+
};
|
|
2374
|
+
const DEFAULT_DELEGATE_FACTORY = (module$1) => new UnsafeWasmResolver(module$1);
|
|
2375
|
+
var WasmResolver = class {
|
|
2376
|
+
delegate;
|
|
2377
|
+
currentState;
|
|
2378
|
+
bufferedLogs = [];
|
|
2379
|
+
constructor(module$1, delegateFactory = DEFAULT_DELEGATE_FACTORY) {
|
|
2380
|
+
this.module = module$1;
|
|
2381
|
+
this.delegateFactory = delegateFactory;
|
|
2382
|
+
this.delegate = delegateFactory(module$1);
|
|
2383
|
+
}
|
|
2384
|
+
reloadInstance(error) {
|
|
2385
|
+
logger.error("Failure calling into wasm:", error);
|
|
2386
|
+
try {
|
|
2387
|
+
this.bufferedLogs.push(this.delegate.flushLogs());
|
|
2388
|
+
} catch (_) {
|
|
2389
|
+
logger.error("Failed to flushLogs on error");
|
|
2390
|
+
}
|
|
2391
|
+
this.delegate = this.delegateFactory(this.module);
|
|
2392
|
+
if (this.currentState) this.delegate.setResolverState(this.currentState);
|
|
2393
|
+
}
|
|
2394
|
+
resolveWithSticky(request) {
|
|
2395
|
+
try {
|
|
2396
|
+
return this.delegate.resolveWithSticky(request);
|
|
2397
|
+
} catch (error) {
|
|
2398
|
+
if (error instanceof WebAssembly.RuntimeError) this.reloadInstance(error);
|
|
2399
|
+
throw error;
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
setResolverState(request) {
|
|
2403
|
+
this.currentState = request;
|
|
2404
|
+
try {
|
|
2405
|
+
this.delegate.setResolverState(request);
|
|
2406
|
+
} catch (error) {
|
|
2407
|
+
if (error instanceof WebAssembly.RuntimeError) this.reloadInstance(error);
|
|
2408
|
+
throw error;
|
|
2409
|
+
}
|
|
2410
|
+
}
|
|
2411
|
+
flushLogs() {
|
|
2412
|
+
try {
|
|
2413
|
+
this.bufferedLogs.push(this.delegate.flushLogs());
|
|
2414
|
+
const len = this.bufferedLogs.reduce((sum, chunk) => sum + chunk.length, 0);
|
|
2415
|
+
const buffer$1 = new Uint8Array(len);
|
|
2416
|
+
let offset = 0;
|
|
2417
|
+
for (const chunk of this.bufferedLogs) {
|
|
2418
|
+
buffer$1.set(chunk, offset);
|
|
2419
|
+
offset += chunk.length;
|
|
2420
|
+
}
|
|
2421
|
+
this.bufferedLogs.length = 0;
|
|
2422
|
+
return buffer$1;
|
|
2423
|
+
} catch (error) {
|
|
2424
|
+
if (error instanceof WebAssembly.RuntimeError) this.reloadInstance(error);
|
|
2425
|
+
throw error;
|
|
2426
|
+
}
|
|
2176
2427
|
}
|
|
2177
2428
|
};
|
|
2178
2429
|
const wasmPath = __require.resolve("./confidence_resolver.wasm");
|
|
2179
2430
|
const buffer = await fs.readFile(wasmPath);
|
|
2180
2431
|
const module = await WebAssembly.compile(buffer);
|
|
2181
|
-
const resolver =
|
|
2432
|
+
const resolver = new WasmResolver(module);
|
|
2182
2433
|
function createConfidenceServerProvider(options) {
|
|
2183
2434
|
return new ConfidenceServerProviderLocal(resolver, options);
|
|
2184
2435
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spotify-confidence/openfeature-server-provider-local",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Spotify Confidence Open Feature provider",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -32,8 +32,10 @@
|
|
|
32
32
|
"scripts": {
|
|
33
33
|
"build": "tsdown",
|
|
34
34
|
"dev": "tsdown --watch",
|
|
35
|
+
"format": "prettier --config prettier.config.cjs -w .",
|
|
36
|
+
"format:check": "prettier --config prettier.config.cjs -c .",
|
|
35
37
|
"test": "vitest",
|
|
36
|
-
"proto:gen": "rm -rf src/proto && mkdir -p src/proto && protoc --plugin=node_modules/.bin/protoc-gen-ts_proto --ts_proto_opt useOptionals=messages --ts_proto_opt esModuleInterop=true --ts_proto_out src/proto -Iproto api.proto messages.proto"
|
|
38
|
+
"proto:gen": "rm -rf src/proto && mkdir -p src/proto && protoc --plugin=node_modules/.bin/protoc-gen-ts_proto --ts_proto_opt useOptionals=messages --ts_proto_opt esModuleInterop=true --ts_proto_out src/proto -Iproto api.proto messages.proto test-only.proto"
|
|
37
39
|
},
|
|
38
40
|
"dependencies": {
|
|
39
41
|
"@bufbuild/protobuf": "^2.9.0"
|
|
@@ -41,11 +43,13 @@
|
|
|
41
43
|
"devDependencies": {
|
|
42
44
|
"@openfeature/core": "^1.9.0",
|
|
43
45
|
"@openfeature/server-sdk": "^1.19.0",
|
|
46
|
+
"@spotify/prettier-config": "^15.0.0",
|
|
44
47
|
"@types/debug": "^4",
|
|
45
48
|
"@types/node": "^24.0.1",
|
|
46
49
|
"@vitest/coverage-v8": "^3.2.4",
|
|
47
50
|
"debug": "^4.4.3",
|
|
48
51
|
"dotenv": "^17.2.2",
|
|
52
|
+
"prettier": "^2.8.8",
|
|
49
53
|
"rolldown": "1.0.0-beta.38",
|
|
50
54
|
"ts-proto": "^2.7.3",
|
|
51
55
|
"tsdown": "latest",
|
|
@@ -62,7 +66,7 @@
|
|
|
62
66
|
"packageManager": "yarn@4.6.0",
|
|
63
67
|
"repository": {
|
|
64
68
|
"type": "git",
|
|
65
|
-
"url": "https://github.com/spotify/confidence-resolver
|
|
69
|
+
"url": "https://github.com/spotify/confidence-resolver",
|
|
66
70
|
"directory": "openfeature-provider/js"
|
|
67
71
|
},
|
|
68
72
|
"license": "Apache-2.0",
|
|
@@ -76,7 +80,7 @@
|
|
|
76
80
|
],
|
|
77
81
|
"author": "Spotify",
|
|
78
82
|
"bugs": {
|
|
79
|
-
"url": "https://github.com/spotify/confidence-resolver
|
|
83
|
+
"url": "https://github.com/spotify/confidence-resolver/issues"
|
|
80
84
|
},
|
|
81
|
-
"homepage": "https://github.com/spotify/confidence-resolver
|
|
85
|
+
"homepage": "https://github.com/spotify/confidence-resolver?tab=readme-ov-file#confidence-rust-flags-resolver"
|
|
82
86
|
}
|