@alwaysmeticulous/recorder-loader 2.295.0 → 2.300.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.
package/README.md CHANGED
@@ -17,22 +17,21 @@ pnpm add @alwaysmeticulous/recorder-loader
17
17
  Within your app entrypoint:
18
18
 
19
19
  ```javascript
20
- import { loadAndStartRecorder } from '@alwaysmeticulous/recorder-loader'
20
+ import { loadAndStartRecorder } from "@alwaysmeticulous/recorder-loader";
21
21
 
22
22
  async function startApp() {
23
- // Start the Meticulous recorder before you initialise your app.
24
- try {
25
- await loadAndStartRecorder({
26
- recordingToken: '<recording token>',
27
- })
28
- } catch (err) {
29
- console.error(`Meticulous failed to initialise ${err}`)
30
- }
31
-
32
- // Initalise app after Meticulous' snippet, e.g:
33
- ReactDOM.render(component, document.getElementById('root'))
23
+ // Start the Meticulous recorder before you initialise your app.
24
+ try {
25
+ await loadAndStartRecorder({
26
+ recordingToken: "<recording token>",
27
+ });
28
+ } catch (err) {
29
+ console.error(`Meticulous failed to initialise ${err}`);
30
+ }
31
+
32
+ // Initalise app after Meticulous' snippet, e.g:
33
+ ReactDOM.render(component, document.getElementById("root"));
34
34
  }
35
35
 
36
-
37
36
  startApp();
38
37
  ```
@@ -1 +1 @@
1
- {"mappings":";AEKA;IACE;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IAEvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;;;;;;;OASG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,wBAAwB,EAAE,CAAC;IAEhD;;;;;OAKG;IACH,UAAU,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAElC;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;;;;;;;;;;;;;OAeG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,+BACI;IACE;;;;;;;OAOG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GACD;IACE,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC;AAEN;;GAEG;AACH,qBAA4B,iBAAiB,GAAG,uBAAuB,CAAC;AEnHxE;IACE;;;;;OAKG;IACH,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,OAAO,MAAM,0BACX,SAAS,aAAa,KACrB,OAAO,CAAC,QAAQ,CAqBlB,CAAC;AAuJF;;;;GAIG;AACH,OAAO,MAAM,sTAxIV,aAAa,KAAG,OAAO,CAAC,QAAQ,CAwI2B,CAAC;ACjM/D;IACE,qBAAqB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACrE,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED;IACE;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,MAAM,iCACX,SAAS,kBAAkB,KAC1B,OAAO,CAAC,WAAW,CA4DrB,CAAC;AC9HF;;;;;;;;;;;GAWG;AACH,OAAO,MAAM,qCAMZ,CAAC","sources":["packages/recorder-loader/src/src/constants.ts","packages/recorder-loader/src/src/get-snippet-version-folder.ts","packages/recorder-loader/src/src/loader.types.ts","packages/recorder-loader/src/src/private-window-api.ts","packages/recorder-loader/src/src/loader.ts","packages/recorder-loader/src/src/install-meticulous-intercepts.ts","packages/recorder-loader/src/src/early-network-recorder.ts","packages/recorder-loader/src/src/index.ts","packages/recorder-loader/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,"export { loadAndStartRecorder, tryLoadAndStartRecorder } from \"./loader\";\nexport { tryInstallMeticulousIntercepts } from \"./install-meticulous-intercepts\";\nexport { stopIntercepting } from \"./early-network-recorder\";\n"],"names":[],"version":3,"file":"index.d.ts.map"}
1
+ {"mappings":";AEKA;IACE;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IAEvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;;;;;;;OASG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,wBAAwB,EAAE,CAAC;IAEhD;;;;;OAKG;IACH,UAAU,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAElC;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;;;;;;;;;;;;;OAeG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,+BACI;IACE;;;;;;;OAOG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GACD;IACE,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC;AAEN;;GAEG;AACH,qBAA4B,iBAAiB,GAAG,uBAAuB,CAAC;AEnHxE;IACE;;;;;OAKG;IACH,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,OAAO,MAAM,mCACF,aAAa,KACrB,OAAO,CAAC,QAAQ,CAqBlB,CAAC;AAuJF;;;;GAIG;AACH,OAAO,MAAM,sTAxIV,aAAa,KAAG,OAAO,CAAC,QAAQ,CAwI2B,CAAC;AChM/D;IACE,qBAAqB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACrE,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED;IACE;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,MAAM,0CACF,kBAAkB,KAC1B,OAAO,CAAC,WAAW,CA8DrB,CAAC;ACjIF;;;;;;;;;;;GAWG;AACH,OAAO,MAAM,qCAMZ,CAAC","sources":["public_packages/recorder-loader/src/src/constants.ts","public_packages/recorder-loader/src/src/get-snippet-version-folder.ts","public_packages/recorder-loader/src/src/loader.types.ts","public_packages/recorder-loader/src/src/private-window-api.ts","public_packages/recorder-loader/src/src/loader.ts","public_packages/recorder-loader/src/src/install-meticulous-intercepts.ts","public_packages/recorder-loader/src/src/early-network-recorder.ts","public_packages/recorder-loader/src/src/index.ts","public_packages/recorder-loader/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,"export { loadAndStartRecorder, tryLoadAndStartRecorder } from \"./loader\";\nexport { tryInstallMeticulousIntercepts } from \"./install-meticulous-intercepts\";\nexport { stopIntercepting } from \"./early-network-recorder\";\n"],"names":[],"version":3,"file":"index.d.ts.map"}
package/dist/index.js CHANGED
@@ -1,25 +1,25 @@
1
1
 
2
2
 
3
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="934b333a-8aaf-5956-9340-933ff04d643d")}catch(e){}}();
3
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="d113eb43-402e-503e-845f-282674dc5366")}catch(e){}}();
4
4
  function $parcel$export(e, n, v, s) {
5
5
  Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
6
6
  }
7
7
 
8
- $parcel$export(module.exports, "loadAndStartRecorder", () => $c97024bcb09807fa$export$9da0cde53b499187);
9
- $parcel$export(module.exports, "tryLoadAndStartRecorder", () => $c97024bcb09807fa$export$f80553af9d70f9fd);
10
- $parcel$export(module.exports, "tryInstallMeticulousIntercepts", () => $f8da777fb815521f$export$c0c9d1ed5ecb2675);
11
- $parcel$export(module.exports, "stopIntercepting", () => $6795f29cc093eb86$export$e592d04d772ce0ec);
12
- const $d2f90b927d91d104$export$d16af6ab0c202bae = "https://snippet.meticulous.ai";
8
+ $parcel$export(module.exports, "loadAndStartRecorder", () => $8464900cffc97239$export$9da0cde53b499187);
9
+ $parcel$export(module.exports, "tryLoadAndStartRecorder", () => $8464900cffc97239$export$f80553af9d70f9fd);
10
+ $parcel$export(module.exports, "tryInstallMeticulousIntercepts", () => $e7de436bb6729d45$export$c0c9d1ed5ecb2675);
11
+ $parcel$export(module.exports, "stopIntercepting", () => $1aeeb3a57c4327e1$export$e592d04d772ce0ec);
12
+ const $09fc4077413343a3$export$d16af6ab0c202bae = "https://snippet.meticulous.ai";
13
13
 
14
14
 
