@fireweaveai/web-sdk 2.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.
Files changed (49) hide show
  1. package/dist/adapter.d.ts +87 -0
  2. package/dist/adapter.d.ts.map +1 -0
  3. package/dist/adapter.js +2 -0
  4. package/dist/adapter.js.map +1 -0
  5. package/dist/adapters/inmemory.d.ts +51 -0
  6. package/dist/adapters/inmemory.d.ts.map +1 -0
  7. package/dist/adapters/inmemory.js +91 -0
  8. package/dist/adapters/inmemory.js.map +1 -0
  9. package/dist/adapters/local.d.ts +38 -0
  10. package/dist/adapters/local.d.ts.map +1 -0
  11. package/dist/adapters/local.js +51 -0
  12. package/dist/adapters/local.js.map +1 -0
  13. package/dist/adapters/remote.d.ts +45 -0
  14. package/dist/adapters/remote.d.ts.map +1 -0
  15. package/dist/adapters/remote.js +332 -0
  16. package/dist/adapters/remote.js.map +1 -0
  17. package/dist/client.d.ts +134 -0
  18. package/dist/client.d.ts.map +1 -0
  19. package/dist/client.js +0 -0
  20. package/dist/client.js.map +1 -0
  21. package/dist/context.d.ts +26 -0
  22. package/dist/context.d.ts.map +1 -0
  23. package/dist/context.js +106 -0
  24. package/dist/context.js.map +1 -0
  25. package/dist/errors.d.ts +37 -0
  26. package/dist/errors.d.ts.map +1 -0
  27. package/dist/errors.js +93 -0
  28. package/dist/errors.js.map +1 -0
  29. package/dist/hosts.d.ts +11 -0
  30. package/dist/hosts.d.ts.map +1 -0
  31. package/dist/hosts.js +79 -0
  32. package/dist/hosts.js.map +1 -0
  33. package/dist/index.d.ts +45 -0
  34. package/dist/index.d.ts.map +1 -0
  35. package/dist/index.js +35 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/provider.d.ts +39 -0
  38. package/dist/provider.d.ts.map +1 -0
  39. package/dist/provider.js +93 -0
  40. package/dist/provider.js.map +1 -0
  41. package/dist/runtime.d.ts +62 -0
  42. package/dist/runtime.d.ts.map +1 -0
  43. package/dist/runtime.js +289 -0
  44. package/dist/runtime.js.map +1 -0
  45. package/dist/types.d.ts +90 -0
  46. package/dist/types.d.ts.map +1 -0
  47. package/dist/types.js +10 -0
  48. package/dist/types.js.map +1 -0
  49. package/package.json +45 -0
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Error taxonomy for the browser SDK.
3
+ *
4
+ * Same kinds and same OpenFeature mapping as the server SDK, because the wire
5
+ * protocol and the failure modes are the same — a 401 is a 401 whether it is a
6
+ * server or a browser asking. Reimplemented here rather than shared so the
7
+ * browser package keeps zero cross-package coupling and can be audited on its
8
+ * own; `spec/errors.schema.json` is the source both follow.
9
+ *
10
+ * Messages are FIXED per kind. A browser error is visible in a devtools console
11
+ * on a machine we do not control, so nothing host-, key-, or response-derived
12
+ * is ever interpolated into one.
13
+ */
14
+ export type FireweaveErrorKind = 'Configuration' | 'Authentication' | 'Authorization' | 'Network' | 'Timeout' | 'RateLimited' | 'BackendUnavailable' | 'MalformedResponse' | 'InvalidContext' | 'FlagNotFound' | 'TypeMismatch' | 'NotReady' | 'AlreadyClosed' | 'UnsupportedCapability' | 'Internal';
15
+ export type OpenFeatureErrorCode = 'PROVIDER_NOT_READY' | 'PROVIDER_FATAL' | 'FLAG_NOT_FOUND' | 'PARSE_ERROR' | 'TYPE_MISMATCH' | 'TARGETING_KEY_MISSING' | 'INVALID_CONTEXT' | 'GENERAL';
16
+ export interface ErrorKindSpec {
17
+ readonly message: string;
18
+ readonly openFeatureErrorCode: OpenFeatureErrorCode;
19
+ /** Whether an identical retry could plausibly succeed. */
20
+ readonly retryable: boolean;
21
+ }
22
+ export declare const ERROR_TAXONOMY: Readonly<Record<FireweaveErrorKind, ErrorKindSpec>>;
23
+ export interface FireweaveErrorOptions {
24
+ /** Overrides the taxonomy's OpenFeature code (e.g. a missing targeting key). */
25
+ readonly openFeatureErrorCode?: OpenFeatureErrorCode;
26
+ readonly metadata?: Record<string, string | number | boolean>;
27
+ readonly cause?: unknown;
28
+ }
29
+ export declare class FireweaveError extends Error {
30
+ readonly kind: FireweaveErrorKind;
31
+ readonly openFeatureErrorCode: OpenFeatureErrorCode;
32
+ readonly retryable: boolean;
33
+ readonly metadata: Record<string, string | number | boolean>;
34
+ constructor(kind: FireweaveErrorKind, options?: FireweaveErrorOptions);
35
+ }
36
+ export declare function isFireweaveError(value: unknown): value is FireweaveError;
37
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,kBAAkB,GAC1B,eAAe,GACf,gBAAgB,GAChB,eAAe,GACf,SAAS,GACT,SAAS,GACT,aAAa,GACb,oBAAoB,GACpB,mBAAmB,GACnB,gBAAgB,GAChB,cAAc,GACd,cAAc,GACd,UAAU,GACV,eAAe,GACf,uBAAuB,GACvB,UAAU,CAAC;AAEf,MAAM,MAAM,oBAAoB,GAC5B,oBAAoB,GACpB,gBAAgB,GAChB,gBAAgB,GAChB,aAAa,GACb,eAAe,GACf,uBAAuB,GACvB,iBAAiB,GACjB,SAAS,CAAC;AAEd,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;IACpD,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,kBAAkB,EAAE,aAAa,CAAC,CA4D7E,CAAC;AAEH,MAAM,WAAW,qBAAqB;IACpC,gFAAgF;IAChF,QAAQ,CAAC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IACrD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IAC9D,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;IACpD,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;gBAEjD,IAAI,EAAE,kBAAkB,EAAE,OAAO,GAAE,qBAA0B;CAS1E;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAExE"}
package/dist/errors.js ADDED
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Error taxonomy for the browser SDK.
3
+ *
4
+ * Same kinds and same OpenFeature mapping as the server SDK, because the wire
5
+ * protocol and the failure modes are the same — a 401 is a 401 whether it is a
6
+ * server or a browser asking. Reimplemented here rather than shared so the
7
+ * browser package keeps zero cross-package coupling and can be audited on its
8
+ * own; `spec/errors.schema.json` is the source both follow.
9
+ *
10
+ * Messages are FIXED per kind. A browser error is visible in a devtools console
11
+ * on a machine we do not control, so nothing host-, key-, or response-derived
12
+ * is ever interpolated into one.
13
+ */
14
+ export const ERROR_TAXONOMY = Object.freeze({
15
+ Configuration: {
16
+ message: 'invalid configuration',
17
+ openFeatureErrorCode: 'PROVIDER_FATAL',
18
+ retryable: false,
19
+ },
20
+ Authentication: {
21
+ message: 'authentication failed',
22
+ openFeatureErrorCode: 'PROVIDER_FATAL',
23
+ retryable: false,
24
+ },
25
+ Authorization: {
26
+ message: 'not authorized',
27
+ openFeatureErrorCode: 'PROVIDER_FATAL',
28
+ retryable: false,
29
+ },
30
+ Network: { message: 'network error', openFeatureErrorCode: 'GENERAL', retryable: true },
31
+ Timeout: { message: 'request timed out', openFeatureErrorCode: 'GENERAL', retryable: true },
32
+ RateLimited: { message: 'rate limited', openFeatureErrorCode: 'GENERAL', retryable: true },
33
+ BackendUnavailable: {
34
+ message: 'backend unavailable',
35
+ openFeatureErrorCode: 'GENERAL',
36
+ retryable: true,
37
+ },
38
+ MalformedResponse: {
39
+ message: 'malformed response',
40
+ openFeatureErrorCode: 'PARSE_ERROR',
41
+ retryable: false,
42
+ },
43
+ InvalidContext: {
44
+ message: 'invalid evaluation context',
45
+ openFeatureErrorCode: 'INVALID_CONTEXT',
46
+ retryable: false,
47
+ },
48
+ FlagNotFound: {
49
+ message: 'flag not found',
50
+ openFeatureErrorCode: 'FLAG_NOT_FOUND',
51
+ retryable: false,
52
+ },
53
+ TypeMismatch: {
54
+ message: 'type mismatch',
55
+ openFeatureErrorCode: 'TYPE_MISMATCH',
56
+ retryable: false,
57
+ },
58
+ NotReady: {
59
+ message: 'provider not ready',
60
+ openFeatureErrorCode: 'PROVIDER_NOT_READY',
61
+ retryable: true,
62
+ },
63
+ AlreadyClosed: {
64
+ message: 'provider already closed',
65
+ openFeatureErrorCode: 'PROVIDER_FATAL',
66
+ retryable: false,
67
+ },
68
+ UnsupportedCapability: {
69
+ message: 'unsupported capability',
70
+ openFeatureErrorCode: 'GENERAL',
71
+ retryable: false,
72
+ },
73
+ Internal: { message: 'internal error', openFeatureErrorCode: 'GENERAL', retryable: false },
74
+ });
75
+ export class FireweaveError extends Error {
76
+ kind;
77
+ openFeatureErrorCode;
78
+ retryable;
79
+ metadata;
80
+ constructor(kind, options = {}) {
81
+ const spec = ERROR_TAXONOMY[kind];
82
+ super(spec.message, options.cause !== undefined ? { cause: options.cause } : undefined);
83
+ this.name = 'FireweaveError';
84
+ this.kind = kind;
85
+ this.openFeatureErrorCode = options.openFeatureErrorCode ?? spec.openFeatureErrorCode;
86
+ this.retryable = spec.retryable;
87
+ this.metadata = { ...(options.metadata ?? {}) };
88
+ }
89
+ }
90
+ export function isFireweaveError(value) {
91
+ return value instanceof FireweaveError;
92
+ }
93
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export declare const DEFAULT_ALLOWED_HOSTS: readonly string[];
2
+ export declare function isLoopbackHostname(hostname: string): boolean;
3
+ /**
4
+ * Validate a backend URL against the allowlist.
5
+ * Throws `FireweaveError('Configuration')` — fixed message, no host echoed,
6
+ * because this message can land in a shared browser console.
7
+ */
8
+ export declare function assertHostAllowed(host: string, allowedHosts?: readonly string[]): void;
9
+ /** Throw if `apiKey` looks like a vendor or secret key rather than a Fireweave project key. */
10
+ export declare function assertNotSecretKey(apiKey: string): void;
11
+ //# sourceMappingURL=hosts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hosts.d.ts","sourceRoot":"","sources":["../src/hosts.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,qBAAqB,EAAE,SAAS,MAAM,EAMjD,CAAC;AAEH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAO5D;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CA0BtF;AAYD,+FAA+F;AAC/F,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAQvD"}
package/dist/hosts.js ADDED
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Backend host allowlist — the same SSRF guard the server SDK applies, kept
3
+ * for a different reason.
4
+ *
5
+ * A browser cannot be tricked into reaching a cloud metadata endpoint the way a
6
+ * server can; the browser's own origin model already prevents that. What this
7
+ * guard buys here is narrower and still worth having: a mistyped or tampered
8
+ * `apiUrl` cannot quietly send a project key, a targeting key, and a user's
9
+ * evaluation attributes to an unintended host. The allowlist is ON by default,
10
+ * so reaching a self-hosted fw-server is a deliberate, explicit act.
11
+ *
12
+ * Scheme policy matches the server SDK: https everywhere except loopback,
13
+ * where plain http is allowed for local development against a dev server.
14
+ */
15
+ import { FireweaveError } from './errors.js';
16
+ export const DEFAULT_ALLOWED_HOSTS = Object.freeze([
17
+ 'app-server.fireweave.ai',
18
+ 'staging-app-server.fireweave.ai',
19
+ 'localhost',
20
+ '127.0.0.1',
21
+ '::1',
22
+ ]);
23
+ export function isLoopbackHostname(hostname) {
24
+ return (hostname === 'localhost' ||
25
+ hostname === '127.0.0.1' ||
26
+ hostname === '::1' ||
27
+ hostname === '[::1]');
28
+ }
29
+ /**
30
+ * Validate a backend URL against the allowlist.
31
+ * Throws `FireweaveError('Configuration')` — fixed message, no host echoed,
32
+ * because this message can land in a shared browser console.
33
+ */
34
+ export function assertHostAllowed(host, allowedHosts) {
35
+ let url;
36
+ try {
37
+ url = new URL(host);
38
+ }
39
+ catch {
40
+ throw new FireweaveError('Configuration');
41
+ }
42
+ if (url.protocol !== 'http:' && url.protocol !== 'https:') {
43
+ throw new FireweaveError('Configuration');
44
+ }
45
+ const loopback = isLoopbackHostname(url.hostname);
46
+ if (url.protocol === 'http:' && !loopback) {
47
+ throw new FireweaveError('Configuration');
48
+ }
49
+ const list = allowedHosts !== undefined && allowedHosts.length > 0 ? allowedHosts : DEFAULT_ALLOWED_HOSTS;
50
+ if (list.includes('*'))
51
+ return; // explicit opt-out
52
+ const allowed = list.some((h) => url.hostname === h ||
53
+ (h === 'localhost' && loopback) ||
54
+ (h === '::1' && url.hostname === '[::1]'));
55
+ if (!allowed) {
56
+ throw new FireweaveError('Configuration');
57
+ }
58
+ }
59
+ /**
60
+ * Key shapes this SDK refuses to accept.
61
+ *
62
+ * The whole security argument for a browser package (ADR-0009) is that it never
63
+ * wants a secret. Enforcing that at the door — rather than trusting that no
64
+ * code path asks for one — turns the claim into something a caller cannot
65
+ * accidentally violate by pasting the wrong value into their bundle config.
66
+ */
67
+ const FORBIDDEN_KEY_PREFIXES = Object.freeze(['phs_', 'phx_', 'phc_']);
68
+ /** Throw if `apiKey` looks like a vendor or secret key rather than a Fireweave project key. */
69
+ export function assertNotSecretKey(apiKey) {
70
+ const key = apiKey.trim();
71
+ if (key.length === 0)
72
+ throw new FireweaveError('Configuration');
73
+ for (const prefix of FORBIDDEN_KEY_PREFIXES) {
74
+ if (key.startsWith(prefix)) {
75
+ throw new FireweaveError('Configuration');
76
+ }
77
+ }
78
+ }
79
+ //# sourceMappingURL=hosts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hosts.js","sourceRoot":"","sources":["../src/hosts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,CAAC,MAAM,qBAAqB,GAAsB,MAAM,CAAC,MAAM,CAAC;IACpE,yBAAyB;IACzB,iCAAiC;IACjC,WAAW;IACX,WAAW;IACX,KAAK;CACN,CAAC,CAAC;AAEH,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,OAAO,CACL,QAAQ,KAAK,WAAW;QACxB,QAAQ,KAAK,WAAW;QACxB,QAAQ,KAAK,KAAK;QAClB,QAAQ,KAAK,OAAO,CACrB,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,YAAgC;IAC9E,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,cAAc,CAAC,eAAe,CAAC,CAAC;IAC5C,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1D,MAAM,IAAI,cAAc,CAAC,eAAe,CAAC,CAAC;IAC5C,CAAC;IACD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAClD,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC1C,MAAM,IAAI,cAAc,CAAC,eAAe,CAAC,CAAC;IAC5C,CAAC;IACD,MAAM,IAAI,GACR,YAAY,KAAK,SAAS,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,qBAAqB,CAAC;IAC/F,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,CAAC,mBAAmB;IACnD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CACvB,CAAC,CAAC,EAAE,EAAE,CACJ,GAAG,CAAC,QAAQ,KAAK,CAAC;QAClB,CAAC,CAAC,KAAK,WAAW,IAAI,QAAQ,CAAC;QAC/B,CAAC,CAAC,KAAK,KAAK,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,CAAC,CAC5C,CAAC;IACF,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,cAAc,CAAC,eAAe,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,sBAAsB,GAAsB,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE1F,+FAA+F;AAC/F,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC1B,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,cAAc,CAAC,eAAe,CAAC,CAAC;IAChE,KAAK,MAAM,MAAM,IAAI,sBAAsB,EAAE,CAAC;QAC5C,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,cAAc,CAAC,eAAe,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * @fireweaveai/web-sdk — Fireweave control points for the browser (ADR-0009).
3
+ *
4
+ * Remote-only and secret-free by construction: it never evaluates locally, has
5
+ * no vendor SDK dependency, reads no environment, and rejects vendor/secret key
6
+ * shapes at the door. Credentials are passed in explicitly by the embedding app.
7
+ *
8
+ * ```ts
9
+ * import { OpenFeature } from '@openfeature/web-sdk';
10
+ * import {
11
+ * FireweaveRemoteWebAdapter,
12
+ * FireweaveWebProvider,
13
+ * FireweaveWebRuntime,
14
+ * } from '@fireweaveai/web-sdk';
15
+ *
16
+ * const runtime = new FireweaveWebRuntime(
17
+ * new FireweaveRemoteWebAdapter({ apiUrl, apiKey }),
18
+ * { globalContext: { targetingKey: 'anonymous' } }
19
+ * );
20
+ * await OpenFeature.setProviderAndWait(new FireweaveWebProvider(runtime));
21
+ *
22
+ * // Reads are SYNCHRONOUS — no await, safe inside render.
23
+ * const on = OpenFeature.getClient().getBooleanValue('new-checkout', false);
24
+ * ```
25
+ */
26
+ export { FireweaveError, ERROR_TAXONOMY, isFireweaveError, } from './errors.js';
27
+ export type { FireweaveErrorKind, FireweaveErrorOptions, OpenFeatureErrorCode, ErrorKindSpec, } from './errors.js';
28
+ export type { JsonValue, FlagValueType, Decision, DecisionReason, CanonicalContext, LifecycleState, Signal, SignalKind, Exposure, ReleaseContext, ReleaseState, Capabilities, } from './types.js';
29
+ export { DEFAULT_CONTEXT_LIMITS, DEFAULT_RESERVED_ATTRIBUTE_KEYS, canonicalizeContext, mergeContexts, } from './context.js';
30
+ export type { ContextInput, ContextLimits } from './context.js';
31
+ export { DEFAULT_ALLOWED_HOSTS, assertHostAllowed, assertNotSecretKey, isLoopbackHostname, } from './hosts.js';
32
+ export type { WebBackendAdapter, AdapterResolution, AdapterRuntimeFeatures, PrefetchOptions, PrefetchResult, RegisterTargetOptions, RegisterTargetResult, TargetKind, } from './adapter.js';
33
+ export { FireweaveRemoteWebAdapter } from './adapters/remote.js';
34
+ export type { FireweaveRemoteWebAdapterOptions, FireweaveFetchLike, } from './adapters/remote.js';
35
+ export { InMemoryWebAdapter } from './adapters/inmemory.js';
36
+ export type { InMemoryWebAdapterOptions, InMemoryFlagDefinition, InMemoryFault, } from './adapters/inmemory.js';
37
+ export { FireweaveLocalWebAdapter } from './adapters/local.js';
38
+ export type { FireweaveLocalWebAdapterOptions } from './adapters/local.js';
39
+ export { FireweaveWebRuntime, DEFAULT_FLAGS_READY_TIMEOUT_MS } from './runtime.js';
40
+ export type { FireweaveWebRuntimeConfig, ExpectedFlagType } from './runtime.js';
41
+ export { FireweaveWebProvider } from './provider.js';
42
+ export type { FireweaveWebProviderOptions } from './provider.js';
43
+ export { FireweaveWebClient, WebControlPointsApi, WebExposuresApi, WebSignalsApi, WebReleasesApi, DEFAULT_SIGNAL_ATTRIBUTE_ALLOWLIST, } from './client.js';
44
+ export type { FireweaveWebClientOptions, ExtensionResult, ReleaseResult } from './client.js';
45
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EACL,cAAc,EACd,cAAc,EACd,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,GACd,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,SAAS,EACT,aAAa,EACb,QAAQ,EACR,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,MAAM,EACN,UAAU,EACV,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,YAAY,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,sBAAsB,EACtB,+BAA+B,EAC/B,mBAAmB,EACnB,aAAa,GACd,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAEhE,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,eAAe,EACf,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,UAAU,GACX,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AACjE,YAAY,EACV,gCAAgC,EAChC,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,YAAY,EACV,yBAAyB,EACzB,sBAAsB,EACtB,aAAa,GACd,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,YAAY,EAAE,+BAA+B,EAAE,MAAM,qBAAqB,CAAC;AAE3E,OAAO,EAAE,mBAAmB,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAC;AACnF,YAAY,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhF,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,YAAY,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAC;AAEjE,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,cAAc,EACd,kCAAkC,GACnC,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,yBAAyB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @fireweaveai/web-sdk — Fireweave control points for the browser (ADR-0009).
3
+ *
4
+ * Remote-only and secret-free by construction: it never evaluates locally, has
5
+ * no vendor SDK dependency, reads no environment, and rejects vendor/secret key
6
+ * shapes at the door. Credentials are passed in explicitly by the embedding app.
7
+ *
8
+ * ```ts
9
+ * import { OpenFeature } from '@openfeature/web-sdk';
10
+ * import {
11
+ * FireweaveRemoteWebAdapter,
12
+ * FireweaveWebProvider,
13
+ * FireweaveWebRuntime,
14
+ * } from '@fireweaveai/web-sdk';
15
+ *
16
+ * const runtime = new FireweaveWebRuntime(
17
+ * new FireweaveRemoteWebAdapter({ apiUrl, apiKey }),
18
+ * { globalContext: { targetingKey: 'anonymous' } }
19
+ * );
20
+ * await OpenFeature.setProviderAndWait(new FireweaveWebProvider(runtime));
21
+ *
22
+ * // Reads are SYNCHRONOUS — no await, safe inside render.
23
+ * const on = OpenFeature.getClient().getBooleanValue('new-checkout', false);
24
+ * ```
25
+ */
26
+ export { FireweaveError, ERROR_TAXONOMY, isFireweaveError, } from './errors.js';
27
+ export { DEFAULT_CONTEXT_LIMITS, DEFAULT_RESERVED_ATTRIBUTE_KEYS, canonicalizeContext, mergeContexts, } from './context.js';
28
+ export { DEFAULT_ALLOWED_HOSTS, assertHostAllowed, assertNotSecretKey, isLoopbackHostname, } from './hosts.js';
29
+ export { FireweaveRemoteWebAdapter } from './adapters/remote.js';
30
+ export { InMemoryWebAdapter } from './adapters/inmemory.js';
31
+ export { FireweaveLocalWebAdapter } from './adapters/local.js';
32
+ export { FireweaveWebRuntime, DEFAULT_FLAGS_READY_TIMEOUT_MS } from './runtime.js';
33
+ export { FireweaveWebProvider } from './provider.js';
34
+ export { FireweaveWebClient, WebControlPointsApi, WebExposuresApi, WebSignalsApi, WebReleasesApi, DEFAULT_SIGNAL_ATTRIBUTE_ALLOWLIST, } from './client.js';
35
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EACL,cAAc,EACd,cAAc,EACd,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAuBrB,OAAO,EACL,sBAAsB,EACtB,+BAA+B,EAC/B,mBAAmB,EACnB,aAAa,GACd,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAapB,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAMjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAO5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAG/D,OAAO,EAAE,mBAAmB,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAC;AAGnF,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAGrD,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,cAAc,EACd,kCAAkC,GACnC,MAAM,aAAa,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * OpenFeature web provider — the SYNCHRONOUS surface.
3
+ *
4
+ * `resolve*Evaluation` returns `ResolutionDetails` directly, never a Promise.
5
+ * That is the load-bearing web invariant: browser call sites read control
6
+ * points without `await`, inside render paths where awaiting is not an option.
7
+ * Everything asynchronous happens in `initialize` / `onContextChange`, which
8
+ * the OpenFeature web SDK is explicitly allowed to await.
9
+ *
10
+ * Per ADR-0003 the provider is a mapping layer only: OpenFeature types in,
11
+ * runtime decisions out. It owns error-code translation and nothing else.
12
+ */
13
+ import { OpenFeatureEventEmitter, type EvaluationContext, type JsonValue as OFJsonValue, type Paradigm, type Provider, type ProviderMetadata, type ResolutionDetails } from '@openfeature/web-sdk';
14
+ import type { FireweaveWebRuntime } from './runtime.js';
15
+ export interface FireweaveWebProviderOptions {
16
+ /** Provider name reported to OpenFeature. Defaults to `fireweave-web`. */
17
+ readonly name?: string;
18
+ }
19
+ export declare class FireweaveWebProvider implements Provider {
20
+ readonly metadata: ProviderMetadata;
21
+ readonly runsOn: Paradigm;
22
+ readonly events: OpenFeatureEventEmitter;
23
+ readonly runtime: FireweaveWebRuntime;
24
+ constructor(runtime: FireweaveWebRuntime, options?: FireweaveWebProviderOptions);
25
+ initialize(context?: EvaluationContext): Promise<void>;
26
+ /**
27
+ * The identity-change path. Emits ConfigurationChanged with only the control
28
+ * points whose decisions actually moved, so subscribers re-render on real
29
+ * changes rather than on every sign-in.
30
+ */
31
+ onContextChange(_oldContext: EvaluationContext, newContext: EvaluationContext): Promise<void>;
32
+ onClose(): Promise<void>;
33
+ resolveBooleanEvaluation(flagKey: string, defaultValue: boolean, context: EvaluationContext): ResolutionDetails<boolean>;
34
+ resolveStringEvaluation(flagKey: string, defaultValue: string, context: EvaluationContext): ResolutionDetails<string>;
35
+ resolveNumberEvaluation(flagKey: string, defaultValue: number, context: EvaluationContext): ResolutionDetails<number>;
36
+ resolveObjectEvaluation<T extends OFJsonValue>(flagKey: string, defaultValue: T, context: EvaluationContext): ResolutionDetails<T>;
37
+ private resolve;
38
+ }
39
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAEL,uBAAuB,EAEvB,KAAK,iBAAiB,EACtB,KAAK,SAAS,IAAI,WAAW,EAC7B,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACvB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,mBAAmB,EAAoB,MAAM,cAAc,CAAC;AAkC1E,MAAM,WAAW,2BAA2B;IAC1C,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,oBAAqB,YAAW,QAAQ;IACnD,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAY;IACrC,QAAQ,CAAC,MAAM,0BAAiC;IAChD,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;gBAE1B,OAAO,EAAE,mBAAmB,EAAE,OAAO,GAAE,2BAAgC;IAK7E,UAAU,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAW5D;;;;OAIG;IACG,eAAe,CACnB,WAAW,EAAE,iBAAiB,EAC9B,UAAU,EAAE,iBAAiB,GAC5B,OAAO,CAAC,IAAI,CAAC;IAOV,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAI9B,wBAAwB,CACtB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,OAAO,EACrB,OAAO,EAAE,iBAAiB,GACzB,iBAAiB,CAAC,OAAO,CAAC;IAI7B,uBAAuB,CACrB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,iBAAiB,GACzB,iBAAiB,CAAC,MAAM,CAAC;IAI5B,uBAAuB,CACrB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,iBAAiB,GACzB,iBAAiB,CAAC,MAAM,CAAC;IAI5B,uBAAuB,CAAC,CAAC,SAAS,WAAW,EAC3C,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,CAAC,EACf,OAAO,EAAE,iBAAiB,GACzB,iBAAiB,CAAC,CAAC,CAAC;IAIvB,OAAO,CAAC,OAAO;CAchB"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * OpenFeature web provider — the SYNCHRONOUS surface.
3
+ *
4
+ * `resolve*Evaluation` returns `ResolutionDetails` directly, never a Promise.
5
+ * That is the load-bearing web invariant: browser call sites read control
6
+ * points without `await`, inside render paths where awaiting is not an option.
7
+ * Everything asynchronous happens in `initialize` / `onContextChange`, which
8
+ * the OpenFeature web SDK is explicitly allowed to await.
9
+ *
10
+ * Per ADR-0003 the provider is a mapping layer only: OpenFeature types in,
11
+ * runtime decisions out. It owns error-code translation and nothing else.
12
+ */
13
+ import { ErrorCode, OpenFeatureEventEmitter, ProviderEvents, } from '@openfeature/web-sdk';
14
+ const ERROR_CODE_MAP = Object.freeze({
15
+ PROVIDER_NOT_READY: ErrorCode.PROVIDER_NOT_READY,
16
+ PROVIDER_FATAL: ErrorCode.PROVIDER_FATAL,
17
+ FLAG_NOT_FOUND: ErrorCode.FLAG_NOT_FOUND,
18
+ PARSE_ERROR: ErrorCode.PARSE_ERROR,
19
+ TYPE_MISMATCH: ErrorCode.TYPE_MISMATCH,
20
+ TARGETING_KEY_MISSING: ErrorCode.TARGETING_KEY_MISSING,
21
+ INVALID_CONTEXT: ErrorCode.INVALID_CONTEXT,
22
+ GENERAL: ErrorCode.GENERAL,
23
+ });
24
+ function toResolutionDetails(decision, defaultValue) {
25
+ if (decision.errorCode !== undefined) {
26
+ const details = {
27
+ value: defaultValue,
28
+ reason: decision.reason,
29
+ errorCode: ERROR_CODE_MAP[decision.errorCode] ?? ErrorCode.GENERAL,
30
+ flagMetadata: { ...decision.metadata },
31
+ };
32
+ return decision.errorMessage !== undefined
33
+ ? { ...details, errorMessage: decision.errorMessage }
34
+ : details;
35
+ }
36
+ const details = {
37
+ value: decision.value,
38
+ reason: decision.reason,
39
+ flagMetadata: { ...decision.metadata },
40
+ };
41
+ return decision.variant !== undefined ? { ...details, variant: decision.variant } : details;
42
+ }
43
+ export class FireweaveWebProvider {
44
+ metadata;
45
+ runsOn = 'client';
46
+ events = new OpenFeatureEventEmitter();
47
+ runtime;
48
+ constructor(runtime, options = {}) {
49
+ this.runtime = runtime;
50
+ this.metadata = Object.freeze({ name: options.name ?? 'fireweave-web' });
51
+ }
52
+ async initialize(context) {
53
+ await this.runtime.initialize(context);
54
+ if (this.runtime.getState() === 'STALE') {
55
+ // Surfaced, not swallowed: the app booted, but on defaults. A host that
56
+ // cares (a kill-switch, say) can react instead of silently shipping OFF.
57
+ this.events.emit(ProviderEvents.Stale, {
58
+ message: 'fireweave: flag prefetch did not complete; serving defaults',
59
+ });
60
+ }
61
+ }
62
+ /**
63
+ * The identity-change path. Emits ConfigurationChanged with only the control
64
+ * points whose decisions actually moved, so subscribers re-render on real
65
+ * changes rather than on every sign-in.
66
+ */
67
+ async onContextChange(_oldContext, newContext) {
68
+ const changed = await this.runtime.setContext(newContext);
69
+ if (changed.length > 0) {
70
+ this.events.emit(ProviderEvents.ConfigurationChanged, { flagsChanged: [...changed] });
71
+ }
72
+ }
73
+ async onClose() {
74
+ await this.runtime.shutdown();
75
+ }
76
+ resolveBooleanEvaluation(flagKey, defaultValue, context) {
77
+ return this.resolve(flagKey, 'boolean', defaultValue, context);
78
+ }
79
+ resolveStringEvaluation(flagKey, defaultValue, context) {
80
+ return this.resolve(flagKey, 'string', defaultValue, context);
81
+ }
82
+ resolveNumberEvaluation(flagKey, defaultValue, context) {
83
+ return this.resolve(flagKey, 'number', defaultValue, context);
84
+ }
85
+ resolveObjectEvaluation(flagKey, defaultValue, context) {
86
+ return this.resolve(flagKey, 'object', defaultValue, context);
87
+ }
88
+ resolve(flagKey, expectedType, defaultValue, context) {
89
+ const decision = this.runtime.evaluateSync(flagKey, expectedType, defaultValue, context);
90
+ return toResolutionDetails(decision, defaultValue);
91
+ }
92
+ }
93
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EACL,SAAS,EACT,uBAAuB,EACvB,cAAc,GAOf,MAAM,sBAAsB,CAAC;AAK9B,MAAM,cAAc,GAAwC,MAAM,CAAC,MAAM,CAAC;IACxE,kBAAkB,EAAE,SAAS,CAAC,kBAAkB;IAChD,cAAc,EAAE,SAAS,CAAC,cAAc;IACxC,cAAc,EAAE,SAAS,CAAC,cAAc;IACxC,WAAW,EAAE,SAAS,CAAC,WAAW;IAClC,aAAa,EAAE,SAAS,CAAC,aAAa;IACtC,qBAAqB,EAAE,SAAS,CAAC,qBAAqB;IACtD,eAAe,EAAE,SAAS,CAAC,eAAe;IAC1C,OAAO,EAAE,SAAS,CAAC,OAAO;CAC3B,CAAC,CAAC;AAEH,SAAS,mBAAmB,CAAI,QAAkB,EAAE,YAAe;IACjE,IAAI,QAAQ,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACrC,MAAM,OAAO,GAAyB;YACpC,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,SAAS,EAAE,cAAc,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC,OAAO;YAClE,YAAY,EAAE,EAAE,GAAG,QAAQ,CAAC,QAAQ,EAAE;SACvC,CAAC;QACF,OAAO,QAAQ,CAAC,YAAY,KAAK,SAAS;YACxC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,YAAY,EAAE,QAAQ,CAAC,YAAY,EAAE;YACrD,CAAC,CAAC,OAAO,CAAC;IACd,CAAC;IACD,MAAM,OAAO,GAAyB;QACpC,KAAK,EAAE,QAAQ,CAAC,KAAqB;QACrC,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,YAAY,EAAE,EAAE,GAAG,QAAQ,CAAC,QAAQ,EAAE;KACvC,CAAC;IACF,OAAO,QAAQ,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;AAC9F,CAAC;AAOD,MAAM,OAAO,oBAAoB;IACtB,QAAQ,CAAmB;IAC3B,MAAM,GAAa,QAAQ,CAAC;IAC5B,MAAM,GAAG,IAAI,uBAAuB,EAAE,CAAC;IACvC,OAAO,CAAsB;IAEtC,YAAY,OAA4B,EAAE,UAAuC,EAAE;QACjF,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,eAAe,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,OAA2B;QAC1C,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,OAAmC,CAAC,CAAC;QACnE,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,OAAO,EAAE,CAAC;YACxC,wEAAwE;YACxE,yEAAyE;YACzE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE;gBACrC,OAAO,EAAE,6DAA6D;aACvE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,eAAe,CACnB,WAA8B,EAC9B,UAA6B;QAE7B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,UAA0B,CAAC,CAAC;QAC1E,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,oBAAoB,EAAE,EAAE,YAAY,EAAE,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO;QACX,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;IAChC,CAAC;IAED,wBAAwB,CACtB,OAAe,EACf,YAAqB,EACrB,OAA0B;QAE1B,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IACjE,CAAC;IAED,uBAAuB,CACrB,OAAe,EACf,YAAoB,EACpB,OAA0B;QAE1B,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IAChE,CAAC;IAED,uBAAuB,CACrB,OAAe,EACf,YAAoB,EACpB,OAA0B;QAE1B,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IAChE,CAAC;IAED,uBAAuB,CACrB,OAAe,EACf,YAAe,EACf,OAA0B;QAE1B,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IAChE,CAAC;IAEO,OAAO,CACb,OAAe,EACf,YAA8B,EAC9B,YAAe,EACf,OAA0B;QAE1B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CACxC,OAAO,EACP,YAAY,EACZ,YAAoC,EACpC,OAAuB,CACxB,CAAC;QACF,OAAO,mBAAmB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IACrD,CAAC;CACF"}
@@ -0,0 +1,62 @@
1
+ import type { ContextInput, ContextLimits } from './context.js';
2
+ import type { RegisterTargetOptions, RegisterTargetResult, WebBackendAdapter } from './adapter.js';
3
+ import type { Decision, Exposure, JsonValue, LifecycleState, ReleaseContext, Signal } from './types.js';
4
+ export type ExpectedFlagType = 'boolean' | 'string' | 'number' | 'object';
5
+ /** Ceiling on the initial prefetch so a hung backend cannot block boot. */
6
+ export declare const DEFAULT_FLAGS_READY_TIMEOUT_MS = 5000;
7
+ export interface FireweaveWebRuntimeConfig {
8
+ /** Context applied to every evaluation unless overridden per call. */
9
+ readonly globalContext?: ContextInput;
10
+ readonly limits?: Partial<ContextLimits>;
11
+ readonly flagsReadyTimeoutMs?: number;
12
+ /** Restrict prefetch to a known set of control points. */
13
+ readonly flagKeys?: readonly string[];
14
+ /** Emit a Fireweave exposure on each successful evaluation. Default false. */
15
+ readonly sendExposure?: boolean;
16
+ }
17
+ export declare class FireweaveWebRuntime {
18
+ readonly adapter: WebBackendAdapter;
19
+ readonly config: FireweaveWebRuntimeConfig;
20
+ private state;
21
+ private cache;
22
+ private globalContext;
23
+ private readonly limits;
24
+ private releaseContext;
25
+ private readonly listeners;
26
+ constructor(adapter: WebBackendAdapter, config?: FireweaveWebRuntimeConfig);
27
+ getState(): LifecycleState;
28
+ onStateChange(listener: (state: LifecycleState) => void): () => void;
29
+ private setState;
30
+ setReleaseContext(ctx: ReleaseContext): void;
31
+ getReleaseContext(): ReleaseContext;
32
+ /** Initialize the adapter and populate the cache. Never throws. */
33
+ initialize(context?: ContextInput): Promise<void>;
34
+ /**
35
+ * Replace the global context and re-prefetch — the identity-change path.
36
+ *
37
+ * Call this after sign-in with the user's stable id, so percentage ramps
38
+ * bucket on that id rather than on an anonymous one. Returns the keys whose
39
+ * decisions changed, so a provider can emit a targeted ConfigurationChanged.
40
+ */
41
+ setContext(context: ContextInput): Promise<readonly string[]>;
42
+ /** Re-run the prefetch against the current global context. */
43
+ refresh(): Promise<void>;
44
+ /**
45
+ * Synchronous evaluation against the prefetched cache. Never throws —
46
+ * failures surface as ERROR decisions, exactly like the OpenFeature contract.
47
+ */
48
+ evaluateSync(flagKey: string, expectedType: ExpectedFlagType, defaultValue: JsonValue, invocationContext?: ContextInput): Decision;
49
+ private reasonFor;
50
+ private metadataFor;
51
+ private recordExposureFor;
52
+ recordExposure(exposure: Exposure): void;
53
+ recordSignal(signal: Signal): void;
54
+ registerTarget(targetingKey: string, options?: RegisterTargetOptions): Promise<RegisterTargetResult>;
55
+ flush(options?: {
56
+ beacon?: boolean;
57
+ }): Promise<void>;
58
+ shutdown(): Promise<void>;
59
+ private changedKeys;
60
+ private errorDecision;
61
+ }
62
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAGV,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAEV,QAAQ,EAER,QAAQ,EACR,SAAS,EACT,cAAc,EACd,cAAc,EACd,MAAM,EACP,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE1E,2EAA2E;AAC3E,eAAO,MAAM,8BAA8B,OAAQ,CAAC;AAEpD,MAAM,WAAW,yBAAyB;IACxC,sEAAsE;IACtE,QAAQ,CAAC,aAAa,CAAC,EAAE,YAAY,CAAC;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IACzC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,0DAA0D;IAC1D,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,8EAA8E;IAC9E,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;CACjC;AAeD,qBAAa,mBAAmB;IAC9B,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,yBAAyB,CAAC;IAE3C,OAAO,CAAC,KAAK,CAAmC;IAChD,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,cAAc,CAAsB;IAC5C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8C;gBAE5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,GAAE,yBAA8B;IAO9E,QAAQ,IAAI,cAAc;IAI1B,aAAa,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,GAAG,MAAM,IAAI;IAKpE,OAAO,CAAC,QAAQ;IAKhB,iBAAiB,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI;IAI5C,iBAAiB,IAAI,cAAc;IAInC,mEAAmE;IAC7D,UAAU,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAcvD;;;;;;OAMG;IACG,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC;IAOnE,8DAA8D;IACxD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA8C9B;;;OAGG;IACH,YAAY,CACV,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,gBAAgB,EAC9B,YAAY,EAAE,SAAS,EACvB,iBAAiB,CAAC,EAAE,YAAY,GAC/B,QAAQ;IAgDX,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,iBAAiB;IAkBzB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAIxC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI5B,cAAc,CAClB,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,oBAAoB,CAAC;IAiB1B,KAAK,CAAC,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAW/B,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,aAAa;CAetB"}