@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.
- package/dist/adapter.d.ts +87 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +2 -0
- package/dist/adapter.js.map +1 -0
- package/dist/adapters/inmemory.d.ts +51 -0
- package/dist/adapters/inmemory.d.ts.map +1 -0
- package/dist/adapters/inmemory.js +91 -0
- package/dist/adapters/inmemory.js.map +1 -0
- package/dist/adapters/local.d.ts +38 -0
- package/dist/adapters/local.d.ts.map +1 -0
- package/dist/adapters/local.js +51 -0
- package/dist/adapters/local.js.map +1 -0
- package/dist/adapters/remote.d.ts +45 -0
- package/dist/adapters/remote.d.ts.map +1 -0
- package/dist/adapters/remote.js +332 -0
- package/dist/adapters/remote.js.map +1 -0
- package/dist/client.d.ts +134 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +0 -0
- package/dist/client.js.map +1 -0
- package/dist/context.d.ts +26 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +106 -0
- package/dist/context.js.map +1 -0
- package/dist/errors.d.ts +37 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +93 -0
- package/dist/errors.js.map +1 -0
- package/dist/hosts.d.ts +11 -0
- package/dist/hosts.d.ts.map +1 -0
- package/dist/hosts.js +79 -0
- package/dist/hosts.js.map +1 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/provider.d.ts +39 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +93 -0
- package/dist/provider.js.map +1 -0
- package/dist/runtime.d.ts +62 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +289 -0
- package/dist/runtime.js.map +1 -0
- package/dist/types.d.ts +90 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/package.json +45 -0
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fireweave remote adapter for browsers — the production path.
|
|
3
|
+
*
|
|
4
|
+
* Speaks only the vendor-neutral Fireweave remote protocol to fw-server:
|
|
5
|
+
* POST /v1/flags/evaluate (batch — one call per context, not per key)
|
|
6
|
+
* POST /v1/capture
|
|
7
|
+
* POST /v1/targets/register
|
|
8
|
+
*
|
|
9
|
+
* Auth: `Authorization: Bearer <project key>`. Never a vendor key: the
|
|
10
|
+
* constructor rejects `phc_`/`phs_`/`phx_` shapes outright (ADR-0009).
|
|
11
|
+
*
|
|
12
|
+
* Credentials are EXPLICIT constructor options. This package never reads
|
|
13
|
+
* `import.meta.env`, `process.env`, or any other ambient source — the embedding
|
|
14
|
+
* app decides what goes into its bundle, and the SDK never picks something up
|
|
15
|
+
* on its own.
|
|
16
|
+
*
|
|
17
|
+
* See spec/remote-protocol.md § Browser clients.
|
|
18
|
+
*/
|
|
19
|
+
import { FireweaveError } from '../errors.js';
|
|
20
|
+
import { assertHostAllowed, assertNotSecretKey } from '../hosts.js';
|
|
21
|
+
const EVALUATE_PATH = '/v1/flags/evaluate';
|
|
22
|
+
const CAPTURE_PATH = '/v1/capture';
|
|
23
|
+
const REGISTER_TARGET_PATH = '/v1/targets/register';
|
|
24
|
+
const DEFAULT_REQUEST_TIMEOUT_MS = 3_000;
|
|
25
|
+
const ALLOWED_REASONS = new Set([
|
|
26
|
+
'STATIC',
|
|
27
|
+
'DEFAULT',
|
|
28
|
+
'TARGETING_MATCH',
|
|
29
|
+
'SPLIT',
|
|
30
|
+
'CACHED',
|
|
31
|
+
'STALE',
|
|
32
|
+
'DISABLED',
|
|
33
|
+
'UNKNOWN',
|
|
34
|
+
'ERROR',
|
|
35
|
+
]);
|
|
36
|
+
function toReason(reason) {
|
|
37
|
+
return ALLOWED_REASONS.has(reason) ? reason : undefined;
|
|
38
|
+
}
|
|
39
|
+
function mapHttpStatus(status) {
|
|
40
|
+
if (status === 401)
|
|
41
|
+
return new FireweaveError('Authentication');
|
|
42
|
+
if (status === 403)
|
|
43
|
+
return new FireweaveError('Authorization');
|
|
44
|
+
if (status === 429)
|
|
45
|
+
return new FireweaveError('RateLimited');
|
|
46
|
+
return new FireweaveError('BackendUnavailable');
|
|
47
|
+
}
|
|
48
|
+
export class FireweaveRemoteWebAdapter {
|
|
49
|
+
name = 'fireweave';
|
|
50
|
+
apiUrl;
|
|
51
|
+
apiKey;
|
|
52
|
+
allowedHosts;
|
|
53
|
+
requestTimeoutMs;
|
|
54
|
+
fetchImpl;
|
|
55
|
+
pending = [];
|
|
56
|
+
ready = false;
|
|
57
|
+
closed = false;
|
|
58
|
+
constructor(options) {
|
|
59
|
+
// Validate at construction, not at first use: a misconfigured key should
|
|
60
|
+
// fail where the developer can see it, not on a user's first evaluation.
|
|
61
|
+
assertNotSecretKey(options.apiKey);
|
|
62
|
+
this.apiUrl = options.apiUrl.trim().replace(/\/+$/, '');
|
|
63
|
+
this.apiKey = options.apiKey.trim();
|
|
64
|
+
this.allowedHosts = options.allowedHosts;
|
|
65
|
+
this.requestTimeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
66
|
+
this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);
|
|
67
|
+
}
|
|
68
|
+
async initialize(_signal) {
|
|
69
|
+
if (this.closed)
|
|
70
|
+
throw new FireweaveError('AlreadyClosed');
|
|
71
|
+
if (this.apiUrl.length === 0)
|
|
72
|
+
throw new FireweaveError('Configuration');
|
|
73
|
+
assertHostAllowed(this.apiUrl, this.allowedHosts);
|
|
74
|
+
this.ready = true;
|
|
75
|
+
}
|
|
76
|
+
async prefetch(context, options) {
|
|
77
|
+
if (this.closed)
|
|
78
|
+
throw new FireweaveError('AlreadyClosed');
|
|
79
|
+
if (!this.ready)
|
|
80
|
+
throw new FireweaveError('NotReady');
|
|
81
|
+
const targetingKey = context.targetingKey ?? '';
|
|
82
|
+
if (targetingKey === '') {
|
|
83
|
+
throw new FireweaveError('InvalidContext', {
|
|
84
|
+
openFeatureErrorCode: 'TARGETING_KEY_MISSING',
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
// `$`-prefixed and `fireweave.`-prefixed attributes are backend directives,
|
|
88
|
+
// not person properties, and groups travel in their own fields.
|
|
89
|
+
const attributes = {};
|
|
90
|
+
for (const [k, v] of Object.entries(context.attributes)) {
|
|
91
|
+
if (k === 'groups' || k === 'groupProperties')
|
|
92
|
+
continue;
|
|
93
|
+
if (k.startsWith('$') || k.startsWith('fireweave.'))
|
|
94
|
+
continue;
|
|
95
|
+
attributes[k] = v;
|
|
96
|
+
}
|
|
97
|
+
const body = { targetingKey };
|
|
98
|
+
if (Object.keys(attributes).length > 0)
|
|
99
|
+
body['attributes'] = attributes;
|
|
100
|
+
if (context.groups !== undefined)
|
|
101
|
+
body['groups'] = context.groups;
|
|
102
|
+
if (context.groupProperties !== undefined)
|
|
103
|
+
body['groupProperties'] = context.groupProperties;
|
|
104
|
+
if (options?.flagKeys !== undefined && options.flagKeys.length > 0) {
|
|
105
|
+
body['flagKeys'] = options.flagKeys;
|
|
106
|
+
}
|
|
107
|
+
const response = await this.requestJson(EVALUATE_PATH, body, options?.signal);
|
|
108
|
+
const out = new Map();
|
|
109
|
+
for (const item of response.decisions ?? []) {
|
|
110
|
+
out.set(item.flagKey, this.toResolution(item, response.quotaLimited === true));
|
|
111
|
+
}
|
|
112
|
+
return out;
|
|
113
|
+
}
|
|
114
|
+
async registerTarget(targetingKey, options = {}) {
|
|
115
|
+
if (this.closed)
|
|
116
|
+
return { ok: false, error: new FireweaveError('AlreadyClosed') };
|
|
117
|
+
if (!this.ready)
|
|
118
|
+
return { ok: false, error: new FireweaveError('NotReady') };
|
|
119
|
+
if (targetingKey.trim() === '') {
|
|
120
|
+
return {
|
|
121
|
+
ok: false,
|
|
122
|
+
error: new FireweaveError('InvalidContext', {
|
|
123
|
+
openFeatureErrorCode: 'TARGETING_KEY_MISSING',
|
|
124
|
+
}),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
const body = { targetingKey };
|
|
128
|
+
if (options.kind !== undefined)
|
|
129
|
+
body['kind'] = options.kind;
|
|
130
|
+
if (options.environment !== undefined)
|
|
131
|
+
body['environment'] = options.environment;
|
|
132
|
+
if (options.properties !== undefined && Object.keys(options.properties).length > 0) {
|
|
133
|
+
body['properties'] = options.properties;
|
|
134
|
+
}
|
|
135
|
+
// Retried once, and only when the taxonomy says a retry could succeed: a
|
|
136
|
+
// rejected payload or a bad key would be rejected identically.
|
|
137
|
+
let lastError;
|
|
138
|
+
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
139
|
+
try {
|
|
140
|
+
await this.requestJson(REGISTER_TARGET_PATH, body, options.signal);
|
|
141
|
+
return { ok: true };
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
lastError = err instanceof FireweaveError ? err : new FireweaveError('BackendUnavailable');
|
|
145
|
+
if (!lastError.retryable)
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return { ok: false, ...(lastError !== undefined ? { error: lastError } : {}) };
|
|
150
|
+
}
|
|
151
|
+
recordExposure(exposure) {
|
|
152
|
+
if (this.closed || !this.ready)
|
|
153
|
+
return;
|
|
154
|
+
const event = {
|
|
155
|
+
type: 'exposure',
|
|
156
|
+
targetingKey: exposure.targetingKey,
|
|
157
|
+
flagKey: exposure.flagKey,
|
|
158
|
+
value: exposure.value,
|
|
159
|
+
};
|
|
160
|
+
if (exposure.variant !== undefined)
|
|
161
|
+
event.variant = exposure.variant;
|
|
162
|
+
if (exposure.rolloutId !== undefined)
|
|
163
|
+
event.rolloutId = exposure.rolloutId;
|
|
164
|
+
if (exposure.changeId !== undefined)
|
|
165
|
+
event.changeId = exposure.changeId;
|
|
166
|
+
if (exposure.stampId !== undefined)
|
|
167
|
+
event.stampId = exposure.stampId;
|
|
168
|
+
this.pending.push(event);
|
|
169
|
+
}
|
|
170
|
+
recordSignal(signal) {
|
|
171
|
+
if (this.closed || !this.ready)
|
|
172
|
+
return;
|
|
173
|
+
const event = {
|
|
174
|
+
type: 'signal',
|
|
175
|
+
targetingKey: signal.targetingKey ?? signal.rolloutId ?? 'fireweave-web-sdk',
|
|
176
|
+
name: signal.name,
|
|
177
|
+
properties: {
|
|
178
|
+
kind: signal.kind,
|
|
179
|
+
...(signal.status !== undefined ? { status: signal.status } : {}),
|
|
180
|
+
...(signal.errorKind !== undefined ? { errorKind: signal.errorKind } : {}),
|
|
181
|
+
...(signal.message !== undefined ? { message: signal.message } : {}),
|
|
182
|
+
...(signal.value !== undefined ? { value: signal.value } : {}),
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
if (signal.flagKey !== undefined)
|
|
186
|
+
event.flagKey = signal.flagKey;
|
|
187
|
+
if (signal.variant !== undefined)
|
|
188
|
+
event.variant = signal.variant;
|
|
189
|
+
if (signal.rolloutId !== undefined)
|
|
190
|
+
event.rolloutId = signal.rolloutId;
|
|
191
|
+
if (signal.timestamp !== undefined)
|
|
192
|
+
event.timestamp = signal.timestamp;
|
|
193
|
+
this.pending.push(event);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* `beacon: true` is the unload path. It must not await anything the browser
|
|
197
|
+
* will cancel, so it uses `sendBeacon` when available and a `keepalive`
|
|
198
|
+
* fetch otherwise, and it never re-queues on failure — there is no later.
|
|
199
|
+
*/
|
|
200
|
+
async flush(options = {}) {
|
|
201
|
+
if (this.closed || this.pending.length === 0)
|
|
202
|
+
return;
|
|
203
|
+
const batch = this.pending.splice(0, this.pending.length);
|
|
204
|
+
const payload = JSON.stringify({ events: batch });
|
|
205
|
+
if (options.beacon === true) {
|
|
206
|
+
this.sendBeaconOrKeepalive(payload);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
try {
|
|
210
|
+
await this.requestJson(CAPTURE_PATH, { events: batch });
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
// Never throw out of flush; re-queue so a later flush can retry.
|
|
214
|
+
this.pending.unshift(...batch);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
sendBeaconOrKeepalive(payload) {
|
|
218
|
+
const url = `${this.apiUrl}${CAPTURE_PATH}`;
|
|
219
|
+
const nav = globalThis.navigator;
|
|
220
|
+
// sendBeacon cannot set an Authorization header, so it is only usable where
|
|
221
|
+
// the server accepts the key another way. Prefer keepalive fetch, which
|
|
222
|
+
// can, and fall back to a beacon only if fetch is unavailable.
|
|
223
|
+
try {
|
|
224
|
+
void this.fetchImpl(url, {
|
|
225
|
+
method: 'POST',
|
|
226
|
+
headers: { 'content-type': 'application/json', authorization: `Bearer ${this.apiKey}` },
|
|
227
|
+
body: payload,
|
|
228
|
+
keepalive: true,
|
|
229
|
+
}).catch(() => undefined);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
catch {
|
|
233
|
+
// fall through to beacon
|
|
234
|
+
}
|
|
235
|
+
if (typeof nav?.sendBeacon === 'function') {
|
|
236
|
+
try {
|
|
237
|
+
nav.sendBeacon(url, new Blob([payload], { type: 'application/json' }));
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
// Unload-time delivery is best-effort by definition.
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
async shutdown() {
|
|
245
|
+
if (this.closed)
|
|
246
|
+
return;
|
|
247
|
+
await this.flush();
|
|
248
|
+
this.closed = true;
|
|
249
|
+
this.ready = false;
|
|
250
|
+
}
|
|
251
|
+
features() {
|
|
252
|
+
return {
|
|
253
|
+
remoteEvaluation: true,
|
|
254
|
+
// Structural, not configurable — the browser never evaluates locally.
|
|
255
|
+
localEvaluation: false,
|
|
256
|
+
localOnly: false,
|
|
257
|
+
exposureEmission: true,
|
|
258
|
+
sideEffectFreeReads: true,
|
|
259
|
+
groupAnalytics: true,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
toResolution(item, quotaLimited) {
|
|
263
|
+
if (item.found === false) {
|
|
264
|
+
return quotaLimited ? { found: false, quotaLimited: true } : { found: false };
|
|
265
|
+
}
|
|
266
|
+
const resolution = {
|
|
267
|
+
found: true,
|
|
268
|
+
value: item.value,
|
|
269
|
+
enabled: item.enabled ?? true,
|
|
270
|
+
};
|
|
271
|
+
if (item.variant != null)
|
|
272
|
+
resolution.variant = item.variant;
|
|
273
|
+
const reason = toReason(item.reason);
|
|
274
|
+
if (reason !== undefined)
|
|
275
|
+
resolution.reason = reason;
|
|
276
|
+
if (item.payload !== undefined)
|
|
277
|
+
resolution.payload = item.payload;
|
|
278
|
+
const meta = item.flagMetadata ?? {};
|
|
279
|
+
if (typeof meta['fireweave.flagVersion'] === 'number') {
|
|
280
|
+
resolution.version = meta['fireweave.flagVersion'];
|
|
281
|
+
}
|
|
282
|
+
if (typeof meta['fireweave.reasonCode'] === 'string') {
|
|
283
|
+
resolution.reasonCode = meta['fireweave.reasonCode'];
|
|
284
|
+
}
|
|
285
|
+
if (quotaLimited || meta['fireweave.quotaLimited'] === true)
|
|
286
|
+
resolution.quotaLimited = true;
|
|
287
|
+
return resolution;
|
|
288
|
+
}
|
|
289
|
+
async requestJson(path, body, outerSignal) {
|
|
290
|
+
const controller = new AbortController();
|
|
291
|
+
const timer = setTimeout(() => controller.abort(), this.requestTimeoutMs);
|
|
292
|
+
const onOuterAbort = () => controller.abort();
|
|
293
|
+
if (outerSignal !== undefined) {
|
|
294
|
+
if (outerSignal.aborted)
|
|
295
|
+
controller.abort();
|
|
296
|
+
else
|
|
297
|
+
outerSignal.addEventListener('abort', onOuterAbort, { once: true });
|
|
298
|
+
}
|
|
299
|
+
try {
|
|
300
|
+
let response;
|
|
301
|
+
try {
|
|
302
|
+
response = await this.fetchImpl(`${this.apiUrl}${path}`, {
|
|
303
|
+
method: 'POST',
|
|
304
|
+
headers: {
|
|
305
|
+
'content-type': 'application/json',
|
|
306
|
+
authorization: `Bearer ${this.apiKey}`,
|
|
307
|
+
},
|
|
308
|
+
body: JSON.stringify(body),
|
|
309
|
+
signal: controller.signal,
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
catch (err) {
|
|
313
|
+
const aborted = err instanceof Error && err.name === 'AbortError';
|
|
314
|
+
throw aborted ? new FireweaveError('Timeout') : new FireweaveError('Network');
|
|
315
|
+
}
|
|
316
|
+
if (response.status >= 400)
|
|
317
|
+
throw mapHttpStatus(response.status);
|
|
318
|
+
try {
|
|
319
|
+
return (await response.json());
|
|
320
|
+
}
|
|
321
|
+
catch {
|
|
322
|
+
throw new FireweaveError('MalformedResponse');
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
finally {
|
|
326
|
+
clearTimeout(timer);
|
|
327
|
+
if (outerSignal !== undefined)
|
|
328
|
+
outerSignal.removeEventListener('abort', onOuterAbort);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
//# sourceMappingURL=remote.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote.js","sourceRoot":"","sources":["../../src/adapters/remote.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
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
|
+
* One divergence, and it is intentional: `controlPoints.*` is SYNCHRONOUS here
|
|
7
|
+
* and promise-returning on the server. That follows from the OpenFeature web
|
|
8
|
+
* contract — browser reads happen in render paths — and is recorded in
|
|
9
|
+
* docs/compatibility.md as a surface difference rather than a gap.
|
|
10
|
+
*/
|
|
11
|
+
import { FireweaveError } from './errors.js';
|
|
12
|
+
import type { ContextInput } from './context.js';
|
|
13
|
+
import type { FireweaveWebRuntime, ExpectedFlagType } from './runtime.js';
|
|
14
|
+
import type { Capabilities, Decision, Exposure, JsonValue, ReleaseContext, ReleaseState, Signal, SignalKind } from './types.js';
|
|
15
|
+
import type { RegisterTargetOptions, RegisterTargetResult } from './adapter.js';
|
|
16
|
+
export interface ExtensionResult {
|
|
17
|
+
readonly ok: boolean;
|
|
18
|
+
readonly error?: FireweaveError;
|
|
19
|
+
readonly degraded?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Control-point evaluation on the public client surface — decision-returning,
|
|
23
|
+
* without reaching into the runtime. Never throws; errors surface as ERROR
|
|
24
|
+
* decisions, exactly like the OpenFeature path.
|
|
25
|
+
*/
|
|
26
|
+
export declare class WebControlPointsApi {
|
|
27
|
+
private readonly runtime;
|
|
28
|
+
constructor(runtime: FireweaveWebRuntime);
|
|
29
|
+
evaluate(flagKey: string, expectedType: ExpectedFlagType, defaultValue: JsonValue, context?: ContextInput): Decision;
|
|
30
|
+
getBooleanValue(flagKey: string, defaultValue: boolean, context?: ContextInput): boolean;
|
|
31
|
+
getStringValue(flagKey: string, defaultValue: string, context?: ContextInput): string;
|
|
32
|
+
getNumberValue(flagKey: string, defaultValue: number, context?: ContextInput): number;
|
|
33
|
+
getObjectValue(flagKey: string, defaultValue: JsonValue, context?: ContextInput): JsonValue;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Exposure recording, with the browser's defining constraint: a tab can vanish
|
|
37
|
+
* without warning. Queued exposures are therefore flushed on
|
|
38
|
+
* `visibilitychange → hidden` and on `pagehide`, over a transport that survives
|
|
39
|
+
* unload. There is no server analogue for this — a server process gets a
|
|
40
|
+
* shutdown hook; a tab gets nothing.
|
|
41
|
+
*/
|
|
42
|
+
export declare class WebExposuresApi {
|
|
43
|
+
private readonly runtime;
|
|
44
|
+
private readonly seen;
|
|
45
|
+
private detach;
|
|
46
|
+
constructor(runtime: FireweaveWebRuntime);
|
|
47
|
+
/** Record one exposure. Deduped per (flagKey, targetingKey, variant). */
|
|
48
|
+
record(exposure: Exposure): ExtensionResult;
|
|
49
|
+
flush(): Promise<ExtensionResult>;
|
|
50
|
+
/**
|
|
51
|
+
* Attach unload-time flushing. Idempotent; returns a detach function.
|
|
52
|
+
*
|
|
53
|
+
* `visibilitychange → hidden` fires in cases `pagehide` does not (tab switch
|
|
54
|
+
* on mobile, app backgrounded) and vice versa (bfcache navigation), so both
|
|
55
|
+
* are needed. `beforeunload` is deliberately not used: it suppresses bfcache.
|
|
56
|
+
*/
|
|
57
|
+
attachUnloadFlush(): () => void;
|
|
58
|
+
}
|
|
59
|
+
declare const DEFAULT_SIGNAL_ATTRIBUTE_ALLOWLIST: readonly string[];
|
|
60
|
+
export declare class WebSignalsApi {
|
|
61
|
+
private readonly runtime;
|
|
62
|
+
private readonly recorded;
|
|
63
|
+
constructor(runtime: FireweaveWebRuntime);
|
|
64
|
+
private send;
|
|
65
|
+
recordHealth(signal: Omit<Signal, 'kind'>): ExtensionResult;
|
|
66
|
+
recordError(signal: Omit<Signal, 'kind'>): ExtensionResult;
|
|
67
|
+
recordMetric(signal: Omit<Signal, 'kind'>): ExtensionResult;
|
|
68
|
+
recordOutcome(signal: Omit<Signal, 'kind'>): ExtensionResult;
|
|
69
|
+
getRecorded(kind?: SignalKind): readonly Signal[];
|
|
70
|
+
}
|
|
71
|
+
export interface ReleaseResult extends ExtensionResult {
|
|
72
|
+
readonly state?: ReleaseState;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Release lifecycle from the browser.
|
|
76
|
+
*
|
|
77
|
+
* `setContext` is the load-bearing member — it stamps every subsequent exposure
|
|
78
|
+
* and signal with the rollout it belongs to. `start`/`complete`/`fail` exist
|
|
79
|
+
* for parity with the server client; a browser is rarely the thing that decides
|
|
80
|
+
* a release transitioned, so they are recorded as signals rather than pretending
|
|
81
|
+
* to drive state the backend owns.
|
|
82
|
+
*/
|
|
83
|
+
export declare class WebReleasesApi {
|
|
84
|
+
private readonly runtime;
|
|
85
|
+
private readonly signals;
|
|
86
|
+
private state;
|
|
87
|
+
constructor(runtime: FireweaveWebRuntime, signals: WebSignalsApi);
|
|
88
|
+
setContext(context: ReleaseContext): ExtensionResult;
|
|
89
|
+
private transition;
|
|
90
|
+
start(): ReleaseResult;
|
|
91
|
+
complete(): ReleaseResult;
|
|
92
|
+
fail(): ReleaseResult;
|
|
93
|
+
getState(): ReleaseState;
|
|
94
|
+
}
|
|
95
|
+
/** Phase-one stub: every method degrades with UnsupportedCapability. */
|
|
96
|
+
declare class WebGuardrailsApi {
|
|
97
|
+
evaluate(_name: string, _args?: Record<string, JsonValue>): ExtensionResult;
|
|
98
|
+
}
|
|
99
|
+
declare class WebCapabilitiesApi {
|
|
100
|
+
private readonly runtime;
|
|
101
|
+
constructor(runtime: FireweaveWebRuntime);
|
|
102
|
+
list(): readonly string[];
|
|
103
|
+
get(): Capabilities;
|
|
104
|
+
}
|
|
105
|
+
export interface FireweaveWebClientOptions {
|
|
106
|
+
/** Attach unload-time exposure flushing on construction. Default true. */
|
|
107
|
+
readonly autoFlushOnUnload?: boolean;
|
|
108
|
+
}
|
|
109
|
+
export declare class FireweaveWebClient {
|
|
110
|
+
readonly runtime: FireweaveWebRuntime;
|
|
111
|
+
readonly controlPoints: WebControlPointsApi;
|
|
112
|
+
readonly exposures: WebExposuresApi;
|
|
113
|
+
readonly signals: WebSignalsApi;
|
|
114
|
+
readonly releases: WebReleasesApi;
|
|
115
|
+
readonly guardrails: WebGuardrailsApi;
|
|
116
|
+
readonly capabilities: WebCapabilitiesApi;
|
|
117
|
+
constructor(runtime: FireweaveWebRuntime, options?: FireweaveWebClientOptions);
|
|
118
|
+
/** Dynamic capability dispatch. Unknown capabilities degrade; never throws. */
|
|
119
|
+
invokeCapability(capability: string, _args?: Record<string, JsonValue>): ExtensionResult;
|
|
120
|
+
initialize(context?: ContextInput): Promise<void>;
|
|
121
|
+
/**
|
|
122
|
+
* Sign-in hook: register the user's durable targeting properties, then
|
|
123
|
+
* re-prefetch under that id so percentage ramps bucket on a stable key.
|
|
124
|
+
*
|
|
125
|
+
* Two kinds of property feed a rule and both are needed — DURABLE ones
|
|
126
|
+
* registered here, and PER-REQUEST ones carried in the evaluation context. A
|
|
127
|
+
* rule targeting a property that is never registered AND never sent matches
|
|
128
|
+
* nobody, silently.
|
|
129
|
+
*/
|
|
130
|
+
identify(targetingKey: string, options?: RegisterTargetOptions): Promise<RegisterTargetResult>;
|
|
131
|
+
shutdown(): Promise<void>;
|
|
132
|
+
}
|
|
133
|
+
export { DEFAULT_SIGNAL_ATTRIBUTE_ALLOWLIST };
|
|
134
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
ADDED
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAe7C,MAAM,WAAW,GAAG,OAAO,CAAC;AAC5B,MAAM,YAAY,GAAG,OAAO,CAAC;AAQ7B,SAAS,OAAO,CAAC,KAAqB,EAAE,QAAQ,GAAG,KAAK;IACtD,OAAO,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAChF,CAAC;AAED,kFAAkF;AAClF,SAAS,aAAa,CAAC,OAA4B;IACjD,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IACjC,IAAI,KAAK,KAAK,UAAU;QAAE,OAAO,IAAI,cAAc,CAAC,eAAe,CAAC,CAAC;IACrE,IAAI,KAAK,KAAK,eAAe,IAAI,KAAK,KAAK,cAAc;QAAE,OAAO,IAAI,cAAc,CAAC,UAAU,CAAC,CAAC;IACjG,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,mBAAmB;IACb,OAAO,CAAsB;IAE9C,YAAY,OAA4B;QACtC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,QAAQ,CACN,OAAe,EACf,YAA8B,EAC9B,YAAuB,EACvB,OAAsB;QAEtB,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IACjF,CAAC;IAED,eAAe,CAAC,OAAe,EAAE,YAAqB,EAAE,OAAsB;QAC5E,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC,KAAgB,CAAC;IACnF,CAAC;IAED,cAAc,CAAC,OAAe,EAAE,YAAoB,EAAE,OAAsB;QAC1E,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC,KAAe,CAAC;IACjF,CAAC;IAED,cAAc,CAAC,OAAe,EAAE,YAAoB,EAAE,OAAsB;QAC1E,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC,KAAe,CAAC;IACjF,CAAC;IAED,cAAc,CAAC,OAAe,EAAE,YAAuB,EAAE,OAAsB;QAC7E,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC;IACvE,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,OAAO,eAAe;IACT,OAAO,CAAsB;IAC7B,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,CAA2B;IAEzC,YAAY,OAA4B;QACtC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,yEAAyE;IACzE,MAAM,CAAC,QAAkB;QACvB,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzC,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACnD,MAAM,GAAG,GAAG,GAAG,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,YAAY,IAAI,QAAQ,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;QACrF,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QAC5C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnB,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QACtC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC3B,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IAED;;;;;;OAMG;IACH,iBAAiB;QACf,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,MAAM,CAAC;QAClD,MAAM,MAAM,GAAG,UAId,CAAC;QACF,IAAI,OAAO,MAAM,CAAC,gBAAgB,KAAK,UAAU,EAAE,CAAC;YAClD,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC;YAC9B,OAAO,IAAI,CAAC,MAAM,CAAC;QACrB,CAAC;QAED,MAAM,MAAM,GAAG,GAAS,EAAE;YACxB,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,CAAC,CAAC;QACF,MAAM,YAAY,GAAG,GAAS,EAAE;YAC9B,IAAI,MAAM,CAAC,QAAQ,EAAE,eAAe,KAAK,QAAQ;gBAAE,MAAM,EAAE,CAAC;QAC9D,CAAC,CAAC;QAEF,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,YAAY,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE;YACjB,MAAM,CAAC,mBAAmB,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YACjD,MAAM,CAAC,mBAAmB,EAAE,CAAC,kBAAkB,EAAE,YAAY,CAAC,CAAC;YAC/D,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;QAC1B,CAAC,CAAC;QACF,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;CACF;AAED,MAAM,kCAAkC,GAAsB,MAAM,CAAC,MAAM,CAAC;IAC1E,QAAQ;IACR,WAAW;IACX,SAAS;IACT,OAAO;CACR,CAAC,CAAC;AAEH,MAAM,OAAO,aAAa;IACP,OAAO,CAAsB;IAC7B,QAAQ,GAAa,EAAE,CAAC;IAEzC,YAAY,OAA4B;QACtC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAEO,IAAI,CAAC,MAAc;QACzB,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzC,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACnD,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC;QAC5C,MAAM,OAAO,GAAW;YACtB,GAAG,MAAM;YACT,GAAG,CAAC,EAAE,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClE,GAAG,CAAC,EAAE,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/D,GAAG,CAAC,EAAE,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC7D,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5B,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACnC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IAED,YAAY,CAAC,MAA4B;QACvC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,WAAW,CAAC,MAA4B;QACtC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,YAAY,CAAC,MAA4B;QACvC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,aAAa,CAAC,MAA4B;QACxC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,WAAW,CAAC,IAAiB;QAC3B,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IAC3F,CAAC;CACF;AAMD;;;;;;;;GAQG;AACH,MAAM,OAAO,cAAc;IACR,OAAO,CAAsB;IAC7B,OAAO,CAAgB;IAChC,KAAK,GAAiB,SAAS,CAAC;IAExC,YAAY,OAA4B,EAAE,OAAsB;QAC9D,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,UAAU,CAAC,OAAuB;QAChC,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzC,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACnD,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QACxC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IAEO,UAAU,CAAC,IAAkB,EAAE,IAAY;QACjD,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzC,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;QAC1D,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACnC,CAAC;IAED,KAAK;QACH,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,yBAAyB,CAAC,CAAC;IAC/D,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,4BAA4B,CAAC,CAAC;IACpE,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,wBAAwB,CAAC,CAAC;IAC7D,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;CACF;AAED,wEAAwE;AACxE,MAAM,gBAAgB;IACpB,QAAQ,CAAC,KAAa,EAAE,KAAiC;QACvD,OAAO,OAAO,CAAC,IAAI,cAAc,CAAC,uBAAuB,CAAC,EAAE,IAAI,CAAC,CAAC;IACpE,CAAC;CACF;AAED,MAAM,sBAAsB,GAAsB,MAAM,CAAC,MAAM,CAAC;IAC9D,qBAAqB;IACrB,gBAAgB;IAChB,mBAAmB;IACnB,eAAe;IACf,kBAAkB;IAClB,iBAAiB;IACjB,sBAAsB;IACtB,qBAAqB;IACrB,sBAAsB;IACtB,uBAAuB;IACvB,kBAAkB;CACnB,CAAC,CAAC;AAEH,MAAM,kBAAkB;IACL,OAAO,CAAsB;IAE9C,YAAY,OAA4B;QACtC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,IAAI;QACF,OAAO,sBAAsB,CAAC;IAChC,CAAC;IAED,GAAG;QACD,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;QAC1C,OAAO;YACL,MAAM,EAAE;gBACN,QAAQ,EAAE,KAAK;gBACf,UAAU,EAAE,WAAW;gBACvB,WAAW,EAAE,YAAY;gBACzB,WAAW,EAAE;oBACX,SAAS,EAAE,OAAO;oBAClB,YAAY,EAAE,eAAe;oBAC7B,UAAU,EAAE,KAAK;iBAClB;gBACD,QAAQ,EAAE;oBACR,aAAa,EAAE,IAAI;oBACnB,kEAAkE;oBAClE,6CAA6C;oBAC7C,KAAK,EAAE,IAAI;oBACX,QAAQ,EAAE,IAAI;oBACd,SAAS,EAAE,IAAI;oBACf,OAAO,EAAE,IAAI;oBACb,UAAU,EAAE,KAAK;oBACjB,cAAc,EAAE,IAAI;oBACpB,eAAe,EAAE,IAAI;oBACrB,qEAAqE;oBACrE,kEAAkE;oBAClE,sEAAsE;oBACtE,8DAA8D;oBAC9D,sCAAsC;iBACvC;aACF;YACD,OAAO,EAAE;gBACP,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI;gBAClC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE;gBAClC,QAAQ,EAAE;oBACR,gBAAgB,EAAE,CAAC,CAAC,gBAAgB,IAAI,KAAK;oBAC7C,eAAe,EAAE,CAAC,CAAC,eAAe,IAAI,KAAK;oBAC3C,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,KAAK;oBAC/B,gBAAgB,EAAE,CAAC,CAAC,gBAAgB,IAAI,KAAK;oBAC7C,mBAAmB,EAAE,CAAC,CAAC,mBAAmB,IAAI,KAAK;oBACnD,cAAc,EAAE,CAAC,CAAC,cAAc,IAAI,KAAK;iBAC1C;gBACD,MAAM,EAAE,EAAE,aAAa,EAAE,MAAM,CAAC,gBAAgB,EAAE;aACnD;SACF,CAAC;IACJ,CAAC;CACF;AAOD,MAAM,OAAO,kBAAkB;IACpB,OAAO,CAAsB;IAC7B,aAAa,CAAsB;IACnC,SAAS,CAAkB;IAC3B,OAAO,CAAgB;IACvB,QAAQ,CAAiB;IACzB,UAAU,CAAmB;IAC7B,YAAY,CAAqB;IAE1C,YAAY,OAA4B,EAAE,UAAqC,EAAE;QAC/E,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,IAAI,mBAAmB,CAAC,OAAO,CAAC,CAAC;QACtD,IAAI,CAAC,SAAS,GAAG,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO,GAAG,IAAI,aAAa,CAAC,OAAO,CAAC,CAAC;QAC1C,IAAI,CAAC,QAAQ,GAAG,IAAI,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1D,IAAI,CAAC,UAAU,GAAG,IAAI,gBAAgB,EAAE,CAAC;QACzC,IAAI,CAAC,YAAY,GAAG,IAAI,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAEpD,IAAI,OAAO,CAAC,iBAAiB,KAAK,KAAK,EAAE,CAAC;YACxC,IAAI,CAAC,SAAS,CAAC,iBAAiB,EAAE,CAAC;QACrC,CAAC;IACH,CAAC;IAED,+EAA+E;IAC/E,gBAAgB,CAAC,UAAkB,EAAE,KAAiC;QACpE,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACjD,OAAO,OAAO,CAAC,IAAI,cAAc,CAAC,uBAAuB,CAAC,EAAE,IAAI,CAAC,CAAC;QACpE,CAAC;QACD,IAAI,UAAU,KAAK,kBAAkB,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACzC,IAAI,IAAI,KAAK,SAAS;gBAAE,OAAO,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IAED,UAAU,CAAC,OAAsB;QAC/B,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,QAAQ,CACZ,YAAoB,EACpB,UAAiC,EAAE;QAEnC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACxE,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC;QAChD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC3B,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;IAChC,CAAC;CACF;AAED,OAAO,EAAE,kCAAkC,EAAE,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { CanonicalContext } from './types.js';
|
|
2
|
+
export interface ContextLimits {
|
|
3
|
+
readonly maxAttributeCount: number;
|
|
4
|
+
readonly maxKeyBytes: number;
|
|
5
|
+
readonly maxValueBytes: number;
|
|
6
|
+
readonly maxSerializedBytes: number;
|
|
7
|
+
readonly maxNestingDepth: number;
|
|
8
|
+
}
|
|
9
|
+
export declare const DEFAULT_CONTEXT_LIMITS: ContextLimits;
|
|
10
|
+
/**
|
|
11
|
+
* Keys the backend owns. A client that could set these could claim another
|
|
12
|
+
* tenant's identity, so they are rejected rather than dropped — silently
|
|
13
|
+
* discarding them would leave the caller believing targeting was applied.
|
|
14
|
+
*/
|
|
15
|
+
export declare const DEFAULT_RESERVED_ATTRIBUTE_KEYS: readonly string[];
|
|
16
|
+
export type ContextInput = Record<string, unknown> & {
|
|
17
|
+
targetingKey?: string;
|
|
18
|
+
};
|
|
19
|
+
/** Later contexts win, key by key. Mirrors the OpenFeature merge order. */
|
|
20
|
+
export declare function mergeContexts(...contexts: ReadonlyArray<ContextInput | undefined>): ContextInput;
|
|
21
|
+
/**
|
|
22
|
+
* Validate and canonicalize. Throws `FireweaveError('InvalidContext')` on any
|
|
23
|
+
* limit breach or reserved-key use; never mutates the input.
|
|
24
|
+
*/
|
|
25
|
+
export declare function canonicalizeContext(input: ContextInput | undefined, limits?: ContextLimits, reservedKeys?: readonly string[]): CanonicalContext;
|
|
26
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,gBAAgB,EAAa,MAAM,YAAY,CAAC;AAE9D,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC;AAED,eAAO,MAAM,sBAAsB,EAAE,aAMnC,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,+BAA+B,EAAE,SAAS,MAAM,EAI3D,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAiB/E,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,GAAG,QAAQ,EAAE,aAAa,CAAC,YAAY,GAAG,SAAS,CAAC,GAAG,YAAY,CAOhG;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,GAAG,SAAS,EAC/B,MAAM,GAAE,aAAsC,EAC9C,YAAY,GAAE,SAAS,MAAM,EAAoC,GAChE,gBAAgB,CA6ClB"}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evaluation-context normalization.
|
|
3
|
+
*
|
|
4
|
+
* A browser context is smaller than a server one — there is one user per page,
|
|
5
|
+
* not one per request — but the same two rules apply, and for the same reasons:
|
|
6
|
+
* reserved keys cannot be spoofed by the caller, and oversized attributes are
|
|
7
|
+
* rejected rather than silently truncated by the backend.
|
|
8
|
+
*
|
|
9
|
+
* UTF-8 byte length is measured with `TextEncoder`, never `Buffer` — the same
|
|
10
|
+
* choice ADR-0008 made in the server SDK, here because `Buffer` does not exist
|
|
11
|
+
* in a browser at all.
|
|
12
|
+
*/
|
|
13
|
+
import { FireweaveError } from './errors.js';
|
|
14
|
+
export const DEFAULT_CONTEXT_LIMITS = Object.freeze({
|
|
15
|
+
maxAttributeCount: 100,
|
|
16
|
+
maxKeyBytes: 256,
|
|
17
|
+
maxValueBytes: 8_192,
|
|
18
|
+
maxSerializedBytes: 32_768,
|
|
19
|
+
maxNestingDepth: 8,
|
|
20
|
+
});
|
|
21
|
+
/**
|
|
22
|
+
* Keys the backend owns. A client that could set these could claim another
|
|
23
|
+
* tenant's identity, so they are rejected rather than dropped — silently
|
|
24
|
+
* discarding them would leave the caller believing targeting was applied.
|
|
25
|
+
*/
|
|
26
|
+
export const DEFAULT_RESERVED_ATTRIBUTE_KEYS = Object.freeze([
|
|
27
|
+
'fireweave.orgId',
|
|
28
|
+
'fireweave.projectId',
|
|
29
|
+
'fireweave.tenant',
|
|
30
|
+
]);
|
|
31
|
+
const encoder = new TextEncoder();
|
|
32
|
+
function byteLength(value) {
|
|
33
|
+
return encoder.encode(value).length;
|
|
34
|
+
}
|
|
35
|
+
function depthOf(value, depth = 0) {
|
|
36
|
+
if (value === null || typeof value !== 'object')
|
|
37
|
+
return depth;
|
|
38
|
+
let deepest = depth;
|
|
39
|
+
for (const child of Object.values(value)) {
|
|
40
|
+
deepest = Math.max(deepest, depthOf(child, depth + 1));
|
|
41
|
+
}
|
|
42
|
+
return deepest;
|
|
43
|
+
}
|
|
44
|
+
/** Later contexts win, key by key. Mirrors the OpenFeature merge order. */
|
|
45
|
+
export function mergeContexts(...contexts) {
|
|
46
|
+
const merged = {};
|
|
47
|
+
for (const ctx of contexts) {
|
|
48
|
+
if (ctx === undefined)
|
|
49
|
+
continue;
|
|
50
|
+
Object.assign(merged, ctx);
|
|
51
|
+
}
|
|
52
|
+
return merged;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Validate and canonicalize. Throws `FireweaveError('InvalidContext')` on any
|
|
56
|
+
* limit breach or reserved-key use; never mutates the input.
|
|
57
|
+
*/
|
|
58
|
+
export function canonicalizeContext(input, limits = DEFAULT_CONTEXT_LIMITS, reservedKeys = DEFAULT_RESERVED_ATTRIBUTE_KEYS) {
|
|
59
|
+
const source = input ?? {};
|
|
60
|
+
const attributes = {};
|
|
61
|
+
let groups;
|
|
62
|
+
let groupProperties;
|
|
63
|
+
let targetingKey;
|
|
64
|
+
for (const [key, value] of Object.entries(source)) {
|
|
65
|
+
if (key === 'targetingKey') {
|
|
66
|
+
if (typeof value === 'string' && value.length > 0)
|
|
67
|
+
targetingKey = value;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (reservedKeys.includes(key)) {
|
|
71
|
+
throw new FireweaveError('InvalidContext');
|
|
72
|
+
}
|
|
73
|
+
if (key === 'groups' || key === 'fireweave.groups') {
|
|
74
|
+
groups = value;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (key === 'groupProperties' || key === 'fireweave.groupProperties') {
|
|
78
|
+
groupProperties = value;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (value === undefined)
|
|
82
|
+
continue;
|
|
83
|
+
if (byteLength(key) > limits.maxKeyBytes)
|
|
84
|
+
throw new FireweaveError('InvalidContext');
|
|
85
|
+
const serialized = JSON.stringify(value) ?? 'null';
|
|
86
|
+
if (byteLength(serialized) > limits.maxValueBytes)
|
|
87
|
+
throw new FireweaveError('InvalidContext');
|
|
88
|
+
if (depthOf(value) > limits.maxNestingDepth)
|
|
89
|
+
throw new FireweaveError('InvalidContext');
|
|
90
|
+
attributes[key] = value;
|
|
91
|
+
}
|
|
92
|
+
if (Object.keys(attributes).length > limits.maxAttributeCount) {
|
|
93
|
+
throw new FireweaveError('InvalidContext');
|
|
94
|
+
}
|
|
95
|
+
if (byteLength(JSON.stringify(attributes)) > limits.maxSerializedBytes) {
|
|
96
|
+
throw new FireweaveError('InvalidContext');
|
|
97
|
+
}
|
|
98
|
+
const canonical = { attributes };
|
|
99
|
+
return {
|
|
100
|
+
...canonical,
|
|
101
|
+
...(targetingKey !== undefined ? { targetingKey } : {}),
|
|
102
|
+
...(groups !== undefined ? { groups } : {}),
|
|
103
|
+
...(groupProperties !== undefined ? { groupProperties } : {}),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
|