@thumbmarkjs/thumbmarkjs 1.0.0 → 1.1.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -9
- package/dist/thumbmark.cjs.js +1 -1
- package/dist/thumbmark.cjs.js.map +1 -1
- package/dist/thumbmark.esm.d.ts +5 -5
- package/dist/thumbmark.esm.js +1 -1
- package/dist/thumbmark.esm.js.map +1 -1
- package/dist/thumbmark.umd.js +1 -1
- package/dist/thumbmark.umd.js.map +1 -1
- package/dist/types/components/audio/index.d.ts +2 -0
- package/dist/types/components/canvas/index.d.ts +3 -0
- package/dist/types/components/fonts/index.d.ts +4 -0
- package/dist/types/components/hardware/index.d.ts +2 -0
- package/dist/types/components/locales/index.d.ts +2 -0
- package/dist/types/components/math/index.d.ts +2 -0
- package/dist/types/components/permissions/index.d.ts +3 -0
- package/dist/types/components/plugins/index.d.ts +2 -0
- package/dist/types/components/screen/index.d.ts +2 -0
- package/dist/types/components/system/browser.d.ts +7 -0
- package/dist/types/components/system/index.d.ts +2 -0
- package/dist/types/components/webgl/index.d.ts +2 -0
- package/dist/types/factory.d.ts +51 -0
- package/dist/types/functions/filterComponents.d.ts +11 -0
- package/dist/types/functions/index.d.ts +87 -0
- package/dist/types/functions/legacy_functions.d.ts +27 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/options.d.ts +28 -0
- package/dist/types/thumbmark.d.ts +26 -0
- package/dist/types/utils/commonPixels.d.ts +1 -0
- package/dist/types/utils/ephemeralIFrame.d.ts +4 -0
- package/dist/types/utils/getMostFrequent.d.ts +5 -0
- package/dist/types/utils/hash.d.ts +5 -0
- package/dist/types/utils/imageDataToDataURL.d.ts +1 -0
- package/dist/types/utils/log.d.ts +8 -0
- package/dist/types/utils/raceAll.d.ts +9 -0
- package/dist/types/utils/version.d.ts +4 -0
- package/package.json +1 -1
- package/src/components/canvas/index.ts +1 -1
- package/src/components/plugins/index.ts +26 -17
- package/src/functions/index.ts +18 -55
- package/src/index.ts +2 -1
- package/src/options.ts +4 -2
- package/src/thumbmark.ts +2 -1
- package/src/utils/log.ts +34 -0
- package/src/utils/version.ts +8 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ThumbmarkJS: Main fingerprinting and API logic
|
|
3
|
+
*
|
|
4
|
+
* This module handles component collection, API calls, uniqueness scoring, and data filtering
|
|
5
|
+
* for the ThumbmarkJS browser fingerprinting library.
|
|
6
|
+
*
|
|
7
|
+
* Exports:
|
|
8
|
+
* - getThumbmark
|
|
9
|
+
* - getThumbmarkDataFromPromiseMap
|
|
10
|
+
* - resolveClientComponents
|
|
11
|
+
* - filterThumbmarkData
|
|
12
|
+
*
|
|
13
|
+
* Internal helpers and types are also defined here.
|
|
14
|
+
*/
|
|
15
|
+
import { optionsInterface } from "../options";
|
|
16
|
+
import { componentInterface, includeComponent as globalIncludeComponent } from "../factory";
|
|
17
|
+
/**
|
|
18
|
+
* Info returned from the API (IP, classification, uniqueness, etc)
|
|
19
|
+
*/
|
|
20
|
+
interface infoInterface {
|
|
21
|
+
ip_address?: {
|
|
22
|
+
ip_address: string;
|
|
23
|
+
ip_identifier: string;
|
|
24
|
+
autonomous_system_number: number;
|
|
25
|
+
ip_version: 'v6' | 'v4';
|
|
26
|
+
};
|
|
27
|
+
classification?: {
|
|
28
|
+
tor: boolean;
|
|
29
|
+
proxy: boolean;
|
|
30
|
+
datacenter: boolean;
|
|
31
|
+
danger_level: number;
|
|
32
|
+
};
|
|
33
|
+
uniqueness?: {
|
|
34
|
+
score: number | string;
|
|
35
|
+
};
|
|
36
|
+
timed_out?: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* API response structure
|
|
40
|
+
*/
|
|
41
|
+
interface apiResponse {
|
|
42
|
+
thumbmark?: string;
|
|
43
|
+
info?: infoInterface;
|
|
44
|
+
version?: string;
|
|
45
|
+
components?: componentInterface;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Final thumbmark response structure
|
|
49
|
+
*/
|
|
50
|
+
interface thumbmarkResponse {
|
|
51
|
+
components: componentInterface;
|
|
52
|
+
info: {
|
|
53
|
+
[key: string]: any;
|
|
54
|
+
};
|
|
55
|
+
version: string;
|
|
56
|
+
thumbmark: string;
|
|
57
|
+
/**
|
|
58
|
+
* Only present if options.performance is true.
|
|
59
|
+
*/
|
|
60
|
+
elapsed?: any;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Calls the Thumbmark API with the given components, using caching and deduplication.
|
|
64
|
+
* Returns a promise for the API response or null on error.
|
|
65
|
+
*/
|
|
66
|
+
export declare const getApiPromise: (options: optionsInterface, components: componentInterface) => Promise<apiResponse | null>;
|
|
67
|
+
/**
|
|
68
|
+
* Main entry point: collects all components, optionally calls API, and returns thumbmark data.
|
|
69
|
+
*
|
|
70
|
+
* @param options - Options for fingerprinting and API
|
|
71
|
+
* @returns thumbmarkResponse (elapsed is present only if options.performance is true)
|
|
72
|
+
*/
|
|
73
|
+
export declare function getThumbmark(options?: optionsInterface): Promise<thumbmarkResponse>;
|
|
74
|
+
/**
|
|
75
|
+
* Resolves and times all filtered component promises from a component function map.
|
|
76
|
+
*
|
|
77
|
+
* @param comps - Map of component functions
|
|
78
|
+
* @param options - Options for filtering and timing
|
|
79
|
+
* @returns Object with elapsed times and filtered resolved components
|
|
80
|
+
*/
|
|
81
|
+
export declare function resolveClientComponents(comps: {
|
|
82
|
+
[key: string]: (options?: optionsInterface) => Promise<componentInterface | null>;
|
|
83
|
+
}, options?: optionsInterface): Promise<{
|
|
84
|
+
elapsed: Record<string, number>;
|
|
85
|
+
resolvedComponents: componentInterface;
|
|
86
|
+
}>;
|
|
87
|
+
export { globalIncludeComponent as includeComponent };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is here to support legacy implementations.
|
|
3
|
+
* Eventually, these functions will be removed to keep the library small.
|
|
4
|
+
*/
|
|
5
|
+
import { componentInterface } from '../factory';
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @deprecated
|
|
9
|
+
*/
|
|
10
|
+
export declare function getFingerprintData(): Promise<componentInterface>;
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
* @param includeData boolean
|
|
14
|
+
* @deprecated this function is going to be removed. use getThumbmark or Thumbmark class instead.
|
|
15
|
+
*/
|
|
16
|
+
export declare function getFingerprint(includeData?: false): Promise<string>;
|
|
17
|
+
export declare function getFingerprint(includeData: true): Promise<{
|
|
18
|
+
hash: string;
|
|
19
|
+
data: componentInterface;
|
|
20
|
+
}>;
|
|
21
|
+
/**
|
|
22
|
+
*
|
|
23
|
+
* @deprecated use Thumbmark or getThumbmark instead with options
|
|
24
|
+
*/
|
|
25
|
+
export declare function getFingerprintPerformance(): Promise<{
|
|
26
|
+
elapsed: Record<string, number>;
|
|
27
|
+
}>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { getFingerprint, getFingerprintData, getFingerprintPerformance } from './functions/legacy_functions';
|
|
2
|
+
import { getThumbmark } from './functions';
|
|
3
|
+
import { getVersion } from './utils/version';
|
|
4
|
+
import { setOption } from './options';
|
|
5
|
+
import { includeComponent } from './factory';
|
|
6
|
+
import { Thumbmark } from './thumbmark';
|
|
7
|
+
export { Thumbmark, getThumbmark, getVersion, setOption, getFingerprint, getFingerprintData, getFingerprintPerformance, includeComponent };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface optionsInterface {
|
|
2
|
+
exclude?: string[];
|
|
3
|
+
include?: string[];
|
|
4
|
+
permissions_to_check?: PermissionName[];
|
|
5
|
+
timeout?: number;
|
|
6
|
+
logging?: boolean;
|
|
7
|
+
api_key?: string;
|
|
8
|
+
cache_api_call?: boolean;
|
|
9
|
+
performance?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare const API_ENDPOINT = "https://api.thumbmarkjs.com";
|
|
12
|
+
export declare const defaultOptions: optionsInterface;
|
|
13
|
+
export declare let options: {
|
|
14
|
+
exclude?: string[] | undefined;
|
|
15
|
+
include?: string[] | undefined;
|
|
16
|
+
permissions_to_check?: PermissionName[] | undefined;
|
|
17
|
+
timeout?: number | undefined;
|
|
18
|
+
logging?: boolean | undefined;
|
|
19
|
+
api_key?: string | undefined;
|
|
20
|
+
cache_api_call?: boolean | undefined;
|
|
21
|
+
performance?: boolean | undefined;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
*
|
|
25
|
+
* @param key @deprecated this function will be removed
|
|
26
|
+
* @param value
|
|
27
|
+
*/
|
|
28
|
+
export declare function setOption<K extends keyof optionsInterface>(key: K, value: optionsInterface[K]): void;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { optionsInterface } from "./options";
|
|
2
|
+
import { componentInterface } from "./factory";
|
|
3
|
+
/**
|
|
4
|
+
* A client for generating thumbmarks with a persistent configuration.
|
|
5
|
+
*/
|
|
6
|
+
export declare class Thumbmark {
|
|
7
|
+
private options;
|
|
8
|
+
/**
|
|
9
|
+
* Creates a new Thumbmarker client instance.
|
|
10
|
+
* @param options - Default configuration options for this instance.
|
|
11
|
+
*/
|
|
12
|
+
constructor(options?: optionsInterface);
|
|
13
|
+
/**
|
|
14
|
+
* Generates a thumbmark using the instance's configuration.
|
|
15
|
+
* @param overrideOptions - Options to override for this specific call.
|
|
16
|
+
* @returns The thumbmark result.
|
|
17
|
+
*/
|
|
18
|
+
get(overrideOptions?: optionsInterface): Promise<any>;
|
|
19
|
+
getVersion(): string;
|
|
20
|
+
/**
|
|
21
|
+
* Register a custom component to be included in the fingerprint.
|
|
22
|
+
* @param key - The component name
|
|
23
|
+
* @param fn - The component function
|
|
24
|
+
*/
|
|
25
|
+
includeComponent(key: string, fn: (options?: optionsInterface) => Promise<componentInterface | null>): void;
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getCommonPixels(images: ImageData[], width: number, height: number): ImageData;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function imageDataToDataURL(imageData: ImageData): string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { componentInterface } from '../factory';
|
|
2
|
+
import { optionsInterface } from '../options';
|
|
3
|
+
/**
|
|
4
|
+
* Logs thumbmark data to remote logging endpoint (only once per session)
|
|
5
|
+
* You can disable this by setting options.logging to false.
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export declare function logThumbmarkData(thisHash: string, thumbmarkData: componentInterface, options: optionsInterface): Promise<void>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type DelayedPromise<T> = Promise<T>;
|
|
2
|
+
export declare function delay<T>(t: number, val: T): DelayedPromise<T>;
|
|
3
|
+
export interface RaceResult<T> {
|
|
4
|
+
value: T;
|
|
5
|
+
elapsed?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function raceAllPerformance<T>(promises: Promise<T>[], timeoutTime: number, timeoutVal: T): Promise<RaceResult<T>[]>;
|
|
8
|
+
export declare function raceAll<T>(promises: Promise<T>[], timeoutTime: number, timeoutVal: T): Promise<(T | undefined)[]>;
|
|
9
|
+
export {};
|
package/package.json
CHANGED
|
@@ -20,7 +20,7 @@ export default async function getCanvas(): Promise<componentInterface | null> {
|
|
|
20
20
|
const name = browser.name.toLowerCase();
|
|
21
21
|
const ver = browser.version.split('.')[0] || '0';
|
|
22
22
|
const majorVer = parseInt(ver, 10);
|
|
23
|
-
if (
|
|
23
|
+
if (!['firefox', 'brave'].includes(name) && !(name === 'safari' && majorVer >= 17))
|
|
24
24
|
return generateCanvasFingerprint()
|
|
25
25
|
return null;
|
|
26
26
|
}
|
|
@@ -1,20 +1,29 @@
|
|
|
1
1
|
import { componentInterface, includeComponent } from '../../factory'
|
|
2
|
+
import { getBrowser } from '../system/browser';
|
|
2
3
|
|
|
3
|
-
export default function getPlugins(): Promise<componentInterface> {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
export default async function getPlugins(): Promise<componentInterface | null> {
|
|
5
|
+
const browser = getBrowser();
|
|
6
|
+
const name = browser.name.toLowerCase();
|
|
7
|
+
|
|
8
|
+
// Brave will scramble the plugins list, so not including it.
|
|
9
|
+
if (['brave'].includes(name)) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const plugins: string[] = [];
|
|
14
|
+
|
|
15
|
+
if (navigator.plugins) {
|
|
16
|
+
for (let i = 0; i < navigator.plugins.length; i++) {
|
|
17
|
+
const plugin = navigator.plugins[i];
|
|
18
|
+
plugins.push([plugin.name, plugin.filename, plugin.description ].join("|"));
|
|
11
19
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return new Promise((resolve) => {
|
|
23
|
+
resolve(
|
|
24
|
+
{
|
|
25
|
+
'plugins': plugins
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
}
|
package/src/functions/index.ts
CHANGED
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
* - getThumbmark
|
|
9
9
|
* - getThumbmarkDataFromPromiseMap
|
|
10
10
|
* - resolveClientComponents
|
|
11
|
-
* - getVersion
|
|
12
11
|
* - filterThumbmarkData
|
|
13
12
|
*
|
|
14
13
|
* Internal helpers and types are also defined here.
|
|
@@ -25,8 +24,10 @@ import {
|
|
|
25
24
|
} from "../factory";
|
|
26
25
|
import { hash } from "../utils/hash";
|
|
27
26
|
import { raceAllPerformance } from "../utils/raceAll";
|
|
28
|
-
import
|
|
27
|
+
import { getVersion } from "../utils/version";
|
|
29
28
|
import { filterThumbmarkData } from './filterComponents'
|
|
29
|
+
import { logThumbmarkData } from '../utils/log';
|
|
30
|
+
import { API_ENDPOINT } from "../options";
|
|
30
31
|
|
|
31
32
|
// ===================== Types & Interfaces =====================
|
|
32
33
|
|
|
@@ -42,7 +43,7 @@ interface infoInterface {
|
|
|
42
43
|
},
|
|
43
44
|
classification?: {
|
|
44
45
|
tor: boolean,
|
|
45
|
-
proxy: boolean,
|
|
46
|
+
proxy: boolean,
|
|
46
47
|
datacenter: boolean,
|
|
47
48
|
danger_level: number, // 5 is highest and should be blocked. 0 is no danger.
|
|
48
49
|
},
|
|
@@ -59,6 +60,7 @@ interface apiResponse {
|
|
|
59
60
|
thumbmark?: string;
|
|
60
61
|
info?: infoInterface;
|
|
61
62
|
version?: string;
|
|
63
|
+
components?: componentInterface;
|
|
62
64
|
}
|
|
63
65
|
|
|
64
66
|
/**
|
|
@@ -75,14 +77,7 @@ interface thumbmarkResponse {
|
|
|
75
77
|
elapsed?: any;
|
|
76
78
|
}
|
|
77
79
|
|
|
78
|
-
// ===================== Version =====================
|
|
79
80
|
|
|
80
|
-
/**
|
|
81
|
-
* Returns the current package version
|
|
82
|
-
*/
|
|
83
|
-
export function getVersion(): string {
|
|
84
|
-
return packageJson.version;
|
|
85
|
-
}
|
|
86
81
|
|
|
87
82
|
// ===================== API Call Logic =====================
|
|
88
83
|
|
|
@@ -108,14 +103,15 @@ export const getApiPromise = (
|
|
|
108
103
|
}
|
|
109
104
|
|
|
110
105
|
// 3. Otherwise, initiate a new API call with timeout.
|
|
111
|
-
const endpoint =
|
|
106
|
+
const endpoint = `${API_ENDPOINT}/thumbmark`;
|
|
112
107
|
const fetchPromise = fetch(endpoint, {
|
|
113
108
|
method: 'POST',
|
|
114
109
|
headers: {
|
|
115
110
|
'x-api-key': options.api_key!,
|
|
116
111
|
'Authorization': 'custom-authorized',
|
|
112
|
+
'Content-Type': 'application/json',
|
|
117
113
|
},
|
|
118
|
-
body: JSON.stringify({ components
|
|
114
|
+
body: JSON.stringify({ components, options, clientHash: hash(JSON.stringify(components)) }),
|
|
119
115
|
})
|
|
120
116
|
.then(response => {
|
|
121
117
|
// Handle HTTP errors that aren't network errors
|
|
@@ -143,7 +139,7 @@ export const getApiPromise = (
|
|
|
143
139
|
resolve({
|
|
144
140
|
thumbmark: hash(JSON.stringify(components)),
|
|
145
141
|
info: { timed_out: true },
|
|
146
|
-
version:
|
|
142
|
+
version: getVersion(),
|
|
147
143
|
});
|
|
148
144
|
}, timeoutMs);
|
|
149
145
|
});
|
|
@@ -171,24 +167,16 @@ export async function getThumbmark(options?: optionsInterface): Promise<thumbmar
|
|
|
171
167
|
|
|
172
168
|
// Only add 'elapsed' if performance is true
|
|
173
169
|
const maybeElapsed = _options.performance ? { elapsed } : {};
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
info,
|
|
180
|
-
version: getVersion(),
|
|
181
|
-
thumbmark: apiResult.thumbmark || 'undefined',
|
|
182
|
-
...maybeElapsed,
|
|
183
|
-
};
|
|
184
|
-
}
|
|
170
|
+
const components = {...clientComponentsResult, ...apiResult?.components || {}};
|
|
171
|
+
const info: infoInterface = apiResult?.info || { uniqueness: { score: 'api only' } };
|
|
172
|
+
const thumbmark = hash(JSON.stringify(components));
|
|
173
|
+
const version = getVersion();
|
|
174
|
+
logThumbmarkData(thumbmark, components, _options).catch(() => { /* do nothing */ });
|
|
185
175
|
return {
|
|
186
|
-
thumbmark
|
|
187
|
-
components:
|
|
188
|
-
info
|
|
189
|
-
|
|
190
|
-
},
|
|
191
|
-
version: getVersion(),
|
|
176
|
+
thumbmark,
|
|
177
|
+
components: components,
|
|
178
|
+
info,
|
|
179
|
+
version,
|
|
192
180
|
...maybeElapsed,
|
|
193
181
|
};
|
|
194
182
|
}
|
|
@@ -232,31 +220,6 @@ export async function resolveClientComponents(
|
|
|
232
220
|
return { elapsed, resolvedComponents };
|
|
233
221
|
}
|
|
234
222
|
|
|
235
|
-
// ===================== Logging (Internal) =====================
|
|
236
223
|
|
|
237
|
-
/**
|
|
238
|
-
* Logs thumbmark data to remote logging endpoint (only once per session)
|
|
239
|
-
* @internal
|
|
240
|
-
*/
|
|
241
|
-
async function logThumbmarkData(thisHash: string, thumbmarkData: componentInterface) {
|
|
242
|
-
const url = 'https://logging.thumbmarkjs.com/v1/log';
|
|
243
|
-
const payload = {
|
|
244
|
-
thumbmark: thisHash,
|
|
245
|
-
components: thumbmarkData,
|
|
246
|
-
version: getVersion()
|
|
247
|
-
};
|
|
248
|
-
if (!sessionStorage.getItem("_tmjs_l")) {
|
|
249
|
-
sessionStorage.setItem("_tmjs_l", "1");
|
|
250
|
-
try {
|
|
251
|
-
await fetch(url, {
|
|
252
|
-
method: 'POST',
|
|
253
|
-
headers: {
|
|
254
|
-
'Content-Type': 'application/json'
|
|
255
|
-
},
|
|
256
|
-
body: JSON.stringify(payload)
|
|
257
|
-
});
|
|
258
|
-
} catch { /* do nothing */ }
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
224
|
|
|
262
225
|
export { globalIncludeComponent as includeComponent };
|
package/src/index.ts
CHANGED
|
@@ -3,7 +3,8 @@ import {
|
|
|
3
3
|
getFingerprintData,
|
|
4
4
|
getFingerprintPerformance
|
|
5
5
|
} from './functions/legacy_functions'
|
|
6
|
-
import { getThumbmark
|
|
6
|
+
import { getThumbmark } from './functions'
|
|
7
|
+
import { getVersion } from './utils/version';
|
|
7
8
|
import { setOption } from './options'
|
|
8
9
|
import { includeComponent } from './factory'
|
|
9
10
|
import { Thumbmark } from './thumbmark'
|
package/src/options.ts
CHANGED
|
@@ -6,16 +6,18 @@ export interface optionsInterface {
|
|
|
6
6
|
logging?: boolean,
|
|
7
7
|
api_key?: string,
|
|
8
8
|
cache_api_call?: boolean,
|
|
9
|
-
performance?: boolean,
|
|
9
|
+
performance?: boolean,
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
export const API_ENDPOINT = 'https://api.thumbmarkjs.com';
|
|
13
|
+
|
|
12
14
|
export const defaultOptions: optionsInterface = {
|
|
13
15
|
exclude: [],
|
|
14
16
|
include: [],
|
|
15
17
|
logging: true,
|
|
16
18
|
timeout: 5000,
|
|
17
19
|
cache_api_call: true,
|
|
18
|
-
performance: false
|
|
20
|
+
performance: false
|
|
19
21
|
};
|
|
20
22
|
|
|
21
23
|
export let options = {...defaultOptions};
|
package/src/thumbmark.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { optionsInterface } from "./options";
|
|
2
|
-
import { getThumbmark,
|
|
2
|
+
import { getThumbmark, includeComponent as globalIncludeComponent } from './functions';
|
|
3
|
+
import { getVersion } from "./utils/version";
|
|
3
4
|
import { defaultOptions } from "./options";
|
|
4
5
|
import { componentInterface } from "./factory";
|
|
5
6
|
|
package/src/utils/log.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { componentInterface } from '../factory';
|
|
2
|
+
import { optionsInterface } from '../options';
|
|
3
|
+
import { getVersion } from './version';
|
|
4
|
+
import { API_ENDPOINT } from '../options';
|
|
5
|
+
|
|
6
|
+
// ===================== Logging (Internal) =====================
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Logs thumbmark data to remote logging endpoint (only once per session)
|
|
10
|
+
* You can disable this by setting options.logging to false.
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export async function logThumbmarkData(thisHash: string, thumbmarkData: componentInterface, options: optionsInterface): Promise<void> {
|
|
14
|
+
const url = `${API_ENDPOINT}/log`;
|
|
15
|
+
const payload = {
|
|
16
|
+
thumbmark: thisHash,
|
|
17
|
+
components: thumbmarkData,
|
|
18
|
+
version: getVersion(),
|
|
19
|
+
options,
|
|
20
|
+
path: window?.location?.pathname,
|
|
21
|
+
};
|
|
22
|
+
if (!sessionStorage.getItem("_tmjs_l") && Math.random() < 0.0001) { // Only log once per session and very rarely
|
|
23
|
+
sessionStorage.setItem("_tmjs_l", "1");
|
|
24
|
+
try {
|
|
25
|
+
await fetch(url, {
|
|
26
|
+
method: 'POST',
|
|
27
|
+
headers: {
|
|
28
|
+
'Content-Type': 'application/json'
|
|
29
|
+
},
|
|
30
|
+
body: JSON.stringify(payload)
|
|
31
|
+
});
|
|
32
|
+
} catch { /* do nothing */ }
|
|
33
|
+
}
|
|
34
|
+
}
|