@fireweaveai/web-sdk-cjs 0.0.0-reserve.0 → 0.0.0-stage
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/README.md +2 -51
- package/package.json +4 -66
- package/LICENSE +0 -21
- package/dist/application/client.d.ts +0 -104
- package/dist/application/client.js +0 -147
- package/dist/application/mode.d.ts +0 -99
- package/dist/application/mode.js +0 -101
- package/dist/application/ports.d.ts +0 -101
- package/dist/application/ports.js +0 -2
- package/dist/application/runtime.d.ts +0 -70
- package/dist/application/runtime.js +0 -348
- package/dist/build/node/define.d.ts +0 -14
- package/dist/build/node/define.js +0 -38
- package/dist/build/node/shared.d.ts +0 -19
- package/dist/build/node/shared.js +0 -39
- package/dist/build/node/vite.d.ts +0 -53
- package/dist/build/node/vite.js +0 -106
- package/dist/build/src/start/build-info.d.ts +0 -2
- package/dist/build/src/start/build-info.js +0 -9
- package/dist/build/src/start/names.d.ts +0 -38
- package/dist/build/src/start/names.js +0 -41
- package/dist/build/src/start/policy.d.ts +0 -70
- package/dist/build/src/start/policy.js +0 -128
- package/dist/domain/context.d.ts +0 -51
- package/dist/domain/context.js +0 -72
- package/dist/domain/errors.d.ts +0 -36
- package/dist/domain/errors.js +0 -97
- package/dist/domain/target.d.ts +0 -2
- package/dist/domain/target.js +0 -2
- package/dist/domain/types.d.ts +0 -89
- package/dist/domain/types.js +0 -10
- package/dist/domain/validation.d.ts +0 -128
- package/dist/domain/validation.js +0 -358
- package/dist/index.d.ts +0 -50
- package/dist/index.js +0 -66
- package/dist/infrastructure/adapters/inmemory.d.ts +0 -50
- package/dist/infrastructure/adapters/inmemory.js +0 -94
- package/dist/infrastructure/adapters/local.d.ts +0 -79
- package/dist/infrastructure/adapters/local.js +0 -98
- package/dist/infrastructure/adapters/remote.d.ts +0 -44
- package/dist/infrastructure/adapters/remote.js +0 -329
- package/dist/infrastructure/hosts.d.ts +0 -10
- package/dist/infrastructure/hosts.js +0 -84
- package/dist/start/build-info.d.ts +0 -2
- package/dist/start/build-info.js +0 -9
- package/dist/start/control-points.d.ts +0 -24
- package/dist/start/control-points.js +0 -61
- package/dist/start/fw.d.ts +0 -42
- package/dist/start/fw.js +0 -137
- package/dist/start/identity.d.ts +0 -19
- package/dist/start/identity.js +0 -93
- package/dist/start/index.d.ts +0 -34
- package/dist/start/index.js +0 -38
- package/dist/start/names.d.ts +0 -38
- package/dist/start/names.js +0 -41
- package/dist/start/policy.d.ts +0 -70
- package/dist/start/policy.js +0 -128
- package/dist/start/state.d.ts +0 -103
- package/dist/start/state.js +0 -375
package/README.md
CHANGED
|
@@ -1,52 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
> Use it only when your project cannot load ES modules (see
|
|
3
|
-
> [Module formats](https://github.com/FireWeave-HQ/fireweave-sdk/blob/main/docs/module-formats.md)).
|
|
4
|
-
> Same code, same version, same import paths. ES modules are the long-term format;
|
|
5
|
-
> this package will be retired in a future major release.
|
|
1
|
+
# Temporary Holding Version
|
|
6
2
|
|
|
7
|
-
|
|
8
|
-
<picture>
|
|
9
|
-
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/FireWeave-HQ/fireweave-sdk/main/.github/assets/banner-dark.png">
|
|
10
|
-
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/FireWeave-HQ/fireweave-sdk/main/.github/assets/banner-light.png">
|
|
11
|
-
<img alt="Fireweave — agents write the code. We watch every rollout, under control." src="https://raw.githubusercontent.com/FireWeave-HQ/fireweave-sdk/main/.github/assets/banner-light.png" width="100%">
|
|
12
|
-
</picture>
|
|
13
|
-
</a>
|
|
14
|
-
|
|
15
|
-
<p align="center">
|
|
16
|
-
<a href="https://www.npmjs.com/package/@fireweaveai/web-sdk"><img alt="web" src="https://img.shields.io/npm/v/@fireweaveai/web-sdk?label=web&logo=javascript&style=flat&labelColor=0E0E10&color=ED5502&logoColor=white"></a>
|
|
17
|
-
</p>
|
|
18
|
-
|
|
19
|
-
**Fireweave is the AI release engineer for teams shipping with coding agents.** Every change rolls out behind a control point, one step at a time, with guardrails watching real users — and if something breaks, Fireweave pauses or rolls it back before most users ever see it. It's the only way to ship as fast as your agents write code, without the fear of breaking production.
|
|
20
|
-
|
|
21
|
-
## Quick start · Web (browser)
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
npm install @fireweaveai/web-sdk
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
```ts
|
|
28
|
-
import { initFireweave } from '@fireweaveai/web-sdk';
|
|
29
|
-
|
|
30
|
-
const fireweave = await initFireweave({
|
|
31
|
-
mode: 'remote',
|
|
32
|
-
apiUrl: 'https://app-server.fireweave.ai',
|
|
33
|
-
apiKey: 'YOUR_PROJECT_API_KEY',
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
// Register the user, then fetch their decisions.
|
|
37
|
-
await fireweave.identify('user_42', { kind: 'user', properties: { plan: 'pro' } });
|
|
38
|
-
|
|
39
|
-
// Reads are synchronous: safe inside a render path.
|
|
40
|
-
const enabled = fireweave.controlPoints.getBooleanValue('new-checkout', false);
|
|
41
|
-
console.log('new-checkout:', enabled);
|
|
42
|
-
|
|
43
|
-
await fireweave.shutdown();
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## Learn more
|
|
47
|
-
|
|
48
|
-
[Concepts](https://github.com/FireWeave-HQ/fireweave-sdk/blob/main/docs/concepts.md) · [Identity](https://github.com/FireWeave-HQ/fireweave-sdk/blob/main/docs/identity.md) · [Testing](https://github.com/FireWeave-HQ/fireweave-sdk/blob/main/docs/testing.md) · [Troubleshooting](https://github.com/FireWeave-HQ/fireweave-sdk/blob/main/docs/troubleshooting.md) · [Module formats (CommonJS)](https://github.com/FireWeave-HQ/fireweave-sdk/blob/main/docs/module-formats.md) · [All SDKs](https://github.com/FireWeave-HQ/fireweave-sdk#quick-start)
|
|
49
|
-
|
|
50
|
-
## License
|
|
51
|
-
|
|
52
|
-
[MIT](https://github.com/FireWeave-HQ/fireweave-sdk/blob/main/LICENSE)
|
|
3
|
+
This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
|
package/package.json
CHANGED
|
@@ -1,68 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fireweaveai/web-sdk-cjs",
|
|
3
|
-
"version": "0.0.0-
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
"type": "git",
|
|
8
|
-
"url": "git+https://github.com/FireWeave-HQ/fireweave-sdk.git",
|
|
9
|
-
"directory": "sdks/web"
|
|
10
|
-
},
|
|
11
|
-
"homepage": "https://github.com/FireWeave-HQ/fireweave-sdk/tree/master/sdks/web#readme",
|
|
12
|
-
"bugs": "https://github.com/FireWeave-HQ/fireweave-sdk/issues",
|
|
13
|
-
"sideEffects": false,
|
|
14
|
-
"type": "commonjs",
|
|
15
|
-
"main": "./dist/index.js",
|
|
16
|
-
"types": "./dist/index.d.ts",
|
|
17
|
-
"typesVersions": {
|
|
18
|
-
"*": {
|
|
19
|
-
"start": [
|
|
20
|
-
"./dist/start/index.d.ts"
|
|
21
|
-
],
|
|
22
|
-
"vite": [
|
|
23
|
-
"./dist/build/node/vite.d.ts"
|
|
24
|
-
],
|
|
25
|
-
"define": [
|
|
26
|
-
"./dist/build/node/define.d.ts"
|
|
27
|
-
]
|
|
28
|
-
}
|
|
29
|
-
},
|
|
30
|
-
"exports": {
|
|
31
|
-
".": {
|
|
32
|
-
"types": "./dist/index.d.ts",
|
|
33
|
-
"default": "./dist/index.js"
|
|
34
|
-
},
|
|
35
|
-
"./start": {
|
|
36
|
-
"types": "./dist/start/index.d.ts",
|
|
37
|
-
"default": "./dist/start/index.js"
|
|
38
|
-
},
|
|
39
|
-
"./vite": {
|
|
40
|
-
"types": "./dist/build/node/vite.d.ts",
|
|
41
|
-
"default": "./dist/build/node/vite.js"
|
|
42
|
-
},
|
|
43
|
-
"./define": {
|
|
44
|
-
"types": "./dist/build/node/define.d.ts",
|
|
45
|
-
"default": "./dist/build/node/define.js"
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
"files": [
|
|
49
|
-
"dist"
|
|
50
|
-
],
|
|
51
|
-
"peerDependencies": {
|
|
52
|
-
"vite": ">=5.0.0"
|
|
53
|
-
},
|
|
54
|
-
"peerDependenciesMeta": {
|
|
55
|
-
"vite": {
|
|
56
|
-
"optional": true
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
"keywords": [
|
|
60
|
-
"fireweave",
|
|
61
|
-
"release-engineering",
|
|
62
|
-
"progressive-delivery",
|
|
63
|
-
"control-points",
|
|
64
|
-
"feature-flags",
|
|
65
|
-
"browser",
|
|
66
|
-
"web"
|
|
67
|
-
]
|
|
68
|
-
}
|
|
3
|
+
"version": "0.0.0-stage",
|
|
4
|
+
"stub": true,
|
|
5
|
+
"description": "Temporary package placeholder for staged publishing"
|
|
6
|
+
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Fireweave AI, Inc.
|
|
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.
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* FireweaveWebClient — the Fireweave-native surface, mirroring the server
|
|
3
|
-
* SDK's `FireweaveClient` namespace for namespace (ADR-0003: extensions live
|
|
4
|
-
* beside the OpenFeature client, never inside it).
|
|
5
|
-
*
|
|
6
|
-
* Scope of v1 (spec/control-points.md "Scope of v1"): exactly two
|
|
7
|
-
* capabilities — control points and target registration. Releases,
|
|
8
|
-
* exposures, signals, capabilities discovery and guardrails are out of v1;
|
|
9
|
-
* this client MUST NOT expose them (conformance/surface/control-points.surface.json
|
|
10
|
-
* "mustNotExpose"). The dynamic `invokeCapability` dispatcher survives
|
|
11
|
-
* unchanged.
|
|
12
|
-
*
|
|
13
|
-
* One divergence from the server SDK, and it is intentional: `controlPoints.*`
|
|
14
|
-
* is SYNCHRONOUS here and promise-returning on the server. That follows from
|
|
15
|
-
* the OpenFeature web contract — browser reads happen in render paths.
|
|
16
|
-
*/
|
|
17
|
-
import { FireweaveError } from '../domain/errors.js';
|
|
18
|
-
import type { ContextInput } from '../domain/context.js';
|
|
19
|
-
import type { FireweaveWebRuntime, ExpectedFlagType } from './runtime.js';
|
|
20
|
-
import type { Decision, JsonValue } from '../domain/types.js';
|
|
21
|
-
import type { RegisterTargetOptions, RegisterTargetResult } from './ports.js';
|
|
22
|
-
export interface ExtensionResult {
|
|
23
|
-
readonly ok: boolean;
|
|
24
|
-
readonly error?: FireweaveError;
|
|
25
|
-
readonly degraded?: boolean;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Reserved for cross-language surface parity
|
|
29
|
-
* (conformance/surface/control-points.surface.json pins `evaluate(key, type,
|
|
30
|
-
* default, context?, options?)` across every language). Currently INERT on
|
|
31
|
-
* web — accepted and typed, nothing reads it.
|
|
32
|
-
*
|
|
33
|
-
* Node's `EvaluateOptions` carries `signal` (abort an in-flight network
|
|
34
|
-
* call), `includePayload` (attach raw flag payload metadata), and
|
|
35
|
-
* `sendExposure` (opt into exposure emission for this one call). None of
|
|
36
|
-
* those map cleanly onto web's contract: `evaluate` here is a SYNCHRONOUS
|
|
37
|
-
* read of an already-prefetched cache (ADR-0009), so there is no in-flight
|
|
38
|
-
* I/O to abort at read time, and exposure emission is a constructor-level
|
|
39
|
-
* opt-in (`FireweaveWebRuntimeConfig.sendExposure`) rather than a per-call
|
|
40
|
-
* one. The parameter exists so this method's ARITY matches the descriptor
|
|
41
|
-
* every language is pinned to, not because it does anything yet.
|
|
42
|
-
*/
|
|
43
|
-
export interface EvaluateOptions {
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Control-point evaluation on the public client surface — decision-returning,
|
|
47
|
-
* without reaching into the runtime. Never throws; errors surface as ERROR
|
|
48
|
-
* decisions, exactly like the OpenFeature path.
|
|
49
|
-
*/
|
|
50
|
-
export declare class WebControlPointsApi {
|
|
51
|
-
private readonly runtime;
|
|
52
|
-
constructor(runtime: FireweaveWebRuntime);
|
|
53
|
-
evaluate(controlPointKey: string, expectedType: ExpectedFlagType, defaultValue: JsonValue, context?: ContextInput, _options?: EvaluateOptions): Decision;
|
|
54
|
-
getBooleanValue(controlPointKey: string, defaultValue: boolean, context?: ContextInput): boolean;
|
|
55
|
-
getStringValue(controlPointKey: string, defaultValue: string, context?: ContextInput): string;
|
|
56
|
-
getNumberValue(controlPointKey: string, defaultValue: number, context?: ContextInput): number;
|
|
57
|
-
getObjectValue(controlPointKey: string, defaultValue: JsonValue, context?: ContextInput): JsonValue;
|
|
58
|
-
/**
|
|
59
|
-
* Detailed reads — the whole {@link Decision} rather than just its value.
|
|
60
|
-
*
|
|
61
|
-
* Same arguments as the `*Value` pair above, so a caller upgrades from one
|
|
62
|
-
* to the other without restructuring the call (spec/control-points.md "The
|
|
63
|
-
* nine methods"). SYNCHRONOUS like every other read here (ADR-0009).
|
|
64
|
-
*/
|
|
65
|
-
getBooleanDetails(controlPointKey: string, defaultValue: boolean, context?: ContextInput): Decision;
|
|
66
|
-
getStringDetails(controlPointKey: string, defaultValue: string, context?: ContextInput): Decision;
|
|
67
|
-
getNumberDetails(controlPointKey: string, defaultValue: number, context?: ContextInput): Decision;
|
|
68
|
-
getObjectDetails(controlPointKey: string, defaultValue: JsonValue, context?: ContextInput): Decision;
|
|
69
|
-
}
|
|
70
|
-
export interface FireweaveWebClientOptions {
|
|
71
|
-
}
|
|
72
|
-
export declare class FireweaveWebClient {
|
|
73
|
-
readonly runtime: FireweaveWebRuntime;
|
|
74
|
-
readonly controlPoints: WebControlPointsApi;
|
|
75
|
-
constructor(runtime: FireweaveWebRuntime, _options?: FireweaveWebClientOptions);
|
|
76
|
-
/**
|
|
77
|
-
* Dynamic capability dispatch. Unknown capabilities — currently all of
|
|
78
|
-
* them, v1's SUPPORTED_CAPABILITIES is empty — degrade with
|
|
79
|
-
* UnsupportedCapability, never throw. Any future capability listed in
|
|
80
|
-
* SUPPORTED_CAPABILITIES is lifecycle-gated the same way (ruling 17).
|
|
81
|
-
*/
|
|
82
|
-
invokeCapability(capability: string, _args?: Record<string, JsonValue>): ExtensionResult;
|
|
83
|
-
initialize(context?: ContextInput): Promise<void>;
|
|
84
|
-
/**
|
|
85
|
-
* Register durable targeting facts for a target (spec/modes.md).
|
|
86
|
-
*
|
|
87
|
-
* Resolves rather than throwing: this runs in sign-in paths, where a
|
|
88
|
-
* targeting concern must not break authentication. In local mode this
|
|
89
|
-
* records in-process and traces the call; nothing reaches fw-server (see
|
|
90
|
-
* `FireweaveLocalWebAdapter.registerTarget`).
|
|
91
|
-
*/
|
|
92
|
-
registerTarget(targetingKey: string, options?: RegisterTargetOptions): Promise<RegisterTargetResult>;
|
|
93
|
-
/**
|
|
94
|
-
* Sign-in hook: register the user's durable targeting properties, then
|
|
95
|
-
* re-prefetch under that id so percentage ramps bucket on a stable key.
|
|
96
|
-
*
|
|
97
|
-
* Two kinds of property feed a rule and both are needed — DURABLE ones
|
|
98
|
-
* registered here, and PER-REQUEST ones carried in the evaluation context. A
|
|
99
|
-
* rule targeting a property that is never registered AND never sent matches
|
|
100
|
-
* nobody, silently.
|
|
101
|
-
*/
|
|
102
|
-
identify(targetingKey: string, options?: RegisterTargetOptions): Promise<RegisterTargetResult>;
|
|
103
|
-
shutdown(): Promise<void>;
|
|
104
|
-
}
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FireweaveWebClient = exports.WebControlPointsApi = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* FireweaveWebClient — the Fireweave-native surface, mirroring the server
|
|
6
|
-
* SDK's `FireweaveClient` namespace for namespace (ADR-0003: extensions live
|
|
7
|
-
* beside the OpenFeature client, never inside it).
|
|
8
|
-
*
|
|
9
|
-
* Scope of v1 (spec/control-points.md "Scope of v1"): exactly two
|
|
10
|
-
* capabilities — control points and target registration. Releases,
|
|
11
|
-
* exposures, signals, capabilities discovery and guardrails are out of v1;
|
|
12
|
-
* this client MUST NOT expose them (conformance/surface/control-points.surface.json
|
|
13
|
-
* "mustNotExpose"). The dynamic `invokeCapability` dispatcher survives
|
|
14
|
-
* unchanged.
|
|
15
|
-
*
|
|
16
|
-
* One divergence from the server SDK, and it is intentional: `controlPoints.*`
|
|
17
|
-
* is SYNCHRONOUS here and promise-returning on the server. That follows from
|
|
18
|
-
* the OpenFeature web contract — browser reads happen in render paths.
|
|
19
|
-
*/
|
|
20
|
-
const errors_js_1 = require("../domain/errors.js");
|
|
21
|
-
function failure(error, degraded = false) {
|
|
22
|
-
return degraded ? { ok: false, error, degraded: true } : { ok: false, error };
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Lifecycle gate for extension calls. Kept for forward compatibility with
|
|
26
|
-
* `invokeCapability` (ruling 17, Go/Java model) even though v1's
|
|
27
|
-
* SUPPORTED_CAPABILITIES is empty and therefore never reaches it today — a
|
|
28
|
-
* future capability re-added to the allowlist is gated the same way without
|
|
29
|
-
* this function needing to be reinvented.
|
|
30
|
-
*/
|
|
31
|
-
function lifecycleGate(runtime) {
|
|
32
|
-
const state = runtime.getState();
|
|
33
|
-
if (state === 'SHUTDOWN')
|
|
34
|
-
return new errors_js_1.FireweaveError('AlreadyClosed');
|
|
35
|
-
if (state === 'UNINITIALIZED' || state === 'INITIALIZING')
|
|
36
|
-
return new errors_js_1.FireweaveError('NotReady');
|
|
37
|
-
return undefined;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Control-point evaluation on the public client surface — decision-returning,
|
|
41
|
-
* without reaching into the runtime. Never throws; errors surface as ERROR
|
|
42
|
-
* decisions, exactly like the OpenFeature path.
|
|
43
|
-
*/
|
|
44
|
-
class WebControlPointsApi {
|
|
45
|
-
runtime;
|
|
46
|
-
constructor(runtime) {
|
|
47
|
-
this.runtime = runtime;
|
|
48
|
-
}
|
|
49
|
-
evaluate(controlPointKey, expectedType, defaultValue, context, _options) {
|
|
50
|
-
return this.runtime.evaluateSync(controlPointKey, expectedType, defaultValue, context);
|
|
51
|
-
}
|
|
52
|
-
getBooleanValue(controlPointKey, defaultValue, context) {
|
|
53
|
-
return this.evaluate(controlPointKey, 'boolean', defaultValue, context).value;
|
|
54
|
-
}
|
|
55
|
-
getStringValue(controlPointKey, defaultValue, context) {
|
|
56
|
-
return this.evaluate(controlPointKey, 'string', defaultValue, context).value;
|
|
57
|
-
}
|
|
58
|
-
getNumberValue(controlPointKey, defaultValue, context) {
|
|
59
|
-
return this.evaluate(controlPointKey, 'number', defaultValue, context).value;
|
|
60
|
-
}
|
|
61
|
-
getObjectValue(controlPointKey, defaultValue, context) {
|
|
62
|
-
return this.evaluate(controlPointKey, 'object', defaultValue, context).value;
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Detailed reads — the whole {@link Decision} rather than just its value.
|
|
66
|
-
*
|
|
67
|
-
* Same arguments as the `*Value` pair above, so a caller upgrades from one
|
|
68
|
-
* to the other without restructuring the call (spec/control-points.md "The
|
|
69
|
-
* nine methods"). SYNCHRONOUS like every other read here (ADR-0009).
|
|
70
|
-
*/
|
|
71
|
-
getBooleanDetails(controlPointKey, defaultValue, context) {
|
|
72
|
-
return this.evaluate(controlPointKey, 'boolean', defaultValue, context);
|
|
73
|
-
}
|
|
74
|
-
getStringDetails(controlPointKey, defaultValue, context) {
|
|
75
|
-
return this.evaluate(controlPointKey, 'string', defaultValue, context);
|
|
76
|
-
}
|
|
77
|
-
getNumberDetails(controlPointKey, defaultValue, context) {
|
|
78
|
-
return this.evaluate(controlPointKey, 'number', defaultValue, context);
|
|
79
|
-
}
|
|
80
|
-
getObjectDetails(controlPointKey, defaultValue, context) {
|
|
81
|
-
return this.evaluate(controlPointKey, 'object', defaultValue, context);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
exports.WebControlPointsApi = WebControlPointsApi;
|
|
85
|
-
/**
|
|
86
|
-
* Names invokeCapability will dispatch instead of degrading with
|
|
87
|
-
* UnsupportedCapability. Empty in v1: releases, exposures, signals,
|
|
88
|
-
* capabilities discovery, and guardrails are all out of scope
|
|
89
|
-
* (spec/control-points.md) and MUST NOT be exposed, so a cut namespace's
|
|
90
|
-
* capability string resolves exactly like any other unknown string.
|
|
91
|
-
*/
|
|
92
|
-
const SUPPORTED_CAPABILITIES = Object.freeze([]);
|
|
93
|
-
class FireweaveWebClient {
|
|
94
|
-
runtime;
|
|
95
|
-
controlPoints;
|
|
96
|
-
constructor(runtime, _options = {}) {
|
|
97
|
-
this.runtime = runtime;
|
|
98
|
-
this.controlPoints = new WebControlPointsApi(runtime);
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Dynamic capability dispatch. Unknown capabilities — currently all of
|
|
102
|
-
* them, v1's SUPPORTED_CAPABILITIES is empty — degrade with
|
|
103
|
-
* UnsupportedCapability, never throw. Any future capability listed in
|
|
104
|
-
* SUPPORTED_CAPABILITIES is lifecycle-gated the same way (ruling 17).
|
|
105
|
-
*/
|
|
106
|
-
invokeCapability(capability, _args) {
|
|
107
|
-
if (!SUPPORTED_CAPABILITIES.includes(capability)) {
|
|
108
|
-
return failure(new errors_js_1.FireweaveError('UnsupportedCapability'), true);
|
|
109
|
-
}
|
|
110
|
-
const gate = lifecycleGate(this.runtime);
|
|
111
|
-
if (gate !== undefined)
|
|
112
|
-
return failure(gate, true);
|
|
113
|
-
return { ok: true };
|
|
114
|
-
}
|
|
115
|
-
initialize(context) {
|
|
116
|
-
return this.runtime.initialize(context);
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Register durable targeting facts for a target (spec/modes.md).
|
|
120
|
-
*
|
|
121
|
-
* Resolves rather than throwing: this runs in sign-in paths, where a
|
|
122
|
-
* targeting concern must not break authentication. In local mode this
|
|
123
|
-
* records in-process and traces the call; nothing reaches fw-server (see
|
|
124
|
-
* `FireweaveLocalWebAdapter.registerTarget`).
|
|
125
|
-
*/
|
|
126
|
-
registerTarget(targetingKey, options = {}) {
|
|
127
|
-
return this.runtime.registerTarget(targetingKey, options);
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Sign-in hook: register the user's durable targeting properties, then
|
|
131
|
-
* re-prefetch under that id so percentage ramps bucket on a stable key.
|
|
132
|
-
*
|
|
133
|
-
* Two kinds of property feed a rule and both are needed — DURABLE ones
|
|
134
|
-
* registered here, and PER-REQUEST ones carried in the evaluation context. A
|
|
135
|
-
* rule targeting a property that is never registered AND never sent matches
|
|
136
|
-
* nobody, silently.
|
|
137
|
-
*/
|
|
138
|
-
async identify(targetingKey, options = {}) {
|
|
139
|
-
const result = await this.runtime.registerTarget(targetingKey, options);
|
|
140
|
-
await this.runtime.setContext({ targetingKey });
|
|
141
|
-
return result;
|
|
142
|
-
}
|
|
143
|
-
async shutdown() {
|
|
144
|
-
await this.runtime.shutdown();
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
exports.FireweaveWebClient = FireweaveWebClient;
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* initFireweave — the single SDK entry point (spec/modes.md).
|
|
3
|
-
*
|
|
4
|
-
* `mode` is required and never inferred: a missing or mistyped credential
|
|
5
|
-
* must fail loudly at boot, not silently fall back to local evaluation —
|
|
6
|
-
* that failure mode looks like a green boot and a feature that never ramps.
|
|
7
|
-
* This function's only job is to validate the initialisation-time contract
|
|
8
|
-
* and select the matching adapter; nothing downstream branches on mode again
|
|
9
|
-
* (spec/modes.md "Behaviour per mode" — both adapters implement the same
|
|
10
|
-
* WebBackendAdapter port, so FireweaveWebClient / FireweaveWebRuntime stay
|
|
11
|
-
* mode-blind).
|
|
12
|
-
*
|
|
13
|
-
* Initialisation fails loudly (throws); reads on the returned client never do
|
|
14
|
-
* (spec/control-points.md "initialise is the exception").
|
|
15
|
-
*
|
|
16
|
-
* ## A web-specific wrinkle: `FireweaveWebRuntime.initialize()` never throws
|
|
17
|
-
*
|
|
18
|
-
* Node's `FireweaveRuntime.initialize()` rejects on adapter failure, so
|
|
19
|
-
* node's initFireweave can just `await runtime.initialize()` and let a bad
|
|
20
|
-
* host/credential propagate. Web's runtime is deliberately fail-OPEN at
|
|
21
|
-
* `initialize()` — a hung or failing prefetch must not block app boot
|
|
22
|
-
* (ADR-0009 "Fail-open, not fail-silent"), so it swallows adapter failures
|
|
23
|
-
* into ERROR/STALE state instead of rejecting.
|
|
24
|
-
*
|
|
25
|
-
* That non-throwing contract is correct for TRANSIENT failures (the network
|
|
26
|
-
* happened to be down) but wrong for the four Configuration rows below,
|
|
27
|
-
* which spec/modes.md requires to fail loudly at boot. This module closes
|
|
28
|
-
* that gap itself in two parts: `validateInitOptions` (domain/validation.ts)
|
|
29
|
-
* covers rows 1/2/4 (mode absent/unrecognised, remote apiKey/apiUrl blank,
|
|
30
|
-
* local combined with credentials) exactly like node's `initFireweave` does;
|
|
31
|
-
* `initRemote` covers row 3 (the host allowlist) with a direct, SYNCHRONOUS
|
|
32
|
-
* `assertHostAllowed` call, before ever calling into the runtime — that call
|
|
33
|
-
* is what makes a bad host fail LOUDLY here, because the runtime itself
|
|
34
|
-
* deliberately never throws. A genuinely transient prefetch failure (host is
|
|
35
|
-
* fine, network hiccups) still resolves into ERROR/STALE rather than
|
|
36
|
-
* throwing — that fail-open behaviour is unchanged and is not one of the
|
|
37
|
-
* four rows.
|
|
38
|
-
*/
|
|
39
|
-
import { FireweaveWebClient } from './client.js';
|
|
40
|
-
import type { FireweaveFetchLike } from '../infrastructure/adapters/remote.js';
|
|
41
|
-
import type { ContextInput } from '../domain/context.js';
|
|
42
|
-
export interface InitFireweaveRemoteOptions {
|
|
43
|
-
/** Evaluate against fw-server over the network (spec/remote-protocol.md). */
|
|
44
|
-
readonly mode: 'remote';
|
|
45
|
-
/** Fireweave project key. Public by construction (ADR-0009) — required, never read from the environment. */
|
|
46
|
-
readonly apiKey: string;
|
|
47
|
-
/** fw-server base URL. Required — never read from the environment. */
|
|
48
|
-
readonly apiUrl: string;
|
|
49
|
-
/**
|
|
50
|
-
* SSRF/misconfiguration allowlist override (spec/modes.md "apiUrl fails
|
|
51
|
-
* the host allowlist"). Default: the canonical Fireweave hosts + loopback
|
|
52
|
-
* (`DEFAULT_ALLOWED_HOSTS`). A self-hosted fw-server must list its own
|
|
53
|
-
* host explicitly; `['*']` opts out.
|
|
54
|
-
*/
|
|
55
|
-
readonly allowedHosts?: readonly string[];
|
|
56
|
-
/** Injected fetch (tests). Production uses the runtime's global `fetch`. */
|
|
57
|
-
readonly fetch?: FireweaveFetchLike;
|
|
58
|
-
/** Initial evaluation context (e.g. an anonymous targetingKey) to prefetch under. */
|
|
59
|
-
readonly context?: ContextInput;
|
|
60
|
-
}
|
|
61
|
-
export interface InitFireweaveLocalOptions {
|
|
62
|
-
/** Evaluate against an in-process seeded map; no network (spec/modes.md). */
|
|
63
|
-
readonly mode: 'local';
|
|
64
|
-
readonly local?: {
|
|
65
|
-
/**
|
|
66
|
-
* Per-key boolean overrides — the seeded local map. A present key
|
|
67
|
-
* resolves with reason `STATIC`; an absent key misses so the caller's
|
|
68
|
-
* own default is used. May be empty or omitted entirely.
|
|
69
|
-
*/
|
|
70
|
-
readonly controlPoints?: Record<string, boolean>;
|
|
71
|
-
/**
|
|
72
|
-
* Sink for the `[fireweave:local]` registerTarget trace line
|
|
73
|
-
* (spec/modes.md "registerTarget in local mode"). Defaults to
|
|
74
|
-
* `console.info`.
|
|
75
|
-
*/
|
|
76
|
-
readonly log?: (message: string) => void;
|
|
77
|
-
};
|
|
78
|
-
/** Initial evaluation context (e.g. an anonymous targetingKey) to prefetch under. */
|
|
79
|
-
readonly context?: ContextInput;
|
|
80
|
-
}
|
|
81
|
-
export type InitFireweaveOptions = InitFireweaveRemoteOptions | InitFireweaveLocalOptions;
|
|
82
|
-
/**
|
|
83
|
-
* Build the adapter matching `options.mode` and bring a
|
|
84
|
-
* {@link FireweaveWebClient} up.
|
|
85
|
-
*
|
|
86
|
-
* Throws {@link FireweaveError} (kind `Configuration`) for every row of the
|
|
87
|
-
* initialisation-validation table (spec/modes.md):
|
|
88
|
-
* - `mode` absent or unrecognised
|
|
89
|
-
* - `mode: 'remote'` with `apiKey` or `apiUrl` missing/blank
|
|
90
|
-
* - `apiUrl` fails the host allowlist
|
|
91
|
-
* - `mode: 'local'` with credentials supplied
|
|
92
|
-
*
|
|
93
|
-
* The first, second and fourth rows are `validateInitOptions`'s job
|
|
94
|
-
* (domain/validation.ts, shared discipline with node's `initFireweave`); the
|
|
95
|
-
* third is validated downstream, inside `initRemote`, for the reason the
|
|
96
|
-
* module doc comment explains — `FireweaveWebRuntime.initialize()` itself
|
|
97
|
-
* never throws.
|
|
98
|
-
*/
|
|
99
|
-
export declare function initFireweave(options: InitFireweaveOptions): Promise<FireweaveWebClient>;
|
package/dist/application/mode.js
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.initFireweave = initFireweave;
|
|
4
|
-
/**
|
|
5
|
-
* initFireweave — the single SDK entry point (spec/modes.md).
|
|
6
|
-
*
|
|
7
|
-
* `mode` is required and never inferred: a missing or mistyped credential
|
|
8
|
-
* must fail loudly at boot, not silently fall back to local evaluation —
|
|
9
|
-
* that failure mode looks like a green boot and a feature that never ramps.
|
|
10
|
-
* This function's only job is to validate the initialisation-time contract
|
|
11
|
-
* and select the matching adapter; nothing downstream branches on mode again
|
|
12
|
-
* (spec/modes.md "Behaviour per mode" — both adapters implement the same
|
|
13
|
-
* WebBackendAdapter port, so FireweaveWebClient / FireweaveWebRuntime stay
|
|
14
|
-
* mode-blind).
|
|
15
|
-
*
|
|
16
|
-
* Initialisation fails loudly (throws); reads on the returned client never do
|
|
17
|
-
* (spec/control-points.md "initialise is the exception").
|
|
18
|
-
*
|
|
19
|
-
* ## A web-specific wrinkle: `FireweaveWebRuntime.initialize()` never throws
|
|
20
|
-
*
|
|
21
|
-
* Node's `FireweaveRuntime.initialize()` rejects on adapter failure, so
|
|
22
|
-
* node's initFireweave can just `await runtime.initialize()` and let a bad
|
|
23
|
-
* host/credential propagate. Web's runtime is deliberately fail-OPEN at
|
|
24
|
-
* `initialize()` — a hung or failing prefetch must not block app boot
|
|
25
|
-
* (ADR-0009 "Fail-open, not fail-silent"), so it swallows adapter failures
|
|
26
|
-
* into ERROR/STALE state instead of rejecting.
|
|
27
|
-
*
|
|
28
|
-
* That non-throwing contract is correct for TRANSIENT failures (the network
|
|
29
|
-
* happened to be down) but wrong for the four Configuration rows below,
|
|
30
|
-
* which spec/modes.md requires to fail loudly at boot. This module closes
|
|
31
|
-
* that gap itself in two parts: `validateInitOptions` (domain/validation.ts)
|
|
32
|
-
* covers rows 1/2/4 (mode absent/unrecognised, remote apiKey/apiUrl blank,
|
|
33
|
-
* local combined with credentials) exactly like node's `initFireweave` does;
|
|
34
|
-
* `initRemote` covers row 3 (the host allowlist) with a direct, SYNCHRONOUS
|
|
35
|
-
* `assertHostAllowed` call, before ever calling into the runtime — that call
|
|
36
|
-
* is what makes a bad host fail LOUDLY here, because the runtime itself
|
|
37
|
-
* deliberately never throws. A genuinely transient prefetch failure (host is
|
|
38
|
-
* fine, network hiccups) still resolves into ERROR/STALE rather than
|
|
39
|
-
* throwing — that fail-open behaviour is unchanged and is not one of the
|
|
40
|
-
* four rows.
|
|
41
|
-
*/
|
|
42
|
-
const client_js_1 = require("./client.js");
|
|
43
|
-
const runtime_js_1 = require("./runtime.js");
|
|
44
|
-
const local_js_1 = require("../infrastructure/adapters/local.js");
|
|
45
|
-
const remote_js_1 = require("../infrastructure/adapters/remote.js");
|
|
46
|
-
const hosts_js_1 = require("../infrastructure/hosts.js");
|
|
47
|
-
const validation_js_1 = require("../domain/validation.js");
|
|
48
|
-
async function initLocal(options) {
|
|
49
|
-
const local = options.local ?? {};
|
|
50
|
-
const adapter = new local_js_1.FireweaveLocalWebAdapter({
|
|
51
|
-
devFlags: local.controlPoints ?? {},
|
|
52
|
-
...(local.log !== undefined ? { log: local.log } : {}),
|
|
53
|
-
});
|
|
54
|
-
const runtime = new runtime_js_1.FireweaveWebRuntime(adapter);
|
|
55
|
-
const client = new client_js_1.FireweaveWebClient(runtime);
|
|
56
|
-
await client.initialize(options.context);
|
|
57
|
-
return client;
|
|
58
|
-
}
|
|
59
|
-
async function initRemote(options) {
|
|
60
|
-
const { apiKey, apiUrl, allowedHosts, fetch } = options;
|
|
61
|
-
// `validateInitOptions` (called by `initFireweave`, below) has already
|
|
62
|
-
// ruled out blank apiKey/apiUrl by the time this runs — only the host
|
|
63
|
-
// allowlist row remains to check here. See the module doc comment: this
|
|
64
|
-
// call — not runtime.initialize() — is what makes a bad host fail LOUDLY
|
|
65
|
-
// here, because the runtime itself deliberately never throws.
|
|
66
|
-
(0, hosts_js_1.assertHostAllowed)(apiUrl, allowedHosts);
|
|
67
|
-
const adapter = new remote_js_1.FireweaveRemoteWebAdapter({
|
|
68
|
-
apiUrl,
|
|
69
|
-
apiKey,
|
|
70
|
-
...(allowedHosts !== undefined ? { allowedHosts } : {}),
|
|
71
|
-
...(fetch !== undefined ? { fetch } : {}),
|
|
72
|
-
});
|
|
73
|
-
const runtime = new runtime_js_1.FireweaveWebRuntime(adapter);
|
|
74
|
-
const client = new client_js_1.FireweaveWebClient(runtime);
|
|
75
|
-
await client.initialize(options.context);
|
|
76
|
-
return client;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Build the adapter matching `options.mode` and bring a
|
|
80
|
-
* {@link FireweaveWebClient} up.
|
|
81
|
-
*
|
|
82
|
-
* Throws {@link FireweaveError} (kind `Configuration`) for every row of the
|
|
83
|
-
* initialisation-validation table (spec/modes.md):
|
|
84
|
-
* - `mode` absent or unrecognised
|
|
85
|
-
* - `mode: 'remote'` with `apiKey` or `apiUrl` missing/blank
|
|
86
|
-
* - `apiUrl` fails the host allowlist
|
|
87
|
-
* - `mode: 'local'` with credentials supplied
|
|
88
|
-
*
|
|
89
|
-
* The first, second and fourth rows are `validateInitOptions`'s job
|
|
90
|
-
* (domain/validation.ts, shared discipline with node's `initFireweave`); the
|
|
91
|
-
* third is validated downstream, inside `initRemote`, for the reason the
|
|
92
|
-
* module doc comment explains — `FireweaveWebRuntime.initialize()` itself
|
|
93
|
-
* never throws.
|
|
94
|
-
*/
|
|
95
|
-
async function initFireweave(options) {
|
|
96
|
-
const validated = (0, validation_js_1.validateInitOptions)(options);
|
|
97
|
-
if (!validated.ok)
|
|
98
|
-
throw validated.error;
|
|
99
|
-
const validOptions = validated.value;
|
|
100
|
-
return validOptions.mode === 'local' ? initLocal(validOptions) : initRemote(validOptions);
|
|
101
|
-
}
|