@fabricorg/experiments-web-adapters 0.1.0 → 0.1.2
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 +19 -0
- package/dist/index.cjs +38 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -2
- package/dist/index.d.ts +34 -2
- package/dist/index.js +38 -3
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# @fabricorg/experiments-web-adapters
|
|
2
|
+
|
|
3
|
+
Snowplow, GA4, GTM/dataLayer, failure, and Mojito migration adapters for
|
|
4
|
+
`@fabricorg/experiments-web`.
|
|
5
|
+
|
|
6
|
+
```ts
|
|
7
|
+
import { mojitoCompatibilityAdapter } from '@fabricorg/experiments-web-adapters'
|
|
8
|
+
|
|
9
|
+
const hooks = mojitoCompatibilityAdapter(Mojito.options.storageAdapter)
|
|
10
|
+
await init({ manifestUrl, subjectId, ...hooks })
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The bridge maps successful exposure, recipe failure, and activation timeout to
|
|
14
|
+
Mojito's `onExposure`, `onRecipeFailure`, and `onVeilTimeout` callbacks. The
|
|
15
|
+
complete Fabric record remains available on `test.fabric`.
|
|
16
|
+
|
|
17
|
+
Documentation: https://experiments.fabric.pro/docs/reference/web-adapters/
|
|
18
|
+
|
|
19
|
+
MIT
|
package/dist/index.cjs
CHANGED
|
@@ -43,7 +43,8 @@ function dataLayerAdapter(options = {}) {
|
|
|
43
43
|
return (record) => {
|
|
44
44
|
var _a2;
|
|
45
45
|
const w = globalThis;
|
|
46
|
-
|
|
46
|
+
if (!w.dataLayer) w.dataLayer = [];
|
|
47
|
+
const dl = (_a2 = options.dataLayer) != null ? _a2 : w.dataLayer;
|
|
47
48
|
dl.push({
|
|
48
49
|
event: eventName,
|
|
49
50
|
fx_experiment_id: record.experimentId,
|
|
@@ -94,7 +95,8 @@ function dataLayerFailureAdapter(options = {}) {
|
|
|
94
95
|
var _a2;
|
|
95
96
|
if (!record.failure) return;
|
|
96
97
|
const w = globalThis;
|
|
97
|
-
|
|
98
|
+
if (!w.dataLayer) w.dataLayer = [];
|
|
99
|
+
const dl = (_a2 = options.dataLayer) != null ? _a2 : w.dataLayer;
|
|
98
100
|
dl.push({
|
|
99
101
|
event: eventName,
|
|
100
102
|
fx_experiment_id: record.experimentId,
|
|
@@ -105,11 +107,45 @@ function dataLayerFailureAdapter(options = {}) {
|
|
|
105
107
|
});
|
|
106
108
|
};
|
|
107
109
|
}
|
|
110
|
+
function mojitoTestObject(record, options) {
|
|
111
|
+
var _a, _b, _c, _d, _e;
|
|
112
|
+
return {
|
|
113
|
+
options: {
|
|
114
|
+
id: record.experimentId,
|
|
115
|
+
name: (_b = (_a = options.experimentNames) == null ? void 0 : _a[record.experimentId]) != null ? _b : record.experimentId
|
|
116
|
+
},
|
|
117
|
+
chosenRecipe: {
|
|
118
|
+
id: record.variantKey,
|
|
119
|
+
name: (_e = (_d = (_c = options.variantNames) == null ? void 0 : _c[record.experimentId]) == null ? void 0 : _d[record.variantKey]) != null ? _e : record.variantKey
|
|
120
|
+
},
|
|
121
|
+
subjectId: record.subjectId,
|
|
122
|
+
manifestVersion: record.manifestVersion,
|
|
123
|
+
fabric: record
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function mojitoCompatibilityAdapter(adapter, options = {}) {
|
|
127
|
+
return {
|
|
128
|
+
onExposure(record) {
|
|
129
|
+
var _a;
|
|
130
|
+
if (!record.failure) (_a = adapter.onExposure) == null ? void 0 : _a.call(adapter, mojitoTestObject(record, options));
|
|
131
|
+
},
|
|
132
|
+
onRecipeFailure(record) {
|
|
133
|
+
var _a;
|
|
134
|
+
if (!record.failure) return;
|
|
135
|
+
(_a = adapter.onRecipeFailure) == null ? void 0 : _a.call(adapter, mojitoTestObject(record, options), record.failure.message);
|
|
136
|
+
},
|
|
137
|
+
onActivationFailure(record) {
|
|
138
|
+
var _a;
|
|
139
|
+
(_a = adapter.onVeilTimeout) == null ? void 0 : _a.call(adapter, mojitoTestObject(record, options), record.variantKey);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
}
|
|
108
143
|
|
|
109
144
|
exports.compose = compose;
|
|
110
145
|
exports.dataLayerAdapter = dataLayerAdapter;
|
|
111
146
|
exports.dataLayerFailureAdapter = dataLayerFailureAdapter;
|
|
112
147
|
exports.gaAdapter = gaAdapter;
|
|
148
|
+
exports.mojitoCompatibilityAdapter = mojitoCompatibilityAdapter;
|
|
113
149
|
exports.snowplowAdapter = snowplowAdapter;
|
|
114
150
|
exports.snowplowFailureAdapter = snowplowFailureAdapter;
|
|
115
151
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":["_a"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { ExposureRecord } from '@fabricorg/experiments-web';\n\nexport type ExposureAdapter = (record: ExposureRecord) => void;\n\n/**\n * Snowplow self-describing exposure event.\n *\n * Schema: iglu:io.fabric.experiments/exposure/jsonschema/1-0-0\n * (host the schema in your Iglu repo to validate downstream).\n */\nexport interface SnowplowAdapterOptions {\n /** Tracker function: typically `(window as any).snowplow` or the explicit tracker. */\n tracker?: (...args: unknown[]) => void;\n /** Schema URI. Override if you publish a custom schema. */\n schema?: string;\n}\n\nexport function snowplowAdapter(options: SnowplowAdapterOptions = {}): ExposureAdapter {\n const schema = options.schema ?? 'iglu:io.fabric.experiments/exposure/jsonschema/1-0-0';\n return (record) => {\n const tracker =\n options.tracker ??\n (globalThis as { snowplow?: (...args: unknown[]) => void }).snowplow;\n if (!tracker) return;\n tracker('trackSelfDescribingEvent', {\n event: {\n schema,\n data: {\n experimentId: record.experimentId,\n variantKey: record.variantKey,\n subjectId: record.subjectId,\n manifestVersion: record.manifestVersion,\n at: record.at,\n failure: record.failure,\n },\n },\n });\n };\n}\n\n/**\n * Google Analytics 4 (gtag) adapter.\n * Sends an `experiment_exposure` event with custom dimensions.\n */\nexport interface GaAdapterOptions {\n gtag?: (...args: unknown[]) => void;\n /** Override the event name. Default: `experiment_exposure`. */\n eventName?: string;\n}\n\nexport function gaAdapter(options: GaAdapterOptions = {}): ExposureAdapter {\n const eventName = options.eventName ?? 'experiment_exposure';\n return (record) => {\n const gtag =\n options.gtag ?? (globalThis as { gtag?: (...args: unknown[]) => void }).gtag;\n if (!gtag) return;\n gtag('event', eventName, {\n experiment_id: record.experimentId,\n variant_key: record.variantKey,\n manifest_version: record.manifestVersion,\n });\n };\n}\n\n/**\n * Generic GTM dataLayer adapter — pushes a single event GTM tags can listen for.\n * This is also the default tag-loader behavior.\n */\nexport interface DataLayerAdapterOptions {\n /** Override the dataLayer reference (tests). */\n dataLayer?: Array<Record<string, unknown>>;\n /** Override the event name. Default: `fx_exposure`. */\n eventName?: string;\n}\n\nexport function dataLayerAdapter(options: DataLayerAdapterOptions = {}): ExposureAdapter {\n const eventName = options.eventName ?? 'fx_exposure';\n return (record) => {\n const w = globalThis as { dataLayer?: Array<Record<string, unknown>> };\n const dl = options.dataLayer ?? (w.dataLayer = w.dataLayer || []);\n dl.push({\n event: eventName,\n fx_experiment_id: record.experimentId,\n fx_variant_key: record.variantKey,\n fx_subject_id: record.subjectId,\n fx_manifest_version: record.manifestVersion,\n });\n };\n}\n\n/**\n * Fan out a single exposure to multiple adapters. Each adapter is wrapped in\n * a try/catch so a third-party tracker error never breaks the chain.\n */\nexport function compose(...adapters: readonly ExposureAdapter[]): ExposureAdapter {\n return (record) => {\n for (const a of adapters) {\n try {\n a(record);\n } catch {\n /* swallow */\n }\n }\n };\n}\n\n// ---- Failure adapters (Mojito onRecipeFailure parity) ----------------------\n\n/**\n * Snowplow self-describing event for variant failures.\n *\n * Schema: iglu:io.fabric.experiments/recipe_failure/jsonschema/1-0-0\n * Fires once per (experimentId, variantKey, message) — useful for alarming\n * on variant-code crashes without cluttering the exposure stream.\n */\nexport interface SnowplowFailureAdapterOptions extends SnowplowAdapterOptions {\n schema?: string;\n}\n\nexport function snowplowFailureAdapter(\n options: SnowplowFailureAdapterOptions = {},\n): ExposureAdapter {\n const schema =\n options.schema ?? 'iglu:io.fabric.experiments/recipe_failure/jsonschema/1-0-0';\n return (record) => {\n if (!record.failure) return;\n const tracker =\n options.tracker ??\n (globalThis as { snowplow?: (...args: unknown[]) => void }).snowplow;\n if (!tracker) return;\n tracker('trackSelfDescribingEvent', {\n event: {\n schema,\n data: {\n experimentId: record.experimentId,\n variantKey: record.variantKey,\n subjectId: record.subjectId,\n manifestVersion: record.manifestVersion,\n at: record.at,\n message: record.failure.message,\n stack: record.failure.stack,\n },\n },\n });\n };\n}\n\n/** dataLayer push for variant failures — pairs with the default exposure adapter. */\nexport function dataLayerFailureAdapter(\n options: DataLayerAdapterOptions = {},\n): ExposureAdapter {\n const eventName = options.eventName ?? 'fx_recipe_failure';\n return (record) => {\n if (!record.failure) return;\n const w = globalThis as { dataLayer?: Array<Record<string, unknown>> };\n const dl = options.dataLayer ?? (w.dataLayer = w.dataLayer || []);\n dl.push({\n event: eventName,\n fx_experiment_id: record.experimentId,\n fx_variant_key: record.variantKey,\n fx_subject_id: record.subjectId,\n fx_manifest_version: record.manifestVersion,\n fx_failure_message: record.failure.message,\n });\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["_a"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { ActivationFailureRecord, ExposureRecord } from '@fabricorg/experiments-web';\n\nexport type ExposureAdapter = (record: ExposureRecord) => void;\n\n/**\n * Snowplow self-describing exposure event.\n *\n * Schema: iglu:io.fabric.experiments/exposure/jsonschema/1-0-0\n * (host the schema in your Iglu repo to validate downstream).\n */\nexport interface SnowplowAdapterOptions {\n /** Tracker function: typically `(window as any).snowplow` or the explicit tracker. */\n tracker?: (...args: unknown[]) => void;\n /** Schema URI. Override if you publish a custom schema. */\n schema?: string;\n}\n\nexport function snowplowAdapter(options: SnowplowAdapterOptions = {}): ExposureAdapter {\n const schema = options.schema ?? 'iglu:io.fabric.experiments/exposure/jsonschema/1-0-0';\n return (record) => {\n const tracker =\n options.tracker ?? (globalThis as { snowplow?: (...args: unknown[]) => void }).snowplow;\n if (!tracker) return;\n tracker('trackSelfDescribingEvent', {\n event: {\n schema,\n data: {\n experimentId: record.experimentId,\n variantKey: record.variantKey,\n subjectId: record.subjectId,\n manifestVersion: record.manifestVersion,\n at: record.at,\n failure: record.failure,\n },\n },\n });\n };\n}\n\n/**\n * Google Analytics 4 (gtag) adapter.\n * Sends an `experiment_exposure` event with custom dimensions.\n */\nexport interface GaAdapterOptions {\n gtag?: (...args: unknown[]) => void;\n /** Override the event name. Default: `experiment_exposure`. */\n eventName?: string;\n}\n\nexport function gaAdapter(options: GaAdapterOptions = {}): ExposureAdapter {\n const eventName = options.eventName ?? 'experiment_exposure';\n return (record) => {\n const gtag = options.gtag ?? (globalThis as { gtag?: (...args: unknown[]) => void }).gtag;\n if (!gtag) return;\n gtag('event', eventName, {\n experiment_id: record.experimentId,\n variant_key: record.variantKey,\n manifest_version: record.manifestVersion,\n });\n };\n}\n\n/**\n * Generic GTM dataLayer adapter — pushes a single event GTM tags can listen for.\n * This is also the default tag-loader behavior.\n */\nexport interface DataLayerAdapterOptions {\n /** Override the dataLayer reference (tests). */\n dataLayer?: Array<Record<string, unknown>>;\n /** Override the event name. Default: `fx_exposure`. */\n eventName?: string;\n}\n\nexport function dataLayerAdapter(options: DataLayerAdapterOptions = {}): ExposureAdapter {\n const eventName = options.eventName ?? 'fx_exposure';\n return (record) => {\n const w = globalThis as { dataLayer?: Array<Record<string, unknown>> };\n if (!w.dataLayer) w.dataLayer = [];\n const dl = options.dataLayer ?? w.dataLayer;\n dl.push({\n event: eventName,\n fx_experiment_id: record.experimentId,\n fx_variant_key: record.variantKey,\n fx_subject_id: record.subjectId,\n fx_manifest_version: record.manifestVersion,\n });\n };\n}\n\n/**\n * Fan out a single exposure to multiple adapters. Each adapter is wrapped in\n * a try/catch so a third-party tracker error never breaks the chain.\n */\nexport function compose(...adapters: readonly ExposureAdapter[]): ExposureAdapter {\n return (record) => {\n for (const a of adapters) {\n try {\n a(record);\n } catch {\n /* swallow */\n }\n }\n };\n}\n\n// ---- Failure adapters (Mojito onRecipeFailure parity) ----------------------\n\n/**\n * Snowplow self-describing event for variant failures.\n *\n * Schema: iglu:io.fabric.experiments/recipe_failure/jsonschema/1-0-0\n * Fires once per (experimentId, variantKey, message) — useful for alarming\n * on variant-code crashes without cluttering the exposure stream.\n */\nexport interface SnowplowFailureAdapterOptions extends SnowplowAdapterOptions {\n schema?: string;\n}\n\nexport function snowplowFailureAdapter(\n options: SnowplowFailureAdapterOptions = {},\n): ExposureAdapter {\n const schema = options.schema ?? 'iglu:io.fabric.experiments/recipe_failure/jsonschema/1-0-0';\n return (record) => {\n if (!record.failure) return;\n const tracker =\n options.tracker ?? (globalThis as { snowplow?: (...args: unknown[]) => void }).snowplow;\n if (!tracker) return;\n tracker('trackSelfDescribingEvent', {\n event: {\n schema,\n data: {\n experimentId: record.experimentId,\n variantKey: record.variantKey,\n subjectId: record.subjectId,\n manifestVersion: record.manifestVersion,\n at: record.at,\n message: record.failure.message,\n stack: record.failure.stack,\n },\n },\n });\n };\n}\n\n/** dataLayer push for variant failures — pairs with the default exposure adapter. */\nexport function dataLayerFailureAdapter(options: DataLayerAdapterOptions = {}): ExposureAdapter {\n const eventName = options.eventName ?? 'fx_recipe_failure';\n return (record) => {\n if (!record.failure) return;\n const w = globalThis as { dataLayer?: Array<Record<string, unknown>> };\n if (!w.dataLayer) w.dataLayer = [];\n const dl = options.dataLayer ?? w.dataLayer;\n dl.push({\n event: eventName,\n fx_experiment_id: record.experimentId,\n fx_variant_key: record.variantKey,\n fx_subject_id: record.subjectId,\n fx_manifest_version: record.manifestVersion,\n fx_failure_message: record.failure.message,\n });\n };\n}\n\n// ---- Mojito storage-adapter bridge ----------------------------------------\n\n/** Minimal Mojito-shaped object passed to legacy storage-adapter callbacks. */\nexport interface MojitoCompatibleTestObject {\n options: { id: string; name: string };\n chosenRecipe: { id: string; name: string };\n subjectId: string;\n manifestVersion: number;\n fabric: ExposureRecord | ActivationFailureRecord;\n}\n\nexport interface MojitoStorageAdapter {\n onExposure?: (test: MojitoCompatibleTestObject) => void;\n onRecipeFailure?: (test: MojitoCompatibleTestObject, error?: string) => void;\n onVeilTimeout?: (test: MojitoCompatibleTestObject, ultimateRecipe: string) => void;\n}\n\nexport interface MojitoCompatibilityOptions {\n experimentNames?: Record<string, string>;\n variantNames?: Record<string, Record<string, string>>;\n}\n\nfunction mojitoTestObject(\n record: ExposureRecord | ActivationFailureRecord,\n options: MojitoCompatibilityOptions,\n): MojitoCompatibleTestObject {\n return {\n options: {\n id: record.experimentId,\n name: options.experimentNames?.[record.experimentId] ?? record.experimentId,\n },\n chosenRecipe: {\n id: record.variantKey,\n name: options.variantNames?.[record.experimentId]?.[record.variantKey] ?? record.variantKey,\n },\n subjectId: record.subjectId,\n manifestVersion: record.manifestVersion,\n fabric: record,\n };\n}\n\n/**\n * Reuse an existing Mojito `storageAdapter` while migrating delivery to\n * Fabric. Spread the returned hooks into `init()` or `window.__FX__`.\n */\nexport function mojitoCompatibilityAdapter(\n adapter: MojitoStorageAdapter,\n options: MojitoCompatibilityOptions = {},\n): {\n onExposure: ExposureAdapter;\n onRecipeFailure: ExposureAdapter;\n onActivationFailure: (record: ActivationFailureRecord) => void;\n} {\n return {\n onExposure(record) {\n // Failure records are delivered separately, matching Mojito's event split.\n if (!record.failure) adapter.onExposure?.(mojitoTestObject(record, options));\n },\n onRecipeFailure(record) {\n if (!record.failure) return;\n adapter.onRecipeFailure?.(mojitoTestObject(record, options), record.failure.message);\n },\n onActivationFailure(record) {\n adapter.onVeilTimeout?.(mojitoTestObject(record, options), record.variantKey);\n },\n };\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ExposureRecord } from '@fabricorg/experiments-web';
|
|
1
|
+
import { ExposureRecord, ActivationFailureRecord } from '@fabricorg/experiments-web';
|
|
2
2
|
|
|
3
3
|
type ExposureAdapter = (record: ExposureRecord) => void;
|
|
4
4
|
/**
|
|
@@ -53,5 +53,37 @@ interface SnowplowFailureAdapterOptions extends SnowplowAdapterOptions {
|
|
|
53
53
|
declare function snowplowFailureAdapter(options?: SnowplowFailureAdapterOptions): ExposureAdapter;
|
|
54
54
|
/** dataLayer push for variant failures — pairs with the default exposure adapter. */
|
|
55
55
|
declare function dataLayerFailureAdapter(options?: DataLayerAdapterOptions): ExposureAdapter;
|
|
56
|
+
/** Minimal Mojito-shaped object passed to legacy storage-adapter callbacks. */
|
|
57
|
+
interface MojitoCompatibleTestObject {
|
|
58
|
+
options: {
|
|
59
|
+
id: string;
|
|
60
|
+
name: string;
|
|
61
|
+
};
|
|
62
|
+
chosenRecipe: {
|
|
63
|
+
id: string;
|
|
64
|
+
name: string;
|
|
65
|
+
};
|
|
66
|
+
subjectId: string;
|
|
67
|
+
manifestVersion: number;
|
|
68
|
+
fabric: ExposureRecord | ActivationFailureRecord;
|
|
69
|
+
}
|
|
70
|
+
interface MojitoStorageAdapter {
|
|
71
|
+
onExposure?: (test: MojitoCompatibleTestObject) => void;
|
|
72
|
+
onRecipeFailure?: (test: MojitoCompatibleTestObject, error?: string) => void;
|
|
73
|
+
onVeilTimeout?: (test: MojitoCompatibleTestObject, ultimateRecipe: string) => void;
|
|
74
|
+
}
|
|
75
|
+
interface MojitoCompatibilityOptions {
|
|
76
|
+
experimentNames?: Record<string, string>;
|
|
77
|
+
variantNames?: Record<string, Record<string, string>>;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Reuse an existing Mojito `storageAdapter` while migrating delivery to
|
|
81
|
+
* Fabric. Spread the returned hooks into `init()` or `window.__FX__`.
|
|
82
|
+
*/
|
|
83
|
+
declare function mojitoCompatibilityAdapter(adapter: MojitoStorageAdapter, options?: MojitoCompatibilityOptions): {
|
|
84
|
+
onExposure: ExposureAdapter;
|
|
85
|
+
onRecipeFailure: ExposureAdapter;
|
|
86
|
+
onActivationFailure: (record: ActivationFailureRecord) => void;
|
|
87
|
+
};
|
|
56
88
|
|
|
57
|
-
export { type DataLayerAdapterOptions, type ExposureAdapter, type GaAdapterOptions, type SnowplowAdapterOptions, type SnowplowFailureAdapterOptions, compose, dataLayerAdapter, dataLayerFailureAdapter, gaAdapter, snowplowAdapter, snowplowFailureAdapter };
|
|
89
|
+
export { type DataLayerAdapterOptions, type ExposureAdapter, type GaAdapterOptions, type MojitoCompatibilityOptions, type MojitoCompatibleTestObject, type MojitoStorageAdapter, type SnowplowAdapterOptions, type SnowplowFailureAdapterOptions, compose, dataLayerAdapter, dataLayerFailureAdapter, gaAdapter, mojitoCompatibilityAdapter, snowplowAdapter, snowplowFailureAdapter };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ExposureRecord } from '@fabricorg/experiments-web';
|
|
1
|
+
import { ExposureRecord, ActivationFailureRecord } from '@fabricorg/experiments-web';
|
|
2
2
|
|
|
3
3
|
type ExposureAdapter = (record: ExposureRecord) => void;
|
|
4
4
|
/**
|
|
@@ -53,5 +53,37 @@ interface SnowplowFailureAdapterOptions extends SnowplowAdapterOptions {
|
|
|
53
53
|
declare function snowplowFailureAdapter(options?: SnowplowFailureAdapterOptions): ExposureAdapter;
|
|
54
54
|
/** dataLayer push for variant failures — pairs with the default exposure adapter. */
|
|
55
55
|
declare function dataLayerFailureAdapter(options?: DataLayerAdapterOptions): ExposureAdapter;
|
|
56
|
+
/** Minimal Mojito-shaped object passed to legacy storage-adapter callbacks. */
|
|
57
|
+
interface MojitoCompatibleTestObject {
|
|
58
|
+
options: {
|
|
59
|
+
id: string;
|
|
60
|
+
name: string;
|
|
61
|
+
};
|
|
62
|
+
chosenRecipe: {
|
|
63
|
+
id: string;
|
|
64
|
+
name: string;
|
|
65
|
+
};
|
|
66
|
+
subjectId: string;
|
|
67
|
+
manifestVersion: number;
|
|
68
|
+
fabric: ExposureRecord | ActivationFailureRecord;
|
|
69
|
+
}
|
|
70
|
+
interface MojitoStorageAdapter {
|
|
71
|
+
onExposure?: (test: MojitoCompatibleTestObject) => void;
|
|
72
|
+
onRecipeFailure?: (test: MojitoCompatibleTestObject, error?: string) => void;
|
|
73
|
+
onVeilTimeout?: (test: MojitoCompatibleTestObject, ultimateRecipe: string) => void;
|
|
74
|
+
}
|
|
75
|
+
interface MojitoCompatibilityOptions {
|
|
76
|
+
experimentNames?: Record<string, string>;
|
|
77
|
+
variantNames?: Record<string, Record<string, string>>;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Reuse an existing Mojito `storageAdapter` while migrating delivery to
|
|
81
|
+
* Fabric. Spread the returned hooks into `init()` or `window.__FX__`.
|
|
82
|
+
*/
|
|
83
|
+
declare function mojitoCompatibilityAdapter(adapter: MojitoStorageAdapter, options?: MojitoCompatibilityOptions): {
|
|
84
|
+
onExposure: ExposureAdapter;
|
|
85
|
+
onRecipeFailure: ExposureAdapter;
|
|
86
|
+
onActivationFailure: (record: ActivationFailureRecord) => void;
|
|
87
|
+
};
|
|
56
88
|
|
|
57
|
-
export { type DataLayerAdapterOptions, type ExposureAdapter, type GaAdapterOptions, type SnowplowAdapterOptions, type SnowplowFailureAdapterOptions, compose, dataLayerAdapter, dataLayerFailureAdapter, gaAdapter, snowplowAdapter, snowplowFailureAdapter };
|
|
89
|
+
export { type DataLayerAdapterOptions, type ExposureAdapter, type GaAdapterOptions, type MojitoCompatibilityOptions, type MojitoCompatibleTestObject, type MojitoStorageAdapter, type SnowplowAdapterOptions, type SnowplowFailureAdapterOptions, compose, dataLayerAdapter, dataLayerFailureAdapter, gaAdapter, mojitoCompatibilityAdapter, snowplowAdapter, snowplowFailureAdapter };
|
package/dist/index.js
CHANGED
|
@@ -41,7 +41,8 @@ function dataLayerAdapter(options = {}) {
|
|
|
41
41
|
return (record) => {
|
|
42
42
|
var _a2;
|
|
43
43
|
const w = globalThis;
|
|
44
|
-
|
|
44
|
+
if (!w.dataLayer) w.dataLayer = [];
|
|
45
|
+
const dl = (_a2 = options.dataLayer) != null ? _a2 : w.dataLayer;
|
|
45
46
|
dl.push({
|
|
46
47
|
event: eventName,
|
|
47
48
|
fx_experiment_id: record.experimentId,
|
|
@@ -92,7 +93,8 @@ function dataLayerFailureAdapter(options = {}) {
|
|
|
92
93
|
var _a2;
|
|
93
94
|
if (!record.failure) return;
|
|
94
95
|
const w = globalThis;
|
|
95
|
-
|
|
96
|
+
if (!w.dataLayer) w.dataLayer = [];
|
|
97
|
+
const dl = (_a2 = options.dataLayer) != null ? _a2 : w.dataLayer;
|
|
96
98
|
dl.push({
|
|
97
99
|
event: eventName,
|
|
98
100
|
fx_experiment_id: record.experimentId,
|
|
@@ -103,7 +105,40 @@ function dataLayerFailureAdapter(options = {}) {
|
|
|
103
105
|
});
|
|
104
106
|
};
|
|
105
107
|
}
|
|
108
|
+
function mojitoTestObject(record, options) {
|
|
109
|
+
var _a, _b, _c, _d, _e;
|
|
110
|
+
return {
|
|
111
|
+
options: {
|
|
112
|
+
id: record.experimentId,
|
|
113
|
+
name: (_b = (_a = options.experimentNames) == null ? void 0 : _a[record.experimentId]) != null ? _b : record.experimentId
|
|
114
|
+
},
|
|
115
|
+
chosenRecipe: {
|
|
116
|
+
id: record.variantKey,
|
|
117
|
+
name: (_e = (_d = (_c = options.variantNames) == null ? void 0 : _c[record.experimentId]) == null ? void 0 : _d[record.variantKey]) != null ? _e : record.variantKey
|
|
118
|
+
},
|
|
119
|
+
subjectId: record.subjectId,
|
|
120
|
+
manifestVersion: record.manifestVersion,
|
|
121
|
+
fabric: record
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function mojitoCompatibilityAdapter(adapter, options = {}) {
|
|
125
|
+
return {
|
|
126
|
+
onExposure(record) {
|
|
127
|
+
var _a;
|
|
128
|
+
if (!record.failure) (_a = adapter.onExposure) == null ? void 0 : _a.call(adapter, mojitoTestObject(record, options));
|
|
129
|
+
},
|
|
130
|
+
onRecipeFailure(record) {
|
|
131
|
+
var _a;
|
|
132
|
+
if (!record.failure) return;
|
|
133
|
+
(_a = adapter.onRecipeFailure) == null ? void 0 : _a.call(adapter, mojitoTestObject(record, options), record.failure.message);
|
|
134
|
+
},
|
|
135
|
+
onActivationFailure(record) {
|
|
136
|
+
var _a;
|
|
137
|
+
(_a = adapter.onVeilTimeout) == null ? void 0 : _a.call(adapter, mojitoTestObject(record, options), record.variantKey);
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
106
141
|
|
|
107
|
-
export { compose, dataLayerAdapter, dataLayerFailureAdapter, gaAdapter, snowplowAdapter, snowplowFailureAdapter };
|
|
142
|
+
export { compose, dataLayerAdapter, dataLayerFailureAdapter, gaAdapter, mojitoCompatibilityAdapter, snowplowAdapter, snowplowFailureAdapter };
|
|
108
143
|
//# sourceMappingURL=index.js.map
|
|
109
144
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":["_a"],"mappings":"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","file":"index.js","sourcesContent":["import type { ExposureRecord } from '@fabricorg/experiments-web';\n\nexport type ExposureAdapter = (record: ExposureRecord) => void;\n\n/**\n * Snowplow self-describing exposure event.\n *\n * Schema: iglu:io.fabric.experiments/exposure/jsonschema/1-0-0\n * (host the schema in your Iglu repo to validate downstream).\n */\nexport interface SnowplowAdapterOptions {\n /** Tracker function: typically `(window as any).snowplow` or the explicit tracker. */\n tracker?: (...args: unknown[]) => void;\n /** Schema URI. Override if you publish a custom schema. */\n schema?: string;\n}\n\nexport function snowplowAdapter(options: SnowplowAdapterOptions = {}): ExposureAdapter {\n const schema = options.schema ?? 'iglu:io.fabric.experiments/exposure/jsonschema/1-0-0';\n return (record) => {\n const tracker =\n options.tracker ??\n (globalThis as { snowplow?: (...args: unknown[]) => void }).snowplow;\n if (!tracker) return;\n tracker('trackSelfDescribingEvent', {\n event: {\n schema,\n data: {\n experimentId: record.experimentId,\n variantKey: record.variantKey,\n subjectId: record.subjectId,\n manifestVersion: record.manifestVersion,\n at: record.at,\n failure: record.failure,\n },\n },\n });\n };\n}\n\n/**\n * Google Analytics 4 (gtag) adapter.\n * Sends an `experiment_exposure` event with custom dimensions.\n */\nexport interface GaAdapterOptions {\n gtag?: (...args: unknown[]) => void;\n /** Override the event name. Default: `experiment_exposure`. */\n eventName?: string;\n}\n\nexport function gaAdapter(options: GaAdapterOptions = {}): ExposureAdapter {\n const eventName = options.eventName ?? 'experiment_exposure';\n return (record) => {\n const gtag =\n options.gtag ?? (globalThis as { gtag?: (...args: unknown[]) => void }).gtag;\n if (!gtag) return;\n gtag('event', eventName, {\n experiment_id: record.experimentId,\n variant_key: record.variantKey,\n manifest_version: record.manifestVersion,\n });\n };\n}\n\n/**\n * Generic GTM dataLayer adapter — pushes a single event GTM tags can listen for.\n * This is also the default tag-loader behavior.\n */\nexport interface DataLayerAdapterOptions {\n /** Override the dataLayer reference (tests). */\n dataLayer?: Array<Record<string, unknown>>;\n /** Override the event name. Default: `fx_exposure`. */\n eventName?: string;\n}\n\nexport function dataLayerAdapter(options: DataLayerAdapterOptions = {}): ExposureAdapter {\n const eventName = options.eventName ?? 'fx_exposure';\n return (record) => {\n const w = globalThis as { dataLayer?: Array<Record<string, unknown>> };\n const dl = options.dataLayer ?? (w.dataLayer = w.dataLayer || []);\n dl.push({\n event: eventName,\n fx_experiment_id: record.experimentId,\n fx_variant_key: record.variantKey,\n fx_subject_id: record.subjectId,\n fx_manifest_version: record.manifestVersion,\n });\n };\n}\n\n/**\n * Fan out a single exposure to multiple adapters. Each adapter is wrapped in\n * a try/catch so a third-party tracker error never breaks the chain.\n */\nexport function compose(...adapters: readonly ExposureAdapter[]): ExposureAdapter {\n return (record) => {\n for (const a of adapters) {\n try {\n a(record);\n } catch {\n /* swallow */\n }\n }\n };\n}\n\n// ---- Failure adapters (Mojito onRecipeFailure parity) ----------------------\n\n/**\n * Snowplow self-describing event for variant failures.\n *\n * Schema: iglu:io.fabric.experiments/recipe_failure/jsonschema/1-0-0\n * Fires once per (experimentId, variantKey, message) — useful for alarming\n * on variant-code crashes without cluttering the exposure stream.\n */\nexport interface SnowplowFailureAdapterOptions extends SnowplowAdapterOptions {\n schema?: string;\n}\n\nexport function snowplowFailureAdapter(\n options: SnowplowFailureAdapterOptions = {},\n): ExposureAdapter {\n const schema =\n options.schema ?? 'iglu:io.fabric.experiments/recipe_failure/jsonschema/1-0-0';\n return (record) => {\n if (!record.failure) return;\n const tracker =\n options.tracker ??\n (globalThis as { snowplow?: (...args: unknown[]) => void }).snowplow;\n if (!tracker) return;\n tracker('trackSelfDescribingEvent', {\n event: {\n schema,\n data: {\n experimentId: record.experimentId,\n variantKey: record.variantKey,\n subjectId: record.subjectId,\n manifestVersion: record.manifestVersion,\n at: record.at,\n message: record.failure.message,\n stack: record.failure.stack,\n },\n },\n });\n };\n}\n\n/** dataLayer push for variant failures — pairs with the default exposure adapter. */\nexport function dataLayerFailureAdapter(\n options: DataLayerAdapterOptions = {},\n): ExposureAdapter {\n const eventName = options.eventName ?? 'fx_recipe_failure';\n return (record) => {\n if (!record.failure) return;\n const w = globalThis as { dataLayer?: Array<Record<string, unknown>> };\n const dl = options.dataLayer ?? (w.dataLayer = w.dataLayer || []);\n dl.push({\n event: eventName,\n fx_experiment_id: record.experimentId,\n fx_variant_key: record.variantKey,\n fx_subject_id: record.subjectId,\n fx_manifest_version: record.manifestVersion,\n fx_failure_message: record.failure.message,\n });\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["_a"],"mappings":"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","file":"index.js","sourcesContent":["import type { ActivationFailureRecord, ExposureRecord } from '@fabricorg/experiments-web';\n\nexport type ExposureAdapter = (record: ExposureRecord) => void;\n\n/**\n * Snowplow self-describing exposure event.\n *\n * Schema: iglu:io.fabric.experiments/exposure/jsonschema/1-0-0\n * (host the schema in your Iglu repo to validate downstream).\n */\nexport interface SnowplowAdapterOptions {\n /** Tracker function: typically `(window as any).snowplow` or the explicit tracker. */\n tracker?: (...args: unknown[]) => void;\n /** Schema URI. Override if you publish a custom schema. */\n schema?: string;\n}\n\nexport function snowplowAdapter(options: SnowplowAdapterOptions = {}): ExposureAdapter {\n const schema = options.schema ?? 'iglu:io.fabric.experiments/exposure/jsonschema/1-0-0';\n return (record) => {\n const tracker =\n options.tracker ?? (globalThis as { snowplow?: (...args: unknown[]) => void }).snowplow;\n if (!tracker) return;\n tracker('trackSelfDescribingEvent', {\n event: {\n schema,\n data: {\n experimentId: record.experimentId,\n variantKey: record.variantKey,\n subjectId: record.subjectId,\n manifestVersion: record.manifestVersion,\n at: record.at,\n failure: record.failure,\n },\n },\n });\n };\n}\n\n/**\n * Google Analytics 4 (gtag) adapter.\n * Sends an `experiment_exposure` event with custom dimensions.\n */\nexport interface GaAdapterOptions {\n gtag?: (...args: unknown[]) => void;\n /** Override the event name. Default: `experiment_exposure`. */\n eventName?: string;\n}\n\nexport function gaAdapter(options: GaAdapterOptions = {}): ExposureAdapter {\n const eventName = options.eventName ?? 'experiment_exposure';\n return (record) => {\n const gtag = options.gtag ?? (globalThis as { gtag?: (...args: unknown[]) => void }).gtag;\n if (!gtag) return;\n gtag('event', eventName, {\n experiment_id: record.experimentId,\n variant_key: record.variantKey,\n manifest_version: record.manifestVersion,\n });\n };\n}\n\n/**\n * Generic GTM dataLayer adapter — pushes a single event GTM tags can listen for.\n * This is also the default tag-loader behavior.\n */\nexport interface DataLayerAdapterOptions {\n /** Override the dataLayer reference (tests). */\n dataLayer?: Array<Record<string, unknown>>;\n /** Override the event name. Default: `fx_exposure`. */\n eventName?: string;\n}\n\nexport function dataLayerAdapter(options: DataLayerAdapterOptions = {}): ExposureAdapter {\n const eventName = options.eventName ?? 'fx_exposure';\n return (record) => {\n const w = globalThis as { dataLayer?: Array<Record<string, unknown>> };\n if (!w.dataLayer) w.dataLayer = [];\n const dl = options.dataLayer ?? w.dataLayer;\n dl.push({\n event: eventName,\n fx_experiment_id: record.experimentId,\n fx_variant_key: record.variantKey,\n fx_subject_id: record.subjectId,\n fx_manifest_version: record.manifestVersion,\n });\n };\n}\n\n/**\n * Fan out a single exposure to multiple adapters. Each adapter is wrapped in\n * a try/catch so a third-party tracker error never breaks the chain.\n */\nexport function compose(...adapters: readonly ExposureAdapter[]): ExposureAdapter {\n return (record) => {\n for (const a of adapters) {\n try {\n a(record);\n } catch {\n /* swallow */\n }\n }\n };\n}\n\n// ---- Failure adapters (Mojito onRecipeFailure parity) ----------------------\n\n/**\n * Snowplow self-describing event for variant failures.\n *\n * Schema: iglu:io.fabric.experiments/recipe_failure/jsonschema/1-0-0\n * Fires once per (experimentId, variantKey, message) — useful for alarming\n * on variant-code crashes without cluttering the exposure stream.\n */\nexport interface SnowplowFailureAdapterOptions extends SnowplowAdapterOptions {\n schema?: string;\n}\n\nexport function snowplowFailureAdapter(\n options: SnowplowFailureAdapterOptions = {},\n): ExposureAdapter {\n const schema = options.schema ?? 'iglu:io.fabric.experiments/recipe_failure/jsonschema/1-0-0';\n return (record) => {\n if (!record.failure) return;\n const tracker =\n options.tracker ?? (globalThis as { snowplow?: (...args: unknown[]) => void }).snowplow;\n if (!tracker) return;\n tracker('trackSelfDescribingEvent', {\n event: {\n schema,\n data: {\n experimentId: record.experimentId,\n variantKey: record.variantKey,\n subjectId: record.subjectId,\n manifestVersion: record.manifestVersion,\n at: record.at,\n message: record.failure.message,\n stack: record.failure.stack,\n },\n },\n });\n };\n}\n\n/** dataLayer push for variant failures — pairs with the default exposure adapter. */\nexport function dataLayerFailureAdapter(options: DataLayerAdapterOptions = {}): ExposureAdapter {\n const eventName = options.eventName ?? 'fx_recipe_failure';\n return (record) => {\n if (!record.failure) return;\n const w = globalThis as { dataLayer?: Array<Record<string, unknown>> };\n if (!w.dataLayer) w.dataLayer = [];\n const dl = options.dataLayer ?? w.dataLayer;\n dl.push({\n event: eventName,\n fx_experiment_id: record.experimentId,\n fx_variant_key: record.variantKey,\n fx_subject_id: record.subjectId,\n fx_manifest_version: record.manifestVersion,\n fx_failure_message: record.failure.message,\n });\n };\n}\n\n// ---- Mojito storage-adapter bridge ----------------------------------------\n\n/** Minimal Mojito-shaped object passed to legacy storage-adapter callbacks. */\nexport interface MojitoCompatibleTestObject {\n options: { id: string; name: string };\n chosenRecipe: { id: string; name: string };\n subjectId: string;\n manifestVersion: number;\n fabric: ExposureRecord | ActivationFailureRecord;\n}\n\nexport interface MojitoStorageAdapter {\n onExposure?: (test: MojitoCompatibleTestObject) => void;\n onRecipeFailure?: (test: MojitoCompatibleTestObject, error?: string) => void;\n onVeilTimeout?: (test: MojitoCompatibleTestObject, ultimateRecipe: string) => void;\n}\n\nexport interface MojitoCompatibilityOptions {\n experimentNames?: Record<string, string>;\n variantNames?: Record<string, Record<string, string>>;\n}\n\nfunction mojitoTestObject(\n record: ExposureRecord | ActivationFailureRecord,\n options: MojitoCompatibilityOptions,\n): MojitoCompatibleTestObject {\n return {\n options: {\n id: record.experimentId,\n name: options.experimentNames?.[record.experimentId] ?? record.experimentId,\n },\n chosenRecipe: {\n id: record.variantKey,\n name: options.variantNames?.[record.experimentId]?.[record.variantKey] ?? record.variantKey,\n },\n subjectId: record.subjectId,\n manifestVersion: record.manifestVersion,\n fabric: record,\n };\n}\n\n/**\n * Reuse an existing Mojito `storageAdapter` while migrating delivery to\n * Fabric. Spread the returned hooks into `init()` or `window.__FX__`.\n */\nexport function mojitoCompatibilityAdapter(\n adapter: MojitoStorageAdapter,\n options: MojitoCompatibilityOptions = {},\n): {\n onExposure: ExposureAdapter;\n onRecipeFailure: ExposureAdapter;\n onActivationFailure: (record: ActivationFailureRecord) => void;\n} {\n return {\n onExposure(record) {\n // Failure records are delivered separately, matching Mojito's event split.\n if (!record.failure) adapter.onExposure?.(mojitoTestObject(record, options));\n },\n onRecipeFailure(record) {\n if (!record.failure) return;\n adapter.onRecipeFailure?.(mojitoTestObject(record, options), record.failure.message);\n },\n onActivationFailure(record) {\n adapter.onVeilTimeout?.(mojitoTestObject(record, options), record.variantKey);\n },\n };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fabricorg/experiments-web-adapters",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"registry": "https://registry.npmjs.org",
|
|
6
6
|
"access": "public"
|
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
"scripts": {
|
|
23
23
|
"build": "tsup",
|
|
24
24
|
"type-check": "tsc --noEmit",
|
|
25
|
-
"test": "vitest run
|
|
25
|
+
"test": "vitest run",
|
|
26
26
|
"clean": "rm -rf dist"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@fabricorg/experiments-web": "
|
|
29
|
+
"@fabricorg/experiments-web": "^0.2.1"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"tsup": "^8.3.5",
|