15
- const $b0bd6ecf0d8b9152$export$1595d9c512db1389 = (version)=>{
15
+ const $d52c61ebafe43549$export$1595d9c512db1389 = (version)=>{
16
16
  if (version == null) return "v1";
17
17
  return `v/${version}`;
18
18
  };
19
19
 
20
20
 
21
- const $c97024bcb09807fa$var$DEFAULT_MAX_MS_TO_BLOCK_FOR = 2000;
22
- const $c97024bcb09807fa$export$f80553af9d70f9fd = async (options)=>{
21
+ const $8464900cffc97239$var$DEFAULT_MAX_MS_TO_BLOCK_FOR = 2000;
22
+ const $8464900cffc97239$export$f80553af9d70f9fd = async (options)=>{
23
23
  if (window.Meticulous?.isRunningAsTest) {
24
24
  console.debug("Running as part of a Meticulous test case, so skipping loading the Meticulous recorder.");
25
25
  return {
@@ -29,7 +29,7 @@ const $c97024bcb09807fa$export$f80553af9d70f9fd = async (options)=>{
29
29
  };
30
30
  }
31
31
  // Try to load the recorder and silence any initialisation error.
32
- return await $c97024bcb09807fa$var$unsafeLoadAndStartRecorder(options).catch((error)=>{
32
+ return await $8464900cffc97239$var$unsafeLoadAndStartRecorder(options).catch((error)=>{
33
33
  console.error(error);
34
34
  return {
35
35
  stopRecording: async ()=>{
@@ -38,10 +38,10 @@ const $c97024bcb09807fa$export$f80553af9d70f9fd = async (options)=>{
38
38
  };
39
39
  });
40
40
  };
41
- const $c97024bcb09807fa$var$unsafeLoadAndStartRecorder = ({ projectId: projectId, recordingToken: recordingToken, uploadIntervalMs: uploadIntervalMs, snapshotLinkedStylesheets: snapshotLinkedStylesheets, commitHash: commitHash, maxMsToBlockFor: maxMsToBlockFor_, snippetsBaseUrl: snippetsBaseUrl, forceRecording: forceRecording, middleware: middleware, responseSanitizers: responseSanitizers, isProduction: isProduction, version: version, integrity: integrity, nonce: nonce, disableErrorReporting: disableErrorReporting, disableTrackerId: disableTrackerId, maxPayloadSize: maxPayloadSize })=>{
41
+ const $8464900cffc97239$var$unsafeLoadAndStartRecorder = ({ projectId: projectId, recordingToken: recordingToken, uploadIntervalMs: uploadIntervalMs, snapshotLinkedStylesheets: snapshotLinkedStylesheets, commitHash: commitHash, maxMsToBlockFor: maxMsToBlockFor_, snippetsBaseUrl: snippetsBaseUrl, forceRecording: forceRecording, middleware: middleware, responseSanitizers: responseSanitizers, isProduction: isProduction, version: version, integrity: integrity, nonce: nonce, disableErrorReporting: disableErrorReporting, disableTrackerId: disableTrackerId, maxPayloadSize: maxPayloadSize })=>{
42
42
  let abandoned = false;
43
43
  return new Promise((resolve, reject)=>{
44
- const maxMsToBlockFor = maxMsToBlockFor_ ?? $c97024bcb09807fa$var$DEFAULT_MAX_MS_TO_BLOCK_FOR;
44
+ const maxMsToBlockFor = maxMsToBlockFor_ ?? $8464900cffc97239$var$DEFAULT_MAX_MS_TO_BLOCK_FOR;
45
45
  if (maxMsToBlockFor > 0) setTimeout(()=>{
46
46
  abandoned = true;
47
47
  resolve({
@@ -61,8 +61,8 @@ const $c97024bcb09807fa$var$unsafeLoadAndStartRecorder = ({ projectId: projectId
61
61
  }
62
62
  if (nonce) script.nonce = nonce;
63
63
  script.type = "text/javascript";
64
- const baseSnippetsUrl = snippetsBaseUrl || (0, $d2f90b927d91d104$export$d16af6ab0c202bae);
65
- script.src = new URL(`${version != null ? "record/" : ""}${(0, $b0bd6ecf0d8b9152$export$1595d9c512db1389)(version ?? null)}/meticulous-manual-init.js`, baseSnippetsUrl).href;
64
+ const baseSnippetsUrl = snippetsBaseUrl || (0, $09fc4077413343a3$export$d16af6ab0c202bae);
65
+ script.src = new URL(`${version != null ? "record/" : ""}${(0, $d52c61ebafe43549$export$1595d9c512db1389)(version ?? null)}/meticulous-manual-init.js`, baseSnippetsUrl).href;
66
66
  // Setup configuration
67
67
  const typedWindow = window;
68
68
  typedWindow.METICULOUS_RECORDING_TOKEN = recordingToken ?? projectId;
@@ -84,37 +84,37 @@ const $c97024bcb09807fa$var$unsafeLoadAndStartRecorder = ({ projectId: projectId
84
84
  }
85
85
  const initialiseRecorder = window.__meticulous?.initialiseRecorder;
86
86
  if (typeof initialiseRecorder !== "function") {
87
- reject("Meticulous recorder failed to initialise.");
87
+ reject(new Error("Meticulous recorder failed to initialise."));
88
88
  return;
89
89
  }
90
90
  try {
91
91
  initialiseRecorder();
92
92
  } catch (error) {
93
- reject(error);
93
+ reject(error instanceof Error ? error : new Error(String(error)));
94
94
  }
95
95
  resolve({
96
- stopRecording: async ()=>{
96
+ stopRecording: ()=>{
97
97
  const stopRecording = window.__meticulous?.stopRecording;
98
98
  if (!stopRecording) throw new Error("Recorder not initialised: window.__meticulous.stopRecording is not defined.");
99
- await stopRecording();
100
- return;
99
+ stopRecording();
100
+ return Promise.resolve();
101
101
  }
102
102
  });
103
103
  };
104
104
  script.onerror = ()=>{
105
- reject("Meticulous recorder failed to initialise.");
105
+ reject(new Error("Meticulous recorder failed to initialise."));
106
106
  };
107
107
  document.head.appendChild(script);
108
108
  });
109
109
  };
110
- const $c97024bcb09807fa$export$9da0cde53b499187 = $c97024bcb09807fa$var$unsafeLoadAndStartRecorder;
110
+ const $8464900cffc97239$export$9da0cde53b499187 = $8464900cffc97239$var$unsafeLoadAndStartRecorder;
111
111
 
112
112
 
113
113
 
114
114
 
115
115
 
116
- const $f8da777fb815521f$var$DEFAULT_MAX_MS_TO_BLOCK_FOR = 2000;
117
- const $f8da777fb815521f$export$c0c9d1ed5ecb2675 = async (options)=>{
116
+ const $e7de436bb6729d45$var$DEFAULT_MAX_MS_TO_BLOCK_FOR = 2000;
117
+ const $e7de436bb6729d45$export$c0c9d1ed5ecb2675 = async (options)=>{
118
118
  let requestedToStopIntercepting = false;
119
119
  let disposedEarlyNetworkRecorder = false;
120
120
  const stopIntercepting = async ()=>{
@@ -126,24 +126,24 @@ const $f8da777fb815521f$export$c0c9d1ed5ecb2675 = async (options)=>{
126
126
  }
127
127
  };
128
128
  const interceptor = {
129
- startRecordingSession: (0, $c97024bcb09807fa$export$f80553af9d70f9fd),
129
+ startRecordingSession: (0, $8464900cffc97239$export$f80553af9d70f9fd),
130
130
  stopIntercepting: stopIntercepting
131
131
  };
132
- const maxMsToBlockFor = options.maxMsToBlockFor ?? $f8da777fb815521f$var$DEFAULT_MAX_MS_TO_BLOCK_FOR;
132
+ const maxMsToBlockFor = options.maxMsToBlockFor ?? $e7de436bb6729d45$var$DEFAULT_MAX_MS_TO_BLOCK_FOR;
133
133
  const promise = new Promise((resolve, reject)=>{
134
134
  const timeout = maxMsToBlockFor > 0 ? setTimeout(()=>{
135
135
  resolve(interceptor);
136
136
  }, maxMsToBlockFor) : null;
137
137
  const script = document.createElement("script");
138
138
  script.type = "text/javascript";
139
- script.src = `${0, $d2f90b927d91d104$export$d16af6ab0c202bae}/record/${(0, $b0bd6ecf0d8b9152$export$1595d9c512db1389)(options.version ?? null)}/network-recorder.bundle.js`;
139
+ script.src = `${0, $09fc4077413343a3$export$d16af6ab0c202bae}/record/${(0, $d52c61ebafe43549$export$1595d9c512db1389)(options.version ?? null)}/network-recorder.bundle.js`;
140
140
  script.onload = function() {
141
141
  if (timeout) window.clearTimeout(timeout);
142
142
  resolve(interceptor);
143
143
  };
144
144
  script.onerror = ()=>{
145
145
  if (timeout) window.clearTimeout(timeout);
146
- reject("Meticulous early network recorder failed to initialise.");
146
+ reject(new Error("Meticulous early network recorder failed to initialise."));
147
147
  };
148
148
  document.head.appendChild(script);
149
149
  });
@@ -157,7 +157,7 @@ const $f8da777fb815521f$export$c0c9d1ed5ecb2675 = async (options)=>{
157
157
  };
158
158
 
159
159
 
160
- const $6795f29cc093eb86$export$e592d04d772ce0ec = async ()=>{
160
+ const $1aeeb3a57c4327e1$export$e592d04d772ce0ec = async ()=>{
161
161
  const disposeFunction = window?.__meticulous?.earlyNetworkRecorder?.dispose;
162
162
  if (disposeFunction) await disposeFunction();
163
163
  };
@@ -167,4 +167,4 @@ const $6795f29cc093eb86$export$e592d04d772ce0ec = async ()=>{
167
167
 
168
168
  //# sourceMappingURL=index.js.map
169
169
 
170
- //# debugId=934b333a-8aaf-5956-9340-933ff04d643d
170
+ //# debugId=d113eb43-402e-503e-845f-282674dc5366
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js.map","sources":["packages/recorder-loader/src/index.ts","packages/recorder-loader/src/loader.ts","packages/recorder-loader/src/constants.ts","packages/recorder-loader/src/get-snippet-version-folder.ts","packages/recorder-loader/src/install-meticulous-intercepts.ts","packages/recorder-loader/src/early-network-recorder.ts"],"sourcesContent":["export { loadAndStartRecorder, tryLoadAndStartRecorder } from \"./loader\";\nexport { tryInstallMeticulousIntercepts } from \"./install-meticulous-intercepts\";\nexport { stopIntercepting } from \"./early-network-recorder\";\n","import { SNIPPETS_BASE_URL } from \"./constants\";\nimport { getSnippetVersionFolder } from \"./get-snippet-version-folder\";\nimport { LoaderOptions } from \"./loader.types\";\nimport { PrivateWindowApi } from \"./private-window-api\";\n\nconst DEFAULT_MAX_MS_TO_BLOCK_FOR = 2_000;\n\nexport interface Recorder {\n /**\n * Disables the recorder for the rest of the user session, and stops sending data to the Meticulous\n * servers.\n *\n * Once this method is called the recorder cannot be restarted (unless the page is reloaded).\n */\n stopRecording: () => Promise<void>;\n}\n\n/**\n * Load and start the Meticulous Recorder\n */\nexport const tryLoadAndStartRecorder = async (\n options: LoaderOptions,\n): Promise<Recorder> => {\n if (window.Meticulous?.isRunningAsTest) {\n console.debug(\n \"Running as part of a Meticulous test case, so skipping loading the Meticulous recorder.\",\n );\n return {\n stopRecording: async () => {\n // No op\n },\n };\n }\n\n // Try to load the recorder and silence any initialisation error.\n return await unsafeLoadAndStartRecorder(options).catch((error) => {\n console.error(error);\n return {\n stopRecording: async () => {\n // No op\n },\n };\n });\n};\n\nconst unsafeLoadAndStartRecorder = ({\n projectId,\n recordingToken,\n uploadIntervalMs,\n snapshotLinkedStylesheets,\n commitHash,\n maxMsToBlockFor: maxMsToBlockFor_,\n snippetsBaseUrl,\n forceRecording,\n middleware,\n responseSanitizers,\n isProduction,\n version,\n integrity,\n nonce,\n disableErrorReporting,\n disableTrackerId,\n maxPayloadSize,\n}: LoaderOptions): Promise<Recorder> => {\n let abandoned = false;\n\n return new Promise<Recorder>((resolve, reject) => {\n const maxMsToBlockFor = maxMsToBlockFor_ ?? DEFAULT_MAX_MS_TO_BLOCK_FOR;\n\n if (maxMsToBlockFor > 0) {\n setTimeout(() => {\n abandoned = true;\n resolve({\n stopRecording: async () => {\n // No op: we never started recording\n },\n });\n }, maxMsToBlockFor);\n }\n\n const script = document.createElement(\"script\");\n if (integrity) {\n if (!version) {\n throw new Error(\n \"Meticulous failed to initialise: integrity can only be provided when version is also provided\",\n );\n }\n script.integrity = integrity;\n // We need to set the crossOrigin to anonymous to avoid CORS issues. Without this we get a failure like:\n // \"... has an integrity attribute, but the resource requires the request to be CORS enabled to check the\n // integrity, and it is not. The resource has been blocked because the integrity cannot be enforced.\"\n script.crossOrigin = \"anonymous\";\n }\n if (nonce) {\n script.nonce = nonce;\n }\n script.type = \"text/javascript\";\n const baseSnippetsUrl = snippetsBaseUrl || SNIPPETS_BASE_URL;\n script.src = new URL(\n `${version != null ? \"record/\" : \"\"}${getSnippetVersionFolder(\n version ?? null,\n )}/meticulous-manual-init.js`,\n baseSnippetsUrl,\n ).href;\n\n // Setup configuration\n const typedWindow = window;\n typedWindow.METICULOUS_RECORDING_TOKEN = recordingToken ?? projectId;\n\n if (uploadIntervalMs !== undefined) {\n typedWindow.METICULOUS_UPLOAD_INTERVAL_MS = uploadIntervalMs;\n }\n\n if (commitHash !== undefined) {\n typedWindow.METICULOUS_APP_COMMIT_HASH = commitHash;\n }\n\n if (snapshotLinkedStylesheets !== undefined) {\n typedWindow.METICULOUS_SNAPSHOT_LINKED_STYLESHEETS =\n snapshotLinkedStylesheets;\n }\n\n if (forceRecording !== undefined) {\n typedWindow.METICULOUS_FORCE_RECORDING = forceRecording;\n }\n\n if (isProduction !== undefined) {\n typedWindow.METICULOUS_IS_PRODUCTION_ENVIRONMENT = isProduction;\n }\n\n if (responseSanitizers != null && responseSanitizers.length > 0) {\n typedWindow.METICULOUS_NETWORK_RESPONSE_SANITIZERS = responseSanitizers;\n }\n\n if (middleware != null && middleware.length > 0) {\n typedWindow.METICULOUS_RECORDER_MIDDLEWARE_V1 = middleware;\n }\n\n if (disableErrorReporting != null) {\n typedWindow.METICULOUS_DISABLE_ERROR_REPORTING = disableErrorReporting;\n }\n\n if (disableTrackerId != null) {\n typedWindow.METICULOUS_DISABLE_TRACKER_ID = disableTrackerId;\n }\n\n if (maxPayloadSize !== undefined) {\n typedWindow.METICULOUS_MAX_PAYLOAD_SIZE = maxPayloadSize;\n }\n\n script.onload = function () {\n if (abandoned) {\n console.debug(\n \"Meticulous snippet abandoned due to max blocking time reached.\",\n );\n // At this point the promise has already resolved.\n return;\n }\n\n const initialiseRecorder = (window as PrivateWindowApi).__meticulous\n ?.initialiseRecorder;\n if (typeof initialiseRecorder !== \"function\") {\n reject(\"Meticulous recorder failed to initialise.\");\n return;\n }\n\n try {\n initialiseRecorder();\n } catch (error) {\n reject(error);\n }\n\n resolve({\n stopRecording: async () => {\n const stopRecording = (window as PrivateWindowApi).__meticulous\n ?.stopRecording;\n if (!stopRecording) {\n throw new Error(\n \"Recorder not initialised: window.__meticulous.stopRecording is not defined.\",\n );\n }\n await stopRecording();\n return;\n },\n });\n };\n script.onerror = () => {\n reject(\"Meticulous recorder failed to initialise.\");\n };\n\n document.head.appendChild(script);\n });\n};\n\n/**\n * @deprecated Use `tryLoadAndStartRecorder` instead.\n *\n * Load and start the Meticulous Recorder\n */\nexport const loadAndStartRecorder = unsafeLoadAndStartRecorder;\n","export const SNIPPETS_BASE_URL = \"https://snippet.meticulous.ai\";\n","export const getSnippetVersionFolder = (version: string | null) => {\n if (version == null) {\n return \"v1\";\n }\n return `v/${version}`;\n};\n","import { SNIPPETS_BASE_URL } from \"./constants\";\nimport { getSnippetVersionFolder } from \"./get-snippet-version-folder\";\nimport { Recorder, tryLoadAndStartRecorder } from \"./loader\";\nimport { LoaderOptions } from \"./loader.types\";\nimport { PrivateWindowApi } from \"./private-window-api\";\n\nexport interface Interceptor {\n startRecordingSession: (options: LoaderOptions) => Promise<Recorder>;\n stopIntercepting: () => Promise<void>;\n}\n\nexport interface InterceptorOptions {\n /**\n * If it takes more than the specified number of 'ms' to load the interceptor,\n * then the promise returned by tryInstallMeticulousIntercepts will return\n * immediately (thereby unblocking the load of the application, but preventing\n * Meticulous from recording a correct session, with all required network mocks).\n *\n * Defaults to 2000ms.\n */\n maxMsToBlockFor?: number;\n\n /**\n * Load a specific fixed version of the snippet. If not set will load the\n * latest minor/patch version of the recorder. Bumping to a new major\n * version requires a bump of your @alwaysmeticulous/recorder-loader\n * dependency.\n *\n * Recommendation: leave this unset\n */\n version?: string;\n}\n\nconst DEFAULT_MAX_MS_TO_BLOCK_FOR = 2000;\n\n/**\n * Stores a copy of network requests and responses in memory, but doesn't send them to the\n * server, until the the main recorder is initialised.\n *\n * This is useful if you only want to record sessions for certain users with certain attributes. In\n * this case you have an issue: you need to wait for the user information to load before you know whether\n * you can enable the recorder, but if you enable the recorder after the user information has loaded\n * then the recorder won't be able to capture the initial request & response to load the user information,\n * or other early network responses.\n *\n * The early network recorder solves this: load the early network recorder for all sessions,\n * but only load the main recorder for sessions that you want to record. If when you load the user data\n * you find out you don't want to record the session then you can call the stopRecording() method returned\n * by this method.\n *\n * Example usage:\n *\n * ```\n * // The below call should happen before your app makes any network requests,\n * // or executes any methods that may store a reference to window.fetch or XMLHttpRequest.\n * const interceptor = await tryInstallMeticulousIntercepts();\n *\n * // Later, when you have loaded user data...\n * const userData = await loadUserInfo();\n * if (shouldRecord(userData)) {\n * await interceptor.startRecordingSession({ ... });\n * } else {\n * interceptor.stopIntercepting();\n * }\n * ```\n */\nexport const tryInstallMeticulousIntercepts = async (\n options: InterceptorOptions\n): Promise<Interceptor> => {\n let requestedToStopIntercepting = false;\n let disposedEarlyNetworkRecorder = false;\n const stopIntercepting = async () => {\n requestedToStopIntercepting = true;\n const disposeFunction = (window as PrivateWindowApi)?.__meticulous\n ?.earlyNetworkRecorder?.dispose;\n if (disposeFunction && !disposedEarlyNetworkRecorder) {\n await disposeFunction();\n disposedEarlyNetworkRecorder = true;\n }\n };\n const interceptor = {\n startRecordingSession: tryLoadAndStartRecorder,\n stopIntercepting,\n };\n\n const maxMsToBlockFor =\n options.maxMsToBlockFor ?? DEFAULT_MAX_MS_TO_BLOCK_FOR;\n const promise = new Promise<Interceptor>((resolve, reject) => {\n const timeout =\n maxMsToBlockFor > 0\n ? setTimeout(() => {\n resolve(interceptor);\n }, maxMsToBlockFor)\n : null;\n\n const script = document.createElement(\"script\");\n script.type = \"text/javascript\";\n script.src = `${SNIPPETS_BASE_URL}/record/${getSnippetVersionFolder(\n options.version ?? null\n )}/network-recorder.bundle.js`;\n\n script.onload = function () {\n if (timeout) {\n window.clearTimeout(timeout);\n }\n resolve(interceptor);\n };\n script.onerror = () => {\n if (timeout) {\n window.clearTimeout(timeout);\n }\n reject(\"Meticulous early network recorder failed to initialise.\");\n };\n\n document.head.appendChild(script);\n });\n\n // Try to load the early network recorder and silence any initialisation error.\n return promise\n .catch((error) => {\n console.error(error);\n return interceptor;\n })\n .finally(() => {\n if (requestedToStopIntercepting) {\n void stopIntercepting();\n }\n });\n};\n","import { PrivateWindowApi } from \"./private-window-api\";\n\n/**\n * If you add 'https://snippet.meticulous.ai/record/v1/network-recorder.bundle.js' as a script tag\n * then Meticulous will start off by recording any network requests in memory but not send the data to Meticulous’s\n * servers. Once you have the information to determine whether you want to record and persist the session\n * you can then call {@link tryLoadAndStartRecorder} if you do want to record, or this stopIntercepting method\n * if you do not want to record. When you call stopIntercepting any network requests/responses stored in memory\n * will be dropped and Meticulous will be deactivated. No data will be sent to Meticulous's servers.\n *\n * Please note that if you've already started recording and sending data to Meticulous's services i.e.\n * loaded the main meticulous recorder script or called tryLoadAndStartRecorder then this method will\n * not stop the recording. For that you need to call the stopRecording method returned by tryLoadAndStartRecorder.\n */\nexport const stopIntercepting = async () => {\n const disposeFunction = (window as PrivateWindowApi)?.__meticulous\n ?.earlyNetworkRecorder?.dispose;\n if (disposeFunction) {\n await disposeFunction();\n }\n};\n"],"names":[],"mappings":"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","debugId":"934b333a-8aaf-5956-9340-933ff04d643d"}
1
+ {"version":3,"file":"index.js.map","sources":["public_packages/recorder-loader/src/index.ts","public_packages/recorder-loader/src/loader.ts","public_packages/recorder-loader/src/constants.ts","public_packages/recorder-loader/src/get-snippet-version-folder.ts","public_packages/recorder-loader/src/install-meticulous-intercepts.ts","public_packages/recorder-loader/src/early-network-recorder.ts"],"sourcesContent":["export { loadAndStartRecorder, tryLoadAndStartRecorder } from \"./loader\";\nexport { tryInstallMeticulousIntercepts } from \"./install-meticulous-intercepts\";\nexport { stopIntercepting } from \"./early-network-recorder\";\n","import { SNIPPETS_BASE_URL } from \"./constants\";\nimport { getSnippetVersionFolder } from \"./get-snippet-version-folder\";\nimport type { LoaderOptions } from \"./loader.types\";\nimport type { PrivateWindowApi } from \"./private-window-api\";\n\nconst DEFAULT_MAX_MS_TO_BLOCK_FOR = 2_000;\n\nexport interface Recorder {\n /**\n * Disables the recorder for the rest of the user session, and stops sending data to the Meticulous\n * servers.\n *\n * Once this method is called the recorder cannot be restarted (unless the page is reloaded).\n */\n stopRecording: () => Promise<void>;\n}\n\n/**\n * Load and start the Meticulous Recorder\n */\nexport const tryLoadAndStartRecorder = async (\n options: LoaderOptions,\n): Promise<Recorder> => {\n if (window.Meticulous?.isRunningAsTest) {\n console.debug(\n \"Running as part of a Meticulous test case, so skipping loading the Meticulous recorder.\",\n );\n return {\n stopRecording: async () => {\n // No op\n },\n };\n }\n\n // Try to load the recorder and silence any initialisation error.\n return await unsafeLoadAndStartRecorder(options).catch((error) => {\n console.error(error);\n return {\n stopRecording: async () => {\n // No op\n },\n };\n });\n};\n\nconst unsafeLoadAndStartRecorder = ({\n projectId,\n recordingToken,\n uploadIntervalMs,\n snapshotLinkedStylesheets,\n commitHash,\n maxMsToBlockFor: maxMsToBlockFor_,\n snippetsBaseUrl,\n forceRecording,\n middleware,\n responseSanitizers,\n isProduction,\n version,\n integrity,\n nonce,\n disableErrorReporting,\n disableTrackerId,\n maxPayloadSize,\n}: LoaderOptions): Promise<Recorder> => {\n let abandoned = false;\n\n return new Promise<Recorder>((resolve, reject) => {\n const maxMsToBlockFor = maxMsToBlockFor_ ?? DEFAULT_MAX_MS_TO_BLOCK_FOR;\n\n if (maxMsToBlockFor > 0) {\n setTimeout(() => {\n abandoned = true;\n resolve({\n stopRecording: async () => {\n // No op: we never started recording\n },\n });\n }, maxMsToBlockFor);\n }\n\n const script = document.createElement(\"script\");\n if (integrity) {\n if (!version) {\n throw new Error(\n \"Meticulous failed to initialise: integrity can only be provided when version is also provided\",\n );\n }\n script.integrity = integrity;\n // We need to set the crossOrigin to anonymous to avoid CORS issues. Without this we get a failure like:\n // \"... has an integrity attribute, but the resource requires the request to be CORS enabled to check the\n // integrity, and it is not. The resource has been blocked because the integrity cannot be enforced.\"\n script.crossOrigin = \"anonymous\";\n }\n if (nonce) {\n script.nonce = nonce;\n }\n script.type = \"text/javascript\";\n const baseSnippetsUrl = snippetsBaseUrl || SNIPPETS_BASE_URL;\n script.src = new URL(\n `${version != null ? \"record/\" : \"\"}${getSnippetVersionFolder(\n version ?? null,\n )}/meticulous-manual-init.js`,\n baseSnippetsUrl,\n ).href;\n\n // Setup configuration\n const typedWindow = window;\n typedWindow.METICULOUS_RECORDING_TOKEN = recordingToken ?? projectId;\n\n if (uploadIntervalMs !== undefined) {\n typedWindow.METICULOUS_UPLOAD_INTERVAL_MS = uploadIntervalMs;\n }\n\n if (commitHash !== undefined) {\n typedWindow.METICULOUS_APP_COMMIT_HASH = commitHash;\n }\n\n if (snapshotLinkedStylesheets !== undefined) {\n typedWindow.METICULOUS_SNAPSHOT_LINKED_STYLESHEETS =\n snapshotLinkedStylesheets;\n }\n\n if (forceRecording !== undefined) {\n typedWindow.METICULOUS_FORCE_RECORDING = forceRecording;\n }\n\n if (isProduction !== undefined) {\n typedWindow.METICULOUS_IS_PRODUCTION_ENVIRONMENT = isProduction;\n }\n\n if (responseSanitizers != null && responseSanitizers.length > 0) {\n typedWindow.METICULOUS_NETWORK_RESPONSE_SANITIZERS = responseSanitizers;\n }\n\n if (middleware != null && middleware.length > 0) {\n typedWindow.METICULOUS_RECORDER_MIDDLEWARE_V1 = middleware;\n }\n\n if (disableErrorReporting != null) {\n typedWindow.METICULOUS_DISABLE_ERROR_REPORTING = disableErrorReporting;\n }\n\n if (disableTrackerId != null) {\n typedWindow.METICULOUS_DISABLE_TRACKER_ID = disableTrackerId;\n }\n\n if (maxPayloadSize !== undefined) {\n typedWindow.METICULOUS_MAX_PAYLOAD_SIZE = maxPayloadSize;\n }\n\n script.onload = function () {\n if (abandoned) {\n console.debug(\n \"Meticulous snippet abandoned due to max blocking time reached.\",\n );\n // At this point the promise has already resolved.\n return;\n }\n\n const initialiseRecorder = (window as PrivateWindowApi).__meticulous\n ?.initialiseRecorder;\n if (typeof initialiseRecorder !== \"function\") {\n reject(new Error(\"Meticulous recorder failed to initialise.\"));\n return;\n }\n\n try {\n initialiseRecorder();\n } catch (error) {\n reject(error instanceof Error ? error : new Error(String(error)));\n }\n\n resolve({\n stopRecording: () => {\n const stopRecording = (window as PrivateWindowApi).__meticulous\n ?.stopRecording;\n if (!stopRecording) {\n throw new Error(\n \"Recorder not initialised: window.__meticulous.stopRecording is not defined.\",\n );\n }\n stopRecording();\n return Promise.resolve();\n },\n });\n };\n script.onerror = () => {\n reject(new Error(\"Meticulous recorder failed to initialise.\"));\n };\n\n document.head.appendChild(script);\n });\n};\n\n/**\n * @deprecated Use `tryLoadAndStartRecorder` instead.\n *\n * Load and start the Meticulous Recorder\n */\nexport const loadAndStartRecorder = unsafeLoadAndStartRecorder;\n","export const SNIPPETS_BASE_URL = \"https://snippet.meticulous.ai\";\n","export const getSnippetVersionFolder = (version: string | null) => {\n if (version == null) {\n return \"v1\";\n }\n return `v/${version}`;\n};\n","import { SNIPPETS_BASE_URL } from \"./constants\";\nimport { getSnippetVersionFolder } from \"./get-snippet-version-folder\";\nimport type { Recorder } from \"./loader\";\nimport { tryLoadAndStartRecorder } from \"./loader\";\nimport type { LoaderOptions } from \"./loader.types\";\nimport type { PrivateWindowApi } from \"./private-window-api\";\n\nexport interface Interceptor {\n startRecordingSession: (options: LoaderOptions) => Promise<Recorder>;\n stopIntercepting: () => Promise<void>;\n}\n\nexport interface InterceptorOptions {\n /**\n * If it takes more than the specified number of 'ms' to load the interceptor,\n * then the promise returned by tryInstallMeticulousIntercepts will return\n * immediately (thereby unblocking the load of the application, but preventing\n * Meticulous from recording a correct session, with all required network mocks).\n *\n * Defaults to 2000ms.\n */\n maxMsToBlockFor?: number;\n\n /**\n * Load a specific fixed version of the snippet. If not set will load the\n * latest minor/patch version of the recorder. Bumping to a new major\n * version requires a bump of your @alwaysmeticulous/recorder-loader\n * dependency.\n *\n * Recommendation: leave this unset\n */\n version?: string;\n}\n\nconst DEFAULT_MAX_MS_TO_BLOCK_FOR = 2000;\n\n/**\n * Stores a copy of network requests and responses in memory, but doesn't send them to the\n * server, until the the main recorder is initialised.\n *\n * This is useful if you only want to record sessions for certain users with certain attributes. In\n * this case you have an issue: you need to wait for the user information to load before you know whether\n * you can enable the recorder, but if you enable the recorder after the user information has loaded\n * then the recorder won't be able to capture the initial request & response to load the user information,\n * or other early network responses.\n *\n * The early network recorder solves this: load the early network recorder for all sessions,\n * but only load the main recorder for sessions that you want to record. If when you load the user data\n * you find out you don't want to record the session then you can call the stopRecording() method returned\n * by this method.\n *\n * Example usage:\n *\n * ```\n * // The below call should happen before your app makes any network requests,\n * // or executes any methods that may store a reference to window.fetch or XMLHttpRequest.\n * const interceptor = await tryInstallMeticulousIntercepts();\n *\n * // Later, when you have loaded user data...\n * const userData = await loadUserInfo();\n * if (shouldRecord(userData)) {\n * await interceptor.startRecordingSession({ ... });\n * } else {\n * interceptor.stopIntercepting();\n * }\n * ```\n */\nexport const tryInstallMeticulousIntercepts = async (\n options: InterceptorOptions,\n): Promise<Interceptor> => {\n let requestedToStopIntercepting = false;\n let disposedEarlyNetworkRecorder = false;\n const stopIntercepting = async () => {\n requestedToStopIntercepting = true;\n const disposeFunction = (window as PrivateWindowApi)?.__meticulous\n ?.earlyNetworkRecorder?.dispose;\n if (disposeFunction && !disposedEarlyNetworkRecorder) {\n await disposeFunction();\n disposedEarlyNetworkRecorder = true;\n }\n };\n const interceptor = {\n startRecordingSession: tryLoadAndStartRecorder,\n stopIntercepting,\n };\n\n const maxMsToBlockFor =\n options.maxMsToBlockFor ?? DEFAULT_MAX_MS_TO_BLOCK_FOR;\n const promise = new Promise<Interceptor>((resolve, reject) => {\n const timeout =\n maxMsToBlockFor > 0\n ? setTimeout(() => {\n resolve(interceptor);\n }, maxMsToBlockFor)\n : null;\n\n const script = document.createElement(\"script\");\n script.type = \"text/javascript\";\n script.src = `${SNIPPETS_BASE_URL}/record/${getSnippetVersionFolder(\n options.version ?? null,\n )}/network-recorder.bundle.js`;\n\n script.onload = function () {\n if (timeout) {\n window.clearTimeout(timeout);\n }\n resolve(interceptor);\n };\n script.onerror = () => {\n if (timeout) {\n window.clearTimeout(timeout);\n }\n reject(\n new Error(\"Meticulous early network recorder failed to initialise.\"),\n );\n };\n\n document.head.appendChild(script);\n });\n\n // Try to load the early network recorder and silence any initialisation error.\n return promise\n .catch((error) => {\n console.error(error);\n return interceptor;\n })\n .finally(() => {\n if (requestedToStopIntercepting) {\n void stopIntercepting();\n }\n });\n};\n","import type { PrivateWindowApi } from \"./private-window-api\";\n\n/**\n * If you add 'https://snippet.meticulous.ai/record/v1/network-recorder.bundle.js' as a script tag\n * then Meticulous will start off by recording any network requests in memory but not send the data to Meticulous’s\n * servers. Once you have the information to determine whether you want to record and persist the session\n * you can then call {@link tryLoadAndStartRecorder} if you do want to record, or this stopIntercepting method\n * if you do not want to record. When you call stopIntercepting any network requests/responses stored in memory\n * will be dropped and Meticulous will be deactivated. No data will be sent to Meticulous's servers.\n *\n * Please note that if you've already started recording and sending data to Meticulous's services i.e.\n * loaded the main meticulous recorder script or called tryLoadAndStartRecorder then this method will\n * not stop the recording. For that you need to call the stopRecording method returned by tryLoadAndStartRecorder.\n */\nexport const stopIntercepting = async () => {\n const disposeFunction = (window as PrivateWindowApi)?.__meticulous\n ?.earlyNetworkRecorder?.dispose;\n if (disposeFunction) {\n await disposeFunction();\n }\n};\n"],"names":[],"mappings":"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","debugId":"d113eb43-402e-503e-845f-282674dc5366"}
package/dist/module.js CHANGED
@@ -1,16 +1,16 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="1f1a8331-9aa6-54b5-b736-cc806b1aef31")}catch(e){}}();
3
- const $7d7683134fbb8fec$export$d16af6ab0c202bae = "https://snippet.meticulous.ai";
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="c68db38f-cc00-5c41-a1a7-b9de35e2c52e")}catch(e){}}();
3
+ const $83805c81b4f87f01$export$d16af6ab0c202bae = "https://snippet.meticulous.ai";
4
4
 
5
5
 
6
- const $01ff17ace345060a$export$1595d9c512db1389 = (version)=>{
6
+ const $6de1b31698bdee3c$export$1595d9c512db1389 = (version)=>{
7
7
  if (version == null) return "v1";
8
8
  return `v/${version}`;
9
9
  };
10
10
 
11
11
 
12
- const $5d774bdb3a883001$var$DEFAULT_MAX_MS_TO_BLOCK_FOR = 2000;
13
- const $5d774bdb3a883001$export$f80553af9d70f9fd = async (options)=>{
12
+ const $682601cc03a2a2cb$var$DEFAULT_MAX_MS_TO_BLOCK_FOR = 2000;
13
+ const $682601cc03a2a2cb$export$f80553af9d70f9fd = async (options)=>{
14
14
  if (window.Meticulous?.isRunningAsTest) {
15
15
  console.debug("Running as part of a Meticulous test case, so skipping loading the Meticulous recorder.");
16
16
  return {
@@ -20,7 +20,7 @@ const $5d774bdb3a883001$export$f80553af9d70f9fd = async (options)=>{
20
20
  };
21
21
  }
22
22
  // Try to load the recorder and silence any initialisation error.
23
- return await $5d774bdb3a883001$var$unsafeLoadAndStartRecorder(options).catch((error)=>{
23
+ return await $682601cc03a2a2cb$var$unsafeLoadAndStartRecorder(options).catch((error)=>{
24
24
  console.error(error);
25
25
  return {
26
26
  stopRecording: async ()=>{
@@ -29,10 +29,10 @@ const $5d774bdb3a883001$export$f80553af9d70f9fd = async (options)=>{
29
29
  };
30
30
  });
31
31
  };
32
- const $5d774bdb3a883001$var$unsafeLoadAndStartRecorder = ({ projectId: projectId, recordingToken: recordingToken, uploadIntervalMs: uploadIntervalMs, snapshotLinkedStylesheets: snapshotLinkedStylesheets, commitHash: commitHash, maxMsToBlockFor: maxMsToBlockFor_, snippetsBaseUrl: snippetsBaseUrl, forceRecording: forceRecording, middleware: middleware, responseSanitizers: responseSanitizers, isProduction: isProduction, version: version, integrity: integrity, nonce: nonce, disableErrorReporting: disableErrorReporting, disableTrackerId: disableTrackerId, maxPayloadSize: maxPayloadSize })=>{
32
+ const $682601cc03a2a2cb$var$unsafeLoadAndStartRecorder = ({ projectId: projectId, recordingToken: recordingToken, uploadIntervalMs: uploadIntervalMs, snapshotLinkedStylesheets: snapshotLinkedStylesheets, commitHash: commitHash, maxMsToBlockFor: maxMsToBlockFor_, snippetsBaseUrl: snippetsBaseUrl, forceRecording: forceRecording, middleware: middleware, responseSanitizers: responseSanitizers, isProduction: isProduction, version: version, integrity: integrity, nonce: nonce, disableErrorReporting: disableErrorReporting, disableTrackerId: disableTrackerId, maxPayloadSize: maxPayloadSize })=>{
33
33
  let abandoned = false;
34
34
  return new Promise((resolve, reject)=>{
35
- const maxMsToBlockFor = maxMsToBlockFor_ ?? $5d774bdb3a883001$var$DEFAULT_MAX_MS_TO_BLOCK_FOR;
35
+ const maxMsToBlockFor = maxMsToBlockFor_ ?? $682601cc03a2a2cb$var$DEFAULT_MAX_MS_TO_BLOCK_FOR;
36
36
  if (maxMsToBlockFor > 0) setTimeout(()=>{
37
37
  abandoned = true;
38
38
  resolve({
@@ -52,8 +52,8 @@ const $5d774bdb3a883001$var$unsafeLoadAndStartRecorder = ({ projectId: projectId
52
52
  }
53
53
  if (nonce) script.nonce = nonce;
54
54
  script.type = "text/javascript";
55
- const baseSnippetsUrl = snippetsBaseUrl || (0, $7d7683134fbb8fec$export$d16af6ab0c202bae);
56
- script.src = new URL(`${version != null ? "record/" : ""}${(0, $01ff17ace345060a$export$1595d9c512db1389)(version ?? null)}/meticulous-manual-init.js`, baseSnippetsUrl).href;
55
+ const baseSnippetsUrl = snippetsBaseUrl || (0, $83805c81b4f87f01$export$d16af6ab0c202bae);
56
+ script.src = new URL(`${version != null ? "record/" : ""}${(0, $6de1b31698bdee3c$export$1595d9c512db1389)(version ?? null)}/meticulous-manual-init.js`, baseSnippetsUrl).href;
57
57
  // Setup configuration
58
58
  const typedWindow = window;
59
59
  typedWindow.METICULOUS_RECORDING_TOKEN = recordingToken ?? projectId;
@@ -75,37 +75,37 @@ const $5d774bdb3a883001$var$unsafeLoadAndStartRecorder = ({ projectId: projectId
75
75
  }
76
76
  const initialiseRecorder = window.__meticulous?.initialiseRecorder;
77
77
  if (typeof initialiseRecorder !== "function") {
78
- reject("Meticulous recorder failed to initialise.");
78
+ reject(new Error("Meticulous recorder failed to initialise."));
79
79
  return;
80
80
  }
81
81
  try {
82
82
  initialiseRecorder();
83
83
  } catch (error) {
84
- reject(error);
84
+ reject(error instanceof Error ? error : new Error(String(error)));
85
85
  }
86
86
  resolve({
87
- stopRecording: async ()=>{
87
+ stopRecording: ()=>{
88
88
  const stopRecording = window.__meticulous?.stopRecording;
89
89
  if (!stopRecording) throw new Error("Recorder not initialised: window.__meticulous.stopRecording is not defined.");
90
- await stopRecording();
91
- return;
90
+ stopRecording();
91
+ return Promise.resolve();
92
92
  }
93
93
  });
94
94
  };
95
95
  script.onerror = ()=>{
96
- reject("Meticulous recorder failed to initialise.");
96
+ reject(new Error("Meticulous recorder failed to initialise."));
97
97
  };
98
98
  document.head.appendChild(script);
99
99
  });
100
100
  };
101
- const $5d774bdb3a883001$export$9da0cde53b499187 = $5d774bdb3a883001$var$unsafeLoadAndStartRecorder;
101
+ const $682601cc03a2a2cb$export$9da0cde53b499187 = $682601cc03a2a2cb$var$unsafeLoadAndStartRecorder;
102
102
 
103
103
 
104
104
 
105
105
 
106
106
 
107
- const $d91c442ec5d010f4$var$DEFAULT_MAX_MS_TO_BLOCK_FOR = 2000;
108
- const $d91c442ec5d010f4$export$c0c9d1ed5ecb2675 = async (options)=>{
107
+ const $93c524a5abcb320e$var$DEFAULT_MAX_MS_TO_BLOCK_FOR = 2000;
108
+ const $93c524a5abcb320e$export$c0c9d1ed5ecb2675 = async (options)=>{
109
109
  let requestedToStopIntercepting = false;
110
110
  let disposedEarlyNetworkRecorder = false;
111
111
  const stopIntercepting = async ()=>{
@@ -117,24 +117,24 @@ const $d91c442ec5d010f4$export$c0c9d1ed5ecb2675 = async (options)=>{
117
117
  }
118
118
  };
119
119
  const interceptor = {
120
- startRecordingSession: (0, $5d774bdb3a883001$export$f80553af9d70f9fd),
120
+ startRecordingSession: (0, $682601cc03a2a2cb$export$f80553af9d70f9fd),
121
121
  stopIntercepting: stopIntercepting
122
122
  };
123
- const maxMsToBlockFor = options.maxMsToBlockFor ?? $d91c442ec5d010f4$var$DEFAULT_MAX_MS_TO_BLOCK_FOR;
123
+ const maxMsToBlockFor = options.maxMsToBlockFor ?? $93c524a5abcb320e$var$DEFAULT_MAX_MS_TO_BLOCK_FOR;
124
124
  const promise = new Promise((resolve, reject)=>{
125
125
  const timeout = maxMsToBlockFor > 0 ? setTimeout(()=>{
126
126
  resolve(interceptor);
127
127
  }, maxMsToBlockFor) : null;
128
128
  const script = document.createElement("script");
129
129
  script.type = "text/javascript";
130
- script.src = `${0, $7d7683134fbb8fec$export$d16af6ab0c202bae}/record/${(0, $01ff17ace345060a$export$1595d9c512db1389)(options.version ?? null)}/network-recorder.bundle.js`;
130
+ script.src = `${0, $83805c81b4f87f01$export$d16af6ab0c202bae}/record/${(0, $6de1b31698bdee3c$export$1595d9c512db1389)(options.version ?? null)}/network-recorder.bundle.js`;
131
131
  script.onload = function() {
132
132
  if (timeout) window.clearTimeout(timeout);
133
133
  resolve(interceptor);
134
134
  };
135
135
  script.onerror = ()=>{
136
136
  if (timeout) window.clearTimeout(timeout);
137
- reject("Meticulous early network recorder failed to initialise.");
137
+ reject(new Error("Meticulous early network recorder failed to initialise."));
138
138
  };
139
139
  document.head.appendChild(script);
140
140
  });
@@ -148,7 +148,7 @@ const $d91c442ec5d010f4$export$c0c9d1ed5ecb2675 = async (options)=>{
148
148
  };
149
149
 
150
150
 
151
- const $57efbd113493cb78$export$e592d04d772ce0ec = async ()=>{
151
+ const $bf75c11ed747e2fa$export$e592d04d772ce0ec = async ()=>{
152
152
  const disposeFunction = window?.__meticulous?.earlyNetworkRecorder?.dispose;
153
153
  if (disposeFunction) await disposeFunction();
154
154
  };
@@ -156,7 +156,7 @@ const $57efbd113493cb78$export$e592d04d772ce0ec = async ()=>{
156
156
 
157
157
 
158
158
 
159
- export {$5d774bdb3a883001$export$9da0cde53b499187 as loadAndStartRecorder, $5d774bdb3a883001$export$f80553af9d70f9fd as tryLoadAndStartRecorder, $d91c442ec5d010f4$export$c0c9d1ed5ecb2675 as tryInstallMeticulousIntercepts, $57efbd113493cb78$export$e592d04d772ce0ec as stopIntercepting};
159
+ export {$682601cc03a2a2cb$export$9da0cde53b499187 as loadAndStartRecorder, $682601cc03a2a2cb$export$f80553af9d70f9fd as tryLoadAndStartRecorder, $93c524a5abcb320e$export$c0c9d1ed5ecb2675 as tryInstallMeticulousIntercepts, $bf75c11ed747e2fa$export$e592d04d772ce0ec as stopIntercepting};
160
160
  //# sourceMappingURL=module.js.map
161
161
 
162
- //# debugId=1f1a8331-9aa6-54b5-b736-cc806b1aef31
162
+ //# debugId=c68db38f-cc00-5c41-a1a7-b9de35e2c52e
@@ -1 +1 @@
1
- {"version":3,"file":"module.js.map","sources":["packages/recorder-loader/src/index.ts","packages/recorder-loader/src/loader.ts","packages/recorder-loader/src/constants.ts","packages/recorder-loader/src/get-snippet-version-folder.ts","packages/recorder-loader/src/install-meticulous-intercepts.ts","packages/recorder-loader/src/early-network-recorder.ts"],"sourcesContent":["export { loadAndStartRecorder, tryLoadAndStartRecorder } from \"./loader\";\nexport { tryInstallMeticulousIntercepts } from \"./install-meticulous-intercepts\";\nexport { stopIntercepting } from \"./early-network-recorder\";\n","import { SNIPPETS_BASE_URL } from \"./constants\";\nimport { getSnippetVersionFolder } from \"./get-snippet-version-folder\";\nimport { LoaderOptions } from \"./loader.types\";\nimport { PrivateWindowApi } from \"./private-window-api\";\n\nconst DEFAULT_MAX_MS_TO_BLOCK_FOR = 2_000;\n\nexport interface Recorder {\n /**\n * Disables the recorder for the rest of the user session, and stops sending data to the Meticulous\n * servers.\n *\n * Once this method is called the recorder cannot be restarted (unless the page is reloaded).\n */\n stopRecording: () => Promise<void>;\n}\n\n/**\n * Load and start the Meticulous Recorder\n */\nexport const tryLoadAndStartRecorder = async (\n options: LoaderOptions,\n): Promise<Recorder> => {\n if (window.Meticulous?.isRunningAsTest) {\n console.debug(\n \"Running as part of a Meticulous test case, so skipping loading the Meticulous recorder.\",\n );\n return {\n stopRecording: async () => {\n // No op\n },\n };\n }\n\n // Try to load the recorder and silence any initialisation error.\n return await unsafeLoadAndStartRecorder(options).catch((error) => {\n console.error(error);\n return {\n stopRecording: async () => {\n // No op\n },\n };\n });\n};\n\nconst unsafeLoadAndStartRecorder = ({\n projectId,\n recordingToken,\n uploadIntervalMs,\n snapshotLinkedStylesheets,\n commitHash,\n maxMsToBlockFor: maxMsToBlockFor_,\n snippetsBaseUrl,\n forceRecording,\n middleware,\n responseSanitizers,\n isProduction,\n version,\n integrity,\n nonce,\n disableErrorReporting,\n disableTrackerId,\n maxPayloadSize,\n}: LoaderOptions): Promise<Recorder> => {\n let abandoned = false;\n\n return new Promise<Recorder>((resolve, reject) => {\n const maxMsToBlockFor = maxMsToBlockFor_ ?? DEFAULT_MAX_MS_TO_BLOCK_FOR;\n\n if (maxMsToBlockFor > 0) {\n setTimeout(() => {\n abandoned = true;\n resolve({\n stopRecording: async () => {\n // No op: we never started recording\n },\n });\n }, maxMsToBlockFor);\n }\n\n const script = document.createElement(\"script\");\n if (integrity) {\n if (!version) {\n throw new Error(\n \"Meticulous failed to initialise: integrity can only be provided when version is also provided\",\n );\n }\n script.integrity = integrity;\n // We need to set the crossOrigin to anonymous to avoid CORS issues. Without this we get a failure like:\n // \"... has an integrity attribute, but the resource requires the request to be CORS enabled to check the\n // integrity, and it is not. The resource has been blocked because the integrity cannot be enforced.\"\n script.crossOrigin = \"anonymous\";\n }\n if (nonce) {\n script.nonce = nonce;\n }\n script.type = \"text/javascript\";\n const baseSnippetsUrl = snippetsBaseUrl || SNIPPETS_BASE_URL;\n script.src = new URL(\n `${version != null ? \"record/\" : \"\"}${getSnippetVersionFolder(\n version ?? null,\n )}/meticulous-manual-init.js`,\n baseSnippetsUrl,\n ).href;\n\n // Setup configuration\n const typedWindow = window;\n typedWindow.METICULOUS_RECORDING_TOKEN = recordingToken ?? projectId;\n\n if (uploadIntervalMs !== undefined) {\n typedWindow.METICULOUS_UPLOAD_INTERVAL_MS = uploadIntervalMs;\n }\n\n if (commitHash !== undefined) {\n typedWindow.METICULOUS_APP_COMMIT_HASH = commitHash;\n }\n\n if (snapshotLinkedStylesheets !== undefined) {\n typedWindow.METICULOUS_SNAPSHOT_LINKED_STYLESHEETS =\n snapshotLinkedStylesheets;\n }\n\n if (forceRecording !== undefined) {\n typedWindow.METICULOUS_FORCE_RECORDING = forceRecording;\n }\n\n if (isProduction !== undefined) {\n typedWindow.METICULOUS_IS_PRODUCTION_ENVIRONMENT = isProduction;\n }\n\n if (responseSanitizers != null && responseSanitizers.length > 0) {\n typedWindow.METICULOUS_NETWORK_RESPONSE_SANITIZERS = responseSanitizers;\n }\n\n if (middleware != null && middleware.length > 0) {\n typedWindow.METICULOUS_RECORDER_MIDDLEWARE_V1 = middleware;\n }\n\n if (disableErrorReporting != null) {\n typedWindow.METICULOUS_DISABLE_ERROR_REPORTING = disableErrorReporting;\n }\n\n if (disableTrackerId != null) {\n typedWindow.METICULOUS_DISABLE_TRACKER_ID = disableTrackerId;\n }\n\n if (maxPayloadSize !== undefined) {\n typedWindow.METICULOUS_MAX_PAYLOAD_SIZE = maxPayloadSize;\n }\n\n script.onload = function () {\n if (abandoned) {\n console.debug(\n \"Meticulous snippet abandoned due to max blocking time reached.\",\n );\n // At this point the promise has already resolved.\n return;\n }\n\n const initialiseRecorder = (window as PrivateWindowApi).__meticulous\n ?.initialiseRecorder;\n if (typeof initialiseRecorder !== \"function\") {\n reject(\"Meticulous recorder failed to initialise.\");\n return;\n }\n\n try {\n initialiseRecorder();\n } catch (error) {\n reject(error);\n }\n\n resolve({\n stopRecording: async () => {\n const stopRecording = (window as PrivateWindowApi).__meticulous\n ?.stopRecording;\n if (!stopRecording) {\n throw new Error(\n \"Recorder not initialised: window.__meticulous.stopRecording is not defined.\",\n );\n }\n await stopRecording();\n return;\n },\n });\n };\n script.onerror = () => {\n reject(\"Meticulous recorder failed to initialise.\");\n };\n\n document.head.appendChild(script);\n });\n};\n\n/**\n * @deprecated Use `tryLoadAndStartRecorder` instead.\n *\n * Load and start the Meticulous Recorder\n */\nexport const loadAndStartRecorder = unsafeLoadAndStartRecorder;\n","export const SNIPPETS_BASE_URL = \"https://snippet.meticulous.ai\";\n","export const getSnippetVersionFolder = (version: string | null) => {\n if (version == null) {\n return \"v1\";\n }\n return `v/${version}`;\n};\n","import { SNIPPETS_BASE_URL } from \"./constants\";\nimport { getSnippetVersionFolder } from \"./get-snippet-version-folder\";\nimport { Recorder, tryLoadAndStartRecorder } from \"./loader\";\nimport { LoaderOptions } from \"./loader.types\";\nimport { PrivateWindowApi } from \"./private-window-api\";\n\nexport interface Interceptor {\n startRecordingSession: (options: LoaderOptions) => Promise<Recorder>;\n stopIntercepting: () => Promise<void>;\n}\n\nexport interface InterceptorOptions {\n /**\n * If it takes more than the specified number of 'ms' to load the interceptor,\n * then the promise returned by tryInstallMeticulousIntercepts will return\n * immediately (thereby unblocking the load of the application, but preventing\n * Meticulous from recording a correct session, with all required network mocks).\n *\n * Defaults to 2000ms.\n */\n maxMsToBlockFor?: number;\n\n /**\n * Load a specific fixed version of the snippet. If not set will load the\n * latest minor/patch version of the recorder. Bumping to a new major\n * version requires a bump of your @alwaysmeticulous/recorder-loader\n * dependency.\n *\n * Recommendation: leave this unset\n */\n version?: string;\n}\n\nconst DEFAULT_MAX_MS_TO_BLOCK_FOR = 2000;\n\n/**\n * Stores a copy of network requests and responses in memory, but doesn't send them to the\n * server, until the the main recorder is initialised.\n *\n * This is useful if you only want to record sessions for certain users with certain attributes. In\n * this case you have an issue: you need to wait for the user information to load before you know whether\n * you can enable the recorder, but if you enable the recorder after the user information has loaded\n * then the recorder won't be able to capture the initial request & response to load the user information,\n * or other early network responses.\n *\n * The early network recorder solves this: load the early network recorder for all sessions,\n * but only load the main recorder for sessions that you want to record. If when you load the user data\n * you find out you don't want to record the session then you can call the stopRecording() method returned\n * by this method.\n *\n * Example usage:\n *\n * ```\n * // The below call should happen before your app makes any network requests,\n * // or executes any methods that may store a reference to window.fetch or XMLHttpRequest.\n * const interceptor = await tryInstallMeticulousIntercepts();\n *\n * // Later, when you have loaded user data...\n * const userData = await loadUserInfo();\n * if (shouldRecord(userData)) {\n * await interceptor.startRecordingSession({ ... });\n * } else {\n * interceptor.stopIntercepting();\n * }\n * ```\n */\nexport const tryInstallMeticulousIntercepts = async (\n options: InterceptorOptions\n): Promise<Interceptor> => {\n let requestedToStopIntercepting = false;\n let disposedEarlyNetworkRecorder = false;\n const stopIntercepting = async () => {\n requestedToStopIntercepting = true;\n const disposeFunction = (window as PrivateWindowApi)?.__meticulous\n ?.earlyNetworkRecorder?.dispose;\n if (disposeFunction && !disposedEarlyNetworkRecorder) {\n await disposeFunction();\n disposedEarlyNetworkRecorder = true;\n }\n };\n const interceptor = {\n startRecordingSession: tryLoadAndStartRecorder,\n stopIntercepting,\n };\n\n const maxMsToBlockFor =\n options.maxMsToBlockFor ?? DEFAULT_MAX_MS_TO_BLOCK_FOR;\n const promise = new Promise<Interceptor>((resolve, reject) => {\n const timeout =\n maxMsToBlockFor > 0\n ? setTimeout(() => {\n resolve(interceptor);\n }, maxMsToBlockFor)\n : null;\n\n const script = document.createElement(\"script\");\n script.type = \"text/javascript\";\n script.src = `${SNIPPETS_BASE_URL}/record/${getSnippetVersionFolder(\n options.version ?? null\n )}/network-recorder.bundle.js`;\n\n script.onload = function () {\n if (timeout) {\n window.clearTimeout(timeout);\n }\n resolve(interceptor);\n };\n script.onerror = () => {\n if (timeout) {\n window.clearTimeout(timeout);\n }\n reject(\"Meticulous early network recorder failed to initialise.\");\n };\n\n document.head.appendChild(script);\n });\n\n // Try to load the early network recorder and silence any initialisation error.\n return promise\n .catch((error) => {\n console.error(error);\n return interceptor;\n })\n .finally(() => {\n if (requestedToStopIntercepting) {\n void stopIntercepting();\n }\n });\n};\n","import { PrivateWindowApi } from \"./private-window-api\";\n\n/**\n * If you add 'https://snippet.meticulous.ai/record/v1/network-recorder.bundle.js' as a script tag\n * then Meticulous will start off by recording any network requests in memory but not send the data to Meticulous’s\n * servers. Once you have the information to determine whether you want to record and persist the session\n * you can then call {@link tryLoadAndStartRecorder} if you do want to record, or this stopIntercepting method\n * if you do not want to record. When you call stopIntercepting any network requests/responses stored in memory\n * will be dropped and Meticulous will be deactivated. No data will be sent to Meticulous's servers.\n *\n * Please note that if you've already started recording and sending data to Meticulous's services i.e.\n * loaded the main meticulous recorder script or called tryLoadAndStartRecorder then this method will\n * not stop the recording. For that you need to call the stopRecording method returned by tryLoadAndStartRecorder.\n */\nexport const stopIntercepting = async () => {\n const disposeFunction = (window as PrivateWindowApi)?.__meticulous\n ?.earlyNetworkRecorder?.dispose;\n if (disposeFunction) {\n await disposeFunction();\n }\n};\n"],"names":[],"mappings":"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","debugId":"1f1a8331-9aa6-54b5-b736-cc806b1aef31"}
1
+ {"version":3,"file":"module.js.map","sources":["public_packages/recorder-loader/src/index.ts","public_packages/recorder-loader/src/loader.ts","public_packages/recorder-loader/src/constants.ts","public_packages/recorder-loader/src/get-snippet-version-folder.ts","public_packages/recorder-loader/src/install-meticulous-intercepts.ts","public_packages/recorder-loader/src/early-network-recorder.ts"],"sourcesContent":["export { loadAndStartRecorder, tryLoadAndStartRecorder } from \"./loader\";\nexport { tryInstallMeticulousIntercepts } from \"./install-meticulous-intercepts\";\nexport { stopIntercepting } from \"./early-network-recorder\";\n","import { SNIPPETS_BASE_URL } from \"./constants\";\nimport { getSnippetVersionFolder } from \"./get-snippet-version-folder\";\nimport type { LoaderOptions } from \"./loader.types\";\nimport type { PrivateWindowApi } from \"./private-window-api\";\n\nconst DEFAULT_MAX_MS_TO_BLOCK_FOR = 2_000;\n\nexport interface Recorder {\n /**\n * Disables the recorder for the rest of the user session, and stops sending data to the Meticulous\n * servers.\n *\n * Once this method is called the recorder cannot be restarted (unless the page is reloaded).\n */\n stopRecording: () => Promise<void>;\n}\n\n/**\n * Load and start the Meticulous Recorder\n */\nexport const tryLoadAndStartRecorder = async (\n options: LoaderOptions,\n): Promise<Recorder> => {\n if (window.Meticulous?.isRunningAsTest) {\n console.debug(\n \"Running as part of a Meticulous test case, so skipping loading the Meticulous recorder.\",\n );\n return {\n stopRecording: async () => {\n // No op\n },\n };\n }\n\n // Try to load the recorder and silence any initialisation error.\n return await unsafeLoadAndStartRecorder(options).catch((error) => {\n console.error(error);\n return {\n stopRecording: async () => {\n // No op\n },\n };\n });\n};\n\nconst unsafeLoadAndStartRecorder = ({\n projectId,\n recordingToken,\n uploadIntervalMs,\n snapshotLinkedStylesheets,\n commitHash,\n maxMsToBlockFor: maxMsToBlockFor_,\n snippetsBaseUrl,\n forceRecording,\n middleware,\n responseSanitizers,\n isProduction,\n version,\n integrity,\n nonce,\n disableErrorReporting,\n disableTrackerId,\n maxPayloadSize,\n}: LoaderOptions): Promise<Recorder> => {\n let abandoned = false;\n\n return new Promise<Recorder>((resolve, reject) => {\n const maxMsToBlockFor = maxMsToBlockFor_ ?? DEFAULT_MAX_MS_TO_BLOCK_FOR;\n\n if (maxMsToBlockFor > 0) {\n setTimeout(() => {\n abandoned = true;\n resolve({\n stopRecording: async () => {\n // No op: we never started recording\n },\n });\n }, maxMsToBlockFor);\n }\n\n const script = document.createElement(\"script\");\n if (integrity) {\n if (!version) {\n throw new Error(\n \"Meticulous failed to initialise: integrity can only be provided when version is also provided\",\n );\n }\n script.integrity = integrity;\n // We need to set the crossOrigin to anonymous to avoid CORS issues. Without this we get a failure like:\n // \"... has an integrity attribute, but the resource requires the request to be CORS enabled to check the\n // integrity, and it is not. The resource has been blocked because the integrity cannot be enforced.\"\n script.crossOrigin = \"anonymous\";\n }\n if (nonce) {\n script.nonce = nonce;\n }\n script.type = \"text/javascript\";\n const baseSnippetsUrl = snippetsBaseUrl || SNIPPETS_BASE_URL;\n script.src = new URL(\n `${version != null ? \"record/\" : \"\"}${getSnippetVersionFolder(\n version ?? null,\n )}/meticulous-manual-init.js`,\n baseSnippetsUrl,\n ).href;\n\n // Setup configuration\n const typedWindow = window;\n typedWindow.METICULOUS_RECORDING_TOKEN = recordingToken ?? projectId;\n\n if (uploadIntervalMs !== undefined) {\n typedWindow.METICULOUS_UPLOAD_INTERVAL_MS = uploadIntervalMs;\n }\n\n if (commitHash !== undefined) {\n typedWindow.METICULOUS_APP_COMMIT_HASH = commitHash;\n }\n\n if (snapshotLinkedStylesheets !== undefined) {\n typedWindow.METICULOUS_SNAPSHOT_LINKED_STYLESHEETS =\n snapshotLinkedStylesheets;\n }\n\n if (forceRecording !== undefined) {\n typedWindow.METICULOUS_FORCE_RECORDING = forceRecording;\n }\n\n if (isProduction !== undefined) {\n typedWindow.METICULOUS_IS_PRODUCTION_ENVIRONMENT = isProduction;\n }\n\n if (responseSanitizers != null && responseSanitizers.length > 0) {\n typedWindow.METICULOUS_NETWORK_RESPONSE_SANITIZERS = responseSanitizers;\n }\n\n if (middleware != null && middleware.length > 0) {\n typedWindow.METICULOUS_RECORDER_MIDDLEWARE_V1 = middleware;\n }\n\n if (disableErrorReporting != null) {\n typedWindow.METICULOUS_DISABLE_ERROR_REPORTING = disableErrorReporting;\n }\n\n if (disableTrackerId != null) {\n typedWindow.METICULOUS_DISABLE_TRACKER_ID = disableTrackerId;\n }\n\n if (maxPayloadSize !== undefined) {\n typedWindow.METICULOUS_MAX_PAYLOAD_SIZE = maxPayloadSize;\n }\n\n script.onload = function () {\n if (abandoned) {\n console.debug(\n \"Meticulous snippet abandoned due to max blocking time reached.\",\n );\n // At this point the promise has already resolved.\n return;\n }\n\n const initialiseRecorder = (window as PrivateWindowApi).__meticulous\n ?.initialiseRecorder;\n if (typeof initialiseRecorder !== \"function\") {\n reject(new Error(\"Meticulous recorder failed to initialise.\"));\n return;\n }\n\n try {\n initialiseRecorder();\n } catch (error) {\n reject(error instanceof Error ? error : new Error(String(error)));\n }\n\n resolve({\n stopRecording: () => {\n const stopRecording = (window as PrivateWindowApi).__meticulous\n ?.stopRecording;\n if (!stopRecording) {\n throw new Error(\n \"Recorder not initialised: window.__meticulous.stopRecording is not defined.\",\n );\n }\n stopRecording();\n return Promise.resolve();\n },\n });\n };\n script.onerror = () => {\n reject(new Error(\"Meticulous recorder failed to initialise.\"));\n };\n\n document.head.appendChild(script);\n });\n};\n\n/**\n * @deprecated Use `tryLoadAndStartRecorder` instead.\n *\n * Load and start the Meticulous Recorder\n */\nexport const loadAndStartRecorder = unsafeLoadAndStartRecorder;\n","export const SNIPPETS_BASE_URL = \"https://snippet.meticulous.ai\";\n","export const getSnippetVersionFolder = (version: string | null) => {\n if (version == null) {\n return \"v1\";\n }\n return `v/${version}`;\n};\n","import { SNIPPETS_BASE_URL } from \"./constants\";\nimport { getSnippetVersionFolder } from \"./get-snippet-version-folder\";\nimport type { Recorder } from \"./loader\";\nimport { tryLoadAndStartRecorder } from \"./loader\";\nimport type { LoaderOptions } from \"./loader.types\";\nimport type { PrivateWindowApi } from \"./private-window-api\";\n\nexport interface Interceptor {\n startRecordingSession: (options: LoaderOptions) => Promise<Recorder>;\n stopIntercepting: () => Promise<void>;\n}\n\nexport interface InterceptorOptions {\n /**\n * If it takes more than the specified number of 'ms' to load the interceptor,\n * then the promise returned by tryInstallMeticulousIntercepts will return\n * immediately (thereby unblocking the load of the application, but preventing\n * Meticulous from recording a correct session, with all required network mocks).\n *\n * Defaults to 2000ms.\n */\n maxMsToBlockFor?: number;\n\n /**\n * Load a specific fixed version of the snippet. If not set will load the\n * latest minor/patch version of the recorder. Bumping to a new major\n * version requires a bump of your @alwaysmeticulous/recorder-loader\n * dependency.\n *\n * Recommendation: leave this unset\n */\n version?: string;\n}\n\nconst DEFAULT_MAX_MS_TO_BLOCK_FOR = 2000;\n\n/**\n * Stores a copy of network requests and responses in memory, but doesn't send them to the\n * server, until the the main recorder is initialised.\n *\n * This is useful if you only want to record sessions for certain users with certain attributes. In\n * this case you have an issue: you need to wait for the user information to load before you know whether\n * you can enable the recorder, but if you enable the recorder after the user information has loaded\n * then the recorder won't be able to capture the initial request & response to load the user information,\n * or other early network responses.\n *\n * The early network recorder solves this: load the early network recorder for all sessions,\n * but only load the main recorder for sessions that you want to record. If when you load the user data\n * you find out you don't want to record the session then you can call the stopRecording() method returned\n * by this method.\n *\n * Example usage:\n *\n * ```\n * // The below call should happen before your app makes any network requests,\n * // or executes any methods that may store a reference to window.fetch or XMLHttpRequest.\n * const interceptor = await tryInstallMeticulousIntercepts();\n *\n * // Later, when you have loaded user data...\n * const userData = await loadUserInfo();\n * if (shouldRecord(userData)) {\n * await interceptor.startRecordingSession({ ... });\n * } else {\n * interceptor.stopIntercepting();\n * }\n * ```\n */\nexport const tryInstallMeticulousIntercepts = async (\n options: InterceptorOptions,\n): Promise<Interceptor> => {\n let requestedToStopIntercepting = false;\n let disposedEarlyNetworkRecorder = false;\n const stopIntercepting = async () => {\n requestedToStopIntercepting = true;\n const disposeFunction = (window as PrivateWindowApi)?.__meticulous\n ?.earlyNetworkRecorder?.dispose;\n if (disposeFunction && !disposedEarlyNetworkRecorder) {\n await disposeFunction();\n disposedEarlyNetworkRecorder = true;\n }\n };\n const interceptor = {\n startRecordingSession: tryLoadAndStartRecorder,\n stopIntercepting,\n };\n\n const maxMsToBlockFor =\n options.maxMsToBlockFor ?? DEFAULT_MAX_MS_TO_BLOCK_FOR;\n const promise = new Promise<Interceptor>((resolve, reject) => {\n const timeout =\n maxMsToBlockFor > 0\n ? setTimeout(() => {\n resolve(interceptor);\n }, maxMsToBlockFor)\n : null;\n\n const script = document.createElement(\"script\");\n script.type = \"text/javascript\";\n script.src = `${SNIPPETS_BASE_URL}/record/${getSnippetVersionFolder(\n options.version ?? null,\n )}/network-recorder.bundle.js`;\n\n script.onload = function () {\n if (timeout) {\n window.clearTimeout(timeout);\n }\n resolve(interceptor);\n };\n script.onerror = () => {\n if (timeout) {\n window.clearTimeout(timeout);\n }\n reject(\n new Error(\"Meticulous early network recorder failed to initialise.\"),\n );\n };\n\n document.head.appendChild(script);\n });\n\n // Try to load the early network recorder and silence any initialisation error.\n return promise\n .catch((error) => {\n console.error(error);\n return interceptor;\n })\n .finally(() => {\n if (requestedToStopIntercepting) {\n void stopIntercepting();\n }\n });\n};\n","import type { PrivateWindowApi } from \"./private-window-api\";\n\n/**\n * If you add 'https://snippet.meticulous.ai/record/v1/network-recorder.bundle.js' as a script tag\n * then Meticulous will start off by recording any network requests in memory but not send the data to Meticulous’s\n * servers. Once you have the information to determine whether you want to record and persist the session\n * you can then call {@link tryLoadAndStartRecorder} if you do want to record, or this stopIntercepting method\n * if you do not want to record. When you call stopIntercepting any network requests/responses stored in memory\n * will be dropped and Meticulous will be deactivated. No data will be sent to Meticulous's servers.\n *\n * Please note that if you've already started recording and sending data to Meticulous's services i.e.\n * loaded the main meticulous recorder script or called tryLoadAndStartRecorder then this method will\n * not stop the recording. For that you need to call the stopRecording method returned by tryLoadAndStartRecorder.\n */\nexport const stopIntercepting = async () => {\n const disposeFunction = (window as PrivateWindowApi)?.__meticulous\n ?.earlyNetworkRecorder?.dispose;\n if (disposeFunction) {\n await disposeFunction();\n }\n};\n"],"names":[],"mappings":"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","debugId":"c68db38f-cc00-5c41-a1a7-b9de35e2c52e"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alwaysmeticulous/recorder-loader",
3
- "version": "2.295.0",
3
+ "version": "2.300.0",
4
4
  "license": "ISC",
5
5
  "source": "src/index.ts",
6
6
  "main": "dist/index.js",
@@ -11,7 +11,7 @@
11
11
  ],
12
12
  "sideEffects": false,
13
13
  "dependencies": {
14
- "@alwaysmeticulous/sdk-bundles-api": "2.295.0"
14
+ "@alwaysmeticulous/sdk-bundles-api": "2.300.0"
15
15
  },
16
16
  "devDependencies": {
17
17
  "parcel": "^2.15.2"
@@ -35,9 +35,9 @@
35
35
  "dev": "parcel watch",
36
36
  "build": "parcel build",
37
37
  "format": "prettier --write src",
38
- "lint": "eslint \"src/**/*.{js,ts,tsx}\" --cache",
38
+ "lint": "oxlint --type-aware src",
39
39
  "lint:commit": "eslint --cache $(git diff --relative --name-only --diff-filter=ACMRTUXB master | grep -E \"(.js$|.ts$|.tsx$)\")",
40
- "lint:fix": "eslint \"src/**/*.{js,ts,tsx}\" --cache --fix",
40
+ "lint:fix": "oxlint --type-aware src --fix",
41
41
  "depcheck": "depcheck --ignore-patterns=dist"
42
42
  }
43
43
  }
package/LICENSE DELETED
@@ -1,15 +0,0 @@
1
- ISC License
2
-
3
- Copyright (c) 2022, Meticulous Contributors
4
-
5
- Permission to use, copy, modify, and/or distribute this software for any
6
- purpose with or without fee is hereby granted, provided that the above
7
- copyright notice and this permission notice appear in all copies.
8
-
9
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15
- PERFORMANCE OF THIS SOFTWARE.