@nexly/web 0.13.0 → 0.14.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 +12 -0
- package/dist/events/engagement.d.ts.map +1 -1
- package/dist/events/engagement.js +5 -1
- package/dist/nexly.d.ts +6 -0
- package/dist/nexly.d.ts.map +1 -1
- package/dist/nexly.js +14 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -25,6 +25,18 @@ const stopEngagement = client.startEngagement()
|
|
|
25
25
|
// stopEngagement() on SPA unmount / route change if needed
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
+
`startEngagement()` is idempotent — calling it again stops the previous subscription first, so HMR or double-mounts can't produce duplicate listeners.
|
|
29
|
+
|
|
30
|
+
### Opting elements out of auto-capture
|
|
31
|
+
|
|
32
|
+
Auto-click and auto-focus listeners skip any element (or descendant of an element) marked with `data-nexly-ignore`. Use it on elements where you already emit your own `event(...)` to avoid semantic duplicates:
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
<button data-nexly-ignore onClick={() => client.event({ name: 'signup_clicked', type: 'custom' })}>
|
|
36
|
+
Sign up
|
|
37
|
+
</button>
|
|
38
|
+
```
|
|
39
|
+
|
|
28
40
|
## What you get
|
|
29
41
|
|
|
30
42
|
- `Nexly` — browser client (auto session + visitor IDs via `localStorage`/`sessionStorage`).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engagement.d.ts","sourceRoot":"","sources":["../../src/events/engagement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AA4BrD,KAAK,MAAM,GAAG,MAAM,IAAI,CAAA;AAExB;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"engagement.d.ts","sourceRoot":"","sources":["../../src/events/engagement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AA4BrD,KAAK,MAAM,GAAG,MAAM,IAAI,CAAA;AAExB;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,CAgHzE"}
|
|
@@ -68,10 +68,12 @@ export function startEngagementTracking(creds) {
|
|
|
68
68
|
const now = Date.now();
|
|
69
69
|
if (now - lastClickTs < CLICK_THROTTLE_MS)
|
|
70
70
|
return;
|
|
71
|
-
lastClickTs = now;
|
|
72
71
|
const el = e.target;
|
|
73
72
|
if (!el)
|
|
74
73
|
return;
|
|
74
|
+
if (el.closest('[data-nexly-ignore]'))
|
|
75
|
+
return;
|
|
76
|
+
lastClickTs = now;
|
|
75
77
|
const tag = el.tagName?.toLowerCase() ?? '';
|
|
76
78
|
const rawText = el.innerText ?? '';
|
|
77
79
|
const text = rawText.slice(0, 80).trim();
|
|
@@ -86,6 +88,8 @@ export function startEngagementTracking(creds) {
|
|
|
86
88
|
const el = e.target;
|
|
87
89
|
if (!el)
|
|
88
90
|
return;
|
|
91
|
+
if (el.closest('[data-nexly-ignore]'))
|
|
92
|
+
return;
|
|
89
93
|
const tag = el.tagName?.toLowerCase() ?? '';
|
|
90
94
|
if (tag !== 'input' && tag !== 'textarea' && tag !== 'select')
|
|
91
95
|
return;
|
package/dist/nexly.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { NexlyBase, type NexlyInit } from '@nexly/core';
|
|
|
4
4
|
* and metadata via DOM/Navigator APIs.
|
|
5
5
|
*/
|
|
6
6
|
export declare class Nexly extends NexlyBase {
|
|
7
|
+
private engagementStop;
|
|
7
8
|
/** Creates (or replaces) the browser singleton. Default `client` is `NexlyClient.Web`. */
|
|
8
9
|
static init(options: NexlyInit): Nexly;
|
|
9
10
|
/** Returns the browser singleton, or `null` if not yet initialized. */
|
|
@@ -13,6 +14,11 @@ export declare class Nexly extends NexlyBase {
|
|
|
13
14
|
protected collectEventContext(): Record<string, unknown>;
|
|
14
15
|
protected collectSessionContext(): Record<string, unknown>;
|
|
15
16
|
getDefaultPath(): string;
|
|
17
|
+
/**
|
|
18
|
+
* Attaches engagement listeners. Idempotent: calling again stops the previous
|
|
19
|
+
* subscription first, so HMR / double-mounts can't produce duplicate listeners.
|
|
20
|
+
* Returns a cleanup function.
|
|
21
|
+
*/
|
|
16
22
|
startEngagement(): () => void;
|
|
17
23
|
}
|
|
18
24
|
//# sourceMappingURL=nexly.d.ts.map
|
package/dist/nexly.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nexly.d.ts","sourceRoot":"","sources":["../src/nexly.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAe,KAAK,SAAS,EAAE,MAAM,aAAa,CAAA;AAMpE;;;GAGG;AACH,qBAAa,KAAM,SAAQ,SAAS;IAClC,0FAA0F;IAC1F,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,GAAG,KAAK;IAMtC,uEAAuE;IACvE,MAAM,CAAC,WAAW,IAAI,KAAK,GAAG,IAAI;gBAItB,IAAI,EAAE,SAAS;cAIR,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO;cAKpD,mBAAmB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;cAI9C,qBAAqB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAI1D,cAAc,IAAI,MAAM;
|
|
1
|
+
{"version":3,"file":"nexly.d.ts","sourceRoot":"","sources":["../src/nexly.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAe,KAAK,SAAS,EAAE,MAAM,aAAa,CAAA;AAMpE;;;GAGG;AACH,qBAAa,KAAM,SAAQ,SAAS;IAClC,OAAO,CAAC,cAAc,CAA4B;IAElD,0FAA0F;IAC1F,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,GAAG,KAAK;IAMtC,uEAAuE;IACvE,MAAM,CAAC,WAAW,IAAI,KAAK,GAAG,IAAI;gBAItB,IAAI,EAAE,SAAS;cAIR,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO;cAKpD,mBAAmB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;cAI9C,qBAAqB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAI1D,cAAc,IAAI,MAAM;IAIjC;;;;OAIG;IACH,eAAe,IAAI,MAAM,IAAI;CAe9B"}
|
package/dist/nexly.js
CHANGED
|
@@ -8,6 +8,7 @@ import { getDefaultPathname } from './events/pageview.js';
|
|
|
8
8
|
* and metadata via DOM/Navigator APIs.
|
|
9
9
|
*/
|
|
10
10
|
export class Nexly extends NexlyBase {
|
|
11
|
+
engagementStop = null;
|
|
11
12
|
/** Creates (or replaces) the browser singleton. Default `client` is `NexlyClient.Web`. */
|
|
12
13
|
static init(options) {
|
|
13
14
|
const instance = new Nexly({ ...options, client: options.client ?? NexlyClient.Web });
|
|
@@ -35,14 +36,26 @@ export class Nexly extends NexlyBase {
|
|
|
35
36
|
getDefaultPath() {
|
|
36
37
|
return getDefaultPathname();
|
|
37
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Attaches engagement listeners. Idempotent: calling again stops the previous
|
|
41
|
+
* subscription first, so HMR / double-mounts can't produce duplicate listeners.
|
|
42
|
+
* Returns a cleanup function.
|
|
43
|
+
*/
|
|
38
44
|
startEngagement() {
|
|
39
45
|
if (this.disabled)
|
|
40
46
|
return () => { };
|
|
41
|
-
|
|
47
|
+
this.engagementStop?.();
|
|
48
|
+
const stop = startEngagementTracking({
|
|
42
49
|
collectUrl: this.collectUrl,
|
|
43
50
|
appId: this.appId,
|
|
44
51
|
apiToken: this.key,
|
|
45
52
|
client: this.client,
|
|
46
53
|
});
|
|
54
|
+
this.engagementStop = stop;
|
|
55
|
+
return () => {
|
|
56
|
+
stop();
|
|
57
|
+
if (this.engagementStop === stop)
|
|
58
|
+
this.engagementStop = null;
|
|
59
|
+
};
|
|
47
60
|
}
|
|
48
61
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nexly/web",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "Nexly browser ingest SDK: sendBeacon transport, DOM metadata, engagement listeners on top of @nexly/core",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"node": ">=20"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@nexly/core": "0.
|
|
41
|
+
"@nexly/core": "0.14.0"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"typescript": "~6.0.2"
|