@v-tilt/browser 1.0.11 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,70 +20,69 @@ exports.getTimezoneOffset = getTimezoneOffset;
20
20
  exports.getEventProperties = getEventProperties;
21
21
  const request_utils_1 = require("./request-utils");
22
22
  const index_1 = require("./index");
23
- const index_2 = require("./index");
24
23
  const globals_1 = require("./globals");
25
24
  const user_agent_utils_1 = require("./user-agent-utils");
26
- const URL_REGEX_PREFIX = 'https?://(.*)';
25
+ const URL_REGEX_PREFIX = "https?://(.*)";
27
26
  // Library version - should match package.json version
28
- const LIB_VERSION = '1.0.7'; // TODO: Auto-import from package.json
27
+ const LIB_VERSION = "1.0.7"; // TODO: Auto-import from package.json
29
28
  // Campaign parameters that could be considered personal data (e.g., GDPR)
30
29
  // These can be masked in URLs and properties before being sent
31
30
  exports.PERSONAL_DATA_CAMPAIGN_PARAMS = [
32
- 'gclid', // google ads
33
- 'gclsrc', // google ads 360
34
- 'dclid', // google display ads
35
- 'gbraid', // google ads, web to app
36
- 'wbraid', // google ads, app to web
37
- 'fbclid', // facebook
38
- 'msclkid', // microsoft
39
- 'twclid', // twitter
40
- 'li_fat_id', // linkedin
41
- 'igshid', // instagram
42
- 'ttclid', // tiktok
43
- 'rdt_cid', // reddit
44
- 'epik', // pinterest
45
- 'qclid', // quora
46
- 'sccid', // snapchat
47
- 'irclid', // impact
48
- '_kx', // klaviyo
31
+ "gclid", // google ads
32
+ "gclsrc", // google ads 360
33
+ "dclid", // google display ads
34
+ "gbraid", // google ads, web to app
35
+ "wbraid", // google ads, app to web
36
+ "fbclid", // facebook
37
+ "msclkid", // microsoft
38
+ "twclid", // twitter
39
+ "li_fat_id", // linkedin
40
+ "igshid", // instagram
41
+ "ttclid", // tiktok
42
+ "rdt_cid", // reddit
43
+ "epik", // pinterest
44
+ "qclid", // quora
45
+ "sccid", // snapchat
46
+ "irclid", // impact
47
+ "_kx", // klaviyo
49
48
  ];
