@amplitude/analytics-browser 2.21.1 → 2.22.1

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.
Files changed (75) hide show
  1. package/README.md +1 -1
  2. package/lib/cjs/browser-client.d.ts +2 -1
  3. package/lib/cjs/browser-client.d.ts.map +1 -1
  4. package/lib/cjs/browser-client.js +68 -50
  5. package/lib/cjs/browser-client.js.map +1 -1
  6. package/lib/cjs/config/joined-config.d.ts +37 -15
  7. package/lib/cjs/config/joined-config.d.ts.map +1 -1
  8. package/lib/cjs/config/joined-config.js +155 -123
  9. package/lib/cjs/config/joined-config.js.map +1 -1
  10. package/lib/cjs/config.d.ts +1 -1
  11. package/lib/cjs/storage/local-storage.d.ts +1 -2
  12. package/lib/cjs/storage/local-storage.d.ts.map +1 -1
  13. package/lib/cjs/storage/local-storage.js +1 -2
  14. package/lib/cjs/storage/local-storage.js.map +1 -1
  15. package/lib/cjs/storage/session-storage.d.ts +1 -1
  16. package/lib/cjs/storage/session-storage.d.ts.map +1 -1
  17. package/lib/cjs/storage/session-storage.js +1 -2
  18. package/lib/cjs/storage/session-storage.js.map +1 -1
  19. package/lib/cjs/version.d.ts +1 -1
  20. package/lib/cjs/version.js +1 -1
  21. package/lib/cjs/version.js.map +1 -1
  22. package/lib/esm/browser-client.d.ts +2 -1
  23. package/lib/esm/browser-client.d.ts.map +1 -1
  24. package/lib/esm/browser-client.js +70 -52
  25. package/lib/esm/browser-client.js.map +1 -1
  26. package/lib/esm/config/joined-config.d.ts +37 -15
  27. package/lib/esm/config/joined-config.d.ts.map +1 -1
  28. package/lib/esm/config/joined-config.js +153 -122
  29. package/lib/esm/config/joined-config.js.map +1 -1
  30. package/lib/esm/config.d.ts +1 -1
  31. package/lib/esm/storage/local-storage.d.ts +1 -2
  32. package/lib/esm/storage/local-storage.d.ts.map +1 -1
  33. package/lib/esm/storage/local-storage.js +1 -2
  34. package/lib/esm/storage/local-storage.js.map +1 -1
  35. package/lib/esm/storage/session-storage.d.ts +1 -1
  36. package/lib/esm/storage/session-storage.d.ts.map +1 -1
  37. package/lib/esm/storage/session-storage.js +1 -2
  38. package/lib/esm/storage/session-storage.js.map +1 -1
  39. package/lib/esm/version.d.ts +1 -1
  40. package/lib/esm/version.js +1 -1
  41. package/lib/esm/version.js.map +1 -1
  42. package/lib/scripts/amplitude-bookmarklet-snippet-min.js +1 -1
  43. package/lib/scripts/amplitude-bookmarklet.html +1 -1
  44. package/lib/scripts/amplitude-gtm-min.js +1 -1
  45. package/lib/scripts/amplitude-gtm-min.js.gz +0 -0
  46. package/lib/scripts/amplitude-gtm-min.js.map +1 -1
  47. package/lib/scripts/amplitude-gtm-snippet-min.js +1 -1
  48. package/lib/scripts/amplitude-min.js +1 -1
  49. package/lib/scripts/amplitude-min.js.gz +0 -0
  50. package/lib/scripts/amplitude-min.js.map +1 -1
  51. package/lib/scripts/amplitude-min.umd.js +1 -1
  52. package/lib/scripts/amplitude-min.umd.js.gz +0 -0
  53. package/lib/scripts/amplitude-snippet-instructions.html +1 -1
  54. package/lib/scripts/amplitude-snippet-min.js +1 -1
  55. package/lib/scripts/browser-client.d.ts +2 -1
  56. package/lib/scripts/browser-client.d.ts.map +1 -1
  57. package/lib/scripts/config/joined-config.d.ts +37 -15
  58. package/lib/scripts/config/joined-config.d.ts.map +1 -1
  59. package/lib/scripts/config.d.ts +1 -1
  60. package/lib/scripts/storage/local-storage.d.ts +1 -2
  61. package/lib/scripts/storage/local-storage.d.ts.map +1 -1
  62. package/lib/scripts/storage/session-storage.d.ts +1 -1
  63. package/lib/scripts/storage/session-storage.d.ts.map +1 -1
  64. package/lib/scripts/version.d.ts +1 -1
  65. package/package.json +7 -7
  66. package/lib/cjs/storage/browser-storage.d.ts +0 -12
  67. package/lib/cjs/storage/browser-storage.d.ts.map +0 -1
  68. package/lib/cjs/storage/browser-storage.js +0 -122
  69. package/lib/cjs/storage/browser-storage.js.map +0 -1
  70. package/lib/esm/storage/browser-storage.d.ts +0 -12
  71. package/lib/esm/storage/browser-storage.d.ts.map +0 -1
  72. package/lib/esm/storage/browser-storage.js +0 -119
  73. package/lib/esm/storage/browser-storage.js.map +0 -1
  74. package/lib/scripts/storage/browser-storage.d.ts +0 -12
  75. package/lib/scripts/storage/browser-storage.d.ts.map +0 -1
@@ -1,135 +1,167 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createBrowserJoinedConfigGenerator = exports.BrowserJoinedConfigGenerator = void 0;
3
+ exports.updateBrowserConfigWithRemoteConfig = exports.translateRemoteConfigToLocal = void 0;
4
4
  var tslib_1 = require("tslib");
