@fabricorg/experiments-web-adapters 0.0.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/dist/index.cjs ADDED
@@ -0,0 +1,116 @@
1
+ 'use strict';
2
+
3
+ // src/index.ts
4
+ function snowplowAdapter(options = {}) {
5
+ var _a;
6
+ const schema = (_a = options.schema) != null ? _a : "iglu:io.fabric.experiments/exposure/jsonschema/1-0-0";
7
+ return (record) => {
8
+ var _a2;
9
+ const tracker = (_a2 = options.tracker) != null ? _a2 : globalThis.snowplow;
10
+ if (!tracker) return;
11
+ tracker("trackSelfDescribingEvent", {
12
+ event: {
13
+ schema,
14
+ data: {
15
+ experimentId: record.experimentId,
16
+ variantKey: record.variantKey,
17
+ subjectId: record.subjectId,
18
+ manifestVersion: record.manifestVersion,
19
+ at: record.at,
20
+ failure: record.failure
21
+ }
22
+ }
23
+ });
24
+ };
25
+ }
26
+ function gaAdapter(options = {}) {
27
+ var _a;
28
+ const eventName = (_a = options.eventName) != null ? _a : "experiment_exposure";
29
+ return (record) => {
30
+ var _a2;
31
+ const gtag = (_a2 = options.gtag) != null ? _a2 : globalThis.gtag;
32
+ if (!gtag) return;
33
+ gtag("event", eventName, {
34
+ experiment_id: record.experimentId,
35
+ variant_key: record.variantKey,
36
+ manifest_version: record.manifestVersion
37
+ });
38
+ };
39
+ }
40
+ function dataLayerAdapter(options = {}) {
41
+ var _a;
42
+ const eventName = (_a = options.eventName) != null ? _a : "fx_exposure";
43
+ return (record) => {
44
+ var _a2;
45
+ const w = globalThis;
46
+ const dl = (_a2 = options.dataLayer) != null ? _a2 : w.dataLayer = w.dataLayer || [];
47
+ dl.push({
48
+ event: eventName,
49
+ fx_experiment_id: record.experimentId,
50
+ fx_variant_key: record.variantKey,
51
+ fx_subject_id: record.subjectId,
52
+ fx_manifest_version: record.manifestVersion
53
+ });
54
+ };
55
+ }
56
+ function compose(...adapters) {
57
+ return (record) => {
58
+ for (const a of adapters) {
59
+ try {
60
+ a(record);
61
+ } catch (e) {
62
+ }
63
+ }
64
+ };
65
+ }
66
+ function snowplowFailureAdapter(options = {}) {
67
+ var _a;
68
+ const schema = (_a = options.schema) != null ? _a : "iglu:io.fabric.experiments/recipe_failure/jsonschema/1-0-0";
69
+ return (record) => {
70
+ var _a2;
71
+ if (!record.failure) return;
72
+ const tracker = (_a2 = options.tracker) != null ? _a2 : globalThis.snowplow;
73
+ if (!tracker) return;
74
+ tracker("trackSelfDescribingEvent", {
75
+ event: {
76
+ schema,
77
+ data: {
78
+ experimentId: record.experimentId,
79
+ variantKey: record.variantKey,
80
+ subjectId: record.subjectId,
81
+ manifestVersion: record.manifestVersion,
82
+ at: record.at,
83
+ message: record.failure.message,
84
+ stack: record.failure.stack
85
+ }
86
+ }
87
+ });
88
+ };
89
+ }
90
+ function dataLayerFailureAdapter(options = {}) {
91
+ var _a;
92
+ const eventName = (_a = options.eventName) != null ? _a : "fx_recipe_failure";
93
+ return (record) => {
94
+ var _a2;
95
+ if (!record.failure) return;
96
+ const w = globalThis;
97
+ const dl = (_a2 = options.dataLayer) != null ? _a2 : w.dataLayer = w.dataLayer || [];
98
+ dl.push({
99
+ event: eventName,
100
+ fx_experiment_id: record.experimentId,
101
+ fx_variant_key: record.variantKey,
102
+ fx_subject_id: record.subjectId,
103
+ fx_manifest_version: record.manifestVersion,
104
+ fx_failure_message: record.failure.message
105
+ });
106
+ };
107
+ }
108
+
109
+ exports.compose = compose;
110
+ exports.dataLayerAdapter = dataLayerAdapter;
111
+ exports.dataLayerFailureAdapter = dataLayerFailureAdapter;
112
+ exports.gaAdapter = gaAdapter;
113
+ exports.snowplowAdapter = snowplowAdapter;
114
+ exports.snowplowFailureAdapter = snowplowFailureAdapter;
115
+ //# sourceMappingURL=index.cjs.map
116
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +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"]}
@@ -0,0 +1,57 @@
1
+ import { ExposureRecord } from '@fabricorg/experiments-web';
2
+
3
+ type ExposureAdapter = (record: ExposureRecord) => void;
4
+ /**
5
+ * Snowplow self-describing exposure event.
6
+ *
7
+ * Schema: iglu:io.fabric.experiments/exposure/jsonschema/1-0-0
8
+ * (host the schema in your Iglu repo to validate downstream).
9
+ */
10
+ interface SnowplowAdapterOptions {
11
+ /** Tracker function: typically `(window as any).snowplow` or the explicit tracker. */
12
+ tracker?: (...args: unknown[]) => void;
13
+ /** Schema URI. Override if you publish a custom schema. */
14
+ schema?: string;
15
+ }
16
+ declare function snowplowAdapter(options?: SnowplowAdapterOptions): ExposureAdapter;
17
+ /**
18
+ * Google Analytics 4 (gtag) adapter.
19
+ * Sends an `experiment_exposure` event with custom dimensions.
20
+ */
21
+ interface GaAdapterOptions {
22
+ gtag?: (...args: unknown[]) => void;
23
+ /** Override the event name. Default: `experiment_exposure`. */
24
+ eventName?: string;
25
+ }
26
+ declare function gaAdapter(options?: GaAdapterOptions): ExposureAdapter;
27
+ /**
28
+ * Generic GTM dataLayer adapter — pushes a single event GTM tags can listen for.
29
+ * This is also the default tag-loader behavior.
30
+ */
31
+ interface DataLayerAdapterOptions {
32
+ /** Override the dataLayer reference (tests). */
33
+ dataLayer?: Array<Record<string, unknown>>;
34
+ /** Override the event name. Default: `fx_exposure`. */
35
+ eventName?: string;
36
+ }
37
+ declare function dataLayerAdapter(options?: DataLayerAdapterOptions): ExposureAdapter;
38
+ /**
39
+ * Fan out a single exposure to multiple adapters. Each adapter is wrapped in
40
+ * a try/catch so a third-party tracker error never breaks the chain.
41
+ */
42
+ declare function compose(...adapters: readonly ExposureAdapter[]): ExposureAdapter;
43
+ /**
44
+ * Snowplow self-describing event for variant failures.
45
+ *
46
+ * Schema: iglu:io.fabric.experiments/recipe_failure/jsonschema/1-0-0
47
+ * Fires once per (experimentId, variantKey, message) — useful for alarming
48
+ * on variant-code crashes without cluttering the exposure stream.
49
+ */
50
+ interface SnowplowFailureAdapterOptions extends SnowplowAdapterOptions {
51
+ schema?: string;
52
+ }
53
+ declare function snowplowFailureAdapter(options?: SnowplowFailureAdapterOptions): ExposureAdapter;
54
+ /** dataLayer push for variant failures — pairs with the default exposure adapter. */
55
+ declare function dataLayerFailureAdapter(options?: DataLayerAdapterOptions): ExposureAdapter;
56
+
57
+ export { type DataLayerAdapterOptions, type ExposureAdapter, type GaAdapterOptions, type SnowplowAdapterOptions, type SnowplowFailureAdapterOptions, compose, dataLayerAdapter, dataLayerFailureAdapter, gaAdapter, snowplowAdapter, snowplowFailureAdapter };
@@ -0,0 +1,57 @@
1
+ import { ExposureRecord } from '@fabricorg/experiments-web';
2
+
3
+ type ExposureAdapter = (record: ExposureRecord) => void;
4
+ /**
5
+ * Snowplow self-describing exposure event.
6
+ *
7
+ * Schema: iglu:io.fabric.experiments/exposure/jsonschema/1-0-0
8
+ * (host the schema in your Iglu repo to validate downstream).
9
+ */
10
+ interface SnowplowAdapterOptions {
11
+ /** Tracker function: typically `(window as any).snowplow` or the explicit tracker. */
12
+ tracker?: (...args: unknown[]) => void;
13
+ /** Schema URI. Override if you publish a custom schema. */
14
+ schema?: string;
15
+ }
16
+ declare function snowplowAdapter(options?: SnowplowAdapterOptions): ExposureAdapter;
17
+ /**
18
+ * Google Analytics 4 (gtag) adapter.
19
+ * Sends an `experiment_exposure` event with custom dimensions.
20
+ */
21
+ interface GaAdapterOptions {
22
+ gtag?: (...args: unknown[]) => void;
23
+ /** Override the event name. Default: `experiment_exposure`. */
24
+ eventName?: string;
25
+ }
26
+ declare function gaAdapter(options?: GaAdapterOptions): ExposureAdapter;
27
+ /**
28
+ * Generic GTM dataLayer adapter — pushes a single event GTM tags can listen for.
29
+ * This is also the default tag-loader behavior.
30
+ */
31
+ interface DataLayerAdapterOptions {
32
+ /** Override the dataLayer reference (tests). */
33
+ dataLayer?: Array<Record<string, unknown>>;
34
+ /** Override the event name. Default: `fx_exposure`. */
35
+ eventName?: string;
36
+ }
37
+ declare function dataLayerAdapter(options?: DataLayerAdapterOptions): ExposureAdapter;
38
+ /**
39
+ * Fan out a single exposure to multiple adapters. Each adapter is wrapped in
40
+ * a try/catch so a third-party tracker error never breaks the chain.
41
+ */
42
+ declare function compose(...adapters: readonly ExposureAdapter[]): ExposureAdapter;
43
+ /**
44
+ * Snowplow self-describing event for variant failures.
45
+ *
46
+ * Schema: iglu:io.fabric.experiments/recipe_failure/jsonschema/1-0-0
47
+ * Fires once per (experimentId, variantKey, message) — useful for alarming
48
+ * on variant-code crashes without cluttering the exposure stream.
49
+ */
50
+ interface SnowplowFailureAdapterOptions extends SnowplowAdapterOptions {
51
+ schema?: string;
52
+ }
53
+ declare function snowplowFailureAdapter(options?: SnowplowFailureAdapterOptions): ExposureAdapter;
54
+ /** dataLayer push for variant failures — pairs with the default exposure adapter. */
55
+ declare function dataLayerFailureAdapter(options?: DataLayerAdapterOptions): ExposureAdapter;
56
+
57
+ export { type DataLayerAdapterOptions, type ExposureAdapter, type GaAdapterOptions, type SnowplowAdapterOptions, type SnowplowFailureAdapterOptions, compose, dataLayerAdapter, dataLayerFailureAdapter, gaAdapter, snowplowAdapter, snowplowFailureAdapter };
package/dist/index.js ADDED
@@ -0,0 +1,109 @@
1
+ // src/index.ts
2
+ function snowplowAdapter(options = {}) {
3
+ var _a;
4
+ const schema = (_a = options.schema) != null ? _a : "iglu:io.fabric.experiments/exposure/jsonschema/1-0-0";
5
+ return (record) => {
6
+ var _a2;
7
+ const tracker = (_a2 = options.tracker) != null ? _a2 : globalThis.snowplow;
8
+ if (!tracker) return;
9
+ tracker("trackSelfDescribingEvent", {
10
+ event: {
11
+ schema,
12
+ data: {
13
+ experimentId: record.experimentId,
14
+ variantKey: record.variantKey,
15
+ subjectId: record.subjectId,
16
+ manifestVersion: record.manifestVersion,
17
+ at: record.at,
18
+ failure: record.failure
19
+ }
20
+ }
21
+ });
22
+ };
23
+ }
24
+ function gaAdapter(options = {}) {
25
+ var _a;
26
+ const eventName = (_a = options.eventName) != null ? _a : "experiment_exposure";
27
+ return (record) => {
28
+ var _a2;
29
+ const gtag = (_a2 = options.gtag) != null ? _a2 : globalThis.gtag;
30
+ if (!gtag) return;
31
+ gtag("event", eventName, {
32
+ experiment_id: record.experimentId,
33
+ variant_key: record.variantKey,
34
+ manifest_version: record.manifestVersion
35
+ });
36
+ };
37
+ }
38
+ function dataLayerAdapter(options = {}) {
39
+ var _a;
40
+ const eventName = (_a = options.eventName) != null ? _a : "fx_exposure";
41
+ return (record) => {
42
+ var _a2;
43
+ const w = globalThis;
44
+ const dl = (_a2 = options.dataLayer) != null ? _a2 : w.dataLayer = w.dataLayer || [];
45
+ dl.push({
46
+ event: eventName,
47
+ fx_experiment_id: record.experimentId,
48
+ fx_variant_key: record.variantKey,
49
+ fx_subject_id: record.subjectId,
50
+ fx_manifest_version: record.manifestVersion
51
+ });
52
+ };
53
+ }
54
+ function compose(...adapters) {
55
+ return (record) => {
56
+ for (const a of adapters) {
57
+ try {
58
+ a(record);
59
+ } catch (e) {
60
+ }
61
+ }
62
+ };
63
+ }
64
+ function snowplowFailureAdapter(options = {}) {
65
+ var _a;
66
+ const schema = (_a = options.schema) != null ? _a : "iglu:io.fabric.experiments/recipe_failure/jsonschema/1-0-0";
67
+ return (record) => {
68
+ var _a2;
69
+ if (!record.failure) return;
70
+ const tracker = (_a2 = options.tracker) != null ? _a2 : globalThis.snowplow;
71
+ if (!tracker) return;
72
+ tracker("trackSelfDescribingEvent", {
73
+ event: {
74
+ schema,
75
+ data: {
76
+ experimentId: record.experimentId,
77
+ variantKey: record.variantKey,
78
+ subjectId: record.subjectId,
79
+ manifestVersion: record.manifestVersion,
80
+ at: record.at,
81
+ message: record.failure.message,
82
+ stack: record.failure.stack
83
+ }
84
+ }
85
+ });
86
+ };
87
+ }
88
+ function dataLayerFailureAdapter(options = {}) {
89
+ var _a;
90
+ const eventName = (_a = options.eventName) != null ? _a : "fx_recipe_failure";
91
+ return (record) => {
92
+ var _a2;
93
+ if (!record.failure) return;
94
+ const w = globalThis;
95
+ const dl = (_a2 = options.dataLayer) != null ? _a2 : w.dataLayer = w.dataLayer || [];
96
+ dl.push({
97
+ event: eventName,
98
+ fx_experiment_id: record.experimentId,
99
+ fx_variant_key: record.variantKey,
100
+ fx_subject_id: record.subjectId,
101
+ fx_manifest_version: record.manifestVersion,
102
+ fx_failure_message: record.failure.message
103
+ });
104
+ };
105
+ }
106
+
107
+ export { compose, dataLayerAdapter, dataLayerFailureAdapter, gaAdapter, snowplowAdapter, snowplowFailureAdapter };
108
+ //# sourceMappingURL=index.js.map
109
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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"]}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@fabricorg/experiments-web-adapters",
3
+ "version": "0.0.2",
4
+ "publishConfig": {
5
+ "registry": "https://registry.npmjs.org",
6
+ "access": "public"
7
+ },
8
+ "description": "Pluggable exposure adapters for @fabricorg/experiments-web — Snowplow, GA, GTM, dataLayer.",
9
+ "license": "MIT",
10
+ "type": "module",
11
+ "sideEffects": false,
12
+ "main": "./dist/index.cjs",
13
+ "types": "./dist/index.d.ts",
14
+ "module": "./dist/index.js",
15
+ "exports": {
16
+ ".": {
17
+ "import": { "types": "./dist/index.d.ts", "default": "./dist/index.js" },
18
+ "require": { "types": "./dist/index.d.cts", "default": "./dist/index.cjs" }
19
+ }
20
+ },
21
+ "files": ["dist"],
22
+ "scripts": {
23
+ "build": "tsup",
24
+ "type-check": "tsc --noEmit",
25
+ "test": "vitest run --passWithNoTests",
26
+ "clean": "rm -rf dist"
27
+ },
28
+ "dependencies": {
29
+ "@fabricorg/experiments-web": "workspace:*"
30
+ },
31
+ "devDependencies": {
32
+ "tsup": "^8.3.5",
33
+ "typescript": "^5.8.3",
34
+ "vitest": "^2.1.8"
35
+ }
36
+ }