50
- exports.CAMPAIGN_PARAMS = (0, index_2.extendArray)([
51
- 'utm_source',
52
- 'utm_medium',
53
- 'utm_campaign',
54
- 'utm_content',
55
- 'utm_term',
56
- 'gad_source', // google ads source
57
- 'mc_cid', // mailchimp campaign id
49
+ exports.CAMPAIGN_PARAMS = (0, index_1.extendArray)([
50
+ "utm_source",
51
+ "utm_medium",
52
+ "utm_campaign",
53
+ "utm_content",
54
+ "utm_term",
55
+ "gad_source", // google ads source
56
+ "mc_cid", // mailchimp campaign id
58
57
  ], exports.PERSONAL_DATA_CAMPAIGN_PARAMS);
59
58
  // Properties that should be automatically copied from events to person properties
60
59
  exports.EVENT_TO_PERSON_PROPERTIES = [
61
60
  // Mobile app properties
62
- '$app_build',
63
- '$app_name',
64
- '$app_namespace',
65
- '$app_version',
61
+ "$app_build",
62
+ "$app_name",
63
+ "$app_namespace",
64
+ "$app_version",
66
65
  // Web browser properties
67
- '$browser',
68
- '$browser_version',
69
- '$device_type',
70
- '$current_url',
71
- '$pathname',
72
- '$os',
73
- '$os_name', // Special case: treated as alias of $os
74
- '$os_version',
75
- '$referring_domain',
76
- '$referrer',
77
- '$screen_height',
78
- '$screen_width',
79
- '$viewport_height',
80
- '$viewport_width',
81
- '$raw_user_agent',
66
+ "$browser",
67
+ "$browser_version",
68
+ "$device_type",
69
+ "$current_url",
70
+ "$pathname",
71
+ "$os",
72
+ "$os_name", // Special case: treated as alias of $os
73
+ "$os_version",
74
+ "$referring_domain",
75
+ "$referrer",
76
+ "$screen_height",
77
+ "$screen_width",
78
+ "$viewport_height",
79
+ "$viewport_width",
80
+ "$raw_user_agent",
82
81
  ];
83
- exports.MASKED = '<masked>';
82
+ exports.MASKED = "<masked>";
84
83
  // Campaign params that can be read from cookies (currently not implemented)
85
84
  exports.COOKIE_CAMPAIGN_PARAMS = [
86
- 'li_fat_id', // linkedin
85
+ "li_fat_id", // linkedin
87
86
  ];
88
87
  /**
89
88
  * Get campaign parameters from URL
@@ -95,7 +94,7 @@ function getCampaignParams(customTrackedParams, maskPersonalDataProperties, cust
95
94
  return {};
96
95
  }
97
96
  const paramsToMask = maskPersonalDataProperties
98
- ? (0, index_2.extendArray)([], exports.PERSONAL_DATA_CAMPAIGN_PARAMS, customPersonalDataProperties || [])
97
+ ? (0, index_1.extendArray)([], exports.PERSONAL_DATA_CAMPAIGN_PARAMS, customPersonalDataProperties || [])
99
98
  : [];
100
99
  // Initially get campaign params from the URL
101
100
  const urlCampaignParams = _getCampaignParamsFromUrl((0, request_utils_1.maskQueryParams)(globals_1.document.URL, paramsToMask, exports.MASKED), customTrackedParams);
@@ -104,12 +103,12 @@ function getCampaignParams(customTrackedParams, maskPersonalDataProperties, cust
104
103
  const cookieCampaignParams = {};
105
104
  // Prefer the values found in the urlCampaignParams if possible
106
105
  // `extend` will override the values if found in the second argument
107
- return (0, index_2.extend)(cookieCampaignParams, urlCampaignParams);
106
+ return (0, index_1.extend)(cookieCampaignParams, urlCampaignParams);
108
107
  }
109
108
  function _getCampaignParamsFromUrl(url, customParams) {
110
109
  const campaign_keywords = exports.CAMPAIGN_PARAMS.concat(customParams || []);
111
110
  const params = {};
112
- (0, index_2.each)(campaign_keywords, function (kwkey) {
111
+ (0, index_1.each)(campaign_keywords, function (kwkey) {
113
112
  const kw = (0, request_utils_1.getQueryParam)(url, kwkey);
114
113
  params[kwkey] = kw ? kw : null;
115
114
  });
@@ -120,17 +119,17 @@ function _getSearchEngine(referrer) {
120
119
  return null;
121
120
  }
122
121
  else {
123
- if (referrer.search(URL_REGEX_PREFIX + 'google.([^/?]*)') === 0) {
124
- return 'google';
122
+ if (referrer.search(URL_REGEX_PREFIX + "google.([^/?]*)") === 0) {
123
+ return "google";
125
124
  }
126
- else if (referrer.search(URL_REGEX_PREFIX + 'bing.com') === 0) {
127
- return 'bing';
125
+ else if (referrer.search(URL_REGEX_PREFIX + "bing.com") === 0) {
126
+ return "bing";
128
127
  }
129
- else if (referrer.search(URL_REGEX_PREFIX + 'yahoo.com') === 0) {
130
- return 'yahoo';
128
+ else if (referrer.search(URL_REGEX_PREFIX + "yahoo.com") === 0) {
129
+ return "yahoo";
131
130
  }
132
- else if (referrer.search(URL_REGEX_PREFIX + 'duckduckgo.com') === 0) {
133
- return 'duckduckgo';
131
+ else if (referrer.search(URL_REGEX_PREFIX + "duckduckgo.com") === 0) {
132
+ return "duckduckgo";
134
133
  }
135
134
  else {
136
135
  return null;
@@ -139,13 +138,13 @@ function _getSearchEngine(referrer) {
139
138
  }
140
139
  function _getSearchInfoFromReferrer(referrer) {
141
140
  const search = _getSearchEngine(referrer);
142
- const param = search != 'yahoo' ? 'q' : 'p';
141
+ const param = search !== "yahoo" ? "q" : "p";
143
142
  const ret = {};
144
143
  if (!(0, index_1.isNull)(search)) {
145
- ret['$search_engine'] = search;
146
- const keyword = globals_1.document ? (0, request_utils_1.getQueryParam)(globals_1.document.referrer, param) : '';
144
+ ret["$search_engine"] = search;
145
+ const keyword = globals_1.document ? (0, request_utils_1.getQueryParam)(globals_1.document.referrer, param) : "";
147
146
  if (keyword.length) {
148
- ret['ph_keyword'] = keyword;
147
+ ret["ph_keyword"] = keyword;
149
148
  }
150
149
  }
151
150
  return ret;
@@ -158,7 +157,7 @@ function getSearchInfo() {
158
157
  return _getSearchInfoFromReferrer(referrer);
159
158
  }
160
159
  function getBrowserLanguage() {
161
- if (typeof navigator === 'undefined') {
160
+ if (typeof navigator === "undefined") {
162
161
  return undefined;
163
162
  }
164
163
  return (navigator.language || // Any modern browser
@@ -167,17 +166,17 @@ function getBrowserLanguage() {
167
166
  }
168
167
  function getBrowserLanguagePrefix() {
169
168
  const lang = getBrowserLanguage();
170
- return typeof lang === 'string' ? lang.split('-')[0] : undefined;
169
+ return typeof lang === "string" ? lang.split("-")[0] : undefined;
171
170
  }
172
171
  function getReferrer() {
173
- return (globals_1.document === null || globals_1.document === void 0 ? void 0 : globals_1.document.referrer) || '$direct';
172
+ return (globals_1.document === null || globals_1.document === void 0 ? void 0 : globals_1.document.referrer) || "$direct";
174
173
  }
175
174
  function getReferringDomain() {
176
175
  var _a;
177
176
  if (!(globals_1.document === null || globals_1.document === void 0 ? void 0 : globals_1.document.referrer)) {
178
- return '$direct';
177
+ return "$direct";
179
178
  }
180
- return ((_a = (0, request_utils_1.convertToURL)(globals_1.document.referrer)) === null || _a === void 0 ? void 0 : _a.host) || '$direct';
179
+ return ((_a = (0, request_utils_1.convertToURL)(globals_1.document.referrer)) === null || _a === void 0 ? void 0 : _a.host) || "$direct";
181
180
  }
182
181
  /**
183
182
  * Get referrer information
@@ -196,7 +195,7 @@ function getReferrerInfo() {
196
195
  */
197
196
  function getPersonInfo(maskPersonalDataProperties, customPersonalDataProperties) {
198
197
  const paramsToMask = maskPersonalDataProperties
199
- ? (0, index_2.extendArray)([], exports.PERSONAL_DATA_CAMPAIGN_PARAMS, customPersonalDataProperties || [])
198
+ ? (0, index_1.extendArray)([], exports.PERSONAL_DATA_CAMPAIGN_PARAMS, customPersonalDataProperties || [])
200
199
  : [];
201
200
  const url = globals_1.location === null || globals_1.location === void 0 ? void 0 : globals_1.location.href.substring(0, 1000);
202
201
  // Compact format for storage efficiency (stored in localStorage)
@@ -212,22 +211,26 @@ function getPersonInfo(maskPersonalDataProperties, customPersonalDataProperties)
212
211
  function getPersonPropsFromInfo(info) {
213
212
  var _a;
214
213
  const { r: referrer, u: url } = info;
215
- const referring_domain = referrer == null ? undefined : referrer == '$direct' ? '$direct' : (_a = (0, request_utils_1.convertToURL)(referrer)) === null || _a === void 0 ? void 0 : _a.host;
214
+ const referring_domain = referrer == null
215
+ ? undefined
216
+ : referrer === "$direct"
217
+ ? "$direct"
218
+ : (_a = (0, request_utils_1.convertToURL)(referrer)) === null || _a === void 0 ? void 0 : _a.host;
216
219
  const props = {
217
220
  $referrer: referrer,
218
221
  $referring_domain: referring_domain,
219
222
  };
220
223
  if (url) {
221
- props['$current_url'] = url;
224
+ props["$current_url"] = url;
222
225
  const location = (0, request_utils_1.convertToURL)(url);
223
- props['$host'] = location === null || location === void 0 ? void 0 : location.host;
224
- props['$pathname'] = location === null || location === void 0 ? void 0 : location.pathname;
226
+ props["$host"] = location === null || location === void 0 ? void 0 : location.host;
227
+ props["$pathname"] = location === null || location === void 0 ? void 0 : location.pathname;
225
228
  const campaignParams = _getCampaignParamsFromUrl(url);
226
- (0, index_2.extend)(props, campaignParams);
229
+ (0, index_1.extend)(props, campaignParams);
227
230
  }
228
231
  if (referrer) {
229
232
  const searchInfo = _getSearchInfoFromReferrer(referrer);
230
- (0, index_2.extend)(props, searchInfo);
233
+ (0, index_1.extend)(props, searchInfo);
231
234
  }
232
235
  return props;
233
236
  }
@@ -238,7 +241,7 @@ function getPersonPropsFromInfo(info) {
238
241
  function getInitialPersonPropsFromInfo(info) {
239
242
  const personProps = getPersonPropsFromInfo(info);
240
243
  const props = {};
241
- (0, index_2.each)(personProps, function (val, key) {
244
+ (0, index_1.each)(personProps, function (val, key) {
242
245
  props[`$initial_${(0, index_1.stripLeadingDollar)(String(key))}`] = val;
243
246
  });
244
247
  return props;
@@ -269,10 +272,10 @@ function getEventProperties(maskPersonalDataProperties, customPersonalDataProper
269
272
  return {};
270
273
  }
271
274
  const paramsToMask = maskPersonalDataProperties
272
- ? (0, index_2.extendArray)([], exports.PERSONAL_DATA_CAMPAIGN_PARAMS, customPersonalDataProperties || [])
275
+ ? (0, index_1.extendArray)([], exports.PERSONAL_DATA_CAMPAIGN_PARAMS, customPersonalDataProperties || [])
273
276
  : [];
274
277
  const [os_name, os_version] = (0, user_agent_utils_1.detectOS)(globals_1.userAgent);
275
- return (0, index_2.extend)((0, index_2.stripEmptyProperties)({
278
+ return (0, index_1.extend)((0, index_1.stripEmptyProperties)({
276
279
  $os: os_name,
277
280
  $os_version: os_version,
278
281
  $browser: (0, user_agent_utils_1.detectBrowser)(globals_1.userAgent, navigator.vendor),
@@ -284,7 +287,9 @@ function getEventProperties(maskPersonalDataProperties, customPersonalDataProper
284
287
  $current_url: (0, request_utils_1.maskQueryParams)(globals_1.location === null || globals_1.location === void 0 ? void 0 : globals_1.location.href, paramsToMask, exports.MASKED),
285
288
  $host: globals_1.location === null || globals_1.location === void 0 ? void 0 : globals_1.location.host,
286
289
  $pathname: globals_1.location === null || globals_1.location === void 0 ? void 0 : globals_1.location.pathname,
287
- $raw_user_agent: globals_1.userAgent.length > 1000 ? globals_1.userAgent.substring(0, 997) + '...' : globals_1.userAgent,
290
+ $raw_user_agent: globals_1.userAgent.length > 1000
291
+ ? globals_1.userAgent.substring(0, 997) + "..."
292
+ : globals_1.userAgent,
288
293
  $browser_version: (0, user_agent_utils_1.detectBrowserVersion)(globals_1.userAgent, navigator.vendor),
289
294
  $browser_language: getBrowserLanguage(),
290
295
  $browser_language_prefix: getBrowserLanguagePrefix(),
@@ -292,9 +297,10 @@ function getEventProperties(maskPersonalDataProperties, customPersonalDataProper
292
297
  $screen_width: globals_1.window === null || globals_1.window === void 0 ? void 0 : globals_1.window.screen.width,
293
298
  $viewport_height: globals_1.window === null || globals_1.window === void 0 ? void 0 : globals_1.window.innerHeight,
294
299
  $viewport_width: globals_1.window === null || globals_1.window === void 0 ? void 0 : globals_1.window.innerWidth,
295
- $lib: 'web',
300
+ $lib: "web",
296
301
  $lib_version: LIB_VERSION,
297
- $insert_id: Math.random().toString(36).substring(2, 10) + Math.random().toString(36).substring(2, 10),
302
+ $insert_id: Math.random().toString(36).substring(2, 10) +
303
+ Math.random().toString(36).substring(2, 10),
298
304
  $time: Date.now() / 1000, // epoch time in seconds
299
305
  });
300
306
  }
@@ -113,7 +113,7 @@ function stripEmptyProperties(obj) {
113
113
  for (const key in obj) {
114
114
  if (Object.prototype.hasOwnProperty.call(obj, key)) {
115
115
  const value = obj[key];
116
- if (value !== null && value !== undefined && value !== '') {
116
+ if (value !== null && value !== undefined && value !== "") {
117
117
  result[key] = value;
118
118
  }
119
119
  }
@@ -124,7 +124,7 @@ function stripEmptyProperties(obj) {
124
124
  * Strip leading dollar sign from string
125
125
  */
126
126
  function stripLeadingDollar(str) {
127
- return str.startsWith('$') ? str.substring(1) : str;
127
+ return str.startsWith("$") ? str.substring(1) : str;
128
128
  }
129
129
  /**
130
130
  * Check if value is null
@@ -16,7 +16,7 @@ function convertToURL(url) {
16
16
  if (!globals_1.document) {
17
17
  return null;
18
18
  }
19
- const anchor = globals_1.document.createElement('a');
19
+ const anchor = globals_1.document.createElement("a");
20
20
  anchor.href = url;
21
21
  return anchor;
22
22
  }
@@ -24,15 +24,15 @@ function convertToURL(url) {
24
24
  * Get query parameter from URL
25
25
  */
26
26
  function getQueryParam(url, param) {
27
- const withoutHash = url.split('#')[0] || '';
28
- const queryParams = withoutHash.split(/\?(.*)/)[1] || '';
29
- const cleanedQueryParams = queryParams.replace(/^\?+/g, '');
30
- const queryParts = cleanedQueryParams.split('&');
27
+ const withoutHash = url.split("#")[0] || "";
28
+ const queryParams = withoutHash.split(/\?(.*)/)[1] || "";
29
+ const cleanedQueryParams = queryParams.replace(/^\?+/g, "");
30
+ const queryParts = cleanedQueryParams.split("&");
31
31
  for (let i = 0; i < queryParts.length; i++) {
32
- const parts = queryParts[i].split('=');
32
+ const parts = queryParts[i].split("=");
33
33
  if (parts[0] === param) {
34
34
  if (parts.length < 2) {
35
- return '';
35
+ return "";
36
36
  }
37
37
  let result = parts[1];
38
38
  try {
@@ -41,10 +41,10 @@ function getQueryParam(url, param) {
41
41
  catch (_a) {
42
42
  // Skip decoding for malformed query param
43
43
  }
44
- return result.replace(/\+/g, ' ');
44
+ return result.replace(/\+/g, " ");
45
45
  }
46
46
  }
47
- return '';
47
+ return "";
48
48
  }
49
49
  /**
50
50
  * Mask query parameters in URL
@@ -53,26 +53,28 @@ function maskQueryParams(url, maskedParams, mask) {
53
53
  if (!url || !maskedParams || !maskedParams.length) {
54
54
  return url;
55
55
  }
56
- const splitHash = url.split('#');
57
- const withoutHash = splitHash[0] || '';
56
+ const splitHash = url.split("#");
57
+ const withoutHash = splitHash[0] || "";
58
58
  const hash = splitHash[1];
59
- const splitQuery = withoutHash.split('?');
59
+ const splitQuery = withoutHash.split("?");
60
60
  const queryString = splitQuery[1];
61
61
  const urlWithoutQueryAndHash = splitQuery[0];
62
- const queryParts = (queryString || '').split('&');
62
+ const queryParts = (queryString || "").split("&");
63
63
  const paramStrings = [];
64
64
  for (let i = 0; i < queryParts.length; i++) {
65
- const parts = queryParts[i].split('=');
65
+ const parts = queryParts[i].split("=");
66
66
  const key = parts[0];
67
- const value = parts.slice(1).join('=');
67
+ const value = parts.slice(1).join("=");
68
68
  if (maskedParams.indexOf(key) !== -1) {
69
- paramStrings.push(key + '=' + mask);
69
+ paramStrings.push(key + "=" + mask);
70
70
  }
71
71
  else if (key) {
72
- paramStrings.push(key + (value ? '=' + value : ''));
72
+ paramStrings.push(key + (value ? "=" + value : ""));
73
73
  }
74
74
  }
75
- const newQueryString = paramStrings.join('&');
76
- const newUrl = urlWithoutQueryAndHash + (newQueryString ? '?' + newQueryString : '') + (hash ? '#' + hash : '');
75
+ const newQueryString = paramStrings.join("&");
76
+ const newUrl = urlWithoutQueryAndHash +
77
+ (newQueryString ? "?" + newQueryString : "") +
78
+ (hash ? "#" + hash : "");
77
79
  return newUrl;
78
80
  }
package/lib/vtilt.d.ts CHANGED
@@ -1,20 +1,21 @@
1
1
  import { VTiltConfig, EventPayload } from "./types";
2
2
  import { HistoryAutocapture } from "./extensions/history-autocapture";
3
- interface QueuedRequest {
4
- url: string;
5
- event: any;
6
- }
3
+ import { type QueuedRequest } from "./request-queue";
7
4
  export declare class VTilt {
8
5
  private configManager;
9
6
  private sessionManager;
10
7
  private userManager;
11
8
  private webVitalsManager;
9
+ private requestQueue;
10
+ private retryQueue;
11
+ private rateLimiter;
12
12
  historyAutocapture?: HistoryAutocapture;
13
13
  __loaded: boolean;
14
14
  private _initialPageviewCaptured;
15
15
  private _visibilityStateListener;
16
16
  __request_queue: QueuedRequest[];
17
17
  private _hasWarnedAboutConfig;
18
+ private _setOncePropertiesSent;
18
19
  constructor(config?: Partial<VTiltConfig>);
19
20
  /**
20
21
  * Initializes a new instance of the VTilt tracking object.
@@ -52,6 +53,11 @@ export declare class VTilt {
52
53
  * This internal method should only be called by `init()`.
53
54
  */
54
55
  private _init;
56
+ /**
57
+ * Set up handler to flush event queue on page unload
58
+ * Uses both beforeunload and pagehide for maximum compatibility
59
+ */
60
+ private _setupUnloadHandler;
55
61
  /**
56
62
  * Returns a string representation of the instance name
57
63
  * Used for debugging and logging
@@ -77,8 +83,26 @@ export declare class VTilt {
77
83
  /**
78
84
  * Send HTTP request
79
85
  * This is the central entry point for all tracking requests
86
+ * Events are batched and sent every 3 seconds for better performance
80
87
  */
81
88
  private sendRequest;
89
+ /**
90
+ * Send a batched request with multiple events
91
+ * Called by RequestQueue when flushing
92
+ * Uses RetryQueue for automatic retry on failure
93
+ */
94
+ private _sendBatchedRequest;
95
+ /**
96
+ * Send HTTP request and return status code
97
+ * Uses GZip compression for payloads > 1KB
98
+ * Used by RetryQueue for retryable requests
99
+ */
100
+ private _sendHttpRequest;
101
+ /**
102
+ * Send request using sendBeacon for reliable delivery on page unload
103
+ * Uses GZip compression for payloads > 1KB
104
+ */
105
+ private _sendBeaconRequest;
82
106
  /**
83
107
  * Send a queued request (called after DOM is loaded)
84
108
  */
@@ -92,8 +116,16 @@ export declare class VTilt {
92
116
  *
93
117
  * @param name - Event name
94
118
  * @param payload - Event payload
119
+ * @param options - Optional capture options
120
+ */
121
+ capture(name: string, payload: EventPayload, options?: {
122
+ skip_client_rate_limiting?: boolean;
123
+ }): void;
124
+ /**
125
+ * Internal capture method that bypasses rate limiting
126
+ * Used for system events like rate limit warnings
95
127
  */
96
- capture(name: string, payload: EventPayload): void;
128
+ private _captureInternal;
97
129
  /**
98
130
  * Track a custom event (alias for capture)
99
131
  */
@@ -214,7 +246,7 @@ export declare class VTilt {
214
246
  */
215
247
  _execute_array(array: any[]): void;
216
248
  /**
217
- * Called when DOM is loaded - processes queued requests
249
+ * Called when DOM is loaded - processes queued requests and enables batching
218
250
  */
219
251
  _dom_loaded(): void;
220
252
  }
@@ -254,4 +286,3 @@ export declare function init_as_module(): VTilt;
254
286
  * ]
255
287
  */
256
288
  export declare function init_from_snippet(): void;
257
- export {};