@flagward/openfeature-web 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Brian Suárez
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,131 @@
1
+ # @flagward/openfeature-web
2
+
3
+ [OpenFeature](https://openfeature.dev) web provider for
4
+ [Flagward](https://github.com/basb7/flagward). Flags are downloaded once and
5
+ evaluated in the browser, so an evaluation costs nothing and never blocks on
6
+ the network — and changes still arrive in real time over SSE.
7
+
8
+ If your application already talks to OpenFeature, switching to Flagward is one
9
+ line. If it does not, you probably want the Flagward adapter for your framework
10
+ instead (`@flagward/react`, `@flagward/vue`, `@flagward/solid`,
11
+ `@flagward/svelte`).
12
+
13
+ > [!NOTE]
14
+ > This provider is for the browser (`@openfeature/web-sdk`). A server provider
15
+ > for `@openfeature/server-sdk` is not available yet.
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install @openfeature/web-sdk @flagward/openfeature-web
21
+ ```
22
+
23
+ `@flagward/core` comes with the provider — you do not install it separately.
24
+
25
+ ## Quick start
26
+
27
+ ```ts
28
+ import { OpenFeature } from "@openfeature/web-sdk";
29
+ import { FlagwardWebProvider } from "@flagward/openfeature-web";
30
+
31
+ await OpenFeature.setContext({ targetingKey: user.id, country: user.country });
32
+ await OpenFeature.setProviderAndWait(
33
+ new FlagwardWebProvider({
34
+ apiKey: "your-environment-api-key",
35
+ host: "https://flags.example.com",
36
+ }),
37
+ );
38
+
39
+ const client = OpenFeature.getClient();
40
+
41
+ if (client.getBooleanValue("new-checkout", false)) {
42
+ renderNewCheckout();
43
+ }
44
+ ```
45
+
46
+ `host` is optional and defaults to the hosted service at
47
+ `https://app.flagward.com`. The options are the same as `FlagwardClient`'s:
48
+ `apiKey`, `host`, `timeout` and `logLevel`.
49
+
50
+ Coming from another provider, the change is the provider itself:
51
+
52
+ ```diff
53
+ - OpenFeature.setProvider(new SomeOtherProvider(...));
54
+ + OpenFeature.setProvider(new FlagwardWebProvider({ apiKey }));
55
+ ```
56
+
57
+ ## The evaluation context
58
+
59
+ Flagward rules read the same context OpenFeature holds:
60
+
61
+ - `targetingKey` becomes `user_id`, the identity percentage rollouts and
62
+ variant splits bucket by. A `user_id` attribute is used only when there is no
63
+ targeting key.
64
+ - Every other attribute is a trait, under its own name: `country` in the
65
+ context is what a `country EQUALS US` rule reads.
66
+
67
+ Changing the context (`OpenFeature.setContext`) needs nothing from the server:
68
+ the next evaluation uses it.
69
+
70
+ ## Flag types
71
+
72
+ | OpenFeature call | Flagward flag | Value |
73
+ | --- | --- | --- |
74
+ | `getBooleanValue` | BOOLEAN | the flag's result |
75
+ | `getBooleanValue` | MULTIVARIATE | whether the flag is enabled |
76
+ | `getStringValue` | MULTIVARIATE | the variant's name |
77
+ | `getStringValue` | BOOLEAN | your default, with `TYPE_MISMATCH` |
78
+ | `getNumberValue`, `getObjectValue` | any | your default, with `TYPE_MISMATCH` |
79
+
80
+ A key this environment does not have answers with your default and
81
+ `FLAG_NOT_FOUND`.
82
+
83
+ ## Reasons
84
+
85
+ `getBooleanDetails` and `getStringDetails` say why a value was chosen:
86
+
87
+ | Reason | When |
88
+ | --- | --- |
89
+ | `TARGETING_MATCH` | a rule matched and decided the value |
90
+ | `SPLIT` | the user's hash bucket picked the variant |
91
+ | `DEFAULT` | nothing targeted the user: no rule matched, or there is no targeting key to split by (the control variant) |
92
+ | `STATIC` | the value does not depend on the user: an override, or an enabled flag with nothing to target |
93
+ | `DISABLED` | the flag is off |
94
+
95
+ ```ts
96
+ client.getStringDetails("checkout-flow", "control");
97
+ // { value: "treatment", variant: "treatment", reason: "SPLIT", ... }
98
+ ```
99
+
100
+ ## Real-time updates
101
+
102
+ When a flag changes in the dashboard, the provider emits
103
+ `ConfigurationChanged`:
104
+
105
+ ```ts
106
+ import { ProviderEvents } from "@openfeature/web-sdk";
107
+
108
+ client.addHandler(ProviderEvents.ConfigurationChanged, () => rerender());
109
+ ```
110
+
111
+ If the flags cannot be loaded — a wrong API key, an unreachable host —
112
+ `setProviderAndWait` rejects, the provider is in the `ERROR` state, and every
113
+ evaluation answers with its default.
114
+
115
+ ## Frameworks
116
+
117
+ OpenFeature's own SDKs build on this provider:
118
+
119
+ - React: `@openfeature/react-sdk`
120
+ - Angular: `@openfeature/angular-sdk`
121
+
122
+ Vue, Solid and Svelte have no OpenFeature SDK; there you use
123
+ `@openfeature/web-sdk` directly, or Flagward's adapter for the framework.
124
+
125
+ Pick one entry point per application. The provider and a Flagward adapter each
126
+ create their own client, so using both means two connections and two caches
127
+ that can briefly disagree.
128
+
129
+ ## License
130
+
131
+ MIT
@@ -0,0 +1,4 @@
1
+ export { FlagwardWebProvider, SDK_TYPE } from "./provider.js";
2
+ export type { FlagwardWebProviderOptions } from "./provider.js";
3
+ export { SDK_VERSION } from "./version.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9D,YAAY,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAGhE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { FlagwardWebProvider, SDK_TYPE } from "./provider.js";
2
+ // The version this package reports at registration
3
+ export { SDK_VERSION } from "./version.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG9D,mDAAmD;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,37 @@
1
+ import { OpenFeatureEventEmitter, type EvaluationContext, type JsonValue, type Provider, type ResolutionDetails } from "@openfeature/web-sdk";
2
+ import { FlagwardClient, type FlagwardClientOptions } from "@flagward/core";
3
+ /** The type this provider registers as, so the dashboard can tell it apart. */
4
+ export declare const SDK_TYPE = "OPENFEATURE_WEB";
5
+ export type FlagwardWebProviderOptions = Omit<FlagwardClientOptions, "sdkType" | "sdkVersion">;
6
+ /**
7
+ * OpenFeature provider for the browser, backed by `@flagward/core`.
8
+ *
9
+ * Flags are downloaded once and evaluated locally, which is why the resolvers
10
+ * can be synchronous as the web SDK requires. Changes arrive over SSE and are
11
+ * announced as `ConfigurationChanged`.
12
+ *
13
+ * There is no `onContextChange`: evaluation reads the context on every call
14
+ * and needs nothing from the server, so a new context takes effect on the next
15
+ * evaluation without reconciling.
16
+ */
17
+ export declare class FlagwardWebProvider implements Provider {
18
+ readonly metadata: {
19
+ readonly name: "flagward";
20
+ };
21
+ readonly runsOn = "client";
22
+ readonly events: OpenFeatureEventEmitter;
23
+ /** The underlying Flagward client, for callers that need it directly. */
24
+ readonly client: FlagwardClient;
25
+ private unsubscribe;
26
+ constructor(options: FlagwardWebProviderOptions);
27
+ initialize(): Promise<void>;
28
+ onClose(): Promise<void>;
29
+ resolveBooleanEvaluation(flagKey: string, defaultValue: boolean, context: EvaluationContext): ResolutionDetails<boolean>;
30
+ resolveStringEvaluation(flagKey: string, defaultValue: string, context: EvaluationContext): ResolutionDetails<string>;
31
+ resolveNumberEvaluation(flagKey: string, defaultValue: number): ResolutionDetails<number>;
32
+ resolveObjectEvaluation<T extends JsonValue>(flagKey: string, defaultValue: T): ResolutionDetails<T>;
33
+ private flag;
34
+ /** Flagward has no number or object flags; a known key is the wrong type. */
35
+ private unsupported;
36
+ }
37
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,uBAAuB,EAEvB,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,iBAAiB,EACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,cAAc,EAId,KAAK,qBAAqB,EAE3B,MAAM,gBAAgB,CAAC;AAGxB,+EAA+E;AAC/E,eAAO,MAAM,QAAQ,oBAAoB,CAAC;AAE1C,MAAM,MAAM,0BAA0B,GAAG,IAAI,CAAC,qBAAqB,EAAE,SAAS,GAAG,YAAY,CAAC,CAAC;AAoC/F;;;;;;;;;;GAUG;AACH,qBAAa,mBAAoB,YAAW,QAAQ;IAClD,QAAQ,CAAC,QAAQ;;MAAiC;IAClD,QAAQ,CAAC,MAAM,YAAY;IAC3B,QAAQ,CAAC,MAAM,0BAAiC;IAEhD,yEAAyE;IACzE,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAEhC,OAAO,CAAC,WAAW,CAA6B;gBAEpC,OAAO,EAAE,0BAA0B;IAIzC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAe3B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAM9B,wBAAwB,CACtB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,OAAO,EACrB,OAAO,EAAE,iBAAiB,GACzB,iBAAiB,CAAC,OAAO,CAAC;IAS7B,uBAAuB,CACrB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,iBAAiB,GACzB,iBAAiB,CAAC,MAAM,CAAC;IAmB5B,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC;IAIzF,uBAAuB,CAAC,CAAC,SAAS,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC;IAIpG,OAAO,CAAC,IAAI;IAIZ,6EAA6E;IAC7E,OAAO,CAAC,WAAW;CAOpB"}
@@ -0,0 +1,112 @@
1
+ import { ClientProviderEvents, ErrorCode, OpenFeatureEventEmitter, StandardResolutionReasons, } from "@openfeature/web-sdk";
2
+ import { FlagwardClient, evaluateFlagDetail, evaluateVariantDetail, } from "@flagward/core";
3
+ import { SDK_VERSION } from "./version.js";
4
+ /** The type this provider registers as, so the dashboard can tell it apart. */
5
+ export const SDK_TYPE = "OPENFEATURE_WEB";
6
+ /**
7
+ * Map an OpenFeature evaluation context onto the user context Flagward's rules
8
+ * read. `targetingKey` is the identity OpenFeature standardises on and becomes
9
+ * `user_id`, the attribute the hash buckets by; an explicit `user_id` is kept
10
+ * only when there is no targeting key. Every other attribute passes through as
11
+ * a trait, under its own name.
12
+ */
13
+ function toUserContext(context) {
14
+ const { targetingKey, ...attributes } = context;
15
+ if (targetingKey === undefined) {
16
+ return attributes;
17
+ }
18
+ return { ...attributes, user_id: targetingKey };
19
+ }
20
+ function flagNotFound(flagKey, defaultValue) {
21
+ return {
22
+ value: defaultValue,
23
+ reason: StandardResolutionReasons.ERROR,
24
+ errorCode: ErrorCode.FLAG_NOT_FOUND,
25
+ errorMessage: `Flag "${flagKey}" is not in this environment.`,
26
+ };
27
+ }
28
+ function typeMismatch(flagKey, defaultValue, expected) {
29
+ return {
30
+ value: defaultValue,
31
+ reason: StandardResolutionReasons.ERROR,
32
+ errorCode: ErrorCode.TYPE_MISMATCH,
33
+ errorMessage: `Flag "${flagKey}" cannot be read as ${expected}.`,
34
+ };
35
+ }
36
+ /**
37
+ * OpenFeature provider for the browser, backed by `@flagward/core`.
38
+ *
39
+ * Flags are downloaded once and evaluated locally, which is why the resolvers
40
+ * can be synchronous as the web SDK requires. Changes arrive over SSE and are
41
+ * announced as `ConfigurationChanged`.
42
+ *
43
+ * There is no `onContextChange`: evaluation reads the context on every call
44
+ * and needs nothing from the server, so a new context takes effect on the next
45
+ * evaluation without reconciling.
46
+ */
47
+ export class FlagwardWebProvider {
48
+ constructor(options) {
49
+ this.metadata = { name: "flagward" };
50
+ this.runsOn = "client";
51
+ this.events = new OpenFeatureEventEmitter();
52
+ this.unsubscribe = null;
53
+ this.client = new FlagwardClient({ ...options, sdkType: SDK_TYPE, sdkVersion: SDK_VERSION });
54
+ }
55
+ async initialize() {
56
+ // No PROVIDER_READY or PROVIDER_ERROR is emitted here, on purpose. The
57
+ // spec's hardening draft (2.8.2, 2.8.3) makes the provider their sole
58
+ // source, but @openfeature/web-sdk still derives both from how this
59
+ // promise settles and emits them itself. Emitting them too would run every
60
+ // handler twice. Revisit when the SDK adopts that part of the spec; a test
61
+ // counts the handler calls.
62
+ await this.client.init();
63
+ this.unsubscribe = this.client.subscribe(() => {
64
+ this.events.emit(ClientProviderEvents.ConfigurationChanged);
65
+ });
66
+ this.client.connect();
67
+ }
68
+ async onClose() {
69
+ this.unsubscribe?.();
70
+ this.unsubscribe = null;
71
+ this.client.destroy();
72
+ }
73
+ resolveBooleanEvaluation(flagKey, defaultValue, context) {
74
+ const detail = evaluateFlagDetail(this.flag(flagKey), toUserContext(context));
75
+ if (!detail) {
76
+ return flagNotFound(flagKey, defaultValue);
77
+ }
78
+ return { value: detail.value, reason: detail.reason };
79
+ }
80
+ resolveStringEvaluation(flagKey, defaultValue, context) {
81
+ const flag = this.flag(flagKey);
82
+ if (!flag) {
83
+ return flagNotFound(flagKey, defaultValue);
84
+ }
85
+ // Only a MULTIVARIATE flag has a string to give: its variant name.
86
+ if (flag.flag_type !== "MULTIVARIATE") {
87
+ return typeMismatch(flagKey, defaultValue, "a string: it is not MULTIVARIATE");
88
+ }
89
+ const detail = evaluateVariantDetail(flag, toUserContext(context));
90
+ if (detail.value === undefined) {
91
+ return { value: defaultValue, reason: detail.reason };
92
+ }
93
+ return { value: detail.value, variant: detail.value, reason: detail.reason };
94
+ }
95
+ resolveNumberEvaluation(flagKey, defaultValue) {
96
+ return this.unsupported(flagKey, defaultValue, "a number");
97
+ }
98
+ resolveObjectEvaluation(flagKey, defaultValue) {
99
+ return this.unsupported(flagKey, defaultValue, "an object");
100
+ }
101
+ flag(flagKey) {
102
+ return this.client.snapshot[flagKey];
103
+ }
104
+ /** Flagward has no number or object flags; a known key is the wrong type. */
105
+ unsupported(flagKey, defaultValue, expected) {
106
+ if (!this.flag(flagKey)) {
107
+ return flagNotFound(flagKey, defaultValue);
108
+ }
109
+ return typeMismatch(flagKey, defaultValue, expected);
110
+ }
111
+ }
112
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * The version this package reports when it registers with the server.
3
+ *
4
+ * GENERATED by scripts/sync-version.mjs from package.json. Do not edit: the
5
+ * next build overwrites it, and a test fails if the two disagree.
6
+ */
7
+ export declare const SDK_VERSION = "0.1.0";
8
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,WAAW,UAAU,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * The version this package reports when it registers with the server.
3
+ *
4
+ * GENERATED by scripts/sync-version.mjs from package.json. Do not edit: the
5
+ * next build overwrites it, and a test fails if the two disagree.
6
+ */
7
+ export const SDK_VERSION = "0.1.0";
8
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC"}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@flagward/openfeature-web",
3
+ "version": "0.1.0",
4
+ "description": "OpenFeature web provider for Flagward - Feature Flags as a Service",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "sideEffects": false,
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "prebuild": "node ../../scripts/sync-version.mjs",
20
+ "build": "tsc -p tsconfig.build.json",
21
+ "dev": "tsc --watch",
22
+ "lint": "tsc --noEmit",
23
+ "test": "vitest",
24
+ "test:run": "vitest run",
25
+ "prepublishOnly": "npm run build --prefix ../core && npm run lint && npm run test:run && npm run build"
26
+ },
27
+ "keywords": [
28
+ "feature-flags",
29
+ "flags",
30
+ "openfeature",
31
+ "openfeature-provider",
32
+ "sdk",
33
+ "flagward"
34
+ ],
35
+ "license": "MIT",
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "git+https://github.com/basb7/flagward-sdk-js.git",
39
+ "directory": "packages/openfeature-web"
40
+ },
41
+ "homepage": "https://github.com/basb7/flagward-sdk-js/tree/main/packages/openfeature-web#readme",
42
+ "bugs": {
43
+ "url": "https://github.com/basb7/flagward-sdk-js/issues"
44
+ },
45
+ "publishConfig": {
46
+ "access": "public"
47
+ },
48
+ "dependencies": {
49
+ "@flagward/core": "^0.4.0"
50
+ },
51
+ "peerDependencies": {
52
+ "@openfeature/web-sdk": "^1.10.0"
53
+ },
54
+ "devDependencies": {
55
+ "@openfeature/core": "^1.12.0",
56
+ "@openfeature/web-sdk": "^1.10.0",
57
+ "@types/node": "^22.0.0",
58
+ "jsdom": "^25.0.0",
59
+ "typescript": "^5.7.0",
60
+ "vitest": "^3.0.0"
61
+ }
62
+ }