@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
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
export interface ControlPointDefinition {
|
|
2
|
-
/** Value served in local mode. Ignored in remote mode. */
|
|
3
|
-
readonly local: boolean;
|
|
4
|
-
/** Optional note for humans and agents. Never sent anywhere. */
|
|
5
|
-
readonly description?: string;
|
|
6
|
-
}
|
|
7
|
-
export type ControlPointMap = Readonly<Record<string, ControlPointDefinition>>;
|
|
8
|
-
/**
|
|
9
|
-
* Validate a control-points object and return a frozen copy. Throws a TypeError naming
|
|
10
|
-
* the bad entry: the core's FireweaveError carries fixed messages only, and a
|
|
11
|
-
* typo here should say which key it was.
|
|
12
|
-
*/
|
|
13
|
-
export declare function normalizeControlPoints(controlPoints: unknown): ControlPointMap;
|
|
14
|
-
/**
|
|
15
|
-
* Declare the app's control points. Returns its argument unchanged, typed, and
|
|
16
|
-
* checks it at import time so a typo fails where it was made.
|
|
17
|
-
*
|
|
18
|
-
* export const controlPoints = defineControlPoints({
|
|
19
|
-
* 'new-checkout': { local: true },
|
|
20
|
-
* });
|
|
21
|
-
*/
|
|
22
|
-
export declare function defineControlPoints<const T extends Record<string, ControlPointDefinition>>(controlPoints: T): T;
|
|
23
|
-
/** The core local adapter's seed map. */
|
|
24
|
-
export declare function toLocalControlPoints(controlPoints: ControlPointMap): Record<string, boolean>;
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.normalizeControlPoints = normalizeControlPoints;
|
|
4
|
-
exports.defineControlPoints = defineControlPoints;
|
|
5
|
-
exports.toLocalControlPoints = toLocalControlPoints;
|
|
6
|
-
/**
|
|
7
|
-
* The control-points object: every control point the app reads, with the value
|
|
8
|
-
* served in local mode. It lives in its own file
|
|
9
|
-
* (src/fireweave/control-points.ts by default) and is passed as
|
|
10
|
-
* start({ controlPoints }) — the same shape as the server SDK.
|
|
11
|
-
*
|
|
12
|
-
* It holds local values only. In remote mode fw-server and the rollout decide,
|
|
13
|
-
* and call sites keep `false` as their default (RAMP-1), so this file can
|
|
14
|
-
* never switch a feature on for real visitors.
|
|
15
|
-
*/
|
|
16
|
-
const index_js_1 = require("../index.js");
|
|
17
|
-
/**
|
|
18
|
-
* Validate a control-points object and return a frozen copy. Throws a TypeError naming
|
|
19
|
-
* the bad entry: the core's FireweaveError carries fixed messages only, and a
|
|
20
|
-
* typo here should say which key it was.
|
|
21
|
-
*/
|
|
22
|
-
function normalizeControlPoints(controlPoints) {
|
|
23
|
-
if (controlPoints === undefined || controlPoints === null)
|
|
24
|
-
return Object.freeze({});
|
|
25
|
-
if (typeof controlPoints !== 'object' || Array.isArray(controlPoints)) {
|
|
26
|
-
throw new TypeError('[fireweave] start({ controlPoints }) must be an object of { key: { local: boolean } }.');
|
|
27
|
-
}
|
|
28
|
-
const out = {};
|
|
29
|
-
for (const [key, entry] of Object.entries(controlPoints)) {
|
|
30
|
-
if (!(0, index_js_1.validateControlPointKey)(key).ok)
|
|
31
|
-
throw new TypeError(`[fireweave] controlPoints: '${key}' is not a valid control point key.`);
|
|
32
|
-
if (typeof entry !== 'object' || entry === null || typeof entry.local !== 'boolean') {
|
|
33
|
-
throw new TypeError(`[fireweave] controlPoints['${key}'] must be { local: true } or { local: false }.`);
|
|
34
|
-
}
|
|
35
|
-
const { local, description } = entry;
|
|
36
|
-
if (description !== undefined && typeof description !== 'string') {
|
|
37
|
-
throw new TypeError(`[fireweave] controlPoints['${key}'].description must be a string.`);
|
|
38
|
-
}
|
|
39
|
-
out[key] = Object.freeze(description === undefined ? { local } : { local, description });
|
|
40
|
-
}
|
|
41
|
-
return Object.freeze(out);
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Declare the app's control points. Returns its argument unchanged, typed, and
|
|
45
|
-
* checks it at import time so a typo fails where it was made.
|
|
46
|
-
*
|
|
47
|
-
* export const controlPoints = defineControlPoints({
|
|
48
|
-
* 'new-checkout': { local: true },
|
|
49
|
-
* });
|
|
50
|
-
*/
|
|
51
|
-
function defineControlPoints(controlPoints) {
|
|
52
|
-
normalizeControlPoints(controlPoints);
|
|
53
|
-
return controlPoints;
|
|
54
|
-
}
|
|
55
|
-
/** The core local adapter's seed map. */
|
|
56
|
-
function toLocalControlPoints(controlPoints) {
|
|
57
|
-
const out = {};
|
|
58
|
-
for (const [key, entry] of Object.entries(controlPoints))
|
|
59
|
-
out[key] = entry.local;
|
|
60
|
-
return out;
|
|
61
|
-
}
|
package/dist/start/fw.d.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `fw`: the page-wide accessor beside start(). Safe to import anywhere, in any
|
|
3
|
-
* order, and to destructure at module scope.
|
|
4
|
-
*
|
|
5
|
-
* Reads are synchronous (a browser renders from a prefetched cache) and never
|
|
6
|
-
* throw. Before start settles, or if it failed, they return the caller's
|
|
7
|
-
* default, and the *Details forms an ERROR decision saying why.
|
|
8
|
-
*/
|
|
9
|
-
import { type FireweaveWebClient, type JsonValue, type RegisterTargetResult, type TargetKind, type WebControlPointsApi } from '../index.js';
|
|
10
|
-
import { type Persistence } from './identity.js';
|
|
11
|
-
import { type FireweaveWebStatus, type StartState } from './state.js';
|
|
12
|
-
/** The same nine read methods as the core client's controlPoints. */
|
|
13
|
-
export type ControlPoints = Pick<WebControlPointsApi, 'evaluate' | 'getBooleanValue' | 'getStringValue' | 'getNumberValue' | 'getObjectValue' | 'getBooleanDetails' | 'getStringDetails' | 'getNumberDetails' | 'getObjectDetails'>;
|
|
14
|
-
export interface IdentifyOptions {
|
|
15
|
-
/** Defaults to 'user'. */
|
|
16
|
-
readonly kind?: TargetKind;
|
|
17
|
-
}
|
|
18
|
-
export interface FireweaveWebStart {
|
|
19
|
-
/** Read control points: `fw.controlPoints.getBooleanValue('key', false)`. Synchronous. */
|
|
20
|
-
readonly controlPoints: ControlPoints;
|
|
21
|
-
/** Sign-in and session restore: register the user, then switch decisions to their key. Never throws. */
|
|
22
|
-
identify(targetingKey: string, properties?: Record<string, JsonValue>, options?: IdentifyOptions): Promise<RegisterTargetResult>;
|
|
23
|
-
/** Sign-out: back to this browser's device id. Never throws. */
|
|
24
|
-
reset(): Promise<void>;
|
|
25
|
-
/** The anonymous key, for joining with analytics. Undefined before start. */
|
|
26
|
-
deviceId(): string | undefined;
|
|
27
|
-
/** Change storage at runtime, for consent: 'memory' deletes what was stored. */
|
|
28
|
-
setPersistence(mode: Persistence): void;
|
|
29
|
-
/** Withdraw consent and start over: clears storage and mints a fresh in-memory device id. */
|
|
30
|
-
forget(): Promise<void>;
|
|
31
|
-
/** Settles when the current start attempt does. Never rejects; already resolved when nothing is starting. */
|
|
32
|
-
readonly ready: Promise<void>;
|
|
33
|
-
/** What start() decided and how it went: mode, channel, host, key source, problem. Never the key. */
|
|
34
|
-
status(): FireweaveWebStatus;
|
|
35
|
-
/** Called on every state change, including the re-prefetch after identify or reset. Returns unsubscribe. */
|
|
36
|
-
subscribe(listener: (state: StartState) => void): () => void;
|
|
37
|
-
/** The core client, for anything the facade does not cover. Undefined until start settles. */
|
|
38
|
-
client(): FireweaveWebClient | undefined;
|
|
39
|
-
/** Flush and close. A later start() begins fresh. */
|
|
40
|
-
shutdown(): Promise<void>;
|
|
41
|
-
}
|
|
42
|
-
export declare const fw: FireweaveWebStart;
|
package/dist/start/fw.js
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.fw = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* `fw`: the page-wide accessor beside start(). Safe to import anywhere, in any
|
|
6
|
-
* order, and to destructure at module scope.
|
|
7
|
-
*
|
|
8
|
-
* Reads are synchronous (a browser renders from a prefetched cache) and never
|
|
9
|
-
* throw. Before start settles, or if it failed, they return the caller's
|
|
10
|
-
* default, and the *Details forms an ERROR decision saying why.
|
|
11
|
-
*/
|
|
12
|
-
const index_js_1 = require("../index.js");
|
|
13
|
-
const identity_js_1 = require("./identity.js");
|
|
14
|
-
const names_js_1 = require("./names.js");
|
|
15
|
-
const state_js_1 = require("./state.js");
|
|
16
|
-
function errorDecision(controlPointKey, defaultValue, err) {
|
|
17
|
-
return {
|
|
18
|
-
controlPointKey,
|
|
19
|
-
value: defaultValue,
|
|
20
|
-
reason: 'ERROR',
|
|
21
|
-
errorKind: err.kind,
|
|
22
|
-
errorCode: err.openFeatureErrorCode,
|
|
23
|
-
errorMessage: err.message,
|
|
24
|
-
metadata: { 'fireweave.errorKind': err.kind },
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
function notes(controlPointKey, context) {
|
|
28
|
-
const s = (0, state_js_1.slot)();
|
|
29
|
-
if (s.config?.mode === 'local' && !Object.prototype.hasOwnProperty.call(s.controlPoints, controlPointKey)) {
|
|
30
|
-
(0, state_js_1.warnOnce)(s, `[fireweave:local] '${controlPointKey}' is not in your control points (${names_js_1.CONTROL_POINTS_FILE}), so it gets its default. Add it there to try it locally.`);
|
|
31
|
-
}
|
|
32
|
-
const perCall = context?.targetingKey;
|
|
33
|
-
if (typeof perCall === 'string' && perCall !== s.currentKey) {
|
|
34
|
-
(0, state_js_1.warnOnce)(s, '[fireweave] A per-call targetingKey does not change the decision in the browser: decisions follow fw.identify(). Drop the context argument.');
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
function read(controlPointKey, context, fallback, run) {
|
|
38
|
-
const s = (0, state_js_1.slot)();
|
|
39
|
-
if (s.client === undefined) {
|
|
40
|
-
if (s.state === 'NOT_STARTED') {
|
|
41
|
-
(0, state_js_1.warnOnce)(s, "[fireweave] A control point was read before start(). Import './fireweave/start' first in your entry module; reads serve their defaults until then.");
|
|
42
|
-
}
|
|
43
|
-
return fallback((0, state_js_1.notStartedError)(s.state));
|
|
44
|
-
}
|
|
45
|
-
notes(controlPointKey, context);
|
|
46
|
-
return run(s.client.controlPoints);
|
|
47
|
-
}
|
|
48
|
-
const controlPoints = {
|
|
49
|
-
evaluate: (controlPointKey, expectedType, defaultValue, context, options) => read(controlPointKey, context, (e) => errorDecision(controlPointKey, defaultValue, e), (c) => c.evaluate(controlPointKey, expectedType, defaultValue, context, options)),
|
|
50
|
-
getBooleanValue: (controlPointKey, defaultValue, context) => read(controlPointKey, context, () => defaultValue, (c) => c.getBooleanValue(controlPointKey, defaultValue, context)),
|
|
51
|
-
getStringValue: (controlPointKey, defaultValue, context) => read(controlPointKey, context, () => defaultValue, (c) => c.getStringValue(controlPointKey, defaultValue, context)),
|
|
52
|
-
getNumberValue: (controlPointKey, defaultValue, context) => read(controlPointKey, context, () => defaultValue, (c) => c.getNumberValue(controlPointKey, defaultValue, context)),
|
|
53
|
-
getObjectValue: (controlPointKey, defaultValue, context) => read(controlPointKey, context, () => defaultValue, (c) => c.getObjectValue(controlPointKey, defaultValue, context)),
|
|
54
|
-
getBooleanDetails: (controlPointKey, defaultValue, context) => read(controlPointKey, context, (e) => errorDecision(controlPointKey, defaultValue, e), (c) => c.getBooleanDetails(controlPointKey, defaultValue, context)),
|
|
55
|
-
getStringDetails: (controlPointKey, defaultValue, context) => read(controlPointKey, context, (e) => errorDecision(controlPointKey, defaultValue, e), (c) => c.getStringDetails(controlPointKey, defaultValue, context)),
|
|
56
|
-
getNumberDetails: (controlPointKey, defaultValue, context) => read(controlPointKey, context, (e) => errorDecision(controlPointKey, defaultValue, e), (c) => c.getNumberDetails(controlPointKey, defaultValue, context)),
|
|
57
|
-
getObjectDetails: (controlPointKey, defaultValue, context) => read(controlPointKey, context, (e) => errorDecision(controlPointKey, defaultValue, e), (c) => c.getObjectDetails(controlPointKey, defaultValue, context)),
|
|
58
|
-
};
|
|
59
|
-
/** Run identity changes one at a time, after start settles. */
|
|
60
|
-
function serialized(task) {
|
|
61
|
-
const s = (0, state_js_1.slot)();
|
|
62
|
-
const run = s.chain.then(() => s.ready).then(task);
|
|
63
|
-
s.chain = run.catch(() => undefined);
|
|
64
|
-
return run;
|
|
65
|
-
}
|
|
66
|
-
/** Re-prefetch under `key` when it differs from the current one. */
|
|
67
|
-
async function switchTo(key) {
|
|
68
|
-
const s = (0, state_js_1.slot)();
|
|
69
|
-
if (s.client === undefined || key === s.currentKey)
|
|
70
|
-
return;
|
|
71
|
-
s.currentKey = key;
|
|
72
|
-
try {
|
|
73
|
-
await s.client.runtime.setContext({ targetingKey: key });
|
|
74
|
-
}
|
|
75
|
-
catch {
|
|
76
|
-
// the runtime reports a failed prefetch through its state; never throw from here
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
exports.fw = Object.freeze({
|
|
80
|
-
controlPoints: Object.freeze(controlPoints),
|
|
81
|
-
identify(targetingKey, properties, options = {}) {
|
|
82
|
-
return serialized(async () => {
|
|
83
|
-
const s = (0, state_js_1.slot)();
|
|
84
|
-
if (s.client === undefined) {
|
|
85
|
-
(0, state_js_1.warnOnce)(s, '[fireweave] fw.identify() ran before FireWeave started; the user was not registered.');
|
|
86
|
-
return { ok: false, error: (0, state_js_1.notStartedError)(s.state) };
|
|
87
|
-
}
|
|
88
|
-
if (typeof targetingKey !== 'string' || targetingKey.trim() === '') {
|
|
89
|
-
return { ok: false, error: new index_js_1.FireweaveError('InvalidContext') };
|
|
90
|
-
}
|
|
91
|
-
const result = await s.client.registerTarget(targetingKey, {
|
|
92
|
-
kind: options.kind ?? 'user',
|
|
93
|
-
...(properties !== undefined ? { properties } : {}),
|
|
94
|
-
});
|
|
95
|
-
await switchTo(targetingKey);
|
|
96
|
-
(0, state_js_1.rememberUser)(s, targetingKey);
|
|
97
|
-
return result;
|
|
98
|
-
}).catch(() => ({ ok: false, error: new index_js_1.FireweaveError('Internal') }));
|
|
99
|
-
},
|
|
100
|
-
reset() {
|
|
101
|
-
return serialized(async () => {
|
|
102
|
-
const s = (0, state_js_1.slot)();
|
|
103
|
-
(0, state_js_1.rememberUser)(s, undefined);
|
|
104
|
-
if (s.identity !== undefined)
|
|
105
|
-
await switchTo(s.identity.deviceId);
|
|
106
|
-
}).catch(() => undefined);
|
|
107
|
-
},
|
|
108
|
-
deviceId: () => (0, state_js_1.slot)().identity?.deviceId,
|
|
109
|
-
setPersistence(mode) {
|
|
110
|
-
(0, state_js_1.setPersistenceFor)(mode);
|
|
111
|
-
},
|
|
112
|
-
forget() {
|
|
113
|
-
return serialized(async () => {
|
|
114
|
-
const s = (0, state_js_1.slot)();
|
|
115
|
-
(0, state_js_1.setPersistenceFor)('memory');
|
|
116
|
-
(0, identity_js_1.clearStoredIdentity)();
|
|
117
|
-
if (s.identity === undefined)
|
|
118
|
-
return;
|
|
119
|
-
s.identity = { deviceId: (0, identity_js_1.mintDeviceId)(), durable: false };
|
|
120
|
-
s.appDeviceId = false;
|
|
121
|
-
await switchTo(s.identity.deviceId);
|
|
122
|
-
}).catch(() => undefined);
|
|
123
|
-
},
|
|
124
|
-
get ready() {
|
|
125
|
-
return (0, state_js_1.slot)().ready;
|
|
126
|
-
},
|
|
127
|
-
status: () => (0, state_js_1.currentStatus)(),
|
|
128
|
-
subscribe(listener) {
|
|
129
|
-
const s = (0, state_js_1.slot)();
|
|
130
|
-
s.listeners.add(listener);
|
|
131
|
-
return () => {
|
|
132
|
-
s.listeners.delete(listener);
|
|
133
|
-
};
|
|
134
|
-
},
|
|
135
|
-
client: () => (0, state_js_1.slot)().client,
|
|
136
|
-
shutdown: () => (0, state_js_1.shutdownSlot)(),
|
|
137
|
-
});
|
package/dist/start/identity.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export type Persistence = 'localStorage' | 'memory';
|
|
2
|
-
export interface Identity {
|
|
3
|
-
/** The anonymous key. */
|
|
4
|
-
deviceId: string;
|
|
5
|
-
/** True when the id outlives this page (stored, or supplied by the app). Only durable ids are registered. */
|
|
6
|
-
durable: boolean;
|
|
7
|
-
/** The signed-in key restored from storage, if any. */
|
|
8
|
-
user?: string;
|
|
9
|
-
}
|
|
10
|
-
export declare function readItem(name: string): string | undefined;
|
|
11
|
-
export declare function writeItem(name: string, value: string): boolean;
|
|
12
|
-
export declare function removeItem(name: string): void;
|
|
13
|
-
export declare function mintDeviceId(): string;
|
|
14
|
-
/** Load (or mint) the identity a start boots under. Writes nothing in memory mode. */
|
|
15
|
-
export declare function loadIdentity(persistence: Persistence, deviceIdOption: string | undefined): Identity;
|
|
16
|
-
/** Write the current ids (consent given). Returns whether the device id is now durable. */
|
|
17
|
-
export declare function persistIdentity(identity: Identity, user: string | undefined, appSuppliedDeviceId: boolean): boolean;
|
|
18
|
-
/** Remove everything the start profile stores (consent withdrawn). */
|
|
19
|
-
export declare function clearStoredIdentity(): void;
|
package/dist/start/identity.js
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.readItem = readItem;
|
|
4
|
-
exports.writeItem = writeItem;
|
|
5
|
-
exports.removeItem = removeItem;
|
|
6
|
-
exports.mintDeviceId = mintDeviceId;
|
|
7
|
-
exports.loadIdentity = loadIdentity;
|
|
8
|
-
exports.persistIdentity = persistIdentity;
|
|
9
|
-
exports.clearStoredIdentity = clearStoredIdentity;
|
|
10
|
-
/**
|
|
11
|
-
* Browser identity for the start profile: the anonymous device id, the signed-in
|
|
12
|
-
* key, and how (or whether) they persist.
|
|
13
|
-
*
|
|
14
|
-
* The device id key and its dev_ prefix are the scaffolded harness's, so an app
|
|
15
|
-
* that migrates keeps every returning visitor in the same ramp bucket. Every
|
|
16
|
-
* storage access is guarded: storage that throws (privacy modes, sandboxed
|
|
17
|
-
* iframes) means one id per page load, never an error.
|
|
18
|
-
*/
|
|
19
|
-
const names_js_1 = require("./names.js");
|
|
20
|
-
const storage = () => {
|
|
21
|
-
try {
|
|
22
|
-
return globalThis.localStorage ?? undefined;
|
|
23
|
-
}
|
|
24
|
-
catch {
|
|
25
|
-
return undefined;
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
function readItem(name) {
|
|
29
|
-
try {
|
|
30
|
-
const value = storage()?.getItem(name);
|
|
31
|
-
return typeof value === 'string' && value.trim() !== '' ? value : undefined;
|
|
32
|
-
}
|
|
33
|
-
catch {
|
|
34
|
-
return undefined;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
function writeItem(name, value) {
|
|
38
|
-
try {
|
|
39
|
-
const s = storage();
|
|
40
|
-
if (s === undefined)
|
|
41
|
-
return false;
|
|
42
|
-
s.setItem(name, value);
|
|
43
|
-
return true;
|
|
44
|
-
}
|
|
45
|
-
catch {
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
function removeItem(name) {
|
|
50
|
-
try {
|
|
51
|
-
storage()?.removeItem(name);
|
|
52
|
-
}
|
|
53
|
-
catch {
|
|
54
|
-
// nothing to clean up if storage is unavailable
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
function mintDeviceId() {
|
|
58
|
-
try {
|
|
59
|
-
return `dev_${globalThis.crypto.randomUUID()}`;
|
|
60
|
-
}
|
|
61
|
-
catch {
|
|
62
|
-
// randomUUID needs a secure context; the fallback is per page and never stored as stronger than it is.
|
|
63
|
-
return `dev_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 12)}`;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
/** Load (or mint) the identity a start boots under. Writes nothing in memory mode. */
|
|
67
|
-
function loadIdentity(persistence, deviceIdOption) {
|
|
68
|
-
const user = persistence === 'localStorage' ? readItem(names_js_1.STORAGE_KEYS.identity) : undefined;
|
|
69
|
-
const withUser = (identity) => (user !== undefined ? { ...identity, user } : identity);
|
|
70
|
-
if (deviceIdOption !== undefined)
|
|
71
|
-
return withUser({ deviceId: deviceIdOption, durable: true });
|
|
72
|
-
if (persistence === 'memory')
|
|
73
|
-
return { deviceId: mintDeviceId(), durable: false };
|
|
74
|
-
const stored = readItem(names_js_1.STORAGE_KEYS.deviceId);
|
|
75
|
-
if (stored !== undefined)
|
|
76
|
-
return withUser({ deviceId: stored, durable: true });
|
|
77
|
-
const deviceId = mintDeviceId();
|
|
78
|
-
return withUser({ deviceId, durable: writeItem(names_js_1.STORAGE_KEYS.deviceId, deviceId) });
|
|
79
|
-
}
|
|
80
|
-
/** Write the current ids (consent given). Returns whether the device id is now durable. */
|
|
81
|
-
function persistIdentity(identity, user, appSuppliedDeviceId) {
|
|
82
|
-
if (user !== undefined)
|
|
83
|
-
writeItem(names_js_1.STORAGE_KEYS.identity, user);
|
|
84
|
-
if (appSuppliedDeviceId)
|
|
85
|
-
return true;
|
|
86
|
-
return writeItem(names_js_1.STORAGE_KEYS.deviceId, identity.deviceId);
|
|
87
|
-
}
|
|
88
|
-
/** Remove everything the start profile stores (consent withdrawn). */
|
|
89
|
-
function clearStoredIdentity() {
|
|
90
|
-
removeItem(names_js_1.STORAGE_KEYS.deviceId);
|
|
91
|
-
removeItem(names_js_1.STORAGE_KEYS.identity);
|
|
92
|
-
removeItem(names_js_1.STORAGE_KEYS.deviceRegistered);
|
|
93
|
-
}
|
package/dist/start/index.d.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fireweaveai/web-sdk/start: one start() call for a browser app.
|
|
3
|
-
*
|
|
4
|
-
* ```ts
|
|
5
|
-
* // src/fireweave/control-points.ts
|
|
6
|
-
* import { defineControlPoints } from '@fireweaveai/web-sdk/start';
|
|
7
|
-
* export const controlPoints = defineControlPoints({ 'new-checkout': { local: true } });
|
|
8
|
-
*
|
|
9
|
-
* // src/fireweave/start.ts — the first import of your entry module
|
|
10
|
-
* import { start } from '@fireweaveai/web-sdk/start';
|
|
11
|
-
* import { controlPoints } from './control-points';
|
|
12
|
-
* export const ready = start({ controlPoints });
|
|
13
|
-
*
|
|
14
|
-
* // anywhere
|
|
15
|
-
* import { fw } from '@fireweaveai/web-sdk/start';
|
|
16
|
-
* if (fw.controlPoints.getBooleanValue('new-checkout', false)) { ... }
|
|
17
|
-
* ```
|
|
18
|
-
*
|
|
19
|
-
* The key, endpoint and environment come from the fireweave() Vite plugin
|
|
20
|
-
* (`@fireweaveai/web-sdk/vite`) or fireweaveDefine() (`/define`) at build
|
|
21
|
-
* time, or from start() options. This module reads no environment.
|
|
22
|
-
*
|
|
23
|
-
* A layer over the unchanged core: it imports only the public barrel
|
|
24
|
-
* (docs/adr/0012-start-profile.md).
|
|
25
|
-
*/
|
|
26
|
-
export { start, resetForTests } from './state.js';
|
|
27
|
-
export type { StartOptions, StartState, StartProblem, FireweaveWebStatus } from './state.js';
|
|
28
|
-
export { fw } from './fw.js';
|
|
29
|
-
export type { FireweaveWebStart, ControlPoints, IdentifyOptions } from './fw.js';
|
|
30
|
-
export { defineControlPoints } from './control-points.js';
|
|
31
|
-
export type { ControlPointDefinition, ControlPointMap } from './control-points.js';
|
|
32
|
-
export type { Persistence } from './identity.js';
|
|
33
|
-
export type { StartMode, SdkChannel } from './policy.js';
|
|
34
|
-
export { SDK_VERSION, SDK_CHANNEL } from './build-info.js';
|
package/dist/start/index.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SDK_CHANNEL = exports.SDK_VERSION = exports.defineControlPoints = exports.fw = exports.resetForTests = exports.start = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* @fireweaveai/web-sdk/start: one start() call for a browser app.
|
|
6
|
-
*
|
|
7
|
-
* ```ts
|
|
8
|
-
* // src/fireweave/control-points.ts
|
|
9
|
-
* import { defineControlPoints } from '@fireweaveai/web-sdk/start';
|
|
10
|
-
* export const controlPoints = defineControlPoints({ 'new-checkout': { local: true } });
|
|
11
|
-
*
|
|
12
|
-
* // src/fireweave/start.ts — the first import of your entry module
|
|
13
|
-
* import { start } from '@fireweaveai/web-sdk/start';
|
|
14
|
-
* import { controlPoints } from './control-points';
|
|
15
|
-
* export const ready = start({ controlPoints });
|
|
16
|
-
*
|
|
17
|
-
* // anywhere
|
|
18
|
-
* import { fw } from '@fireweaveai/web-sdk/start';
|
|
19
|
-
* if (fw.controlPoints.getBooleanValue('new-checkout', false)) { ... }
|
|
20
|
-
* ```
|
|
21
|
-
*
|
|
22
|
-
* The key, endpoint and environment come from the fireweave() Vite plugin
|
|
23
|
-
* (`@fireweaveai/web-sdk/vite`) or fireweaveDefine() (`/define`) at build
|
|
24
|
-
* time, or from start() options. This module reads no environment.
|
|
25
|
-
*
|
|
26
|
-
* A layer over the unchanged core: it imports only the public barrel
|
|
27
|
-
* (docs/adr/0012-start-profile.md).
|
|
28
|
-
*/
|
|
29
|
-
var state_js_1 = require("./state.js");
|
|
30
|
-
Object.defineProperty(exports, "start", { enumerable: true, get: function () { return state_js_1.start; } });
|
|
31
|
-
Object.defineProperty(exports, "resetForTests", { enumerable: true, get: function () { return state_js_1.resetForTests; } });
|
|
32
|
-
var fw_js_1 = require("./fw.js");
|
|
33
|
-
Object.defineProperty(exports, "fw", { enumerable: true, get: function () { return fw_js_1.fw; } });
|
|
34
|
-
var control_points_js_1 = require("./control-points.js");
|
|
35
|
-
Object.defineProperty(exports, "defineControlPoints", { enumerable: true, get: function () { return control_points_js_1.defineControlPoints; } });
|
|
36
|
-
var build_info_js_1 = require("./build-info.js");
|
|
37
|
-
Object.defineProperty(exports, "SDK_VERSION", { enumerable: true, get: function () { return build_info_js_1.SDK_VERSION; } });
|
|
38
|
-
Object.defineProperty(exports, "SDK_CHANNEL", { enumerable: true, get: function () { return build_info_js_1.SDK_CHANNEL; } });
|
package/dist/start/names.d.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Every name the web start profile and its build helpers use, in one place, so
|
|
3
|
-
* the README, the initialise skill and the error messages cannot drift apart.
|
|
4
|
-
*
|
|
5
|
-
* Imported by browser code and by the Node build helpers (node/), so it holds
|
|
6
|
-
* constants only.
|
|
7
|
-
*/
|
|
8
|
-
/** Build-time variables the Vite plugin and the define helper read. The browser reads none. */
|
|
9
|
-
export declare const BUILD_ENV: Readonly<{
|
|
10
|
-
key: "FIREWEAVE_BROWSER_KEY";
|
|
11
|
-
url: "FIREWEAVE_URL";
|
|
12
|
-
environment: "FIREWEAVE_ENV";
|
|
13
|
-
}>;
|
|
14
|
-
/** Fallback environment name after FIREWEAVE_ENV, at build time. */
|
|
15
|
-
export declare const ENVIRONMENT_FALLBACK = "APP_ENV";
|
|
16
|
-
/** Server secrets the Vite plugin looks for in output chunks. Never injected, never printed. */
|
|
17
|
-
export declare const SERVER_KEY_NAMES: readonly string[];
|
|
18
|
-
/** Environment names that mean "local development" when no key is set. Case-insensitive. */
|
|
19
|
-
export declare const DEV_ENVIRONMENTS: ReadonlySet<string>;
|
|
20
|
-
/** fw-server host for each release channel of this package. */
|
|
21
|
-
export declare const CHANNEL_URLS: Readonly<{
|
|
22
|
-
production: "https://app-server.fireweave.ai";
|
|
23
|
-
staging: "https://staging-app-server.fireweave.ai";
|
|
24
|
-
}>;
|
|
25
|
-
/** Hosts always allowed beside a custom endpoint, so local stacks keep working. */
|
|
26
|
-
export declare const LOOPBACK_HOSTS: readonly string[];
|
|
27
|
-
/** The only key family a browser may hold. */
|
|
28
|
-
export declare const BROWSER_KEY_PREFIX = "fw_public_";
|
|
29
|
-
/** localStorage keys. The device id key and its dev_ prefix match the scaffolded harness, so returning visitors keep their bucket. */
|
|
30
|
-
export declare const STORAGE_KEYS: Readonly<{
|
|
31
|
-
deviceId: "fireweave.device-id";
|
|
32
|
-
identity: "fireweave.identity";
|
|
33
|
-
deviceRegistered: "fireweave.device-registered";
|
|
34
|
-
}>;
|
|
35
|
-
/** Where the control-points object lives by convention; named in warnings. */
|
|
36
|
-
export declare const CONTROL_POINTS_FILE = "src/fireweave/control-points.ts";
|
|
37
|
-
/** The identifier the build helpers define and the browser reads behind a typeof guard. */
|
|
38
|
-
export declare const INJECTED_CONFIG_NAME = "__FIREWEAVE_WEB_CONFIG__";
|
package/dist/start/names.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Every name the web start profile and its build helpers use, in one place, so
|
|
4
|
-
* the README, the initialise skill and the error messages cannot drift apart.
|
|
5
|
-
*
|
|
6
|
-
* Imported by browser code and by the Node build helpers (node/), so it holds
|
|
7
|
-
* constants only.
|
|
8
|
-
*/
|
|
9
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.INJECTED_CONFIG_NAME = exports.CONTROL_POINTS_FILE = exports.STORAGE_KEYS = exports.BROWSER_KEY_PREFIX = exports.LOOPBACK_HOSTS = exports.CHANNEL_URLS = exports.DEV_ENVIRONMENTS = exports.SERVER_KEY_NAMES = exports.ENVIRONMENT_FALLBACK = exports.BUILD_ENV = void 0;
|
|
11
|
-
/** Build-time variables the Vite plugin and the define helper read. The browser reads none. */
|
|
12
|
-
exports.BUILD_ENV = Object.freeze({
|
|
13
|
-
key: 'FIREWEAVE_BROWSER_KEY',
|
|
14
|
-
url: 'FIREWEAVE_URL',
|
|
15
|
-
environment: 'FIREWEAVE_ENV',
|
|
16
|
-
});
|
|
17
|
-
/** Fallback environment name after FIREWEAVE_ENV, at build time. */
|
|
18
|
-
exports.ENVIRONMENT_FALLBACK = 'APP_ENV';
|
|
19
|
-
/** Server secrets the Vite plugin looks for in output chunks. Never injected, never printed. */
|
|
20
|
-
exports.SERVER_KEY_NAMES = Object.freeze(['FIREWEAVE_KEY', 'FW_PROJECT_API_KEY']);
|
|
21
|
-
/** Environment names that mean "local development" when no key is set. Case-insensitive. */
|
|
22
|
-
exports.DEV_ENVIRONMENTS = new Set(['development', 'dev', 'local', 'test']);
|
|
23
|
-
/** fw-server host for each release channel of this package. */
|
|
24
|
-
exports.CHANNEL_URLS = Object.freeze({
|
|
25
|
-
production: 'https://app-server.fireweave.ai',
|
|
26
|
-
staging: 'https://staging-app-server.fireweave.ai',
|
|
27
|
-
});
|
|
28
|
-
/** Hosts always allowed beside a custom endpoint, so local stacks keep working. */
|
|
29
|
-
exports.LOOPBACK_HOSTS = Object.freeze(['localhost', '127.0.0.1', '::1']);
|
|
30
|
-
/** The only key family a browser may hold. */
|
|
31
|
-
exports.BROWSER_KEY_PREFIX = 'fw_public_';
|
|
32
|
-
/** localStorage keys. The device id key and its dev_ prefix match the scaffolded harness, so returning visitors keep their bucket. */
|
|
33
|
-
exports.STORAGE_KEYS = Object.freeze({
|
|
34
|
-
deviceId: 'fireweave.device-id',
|
|
35
|
-
identity: 'fireweave.identity',
|
|
36
|
-
deviceRegistered: 'fireweave.device-registered',
|
|
37
|
-
});
|
|
38
|
-
/** Where the control-points object lives by convention; named in warnings. */
|
|
39
|
-
exports.CONTROL_POINTS_FILE = 'src/fireweave/control-points.ts';
|
|
40
|
-
/** The identifier the build helpers define and the browser reads behind a typeof guard. */
|
|
41
|
-
exports.INJECTED_CONFIG_NAME = '__FIREWEAVE_WEB_CONFIG__';
|
package/dist/start/policy.d.ts
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
export type StartMode = 'remote' | 'local';
|
|
2
|
-
export type SdkChannel = 'staging' | 'production';
|
|
3
|
-
/** A value and where it came from ('start({ key })', 'FIREWEAVE_BROWSER_KEY', ...). */
|
|
4
|
-
export interface Sourced {
|
|
5
|
-
readonly value: string;
|
|
6
|
-
readonly source: string;
|
|
7
|
-
}
|
|
8
|
-
export type PolicyReason = 'invalid-mode' | 'missing-key' | 'server-key' | 'wrong-key-family' | 'insecure-url';
|
|
9
|
-
export interface PolicyInput {
|
|
10
|
-
readonly mode?: unknown;
|
|
11
|
-
readonly key?: Sourced | undefined;
|
|
12
|
-
readonly url?: Sourced | undefined;
|
|
13
|
-
readonly environment?: Sourced | undefined;
|
|
14
|
-
readonly channel: SdkChannel;
|
|
15
|
-
/** The variable or option a fix should name, e.g. FIREWEAVE_BROWSER_KEY. */
|
|
16
|
-
readonly keyVariable: string;
|
|
17
|
-
/** Where an environment name was looked for, for the missing-key message. */
|
|
18
|
-
readonly environmentChecked: string;
|
|
19
|
-
}
|
|
20
|
-
export interface PolicyConfig {
|
|
21
|
-
readonly mode: StartMode;
|
|
22
|
-
/** Why this mode: the mode option, a present key, or the environment name. */
|
|
23
|
-
readonly modeSource: 'option' | 'key' | 'environment';
|
|
24
|
-
/** Remote only. A value starting with '/' is a same-origin proxy path. */
|
|
25
|
-
readonly url?: string;
|
|
26
|
-
readonly urlSource?: string;
|
|
27
|
-
/** Remote only, and absent for the channel default (the core's own list covers it). */
|
|
28
|
-
readonly allowedHosts?: readonly string[];
|
|
29
|
-
/** Remote only. Never logged. */
|
|
30
|
-
readonly key?: string;
|
|
31
|
-
readonly keySource: string;
|
|
32
|
-
readonly environment?: string;
|
|
33
|
-
readonly environmentSource?: string;
|
|
34
|
-
}
|
|
35
|
-
export type PolicyResult = {
|
|
36
|
-
readonly ok: true;
|
|
37
|
-
readonly config: PolicyConfig;
|
|
38
|
-
readonly warnings: readonly string[];
|
|
39
|
-
} | {
|
|
40
|
-
readonly ok: false;
|
|
41
|
-
readonly reason: PolicyReason;
|
|
42
|
-
readonly variable: string;
|
|
43
|
-
readonly message: string;
|
|
44
|
-
};
|
|
45
|
-
/** A trimmed, non-empty string with its source, or undefined. Non-strings count as unset. */
|
|
46
|
-
export declare function sourced(value: unknown, source: string): Sourced | undefined;
|
|
47
|
-
/** The first candidate that is set. */
|
|
48
|
-
export declare function firstOf(...candidates: ReadonlyArray<Sourced | undefined>): Sourced | undefined;
|
|
49
|
-
/**
|
|
50
|
-
* Resolve mode, key and endpoint.
|
|
51
|
-
*
|
|
52
|
-
* An explicit mode wins. Otherwise a key means remote; no key and a
|
|
53
|
-
* development environment name means local; anything else fails closed, so a
|
|
54
|
-
* missing key never turns into silent local evaluation for real visitors.
|
|
55
|
-
*/
|
|
56
|
-
export declare function resolvePolicy(input: PolicyInput): PolicyResult;
|
|
57
|
-
/**
|
|
58
|
-
* What the build helpers inject as __FIREWEAVE_WEB_CONFIG__: raw values and
|
|
59
|
-
* their source names, re-resolved in the browser so explicit start() options
|
|
60
|
-
* still win. Never carries a server key or the control-points object.
|
|
61
|
-
*/
|
|
62
|
-
export interface InjectedConfig {
|
|
63
|
-
readonly v: 1;
|
|
64
|
-
readonly key?: string;
|
|
65
|
-
readonly keySource?: string;
|
|
66
|
-
readonly url?: string;
|
|
67
|
-
readonly urlSource?: string;
|
|
68
|
-
readonly environment?: string;
|
|
69
|
-
readonly environmentSource?: string;
|
|
70
|
-
}
|