5
- var analytics_remote_config_1 = require("@amplitude/analytics-remote-config");
6
- var analytics_core_1 = require("@amplitude/analytics-core");
7
- var BrowserJoinedConfigGenerator = /** @class */ (function () {
8
- function BrowserJoinedConfigGenerator(localConfig) {
9
- this.config = localConfig;
10
- this.config.loggerProvider.debug('Local configuration before merging with remote config', JSON.stringify(this.config, null, 2));
5
+ /**
6
+ * Performs a deep transformation of a remote config object so that
7
+ * it matches the expected schema of the local config.
8
+ *
9
+ * Specifically, it normalizes nested `enabled` flags into concise union types.
10
+ *
11
+ * ### Transformation Rules:
12
+ * - If an object has `enabled: true`, it is replaced by the same object without the `enabled` field.
13
+ * - If it has only `enabled: true`, it is replaced with `true`.
14
+ * - If it has `enabled: false`, it is replaced with `false` regardless of other fields.
15
+ *
16
+ * ### Examples:
17
+ * Input: { prop: { enabled: true, hello: 'world' }}
18
+ * Output: { prop: { hello: 'world' } }
19
+ *
20
+ * Input: { prop: { enabled: true }}
21
+ * Output: { prop: true }
22
+ *
23
+ * Input: { prop: { enabled: false, hello: 'world' }}
24
+ * Output: { prop: false }
25
+ *
26
+ * Input: { prop: { hello: 'world' }}
27
+ * Output: { prop: { hello: 'world' } } // No change
28
+ *
29
+ * @param config Remote config object to be transformed
30
+ * @returns Transformed config object compatible with local schema
31
+ */
32
+ function translateRemoteConfigToLocal(config) {
33
+ var e_1, _a;
34
+ // Disabling type checking rules because remote config comes from a remote source
35
+ // and this function needs to handle any unexpected values
36
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access,
37
+ @typescript-eslint/no-unsafe-assignment,
38
+ @typescript-eslint/no-unsafe-argument
39
+ */
40
+ if (typeof config !== 'object' || config === null) {
41
+ return;
11
42
  }
12
- BrowserJoinedConfigGenerator.prototype.initialize = function () {
13
- return tslib_1.__awaiter(this, void 0, void 0, function () {
14
- var _a;
15
- return tslib_1.__generator(this, function (_b) {
16
- switch (_b.label) {
17
- case 0:
18
- _a = this;
19
- return [4 /*yield*/, (0, analytics_remote_config_1.createRemoteConfigFetch)({
20
- localConfig: this.config,
21
- configKeys: ['analyticsSDK'],
22
- })];
23
- case 1:
24
- _a.remoteConfigFetch = _b.sent();
25
- return [2 /*return*/];
43
+ // translations are not applied on array properties
44
+ if (Array.isArray(config)) {
45
+ return;
46
+ }
47
+ var propertyNames = Object.keys(config);
48
+ try {
49
+ for (var propertyNames_1 = tslib_1.__values(propertyNames), propertyNames_1_1 = propertyNames_1.next(); !propertyNames_1_1.done; propertyNames_1_1 = propertyNames_1.next()) {
50
+ var propertyName = propertyNames_1_1.value;
51
+ try {
52
+ var value = config[propertyName];
53
+ // transform objects with { enabled } property to boolean | object
54
+ if (typeof (value === null || value === void 0 ? void 0 : value.enabled) === 'boolean') {
55
+ if (value.enabled) {
56
+ // if enabled is true, set the value to the rest of the object
57
+ // or true if the object has no other properties
58
+ delete value.enabled;
59
+ if (Object.keys(value).length === 0) {
60
+ config[propertyName] = true;
61
+ }
62
+ }
63
+ else {
64
+ // If enabled is false, set the value to false
65
+ config[propertyName] = false;
66
+ }
26
67
  }
27
- });
28
- });
29
- };
30
- BrowserJoinedConfigGenerator.prototype.generateJoinedConfig = function () {
31
- var _a, _b, _c, _d, _e;
32
- var _f;
33
- return tslib_1.__awaiter(this, void 0, void 0, function () {
34
- var remoteConfig, _g, transformedAutocaptureRemoteConfig, transformedRcElementInteractions, exactAllowList, regexList, _h, _j, pattern, combinedPageUrlAllowlist, e_1;
35
- var e_2, _k;
36
- return tslib_1.__generator(this, function (_l) {
37
- switch (_l.label) {
38
- case 0:
39
- _l.trys.push([0, 3, , 4]);
40
- _g = this.remoteConfigFetch;
41
- if (!_g) return [3 /*break*/, 2];
42
- return [4 /*yield*/, this.remoteConfigFetch.getRemoteConfig('analyticsSDK', 'browserSDK', this.config.sessionId)];
43
- case 1:
44
- _g = (_l.sent());
45
- _l.label = 2;
46
- case 2:
47
- remoteConfig = _g;
48
- this.config.loggerProvider.debug('Remote configuration:', JSON.stringify(remoteConfig, null, 2));
49
- // merge remoteConfig.autocapture and this.config.autocapture
50
- // if a field is in remoteConfig.autocapture, use that value
51
- // if a field is not in remoteConfig.autocapture, use the value from this.config.autocapture
52
- if (remoteConfig && 'autocapture' in remoteConfig) {
53
- if (typeof remoteConfig.autocapture === 'boolean') {
54
- this.config.autocapture = remoteConfig.autocapture;
68
+ // recursively translate properties of the value
69
+ translateRemoteConfigToLocal(value);
70
+ }
71
+ catch (e) {
72
+ // a failure here means that an accessor threw an error
73
+ // so don't translate it
74
+ // TODO(diagnostics): add a diagnostic event for this
75
+ }
76
+ }
77
+ }
78
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
79
+ finally {
80
+ try {
81
+ if (propertyNames_1_1 && !propertyNames_1_1.done && (_a = propertyNames_1.return)) _a.call(propertyNames_1);
82
+ }
83
+ finally { if (e_1) throw e_1.error; }
84
+ }
85
+ }
86
+ exports.translateRemoteConfigToLocal = translateRemoteConfigToLocal;
87
+ /**
88
+ * Updates the browser config in place by applying remote configuration settings.
89
+ * Primarily merges autocapture settings from the remote config into the browser config.
90
+ *
91
+ * @param remoteConfig - The remote configuration to apply, or null if none available
92
+ * @param browserConfig - The browser config object to update (modified in place)
93
+ */
94
+ function updateBrowserConfigWithRemoteConfig(remoteConfig, browserConfig) {
95
+ var e_2, _a;
96
+ var _b, _c;
97
+ if (!remoteConfig) {
98
+ return;
99
+ }
100
+ // translate remote config to local compatible format
101
+ translateRemoteConfigToLocal(remoteConfig);
102
+ try {
103
+ browserConfig.loggerProvider.debug('Update browser config with remote configuration:', JSON.stringify(remoteConfig));
104
+ // type cast error will be thrown if remoteConfig is not a valid RemoteConfigBrowserSDK
105
+ // and it will be caught by the try-catch block
106
+ var typedRemoteConfig = remoteConfig;
107
+ // merge remoteConfig.autocapture and browserConfig.autocapture
108
+ // if a field is in remoteConfig.autocapture, use that value
109
+ // if a field is not in remoteConfig.autocapture, use the value from browserConfig.autocapture
110
+ if (typedRemoteConfig && 'autocapture' in typedRemoteConfig) {
111
+ if (typeof typedRemoteConfig.autocapture === 'boolean') {
112
+ browserConfig.autocapture = typedRemoteConfig.autocapture;
113
+ }
114
+ if (typeof typedRemoteConfig.autocapture === 'object' && typedRemoteConfig.autocapture !== null) {
115
+ var transformedAutocaptureRemoteConfig = tslib_1.__assign({}, typedRemoteConfig.autocapture);
116
+ if (browserConfig.autocapture === undefined) {
117
+ browserConfig.autocapture = typedRemoteConfig.autocapture;
118
+ }
119
+ // Handle Element Interactions config initialization
120
+ if (typeof typedRemoteConfig.autocapture.elementInteractions === 'object' &&
121
+ typedRemoteConfig.autocapture.elementInteractions !== null &&
122
+ ((_b = typedRemoteConfig.autocapture.elementInteractions.pageUrlAllowlistRegex) === null || _b === void 0 ? void 0 : _b.length)) {
123
+ transformedAutocaptureRemoteConfig.elementInteractions = tslib_1.__assign({}, typedRemoteConfig.autocapture.elementInteractions);
124
+ var transformedRcElementInteractions = transformedAutocaptureRemoteConfig.elementInteractions;
125
+ var exactAllowList = (_c = transformedRcElementInteractions.pageUrlAllowlist) !== null && _c !== void 0 ? _c : [];
126
+ // Convert string patterns to RegExp objects, warn on invalid patterns and skip them
127
+ var regexList = [];
128
+ try {
129
+ for (var _d = tslib_1.__values(typedRemoteConfig.autocapture.elementInteractions.pageUrlAllowlistRegex), _e = _d.next(); !_e.done; _e = _d.next()) {
130
+ var pattern = _e.value;
131
+ try {
132
+ regexList.push(new RegExp(pattern));
55
133
  }
56
- if (typeof remoteConfig.autocapture === 'object') {
57
- transformedAutocaptureRemoteConfig = tslib_1.__assign({}, remoteConfig.autocapture);
58
- if (this.config.autocapture === undefined) {
59
- this.config.autocapture = remoteConfig.autocapture;
60
- }
61
- // Handle Element Interactions config initialization
62
- if (typeof remoteConfig.autocapture.elementInteractions === 'object' &&
63
- ((_a = remoteConfig.autocapture.elementInteractions.pageUrlAllowlistRegex) === null || _a === void 0 ? void 0 : _a.length)) {
64
- transformedAutocaptureRemoteConfig.elementInteractions = tslib_1.__assign({}, remoteConfig.autocapture.elementInteractions);
65
- transformedRcElementInteractions = transformedAutocaptureRemoteConfig.elementInteractions;
66
- exactAllowList = (_b = transformedRcElementInteractions.pageUrlAllowlist) !== null && _b !== void 0 ? _b : [];
67
- regexList = [];
68
- try {
69
- for (_h = tslib_1.__values(remoteConfig.autocapture.elementInteractions.pageUrlAllowlistRegex), _j = _h.next(); !_j.done; _j = _h.next()) {
70
- pattern = _j.value;
71
- try {
72
- regexList.push(new RegExp(pattern));
73
- }
74
- catch (regexError) {
75
- this.config.loggerProvider.warn("Invalid regex pattern: ".concat(pattern), regexError);
76
- }
77
- }
78
- }
79
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
80
- finally {
81
- try {
82
- if (_j && !_j.done && (_k = _h.return)) _k.call(_h);
83
- }
84
- finally { if (e_2) throw e_2.error; }
85
- }
86
- combinedPageUrlAllowlist = exactAllowList.concat(regexList);
87
- transformedRcElementInteractions.pageUrlAllowlist = combinedPageUrlAllowlist;
88
- delete transformedRcElementInteractions.pageUrlAllowlistRegex;
89
- }
90
- if (typeof this.config.autocapture === 'boolean') {
91
- this.config.autocapture = tslib_1.__assign({ attribution: this.config.autocapture, fileDownloads: this.config.autocapture, formInteractions: this.config.autocapture, pageViews: this.config.autocapture, sessions: this.config.autocapture, elementInteractions: this.config.autocapture, webVitals: this.config.autocapture, frustrationInteractions: this.config.autocapture }, transformedAutocaptureRemoteConfig);
92
- }
93
- if (typeof this.config.autocapture === 'object') {
94
- this.config.autocapture = tslib_1.__assign(tslib_1.__assign({}, this.config.autocapture), transformedAutocaptureRemoteConfig);
95
- }
134
+ catch (regexError) {
135
+ browserConfig.loggerProvider.warn("Invalid regex pattern: ".concat(pattern), regexError);
96
136
  }
97
- // Override default tracking options if autocapture is updated by remote config
98
- this.config.defaultTracking = this.config.autocapture;
99
- }
100
- this.config.loggerProvider.debug('Joined configuration: ', JSON.stringify(this.config, null, 2));
101
- (_c = (_f = this.config).requestMetadata) !== null && _c !== void 0 ? _c : (_f.requestMetadata = new analytics_core_1.RequestMetadata());
102
- if ((_d = this.remoteConfigFetch) === null || _d === void 0 ? void 0 : _d.metrics.fetchTimeAPISuccess) {
103
- this.config.requestMetadata.recordHistogram('remote_config_fetch_time_API_success', this.remoteConfigFetch.metrics.fetchTimeAPISuccess);
104
137
  }
105
- if ((_e = this.remoteConfigFetch) === null || _e === void 0 ? void 0 : _e.metrics.fetchTimeAPIFail) {
106
- this.config.requestMetadata.recordHistogram('remote_config_fetch_time_API_fail', this.remoteConfigFetch.metrics.fetchTimeAPIFail);
138
+ }
139
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
140
+ finally {
141
+ try {
142
+ if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
107
143
  }
108
- return [3 /*break*/, 4];
109
- case 3:
110
- e_1 = _l.sent();
111
- this.config.loggerProvider.error('Failed to fetch remote configuration because of error: ', e_1);
112
- return [3 /*break*/, 4];
113
- case 4: return [2 /*return*/, this.config];
144
+ finally { if (e_2) throw e_2.error; }
145
+ }
146
+ var combinedPageUrlAllowlist = exactAllowList.concat(regexList);
147
+ transformedRcElementInteractions.pageUrlAllowlist = combinedPageUrlAllowlist;
148
+ delete transformedRcElementInteractions.pageUrlAllowlistRegex;
149
+ }
150
+ if (typeof browserConfig.autocapture === 'boolean') {
151
+ browserConfig.autocapture = tslib_1.__assign({ attribution: browserConfig.autocapture, fileDownloads: browserConfig.autocapture, formInteractions: browserConfig.autocapture, pageViews: browserConfig.autocapture, sessions: browserConfig.autocapture, elementInteractions: browserConfig.autocapture, webVitals: browserConfig.autocapture, frustrationInteractions: browserConfig.autocapture }, transformedAutocaptureRemoteConfig);
114
152
  }
115
- });
116
- });
117
- };
118
- return BrowserJoinedConfigGenerator;
119
- }());
120
- exports.BrowserJoinedConfigGenerator = BrowserJoinedConfigGenerator;
121
- var createBrowserJoinedConfigGenerator = function (localConfig) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
122
- var joinedConfigGenerator;
123
- return tslib_1.__generator(this, function (_a) {
124
- switch (_a.label) {
125
- case 0:
126
- joinedConfigGenerator = new BrowserJoinedConfigGenerator(localConfig);
127
- return [4 /*yield*/, joinedConfigGenerator.initialize()];
128
- case 1:
129
- _a.sent();
130
- return [2 /*return*/, joinedConfigGenerator];
153
+ if (typeof browserConfig.autocapture === 'object') {
154
+ browserConfig.autocapture = tslib_1.__assign(tslib_1.__assign({}, browserConfig.autocapture), transformedAutocaptureRemoteConfig);
155
+ }
156
+ }
157
+ // Override default tracking options if autocapture is updated by remote config
158
+ browserConfig.defaultTracking = browserConfig.autocapture;
131
159
  }
132
- });
133
- }); };
134
- exports.createBrowserJoinedConfigGenerator = createBrowserJoinedConfigGenerator;
160
+ browserConfig.loggerProvider.debug('Browser config after remote config update:', JSON.stringify(browserConfig));
161
+ }
162
+ catch (e) {
163
+ browserConfig.loggerProvider.error('Failed to apply remote configuration because of error: ', e);
164
+ }
165
+ }
166
+ exports.updateBrowserConfigWithRemoteConfig = updateBrowserConfigWithRemoteConfig;
135
167
  //# sourceMappingURL=joined-config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"joined-config.js","sourceRoot":"","sources":["../../../src/config/joined-config.ts"],"names":[],"mappings":"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","sourcesContent":["import { createRemoteConfigFetch, RemoteConfigFetch } from '@amplitude/analytics-remote-config';\nimport {\n RequestMetadata,\n BrowserConfig as IBrowserConfig,\n AutocaptureOptions,\n type ElementInteractionsOptions,\n} from '@amplitude/analytics-core';\n\nexport interface AutocaptureOptionsRemoteConfig extends AutocaptureOptions {\n elementInteractions?: boolean | ElementInteractionsOptionsRemoteConfig;\n}\nexport interface ElementInteractionsOptionsRemoteConfig extends ElementInteractionsOptions {\n /**\n * Related to pageUrlAllowlist but holds regex strings which will be initialized and appended to pageUrlAllowlist\n */\n pageUrlAllowlistRegex?: string[];\n}\n\nexport type BrowserRemoteConfig = {\n browserSDK: {\n autocapture?: AutocaptureOptionsRemoteConfig | boolean;\n };\n};\n\nexport class BrowserJoinedConfigGenerator {\n // Local config before generateJoinedConfig is called\n // Joined config after generateJoinedConfig is called\n config: IBrowserConfig;\n remoteConfigFetch: RemoteConfigFetch<BrowserRemoteConfig> | undefined;\n\n constructor(localConfig: IBrowserConfig) {\n this.config = localConfig;\n this.config.loggerProvider.debug(\n 'Local configuration before merging with remote config',\n JSON.stringify(this.config, null, 2),\n );\n }\n\n async initialize() {\n this.remoteConfigFetch = await createRemoteConfigFetch<BrowserRemoteConfig>({\n localConfig: this.config,\n configKeys: ['analyticsSDK'],\n });\n }\n\n async generateJoinedConfig(): Promise<IBrowserConfig> {\n try {\n const remoteConfig =\n this.remoteConfigFetch &&\n (await this.remoteConfigFetch.getRemoteConfig('analyticsSDK', 'browserSDK', this.config.sessionId));\n this.config.loggerProvider.debug('Remote configuration:', JSON.stringify(remoteConfig, null, 2));\n\n // merge remoteConfig.autocapture and this.config.autocapture\n // if a field is in remoteConfig.autocapture, use that value\n // if a field is not in remoteConfig.autocapture, use the value from this.config.autocapture\n if (remoteConfig && 'autocapture' in remoteConfig) {\n if (typeof remoteConfig.autocapture === 'boolean') {\n this.config.autocapture = remoteConfig.autocapture;\n }\n\n if (typeof remoteConfig.autocapture === 'object') {\n const transformedAutocaptureRemoteConfig = { ...remoteConfig.autocapture };\n\n if (this.config.autocapture === undefined) {\n this.config.autocapture = remoteConfig.autocapture;\n }\n\n // Handle Element Interactions config initialization\n if (\n typeof remoteConfig.autocapture.elementInteractions === 'object' &&\n remoteConfig.autocapture.elementInteractions.pageUrlAllowlistRegex?.length\n ) {\n transformedAutocaptureRemoteConfig.elementInteractions = {\n ...remoteConfig.autocapture.elementInteractions,\n };\n const transformedRcElementInteractions = transformedAutocaptureRemoteConfig.elementInteractions;\n\n const exactAllowList = transformedRcElementInteractions.pageUrlAllowlist ?? [];\n // Convert string patterns to RegExp objects, warn on invalid patterns and skip them\n const regexList = [];\n for (const pattern of remoteConfig.autocapture.elementInteractions.pageUrlAllowlistRegex) {\n try {\n regexList.push(new RegExp(pattern));\n } catch (regexError) {\n this.config.loggerProvider.warn(`Invalid regex pattern: ${pattern}`, regexError);\n }\n }\n\n const combinedPageUrlAllowlist = exactAllowList.concat(regexList);\n\n transformedRcElementInteractions.pageUrlAllowlist = combinedPageUrlAllowlist;\n delete transformedRcElementInteractions.pageUrlAllowlistRegex;\n }\n\n if (typeof this.config.autocapture === 'boolean') {\n this.config.autocapture = {\n attribution: this.config.autocapture,\n fileDownloads: this.config.autocapture,\n formInteractions: this.config.autocapture,\n pageViews: this.config.autocapture,\n sessions: this.config.autocapture,\n elementInteractions: this.config.autocapture,\n webVitals: this.config.autocapture,\n frustrationInteractions: this.config.autocapture,\n ...transformedAutocaptureRemoteConfig,\n };\n }\n\n if (typeof this.config.autocapture === 'object') {\n this.config.autocapture = {\n ...this.config.autocapture,\n ...transformedAutocaptureRemoteConfig,\n };\n }\n }\n\n // Override default tracking options if autocapture is updated by remote config\n this.config.defaultTracking = this.config.autocapture;\n }\n\n this.config.loggerProvider.debug('Joined configuration: ', JSON.stringify(this.config, null, 2));\n this.config.requestMetadata ??= new RequestMetadata();\n if (this.remoteConfigFetch?.metrics.fetchTimeAPISuccess) {\n this.config.requestMetadata.recordHistogram(\n 'remote_config_fetch_time_API_success',\n this.remoteConfigFetch.metrics.fetchTimeAPISuccess,\n );\n }\n if (this.remoteConfigFetch?.metrics.fetchTimeAPIFail) {\n this.config.requestMetadata.recordHistogram(\n 'remote_config_fetch_time_API_fail',\n this.remoteConfigFetch.metrics.fetchTimeAPIFail,\n );\n }\n } catch (e) {\n this.config.loggerProvider.error('Failed to fetch remote configuration because of error: ', e);\n }\n\n return this.config;\n }\n}\n\nexport const createBrowserJoinedConfigGenerator = async (localConfig: IBrowserConfig) => {\n const joinedConfigGenerator = new BrowserJoinedConfigGenerator(localConfig);\n await joinedConfigGenerator.initialize();\n return joinedConfigGenerator;\n};\n"]}
1
+ {"version":3,"file":"joined-config.js","sourceRoot":"","sources":["../../../src/config/joined-config.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n AutocaptureOptions,\n type ElementInteractionsOptions,\n BrowserConfig,\n RemoteConfig,\n} from '@amplitude/analytics-core';\n\nexport interface AutocaptureOptionsRemoteConfig extends AutocaptureOptions {\n elementInteractions?: boolean | ElementInteractionsOptionsRemoteConfig;\n}\nexport interface ElementInteractionsOptionsRemoteConfig extends ElementInteractionsOptions {\n /**\n * Related to pageUrlAllowlist but holds regex strings which will be initialized and appended to pageUrlAllowlist\n */\n pageUrlAllowlistRegex?: string[];\n}\n\n// Type alias for the remote config structure we expect (this is what comes from the filtered browserSDK config)\ntype RemoteConfigBrowserSDK = {\n autocapture?: AutocaptureOptionsRemoteConfig | boolean;\n};\n\n/**\n * Performs a deep transformation of a remote config object so that\n * it matches the expected schema of the local config.\n *\n * Specifically, it normalizes nested `enabled` flags into concise union types.\n *\n * ### Transformation Rules:\n * - If an object has `enabled: true`, it is replaced by the same object without the `enabled` field.\n * - If it has only `enabled: true`, it is replaced with `true`.\n * - If it has `enabled: false`, it is replaced with `false` regardless of other fields.\n *\n * ### Examples:\n * Input: { prop: { enabled: true, hello: 'world' }}\n * Output: { prop: { hello: 'world' } }\n *\n * Input: { prop: { enabled: true }}\n * Output: { prop: true }\n *\n * Input: { prop: { enabled: false, hello: 'world' }}\n * Output: { prop: false }\n *\n * Input: { prop: { hello: 'world' }}\n * Output: { prop: { hello: 'world' } } // No change\n *\n * @param config Remote config object to be transformed\n * @returns Transformed config object compatible with local schema\n */\nexport function translateRemoteConfigToLocal(config?: Record<string, any>) {\n // Disabling type checking rules because remote config comes from a remote source\n // and this function needs to handle any unexpected values\n /* eslint-disable @typescript-eslint/no-unsafe-member-access,\n @typescript-eslint/no-unsafe-assignment,\n @typescript-eslint/no-unsafe-argument\n */\n if (typeof config !== 'object' || config === null) {\n return;\n }\n\n // translations are not applied on array properties\n if (Array.isArray(config)) {\n return;\n }\n\n const propertyNames = Object.keys(config);\n for (const propertyName of propertyNames) {\n try {\n const value = config[propertyName];\n // transform objects with { enabled } property to boolean | object\n if (typeof value?.enabled === 'boolean') {\n if (value.enabled) {\n // if enabled is true, set the value to the rest of the object\n // or true if the object has no other properties\n delete value.enabled;\n if (Object.keys(value).length === 0) {\n (config as any)[propertyName] = true;\n }\n } else {\n // If enabled is false, set the value to false\n (config as any)[propertyName] = false;\n }\n }\n\n // recursively translate properties of the value\n translateRemoteConfigToLocal(value as Record<string, any>);\n } catch (e) {\n // a failure here means that an accessor threw an error\n // so don't translate it\n // TODO(diagnostics): add a diagnostic event for this\n }\n }\n}\n\n/**\n * Updates the browser config in place by applying remote configuration settings.\n * Primarily merges autocapture settings from the remote config into the browser config.\n *\n * @param remoteConfig - The remote configuration to apply, or null if none available\n * @param browserConfig - The browser config object to update (modified in place)\n */\nexport function updateBrowserConfigWithRemoteConfig(\n remoteConfig: RemoteConfig | null,\n browserConfig: BrowserConfig,\n): void {\n if (!remoteConfig) {\n return;\n }\n\n // translate remote config to local compatible format\n translateRemoteConfigToLocal(remoteConfig);\n\n try {\n browserConfig.loggerProvider.debug(\n 'Update browser config with remote configuration:',\n JSON.stringify(remoteConfig),\n );\n\n // type cast error will be thrown if remoteConfig is not a valid RemoteConfigBrowserSDK\n // and it will be caught by the try-catch block\n const typedRemoteConfig = remoteConfig as RemoteConfigBrowserSDK;\n\n // merge remoteConfig.autocapture and browserConfig.autocapture\n // if a field is in remoteConfig.autocapture, use that value\n // if a field is not in remoteConfig.autocapture, use the value from browserConfig.autocapture\n if (typedRemoteConfig && 'autocapture' in typedRemoteConfig) {\n if (typeof typedRemoteConfig.autocapture === 'boolean') {\n browserConfig.autocapture = typedRemoteConfig.autocapture;\n }\n\n if (typeof typedRemoteConfig.autocapture === 'object' && typedRemoteConfig.autocapture !== null) {\n const transformedAutocaptureRemoteConfig = { ...typedRemoteConfig.autocapture };\n\n if (browserConfig.autocapture === undefined) {\n browserConfig.autocapture = typedRemoteConfig.autocapture;\n }\n\n // Handle Element Interactions config initialization\n if (\n typeof typedRemoteConfig.autocapture.elementInteractions === 'object' &&\n typedRemoteConfig.autocapture.elementInteractions !== null &&\n typedRemoteConfig.autocapture.elementInteractions.pageUrlAllowlistRegex?.length\n ) {\n transformedAutocaptureRemoteConfig.elementInteractions = {\n ...typedRemoteConfig.autocapture.elementInteractions,\n };\n const transformedRcElementInteractions = transformedAutocaptureRemoteConfig.elementInteractions;\n\n const exactAllowList = transformedRcElementInteractions.pageUrlAllowlist ?? [];\n // Convert string patterns to RegExp objects, warn on invalid patterns and skip them\n const regexList = [];\n for (const pattern of typedRemoteConfig.autocapture.elementInteractions.pageUrlAllowlistRegex) {\n try {\n regexList.push(new RegExp(pattern));\n } catch (regexError) {\n browserConfig.loggerProvider.warn(`Invalid regex pattern: ${pattern}`, regexError);\n }\n }\n\n const combinedPageUrlAllowlist = exactAllowList.concat(regexList);\n\n transformedRcElementInteractions.pageUrlAllowlist = combinedPageUrlAllowlist;\n delete transformedRcElementInteractions.pageUrlAllowlistRegex;\n }\n\n if (typeof browserConfig.autocapture === 'boolean') {\n browserConfig.autocapture = {\n attribution: browserConfig.autocapture,\n fileDownloads: browserConfig.autocapture,\n formInteractions: browserConfig.autocapture,\n pageViews: browserConfig.autocapture,\n sessions: browserConfig.autocapture,\n elementInteractions: browserConfig.autocapture,\n webVitals: browserConfig.autocapture,\n frustrationInteractions: browserConfig.autocapture,\n ...transformedAutocaptureRemoteConfig,\n };\n }\n\n if (typeof browserConfig.autocapture === 'object') {\n browserConfig.autocapture = {\n ...browserConfig.autocapture,\n ...transformedAutocaptureRemoteConfig,\n };\n }\n }\n\n // Override default tracking options if autocapture is updated by remote config\n browserConfig.defaultTracking = browserConfig.autocapture;\n }\n\n browserConfig.loggerProvider.debug('Browser config after remote config update:', JSON.stringify(browserConfig));\n } catch (e) {\n browserConfig.loggerProvider.error('Failed to apply remote configuration because of error: ', e);\n }\n}\n"]}
@@ -31,7 +31,7 @@ export declare class BrowserConfig extends Config implements IBrowserConfig {
31
31
  useBatch: boolean;
32
32
  fetchRemoteConfig: boolean;
33
33
  networkTrackingOptions?: NetworkTrackingOptions | undefined;
34
- readonly version = "2.21.1";
34
+ readonly version = "2.22.1";
35
35
  protected _cookieStorage: Storage<UserSession>;
36
36
  protected _deviceId?: string;
37
37
  protected _lastEventId?: number;
@@ -1,5 +1,4 @@
1
- import { ILogger } from '@amplitude/analytics-core';
2
- import { BrowserStorage } from './browser-storage';
1
+ import { ILogger, BrowserStorage } from '@amplitude/analytics-core';
3
2
  interface LocalStorageOptions {
4
3
  loggerProvider?: ILogger;
5
4
  }
@@ -1 +1 @@
1
- {"version":3,"file":"local-storage.d.ts","sourceRoot":"","sources":["../../../src/storage/local-storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAInD,UAAU,mBAAmB;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AACD,qBAAa,YAAY,CAAC,CAAC,CAAE,SAAQ,cAAc,CAAC,CAAC,CAAC;IACpD,cAAc,CAAC,EAAE,OAAO,CAAC;gBAEb,MAAM,CAAC,EAAE,mBAAmB;IAalC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAWhD"}
1
+ {"version":3,"file":"local-storage.d.ts","sourceRoot":"","sources":["../../../src/storage/local-storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAIpF,UAAU,mBAAmB;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AACD,qBAAa,YAAY,CAAC,CAAC,CAAE,SAAQ,cAAc,CAAC,CAAC,CAAC;IACpD,cAAc,CAAC,EAAE,OAAO,CAAC;gBAEb,MAAM,CAAC,EAAE,mBAAmB;IAalC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAWhD"}
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LocalStorage = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var analytics_core_1 = require("@amplitude/analytics-core");
6
- var browser_storage_1 = require("./browser-storage");
7
6
  var MAX_ARRAY_LENGTH = 1000;
8
7
  var LocalStorage = /** @class */ (function (_super) {
9
8
  tslib_1.__extends(LocalStorage, _super);
@@ -46,6 +45,6 @@ var LocalStorage = /** @class */ (function (_super) {
46
45
  });
47
46
  };
48
47
  return LocalStorage;
49
- }(browser_storage_1.BrowserStorage));
48
+ }(analytics_core_1.BrowserStorage));
50
49
  exports.LocalStorage = LocalStorage;
51
50
  //# sourceMappingURL=local-storage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"local-storage.js","sourceRoot":"","sources":["../../../src/storage/local-storage.ts"],"names":[],"mappings":";;;;AAAA,4DAAoE;AACpE,qDAAmD;AAEnD,IAAM,gBAAgB,GAAG,IAAI,CAAC;AAK9B;IAAqC,wCAAiB;IAGpD,sBAAY,MAA4B;QAAxC,iBAWC;;QAVC,IAAI,YAAY,CAAC;QAEjB,IAAI;YACF,YAAY,GAAG,MAAA,IAAA,+BAAc,GAAE,0CAAE,YAAY,CAAC;SAC/C;QAAC,OAAO,CAAC,EAAE;YACV,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,cAAc,0CAAE,KAAK,CAAC,+CAAwC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC;YAC3F,YAAY,GAAG,SAAS,CAAC;SAC1B;gBACD,kBAAM,YAAY,CAAC;QACnB,KAAI,CAAC,cAAc,GAAG,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,cAAc,CAAC;;IAC/C,CAAC;IAEK,0BAAG,GAAT,UAAU,GAAW,EAAE,KAAQ;;;;;;;6BACzB,CAAA,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,gBAAgB,CAAA,EAAvD,wBAAuD;wBACnD,kBAAkB,GAAG,KAAK,CAAC,MAAM,GAAG,gBAAgB,CAAC;wBAC3D,qBAAM,iBAAM,GAAG,YAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAM,CAAC,EAAA;;wBAA3D,SAA2D,CAAC;wBAC5D,MAAA,IAAI,CAAC,cAAc,0CAAE,KAAK,CACxB,yBAAkB,kBAAkB,uDAA6C,gBAAgB,MAAG,CACrG,CAAC;;4BAEF,qBAAM,iBAAM,GAAG,YAAC,GAAG,EAAE,KAAK,CAAC,EAAA;;wBAA3B,SAA2B,CAAC;;;;;;KAE/B;IACH,mBAAC;AAAD,CAAC,AA3BD,CAAqC,gCAAc,GA2BlD;AA3BY,oCAAY","sourcesContent":["import { getGlobalScope, ILogger } from '@amplitude/analytics-core';\nimport { BrowserStorage } from './browser-storage';\n\nconst MAX_ARRAY_LENGTH = 1000;\n\ninterface LocalStorageOptions {\n loggerProvider?: ILogger;\n}\nexport class LocalStorage<T> extends BrowserStorage<T> {\n loggerProvider?: ILogger;\n\n constructor(config?: LocalStorageOptions) {\n let localStorage;\n\n try {\n localStorage = getGlobalScope()?.localStorage;\n } catch (e) {\n config?.loggerProvider?.debug(`Failed to access localStorage. error=${JSON.stringify(e)}`);\n localStorage = undefined;\n }\n super(localStorage);\n this.loggerProvider = config?.loggerProvider;\n }\n\n async set(key: string, value: T): Promise<void> {\n if (Array.isArray(value) && value.length > MAX_ARRAY_LENGTH) {\n const droppedEventsCount = value.length - MAX_ARRAY_LENGTH;\n await super.set(key, value.slice(0, MAX_ARRAY_LENGTH) as T);\n this.loggerProvider?.error(\n `Failed to save ${droppedEventsCount} events because the queue length exceeded ${MAX_ARRAY_LENGTH}.`,\n );\n } else {\n await super.set(key, value);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"local-storage.js","sourceRoot":"","sources":["../../../src/storage/local-storage.ts"],"names":[],"mappings":";;;;AAAA,4DAAoF;AAEpF,IAAM,gBAAgB,GAAG,IAAI,CAAC;AAK9B;IAAqC,wCAAiB;IAGpD,sBAAY,MAA4B;QAAxC,iBAWC;;QAVC,IAAI,YAAY,CAAC;QAEjB,IAAI;YACF,YAAY,GAAG,MAAA,IAAA,+BAAc,GAAE,0CAAE,YAAY,CAAC;SAC/C;QAAC,OAAO,CAAC,EAAE;YACV,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,cAAc,0CAAE,KAAK,CAAC,+CAAwC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC;YAC3F,YAAY,GAAG,SAAS,CAAC;SAC1B;gBACD,kBAAM,YAAY,CAAC;QACnB,KAAI,CAAC,cAAc,GAAG,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,cAAc,CAAC;;IAC/C,CAAC;IAEK,0BAAG,GAAT,UAAU,GAAW,EAAE,KAAQ;;;;;;;6BACzB,CAAA,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,gBAAgB,CAAA,EAAvD,wBAAuD;wBACnD,kBAAkB,GAAG,KAAK,CAAC,MAAM,GAAG,gBAAgB,CAAC;wBAC3D,qBAAM,iBAAM,GAAG,YAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAM,CAAC,EAAA;;wBAA3D,SAA2D,CAAC;wBAC5D,MAAA,IAAI,CAAC,cAAc,0CAAE,KAAK,CACxB,yBAAkB,kBAAkB,uDAA6C,gBAAgB,MAAG,CACrG,CAAC;;4BAEF,qBAAM,iBAAM,GAAG,YAAC,GAAG,EAAE,KAAK,CAAC,EAAA;;wBAA3B,SAA2B,CAAC;;;;;;KAE/B;IACH,mBAAC;AAAD,CAAC,AA3BD,CAAqC,+BAAc,GA2BlD;AA3BY,oCAAY","sourcesContent":["import { getGlobalScope, ILogger, BrowserStorage } from '@amplitude/analytics-core';\n\nconst MAX_ARRAY_LENGTH = 1000;\n\ninterface LocalStorageOptions {\n loggerProvider?: ILogger;\n}\nexport class LocalStorage<T> extends BrowserStorage<T> {\n loggerProvider?: ILogger;\n\n constructor(config?: LocalStorageOptions) {\n let localStorage;\n\n try {\n localStorage = getGlobalScope()?.localStorage;\n } catch (e) {\n config?.loggerProvider?.debug(`Failed to access localStorage. error=${JSON.stringify(e)}`);\n localStorage = undefined;\n }\n super(localStorage);\n this.loggerProvider = config?.loggerProvider;\n }\n\n async set(key: string, value: T): Promise<void> {\n if (Array.isArray(value) && value.length > MAX_ARRAY_LENGTH) {\n const droppedEventsCount = value.length - MAX_ARRAY_LENGTH;\n await super.set(key, value.slice(0, MAX_ARRAY_LENGTH) as T);\n this.loggerProvider?.error(\n `Failed to save ${droppedEventsCount} events because the queue length exceeded ${MAX_ARRAY_LENGTH}.`,\n );\n } else {\n await super.set(key, value);\n }\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { BrowserStorage } from './browser-storage';
1
+ import { BrowserStorage } from '@amplitude/analytics-core';
2
2
  export declare class SessionStorage<T> extends BrowserStorage<T> {
3
3
  constructor();
4
4
  }
@@ -1 +1 @@
1
- {"version":3,"file":"session-storage.d.ts","sourceRoot":"","sources":["../../../src/storage/session-storage.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,qBAAa,cAAc,CAAC,CAAC,CAAE,SAAQ,cAAc,CAAC,CAAC,CAAC;;CAIvD"}
1
+ {"version":3,"file":"session-storage.d.ts","sourceRoot":"","sources":["../../../src/storage/session-storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3E,qBAAa,cAAc,CAAC,CAAC,CAAE,SAAQ,cAAc,CAAC,CAAC,CAAC;;CAIvD"}
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SessionStorage = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var analytics_core_1 = require("@amplitude/analytics-core");
6
- var browser_storage_1 = require("./browser-storage");
7
6
  var SessionStorage = /** @class */ (function (_super) {
8
7
  tslib_1.__extends(SessionStorage, _super);
9
8
  function SessionStorage() {
@@ -11,6 +10,6 @@ var SessionStorage = /** @class */ (function (_super) {
11
10
  return _super.call(this, (_a = (0, analytics_core_1.getGlobalScope)()) === null || _a === void 0 ? void 0 : _a.sessionStorage) || this;
12
11
  }
13
12
  return SessionStorage;
14
- }(browser_storage_1.BrowserStorage));
13
+ }(analytics_core_1.BrowserStorage));
15
14
  exports.SessionStorage = SessionStorage;
16
15
  //# sourceMappingURL=session-storage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-storage.js","sourceRoot":"","sources":["../../../src/storage/session-storage.ts"],"names":[],"mappings":";;;;AAAA,4DAA2D;AAC3D,qDAAmD;AAEnD;IAAuC,0CAAiB;IACtD;;eACE,kBAAM,MAAA,IAAA,+BAAc,GAAE,0CAAE,cAAc,CAAC;IACzC,CAAC;IACH,qBAAC;AAAD,CAAC,AAJD,CAAuC,gCAAc,GAIpD;AAJY,wCAAc","sourcesContent":["import { getGlobalScope } from '@amplitude/analytics-core';\nimport { BrowserStorage } from './browser-storage';\n\nexport class SessionStorage<T> extends BrowserStorage<T> {\n constructor() {\n super(getGlobalScope()?.sessionStorage);\n }\n}\n"]}
1
+ {"version":3,"file":"session-storage.js","sourceRoot":"","sources":["../../../src/storage/session-storage.ts"],"names":[],"mappings":";;;;AAAA,4DAA2E;AAE3E;IAAuC,0CAAiB;IACtD;;eACE,kBAAM,MAAA,IAAA,+BAAc,GAAE,0CAAE,cAAc,CAAC;IACzC,CAAC;IACH,qBAAC;AAAD,CAAC,AAJD,CAAuC,+BAAc,GAIpD;AAJY,wCAAc","sourcesContent":["import { getGlobalScope, BrowserStorage } from '@amplitude/analytics-core';\n\nexport class SessionStorage<T> extends BrowserStorage<T> {\n constructor() {\n super(getGlobalScope()?.sessionStorage);\n }\n}\n"]}
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "2.21.1";
1
+ export declare const VERSION = "2.22.1";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VERSION = void 0;
4
- exports.VERSION = '2.21.1';
4
+ exports.VERSION = '2.22.1';
5
5
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":";;;AAAa,QAAA,OAAO,GAAG,QAAQ,CAAC","sourcesContent":["export const VERSION = '2.21.1';\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":";;;AAAa,QAAA,OAAO,GAAG,QAAQ,CAAC","sourcesContent":["export const VERSION = '2.22.1';\n"]}
@@ -1,4 +1,4 @@
1
- import { AmplitudeCore, Event, EventOptions, IIdentify, IRevenue, TransportType, Result, BrowserOptions, BrowserConfig, BrowserClient, AnalyticsClient } from '@amplitude/analytics-core';
1
+ import { AmplitudeCore, Event, EventOptions, IIdentify, IRevenue, TransportType, Result, BrowserOptions, BrowserConfig, BrowserClient, AnalyticsClient, IRemoteConfigClient } from '@amplitude/analytics-core';
2
2
  import { WebAttribution } from './attribution/web-attribution';
3
3
  /**
4
4
  * Exported for `@amplitude/unified` or integration with blade plugins.
@@ -12,6 +12,7 @@ export declare class AmplitudeBrowser extends AmplitudeCore implements BrowserCl
12
12
  userProperties: {
13
13
  [key: string]: any;
14
14
  } | undefined;
15
+ remoteConfigClient: IRemoteConfigClient | undefined;
15
16
  init(apiKey?: string, userIdOrOptions?: string | BrowserOptions, maybeOptions?: BrowserOptions): import("@amplitude/analytics-core").AmplitudeReturn<void>;
16
17
  protected _init(options: BrowserOptions & {
17
18
  apiKey: string;
@@ -1 +1 @@
1
- {"version":3,"file":"browser-client.d.ts","sourceRoot":"","sources":["../../src/browser-client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EAYb,KAAK,EACL,YAAY,EACZ,SAAS,EACT,QAAQ,EACR,aAAa,EAEb,MAAM,EACN,cAAc,EACd,aAAa,EACb,aAAa,EAEb,eAAe,EAChB,MAAM,2BAA2B,CAAC;AA8BnC,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,aAAc,YAAW,aAAa,EAAE,eAAe;IAG3F,MAAM,EAAE,aAAa,CAAC;IACtB,uBAAuB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5C,qBAAqB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,cAAc,EAAE,cAAc,GAAG,SAAS,CAAC;IAC3C,cAAc,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,GAAG,SAAS,CAAC;IAEnD,IAAI,CAAC,MAAM,SAAK,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,cAAc,EAAE,YAAY,CAAC,EAAE,cAAc;cAkB1E,KAAK,CAAC,OAAO,EAAE,cAAc,GAAG;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE;IA8GlE,SAAS;IAIT,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS;IAcpC,WAAW;IAIX,WAAW,CAAC,QAAQ,EAAE,MAAM;IAc5B,KAAK;IAKL,WAAW;;;;;;;IAQX,SAAS,IAAI,OAAO,GAAG,SAAS;IAIhC,YAAY;IAIZ,YAAY,CAAC,SAAS,EAAE,MAAM;IA6D9B,aAAa;IAQb,YAAY,CAAC,SAAS,EAAE,aAAa;IAQrC,QAAQ,CAAC,QAAQ,EAAE,SAAS,EAAE,YAAY,CAAC,EAAE,YAAY;IAezD,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,CAAC,EAAE,YAAY;IAS/G,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,CAAC,EAAE,YAAY;IAStD,OAAO,CAAC,0BAA0B;IAe5B,OAAO,CAAC,KAAK,EAAE,KAAK;IA+B1B,OAAO,CAAC,iBAAiB;CAY1B"}
1
+ {"version":3,"file":"browser-client.d.ts","sourceRoot":"","sources":["../../src/browser-client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EAYb,KAAK,EACL,YAAY,EACZ,SAAS,EACT,QAAQ,EACR,aAAa,EAEb,MAAM,EACN,cAAc,EACd,aAAa,EACb,aAAa,EAEb,eAAe,EACf,mBAAmB,EAIpB,MAAM,2BAA2B,CAAC;AA8BnC,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,aAAc,YAAW,aAAa,EAAE,eAAe;IAG3F,MAAM,EAAE,aAAa,CAAC;IACtB,uBAAuB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5C,qBAAqB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,cAAc,EAAE,cAAc,GAAG,SAAS,CAAC;IAC3C,cAAc,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,GAAG,SAAS,CAAC;IACnD,kBAAkB,EAAE,mBAAmB,GAAG,SAAS,CAAC;IAEpD,IAAI,CAAC,MAAM,SAAK,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,cAAc,EAAE,YAAY,CAAC,EAAE,cAAc;cAkB1E,KAAK,CAAC,OAAO,EAAE,cAAc,GAAG;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE;IAmJlE,SAAS;IAIT,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS;IAcpC,WAAW;IAIX,WAAW,CAAC,QAAQ,EAAE,MAAM;IAc5B,KAAK;IAKL,WAAW;;;;;;;IAQX,SAAS,IAAI,OAAO,GAAG,SAAS;IAIhC,YAAY;IAIZ,YAAY,CAAC,SAAS,EAAE,MAAM;IA6D9B,aAAa;IAQb,YAAY,CAAC,SAAS,EAAE,aAAa;IAQrC,QAAQ,CAAC,QAAQ,EAAE,SAAS,EAAE,YAAY,CAAC,EAAE,YAAY;IAezD,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,CAAC,EAAE,YAAY;IAS/G,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,CAAC,EAAE,YAAY;IAStD,OAAO,CAAC,0BAA0B;IAe5B,OAAO,CAAC,KAAK,EAAE,KAAK;IA+B1B,OAAO,CAAC,iBAAiB;CAY1B"}