clarity-js 0.8.11 → 0.8.13-beta
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/build/clarity.extended.js +1 -1
- package/build/clarity.insight.js +1 -1
- package/build/clarity.js +2964 -3181
- package/build/clarity.min.js +1 -1
- package/build/clarity.module.js +2964 -3181
- package/build/clarity.performance.js +1 -1
- package/package.json +69 -76
- package/rollup.config.ts +88 -84
- package/src/clarity.ts +28 -34
- package/src/core/config.ts +2 -2
- package/src/core/event.ts +32 -36
- package/src/core/hash.ts +6 -5
- package/src/core/history.ts +11 -10
- package/src/core/index.ts +11 -21
- package/src/core/measure.ts +5 -9
- package/src/core/report.ts +3 -3
- package/src/core/scrub.ts +20 -29
- package/src/core/task.ts +45 -73
- package/src/core/time.ts +3 -3
- package/src/core/timeout.ts +2 -2
- package/src/core/version.ts +1 -1
- package/src/data/baseline.ts +55 -60
- package/src/data/consent.ts +2 -2
- package/src/data/custom.ts +13 -8
- package/src/data/dimension.ts +7 -11
- package/src/data/encode.ts +30 -36
- package/src/data/envelope.ts +38 -38
- package/src/data/extract.ts +77 -86
- package/src/data/index.ts +6 -10
- package/src/data/limit.ts +1 -1
- package/src/data/metadata.ts +266 -305
- package/src/data/metric.ts +8 -18
- package/src/data/ping.ts +4 -8
- package/src/data/signal.ts +18 -18
- package/src/data/summary.ts +4 -6
- package/src/data/token.ts +8 -10
- package/src/data/upgrade.ts +3 -7
- package/src/data/upload.ts +49 -100
- package/src/data/variable.ts +20 -27
- package/src/diagnostic/encode.ts +2 -2
- package/src/diagnostic/fraud.ts +4 -3
- package/src/diagnostic/internal.ts +5 -11
- package/src/diagnostic/script.ts +8 -12
- package/src/global.ts +1 -1
- package/src/insight/blank.ts +4 -4
- package/src/insight/encode.ts +17 -23
- package/src/insight/snapshot.ts +37 -57
- package/src/interaction/change.ts +6 -9
- package/src/interaction/click.ts +28 -34
- package/src/interaction/clipboard.ts +2 -2
- package/src/interaction/encode.ts +31 -35
- package/src/interaction/input.ts +9 -11
- package/src/interaction/pointer.ts +24 -35
- package/src/interaction/resize.ts +5 -5
- package/src/interaction/scroll.ts +11 -14
- package/src/interaction/selection.ts +8 -12
- package/src/interaction/submit.ts +2 -2
- package/src/interaction/timeline.ts +9 -13
- package/src/interaction/unload.ts +1 -1
- package/src/interaction/visibility.ts +2 -2
- package/src/layout/animation.ts +41 -47
- package/src/layout/discover.ts +5 -5
- package/src/layout/document.ts +19 -31
- package/src/layout/dom.ts +91 -141
- package/src/layout/encode.ts +37 -52
- package/src/layout/mutation.ts +318 -321
- package/src/layout/node.ts +81 -104
- package/src/layout/offset.ts +6 -7
- package/src/layout/region.ts +40 -60
- package/src/layout/schema.ts +8 -15
- package/src/layout/selector.ts +25 -47
- package/src/layout/style.ts +36 -44
- package/src/layout/target.ts +10 -14
- package/src/layout/traverse.ts +11 -17
- package/src/performance/blank.ts +1 -1
- package/src/performance/encode.ts +4 -4
- package/src/performance/interaction.ts +70 -58
- package/src/performance/navigation.ts +2 -2
- package/src/performance/observer.ts +26 -59
- package/src/queue.ts +9 -16
- package/tsconfig.json +1 -1
- package/tslint.json +32 -25
- package/types/core.d.ts +13 -13
- package/types/data.d.ts +29 -32
- package/types/diagnostic.d.ts +1 -1
- package/types/interaction.d.ts +4 -4
- package/types/layout.d.ts +21 -36
- package/types/performance.d.ts +5 -6
- package/.lintstagedrc.yml +0 -3
- package/biome.json +0 -43
package/src/data/extract.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { ExtractSource,
|
|
2
|
-
import { Event,
|
|
1
|
+
import { ExtractSource, Syntax, Type } from "@clarity-types/core";
|
|
2
|
+
import { Event, Setting, ExtractData } from "@clarity-types/data";
|
|
3
|
+
import encode from "./encode";
|
|
4
|
+
import * as internal from "@src/diagnostic/internal";
|
|
3
5
|
import { Code, Constant, Severity } from "@clarity-types/data";
|
|
4
6
|
import { hashText } from "@src/clarity";
|
|
5
7
|
import hash from "@src/core/hash";
|
|
6
|
-
import * as internal from "@src/diagnostic/internal";
|
|
7
|
-
import encode from "./encode";
|
|
8
8
|
|
|
9
|
-
export
|
|
10
|
-
export
|
|
9
|
+
export let data: ExtractData = {};
|
|
10
|
+
export let keys: Set<number> = new Set();
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
let variables : { [key: number]: { [key: number]: Syntax[] }} = {};
|
|
13
|
+
let selectors : { [key: number]: { [key: number]: string }} = {};
|
|
14
|
+
let hashes : { [key: number]: { [key: number]: string }} = {};
|
|
15
|
+
let validation : { [key: number]: string } = {};
|
|
16
16
|
|
|
17
17
|
export function start(): void {
|
|
18
18
|
reset();
|
|
@@ -23,45 +23,44 @@ export function start(): void {
|
|
|
23
23
|
// if element is present on the page it will set up event 101 to grab the contents of the class1 selector into component 1,
|
|
24
24
|
// the javascript evaluated contents of window.a.b into component 2,
|
|
25
25
|
// and the contents of Clarity's hash abc into component 3
|
|
26
|
-
export function trigger(input: string): void {
|
|
26
|
+
export function trigger(input: string): void {
|
|
27
27
|
try {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
var parts = input && input.length > 0 ? input.split(/ (.*)/) : [Constant.Empty];
|
|
29
|
+
var keyparts = parts[0].split(/\|(.*)/);
|
|
30
|
+
var key = parseInt(keyparts[0]);
|
|
31
|
+
var element = keyparts.length > 1 ? keyparts[1] : Constant.Empty;
|
|
32
|
+
var values = parts.length > 1 ? JSON.parse(parts[1]) : {};
|
|
33
33
|
variables[key] = {};
|
|
34
34
|
selectors[key] = {};
|
|
35
35
|
hashes[key] = {};
|
|
36
36
|
validation[key] = element;
|
|
37
|
-
for (
|
|
38
|
-
// values is a set of strings for proper JSON parsing, but it's more efficient
|
|
37
|
+
for (var v in values) {
|
|
38
|
+
// values is a set of strings for proper JSON parsing, but it's more efficient
|
|
39
39
|
// to interact with them as numbers
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
let id = parseInt(v);
|
|
41
|
+
let value = values[v] as string;
|
|
42
42
|
let source = ExtractSource.Text;
|
|
43
43
|
if (value.startsWith(Constant.Tilde)) {
|
|
44
|
-
source = ExtractSource.Javascript
|
|
44
|
+
source = ExtractSource.Javascript
|
|
45
45
|
} else if (value.startsWith(Constant.Bang)) {
|
|
46
|
-
source = ExtractSource.Hash
|
|
46
|
+
source = ExtractSource.Hash
|
|
47
47
|
}
|
|
48
48
|
switch (source) {
|
|
49
|
-
case ExtractSource.Javascript:
|
|
50
|
-
|
|
49
|
+
case ExtractSource.Javascript:
|
|
50
|
+
let variable = value.slice(1);
|
|
51
51
|
variables[key][id] = parse(variable);
|
|
52
52
|
break;
|
|
53
|
-
}
|
|
54
53
|
case ExtractSource.Text:
|
|
55
54
|
selectors[key][id] = value;
|
|
56
55
|
break;
|
|
57
|
-
case ExtractSource.Hash:
|
|
58
|
-
|
|
56
|
+
case ExtractSource.Hash:
|
|
57
|
+
let hash = value.slice(1);
|
|
59
58
|
hashes[key][id] = hash;
|
|
60
59
|
break;
|
|
61
|
-
}
|
|
62
60
|
}
|
|
63
61
|
}
|
|
64
|
-
}
|
|
62
|
+
}
|
|
63
|
+
catch(e) {
|
|
65
64
|
internal.log(Code.Config, Severity.Warning, e ? e.name : null);
|
|
66
65
|
}
|
|
67
66
|
}
|
|
@@ -72,40 +71,39 @@ export function clone(v: Syntax[]): Syntax[] {
|
|
|
72
71
|
|
|
73
72
|
export function compute(): void {
|
|
74
73
|
try {
|
|
75
|
-
for (
|
|
76
|
-
|
|
77
|
-
if (validation[key]
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
74
|
+
for (let v in variables) {
|
|
75
|
+
let key = parseInt(v);
|
|
76
|
+
if (validation[key] == Constant.Empty || document.querySelector(validation[key]))
|
|
77
|
+
{
|
|
78
|
+
let variableData = variables[key];
|
|
79
|
+
for (let v in variableData) {
|
|
80
|
+
let variableKey = parseInt(v);
|
|
81
|
+
let value = str(evaluate(clone(variableData[variableKey])));
|
|
82
|
+
if (value) {
|
|
83
83
|
update(key, variableKey, value);
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
for (
|
|
87
|
+
let selectorData = selectors[key];
|
|
88
|
+
for (let s in selectorData) {
|
|
89
89
|
let shouldMask = false;
|
|
90
|
-
|
|
90
|
+
let selectorKey = parseInt(s);
|
|
91
91
|
let selector = selectorData[selectorKey];
|
|
92
|
-
if (selector.startsWith(Constant.At))
|
|
92
|
+
if (selector.startsWith(Constant.At)){
|
|
93
93
|
shouldMask = true;
|
|
94
94
|
selector = selector.slice(1);
|
|
95
95
|
}
|
|
96
|
-
|
|
96
|
+
let nodes = document.querySelectorAll(selector) as NodeListOf<HTMLElement>;
|
|
97
97
|
if (nodes) {
|
|
98
|
-
|
|
99
|
-
.map((e) => e.textContent)
|
|
100
|
-
.join(Constant.Seperator);
|
|
98
|
+
let text = Array.from(nodes).map(e => e.textContent).join(Constant.Seperator);
|
|
101
99
|
update(key, selectorKey, (shouldMask ? hash(text).trim() : text).slice(0, Setting.ExtractLimit));
|
|
102
100
|
}
|
|
103
101
|
}
|
|
104
102
|
|
|
105
|
-
|
|
106
|
-
for (
|
|
107
|
-
|
|
108
|
-
|
|
103
|
+
let hashData = hashes[key];
|
|
104
|
+
for (let h in hashData) {
|
|
105
|
+
let hashKey = parseInt(h);
|
|
106
|
+
let content = hashText(hashData[hashKey]).trim().slice(0, Setting.ExtractLimit);
|
|
109
107
|
update(key, hashKey, content);
|
|
110
108
|
}
|
|
111
109
|
}
|
|
@@ -114,9 +112,8 @@ export function compute(): void {
|
|
|
114
112
|
if (keys.size > 0) {
|
|
115
113
|
encode(Event.Extract);
|
|
116
114
|
}
|
|
117
|
-
} catch (e) {
|
|
118
|
-
internal.log(Code.Selector, Severity.Warning, e ? e.name : null);
|
|
119
115
|
}
|
|
116
|
+
catch (e) { internal.log(Code.Selector, Severity.Warning, e ? e.name : null); }
|
|
120
117
|
}
|
|
121
118
|
|
|
122
119
|
export function reset(): void {
|
|
@@ -124,13 +121,15 @@ export function reset(): void {
|
|
|
124
121
|
}
|
|
125
122
|
|
|
126
123
|
export function update(key: number, subkey: number, value: string): void {
|
|
127
|
-
|
|
124
|
+
var update = false;
|
|
128
125
|
if (!(key in data)) {
|
|
129
126
|
data[key] = {};
|
|
130
127
|
update = true;
|
|
131
128
|
}
|
|
132
|
-
|
|
133
|
-
if (!isEmpty(hashes[key])
|
|
129
|
+
|
|
130
|
+
if (!isEmpty(hashes[key])
|
|
131
|
+
&& (!(subkey in data[key]) || data[key][subkey] != value))
|
|
132
|
+
{
|
|
134
133
|
update = true;
|
|
135
134
|
}
|
|
136
135
|
|
|
@@ -143,21 +142,21 @@ export function update(key: number, subkey: number, value: string): void {
|
|
|
143
142
|
}
|
|
144
143
|
|
|
145
144
|
export function stop(): void {
|
|
146
|
-
|
|
145
|
+
reset();
|
|
147
146
|
}
|
|
148
147
|
|
|
149
148
|
function parse(variable: string): Syntax[] {
|
|
150
|
-
|
|
151
|
-
|
|
149
|
+
let syntax: Syntax[] = [];
|
|
150
|
+
let parts = variable.split(Constant.Dot);
|
|
152
151
|
while (parts.length > 0) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
152
|
+
let part = parts.shift();
|
|
153
|
+
let arrayStart = part.indexOf(Constant.ArrayStart);
|
|
154
|
+
let conditionStart = part.indexOf(Constant.ConditionStart);
|
|
155
|
+
let conditionEnd = part.indexOf(Constant.ConditionEnd);
|
|
157
156
|
syntax.push({
|
|
158
|
-
name: arrayStart > 0 ? part.slice(0, arrayStart) : conditionStart > 0 ? part.slice(0, conditionStart) : part,
|
|
159
|
-
type: arrayStart > 0 ? Type.Array : conditionStart > 0 ? Type.Object : Type.Simple,
|
|
160
|
-
condition: conditionStart > 0 ? part.slice(conditionStart + 1, conditionEnd) : null
|
|
157
|
+
name : arrayStart > 0 ? part.slice(0, arrayStart) : (conditionStart > 0 ? part.slice(0, conditionStart) : part),
|
|
158
|
+
type : arrayStart > 0 ? Type.Array : (conditionStart > 0 ? Type.Object : Type.Simple),
|
|
159
|
+
condition : conditionStart > 0 ? part.slice(conditionStart + 1, conditionEnd) : null
|
|
161
160
|
});
|
|
162
161
|
}
|
|
163
162
|
|
|
@@ -167,32 +166,26 @@ function parse(variable: string): Syntax[] {
|
|
|
167
166
|
// The function below takes in a variable name in following format: "a.b.c" and safely evaluates its value in javascript context
|
|
168
167
|
// For instance, for a.b.c, it will first check window["a"]. If it exists, it will recursively look at: window["a"]["b"] and finally,
|
|
169
168
|
// return the value for window["a"]["b"]["c"].
|
|
170
|
-
// biome-ignore lint/complexity/noBannedTypes: type of base is intentionally generic
|
|
171
|
-
// biome-ignore lint/suspicious/noExplicitAny: type of return value isn't known
|
|
172
169
|
function evaluate(variable: Syntax[], base: Object = window): any {
|
|
173
|
-
if (variable.length
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
const part = variable.shift();
|
|
177
|
-
// biome-ignore lint/suspicious/noImplicitAnyLet: type of return value isn't known
|
|
170
|
+
if (variable.length == 0) { return base; }
|
|
171
|
+
let part = variable.shift();
|
|
178
172
|
let output;
|
|
179
|
-
if (base
|
|
180
|
-
|
|
173
|
+
if (base && base[part.name]) {
|
|
174
|
+
let obj = base[part.name];
|
|
181
175
|
if (part.type !== Type.Array && match(obj, part.condition)) {
|
|
182
176
|
output = evaluate(variable, obj);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
|
|
177
|
+
}
|
|
178
|
+
else if (Array.isArray(obj)) {
|
|
179
|
+
let filtered = [];
|
|
180
|
+
for (var value of obj) {
|
|
186
181
|
if (match(value, part.condition)) {
|
|
187
|
-
|
|
188
|
-
if (op) {
|
|
189
|
-
filtered.push(op);
|
|
190
|
-
}
|
|
182
|
+
let op = evaluate(variable, value)
|
|
183
|
+
if (op) { filtered.push(op); }
|
|
191
184
|
}
|
|
192
185
|
}
|
|
193
186
|
output = filtered;
|
|
194
187
|
}
|
|
195
|
-
|
|
188
|
+
|
|
196
189
|
return output;
|
|
197
190
|
}
|
|
198
191
|
|
|
@@ -204,17 +197,15 @@ function str(input: string): string {
|
|
|
204
197
|
return input ? JSON.stringify(input).slice(0, Setting.ExtractLimit) : input;
|
|
205
198
|
}
|
|
206
199
|
|
|
207
|
-
// biome-ignore lint/complexity/noBannedTypes: type of base is intentionally generic
|
|
208
200
|
function match(base: Object, condition: string): boolean {
|
|
209
201
|
if (condition) {
|
|
210
|
-
|
|
211
|
-
return prop.length > 1 ? base[prop[0]]
|
|
202
|
+
let prop = condition.split(":");
|
|
203
|
+
return prop.length > 1 ? base[prop[0]] == prop[1] : base[prop[0]]
|
|
212
204
|
}
|
|
213
205
|
|
|
214
206
|
return true;
|
|
215
207
|
}
|
|
216
208
|
|
|
217
|
-
// biome-ignore lint/complexity/noBannedTypes: type of obj is intentionally generic
|
|
218
209
|
function isEmpty(obj: Object): boolean {
|
|
219
|
-
return Object.keys(obj).length
|
|
210
|
+
return Object.keys(obj).length == 0;
|
|
220
211
|
}
|
package/src/data/index.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import type { Module } from "@clarity-types/core";
|
|
2
1
|
import measure from "@src/core/measure";
|
|
3
2
|
import * as baseline from "@src/data/baseline";
|
|
4
|
-
import * as dimension from "@src/data/dimension";
|
|
5
3
|
import * as envelope from "@src/data/envelope";
|
|
6
|
-
import * as
|
|
7
|
-
import * as limit from "@src/data/limit";
|
|
4
|
+
import * as dimension from "@src/data/dimension";
|
|
8
5
|
import * as metadata from "@src/data/metadata";
|
|
6
|
+
import { Module } from "@clarity-types/core";
|
|
9
7
|
import * as metric from "@src/data/metric";
|
|
10
8
|
import * as ping from "@src/data/ping";
|
|
9
|
+
import * as limit from "@src/data/limit";
|
|
11
10
|
import * as summary from "@src/data/summary";
|
|
12
11
|
import * as upgrade from "@src/data/upgrade";
|
|
13
12
|
import * as upload from "@src/data/upload";
|
|
14
13
|
import * as variable from "@src/data/variable";
|
|
14
|
+
import * as extract from "@src/data/extract";
|
|
15
15
|
export { event } from "@src/data/custom";
|
|
16
16
|
export { consent, metadata } from "@src/data/metadata";
|
|
17
17
|
export { upgrade } from "@src/data/upgrade";
|
|
@@ -23,9 +23,7 @@ const modules: Module[] = [baseline, dimension, variable, limit, summary, metada
|
|
|
23
23
|
export function start(): void {
|
|
24
24
|
// Metric needs to be initialized before we can start measuring. so metric is not wrapped in measure
|
|
25
25
|
metric.start();
|
|
26
|
-
|
|
27
|
-
measure(x.start)();
|
|
28
|
-
}
|
|
26
|
+
modules.forEach(x => measure(x.start)());
|
|
29
27
|
}
|
|
30
28
|
|
|
31
29
|
export function stop(): void {
|
|
@@ -33,9 +31,7 @@ export function stop(): void {
|
|
|
33
31
|
// The ordering below should respect inter-module dependency.
|
|
34
32
|
// E.g. if upgrade depends on upload, then upgrade needs to end before upload.
|
|
35
33
|
// Similarly, if upload depends on metadata, upload needs to end before metadata.
|
|
36
|
-
|
|
37
|
-
measure(x.stop)();
|
|
38
|
-
}
|
|
34
|
+
modules.slice().reverse().forEach(x => measure(x.stop)());
|
|
39
35
|
metric.stop();
|
|
40
36
|
}
|
|
41
37
|
|
package/src/data/limit.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Check, Event,
|
|
1
|
+
import { Check, Event, LimitData, Setting } from "@clarity-types/data";
|
|
2
2
|
import * as clarity from "@src/clarity";
|
|
3
3
|
import { time } from "@src/core/time";
|
|
4
4
|
import * as envelope from "@src/data/envelope";
|