@reservamos/browser-analytics 1.1.8-alpha.0 → 1.1.8-alpha.2
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/CHANGELOG.md +21 -3
- package/README.md +33 -7
- package/dist/browser-analytics.cjs +2 -2
- package/dist/browser-analytics.cjs.map +1 -1
- package/dist/browser-analytics.d.ts +15 -2
- package/dist/browser-analytics.esm.js +590 -109
- package/dist/browser-analytics.esm.js.map +1 -1
- package/dist/browser-analytics.iife.js +2 -2
- package/dist/browser-analytics.iife.js.map +1 -1
- package/package.json +2 -2
- package/src/events/identify/identify.robustness.test.ts +112 -13
- package/src/events/identify/identify.ts +84 -34
- package/src/events/passengersCreated/passengersCreatedSchema.test.ts +142 -0
- package/src/events/passengersCreated/passengersCreatedSchema.ts +7 -1
- package/src/events/purchaseConfirmation/purchaseConfirmation.integration.test.ts +49 -0
- package/src/events/purchaseConfirmation/purchaseConfirmation.test.ts +17 -0
- package/src/events/purchaseConfirmation/purchaseConfirmationSchema.ts +2 -0
- package/src/events/sharedSchemas/tripSchema.ts +3 -8
- package/src/index.ts +1 -0
- package/src/init.botDetection.test.ts +187 -0
- package/src/init.test.ts +1 -0
- package/src/init.ts +15 -2
- package/src/services/botDetectionRelay.test.ts +3 -2
- package/src/services/deferredBotDetection.ts +60 -0
- package/src/services/fingerprint.test.ts +190 -0
- package/src/services/fingerprint.ts +141 -13
- package/src/services/fingerprint.wait.integration.test.ts +129 -0
- package/src/services/mixpanel.test.ts +119 -73
- package/src/services/mixpanel.ts +82 -23
- package/src/services/trackingLifecycle.ts +54 -0
- package/src/services/validator/validator.test.ts +79 -0
- package/src/track.readiness.test.ts +131 -0
- package/src/track.recovery.test.ts +339 -0
- package/src/track.storage.test.ts +142 -0
- package/src/track.test.ts +130 -5
- package/src/track.ts +110 -25
- package/src/util/pendingWork.test.ts +164 -0
- package/src/util/pendingWork.ts +148 -0
- package/src/util/snapshotEventData.ts +15 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,10 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
|
|
7
|
-
-
|
|
5
|
+
- Pin js-api-client 6.28.1 to keep an initiated Fingerprint observation relay alive across navigation within browser limits; retain its five-second timeout and add a local redirect fixture.
|
|
6
|
+
|
|
7
|
+
- Apply Identify identity and initial people properties before optional profile/fingerprint enrichment; resolve locally before enrichment and suppress stale results without mutating caller properties.
|
|
8
|
+
- Add `analytics.identifiers.waitForFingerprintId(timeoutMs = 2000)` to await cached or in-flight identity within a caller budget without forcing fresh identification; preserve late successful cache updates when the caller times out and the identity lifecycle remains current.
|
|
9
|
+
- Accept optional validated `product` on Purchase Confirmation Viewed. These additive public changes require minor release impact.
|
|
10
|
+
- Accept an optional `Coupon` on `Passengers Created`, validated like `Payment Attempt`, so checkout events that carry a coupon are no longer rejected.
|
|
11
|
+
|
|
12
|
+
- Accept zero departure and return stops in trip schemas so nonstop journeys can be tracked in Purchase Attempt and Payment Attempt.
|
|
13
|
+
|
|
14
|
+
- Submit View Results with cached or empty identity before refreshing Fingerprint, so pending identification cannot block the event.
|
|
15
|
+
|
|
16
|
+
- Retain valid events that have not reached Mixpanel for up to 60 seconds with bounded memory and a five-second foreground wait. Claim each event once and never retry a submission that throws, preventing SDK recovery from replaying uncertain sends.
|
|
17
|
+
- Defer Bot Detection observations for up to ten seconds while Fingerprint loads, cap actual identification concurrency at three, and suppress expired or stale identity/configuration effects without replaying original Mixpanel events.
|
|
18
|
+
- Invalidate stale readiness during reinitialization, preserve original pending payload snapshots, and reuse matching Mixpanel singleton initialization without awaiting an unavailable callback. Reject unsupported in-place project/proxy changes before disturbing the active session.
|
|
19
|
+
|
|
8
20
|
- Search, Payment Attempt, and Purchase Attempt are submitted before fresh Fingerprint identification and Bot Detection relay. View Results and other non-bot events continue with an empty fingerprint when retrieval fails.
|
|
21
|
+
|
|
22
|
+
- A pending location permission or Fingerprint load no longer holds Tracker Ready. Core API is configured before listeners run; optional initialization waits are bounded to 3 seconds and pre-initialization fingerprint cache reads remain safe.
|
|
23
|
+
- Document that Search, Payment Attempt and Purchase Attempt fired before Fingerprint readiness can omit Bot Detection observations when Fingerprint remains unavailable throughout the ten-second deferral window; regression coverage verifies original event submission and no replay after optional initialization.
|
|
24
|
+
|
|
25
|
+
- Events called before Mixpanel is ready now wait up to 5 seconds instead of rejecting an unobserved promise, and resume directly when Mixpanel loads without waiting for optional initialization or `Tracker Ready`. Expired attempts log a controlled diagnostic, release their resources, and do not replay after late readiness.
|
|
26
|
+
- Add manual alpha and stable publication alongside automatic patch/minor/major releases for PRs merged into main. Alphas also support the temporary alpha-sbx branch; both paths allocate versions from npm, validate fully, and tag the exact source commit without version commits on main.
|
|
9
27
|
- Blocked SDK localStorage no longer discards events or live Mixpanel identity. Cache fallback safely returns null when unavailable, and identify retains its controlled cache diagnostic and people updates.
|
|
10
28
|
|
|
11
29
|
## 1.1.7
|
package/README.md
CHANGED
|
@@ -44,40 +44,44 @@ window.addEventListener('Tracker Ready', () => {
|
|
|
44
44
|
});
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
Events called before Mixpanel is ready wait up to 5 seconds.
|
|
47
|
+
Events called before Mixpanel is ready wait up to 5 seconds in the foreground. Valid unsent events can remain in memory for up to 60 seconds, bounded to 100 entries and 1 MiB of serialized snapshots. A later ready signal submits each retained event once. The oldest waiting entry is discarded when capacity is exhausted; individually oversized or unserializable pending payloads are discarded with a local diagnostic. Navigation or reload can lose retained work.
|
|
48
|
+
|
|
49
|
+
Once this SDK invokes Mixpanel for an original event, it never retries that call, even if it throws: the provider might already have accepted the event. Separate consumer calls remain separate events, including calls with identical payloads. This limits SDK invocation to once per call; it does not guarantee remote delivery or end-to-end deduplication. Retained work is invalidated when the SDK switches user or starts a subsequent initialization; calls before the first init can join that initial anonymous session.
|
|
48
50
|
|
|
49
51
|
`Tracker Ready` means Mixpanel and Core API configuration are ready. Fingerprint and geolocation initialize concurrently afterward and may still be unavailable. `await analytics.init(config)` waits up to 3 seconds for those optional stages after Mixpanel loads; browser permission prompts and late results can outlive that wait.
|
|
50
52
|
|
|
53
|
+
Repeated SDK initialization with the same Mixpanel project and proxy reuses the initialized provider. Changing the project token or proxy after successful initialization is rejected before altering that active session; use a new page session for that change. Superseded initialization calls cannot replace newer Core API or Fingerprint configuration.
|
|
54
|
+
|
|
51
55
|
`appName` is optional. When provided, it is sent as the `x-app-name` HTTP header on Datalake identify and anonymous-profile requests so the API can identify the originating client platform.
|
|
52
56
|
|
|
53
57
|
## Fingerprint Bot Detection relay
|
|
54
58
|
|
|
55
|
-
For `Search`, `Payment Attempt`, and `Purchase Attempt`, the original Mixpanel event uses the cached visitor ID or an empty fingerprint. Fresh identification and relay run afterward in the background. A pending or failed identification does not delay that submission.
|
|
59
|
+
For `Search`, `Payment Attempt`, and `Purchase Attempt`, the original Mixpanel event uses the cached visitor ID or an empty fingerprint. Fresh identification and relay run afterward in the background. A pending or failed identification does not delay that submission. Eligible observation work waits up to 10 seconds for the agent and is bounded to 100 intents and three actual identification requests in flight. Navigation may interrupt background work. View Results also submits cached or empty identity before refreshing Fingerprint in the background; its late result does not replay the event. Other events continue with an empty fingerprint if retrieval rejects.
|
|
56
60
|
|
|
57
61
|
Fingerprint Bot Detection results are retrieved through Fingerprint Server API by Core API. This browser SDK does not call Server API or accept its Secret API Key. It can obtain the request-scoped `requestId` and relay the identification context to Core API.
|
|
58
62
|
|
|
59
63
|
The SDK owns the eligible event list. Consumers do not configure a URL or choose events. Bot Detection currently runs on `Search`, `Payment Attempt`, and `Purchase Attempt`. The destination is built from the Core API `baseUrl`.
|
|
60
64
|
|
|
61
|
-
For those events, fresh identification bypasses the Fingerprint SPA cache and runs in the background after the original event has been submitted. Its returned visitor ID and request ID are used for the relay; they do not replace the cached or empty fingerprint already submitted with the original event. Other events retain their existing cache selection and continue with an empty fingerprint if retrieval rejects.
|
|
65
|
+
For those events, fresh identification bypasses the Fingerprint SPA cache and runs in the background after the original event has been submitted. Its returned visitor ID and request ID are used for the relay; they do not replace the cached or empty fingerprint already submitted with the original event. View Results submits cached or empty identity before refreshing Fingerprint without a Bot Detection relay. Other events retain their existing cache selection and continue with an empty fingerprint if retrieval rejects.
|
|
62
66
|
|
|
63
|
-
After handing the original event to Mixpanel, the SDK sends this JSON payload to `${coreApiBaseUrl}/v1/fingerprint/bot-detection` with `POST`, `Content-Type: application/json`, optional `x-app-name`,
|
|
67
|
+
After handing the original event to Mixpanel, the SDK sends this JSON payload to `${coreApiBaseUrl}/v1/fingerprint/bot-detection` with `POST`, `Content-Type: application/json`, optional `x-app-name`, through `js-api-client`. The pinned 6.28.1 client uses fetch `keepalive` with a five-second abort, allowing an already-started relay to continue after navigation within browser transport limits. The browser supplies the actual `Origin` header:
|
|
64
68
|
|
|
65
69
|
```json
|
|
66
70
|
{
|
|
67
71
|
"requestId": "request-123",
|
|
68
72
|
"visitorId": "visitor-123",
|
|
69
73
|
"distinctId": "mixpanel-distinct-123",
|
|
70
|
-
"eventName": "
|
|
74
|
+
"eventName": "Fingerprint Requested"
|
|
71
75
|
}
|
|
72
76
|
```
|
|
73
77
|
|
|
74
78
|
`distinctId` is omitted when Mixpanel cannot provide one. The Core API response is not used to modify the original event. The SDK sends the generated `requestId` only in the Core API relay payload. Core API owns the Fingerprint Server API lookup and any later enrichment.
|
|
75
79
|
|
|
76
|
-
Relay failures are logged with `console.error` and do not turn an event already submitted to Mixpanel into a tracking failure. If the Fingerprint agent is
|
|
80
|
+
Relay failures are logged with `console.error` and do not turn an event already submitted to Mixpanel into a tracking failure. If the Fingerprint agent is still loading, the SDK sends the Mixpanel event immediately and defers only the observation within its ten-second budget. Expired observations, changed identity/configuration, and capacity overflow produce local diagnostics. Late identification results after expiry or identity/configuration changes do not update the cache or profile or start a relay. A provider request that remains pending still occupies one of the three concurrency slots until it settles; the SDK does not cancel the underlying request. Background identification failures are logged without changing or replacing the already-submitted event.
|
|
77
81
|
|
|
78
82
|
## Identifying Users
|
|
79
83
|
|
|
80
|
-
`await analytics.identify(...)`
|
|
84
|
+
`await analytics.identify(...)` resolves after Mixpanel identity and initial people properties are submitted locally, without waiting for optional enrichment or confirming remote delivery. Readiness is limited to 5 seconds before that submission; anonymous-profile enrichment and fingerprint enrichment run afterward with limits of 3 and 2 seconds. Once readiness expires, a later `Tracker Ready` does not reactivate that call.
|
|
81
85
|
|
|
82
86
|
Mixpanel profile callbacks and the existing geolocation request are observed separately for up to 5 seconds. The SDK does not retry requests; a missing callback means its outcome was not observed. Diagnostics use controlled stage/reason values without user identifiers or personal properties. `Visitor Found` is optional metadata: available booleans are preserved, and absent values are not replaced with `false` or inferred from cache state.
|
|
83
87
|
|
|
@@ -161,3 +165,25 @@ Use these slash commands in Cursor or Claude Code:
|
|
|
161
165
|
5. `/opsx-archive` — move the change to `openspec/changes/archive/`
|
|
162
166
|
|
|
163
167
|
When OpenSpec is used, `tasks.md` is the canonical implementation plan. Do not also run `ce-plan` for the same change.
|
|
168
|
+
|
|
169
|
+
## Comporte redirect and identity readiness
|
|
170
|
+
|
|
171
|
+
`await analytics.identify(userId, properties)` resolves after Mixpanel identity and the initial people properties are submitted locally. Anonymous profile and fingerprint enrichment run afterward, with their existing time limits. A later profile ID updates `reservamos_one_id` without identifying again. New identify attempts or initialization invalidate stale enrichment; caller properties are not mutated. Redirects can interrupt background work, and local completion does not guarantee remote delivery.
|
|
172
|
+
|
|
173
|
+
`analytics.identifiers.getFingerprintId()` remains a synchronous cache lookup. To wait for agent loading or an identification already in flight, use:
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
const fingerprintId = await analytics.identifiers.waitForFingerprintId(2000);
|
|
177
|
+
// fingerprintId is string | null. Waiting does not force a fresh FPJS request.
|
|
178
|
+
analytics.track.search(searchProperties);
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
The wait defaults to 2000 ms and resolves `null` on timeout, failure or replaced session/initialization. Concurrent waits share identification; the timeout does not cancel an underlying provider request, and a late successful result still fills the cache while its initialization and identity lifecycle remain current. When neither cache nor in-flight work exists, waiting can start one cache-eligible FPJS identification. Eligible Bot Detection events still request their own fresh identification as before. Events keep their nonblocking cached-or-empty fingerprint behavior. If the cache cannot be written, the returned ID is still available, but later events may carry an empty fingerprint.
|
|
182
|
+
|
|
183
|
+
Send `analytics.track.purchaseConfirmation` when the confirmation page is viewed, with `Operation Id` and `Payment Status` (`confirmed` or `pending_pix`). Optional `product` accepts the same values as other SDK events (`web`, `web-mobile`, `ios`, `android`, `app`). This browser event is separate from datalake's Purchase Completed.
|
|
184
|
+
|
|
185
|
+
## Local relay navigation check
|
|
186
|
+
|
|
187
|
+
Run `node scripts/serve-relay-redirect.mjs` and open the printed URL in a browser. The fixture invokes the real SDK relay with dummy IDs and credentials against a second local origin, then navigates without awaiting it. The local backend delays its response by 1.5 seconds. Read its `/observations` endpoint afterward to check CORS preflight, one POST, headers, normal completion or early disconnection. The pending-IDs button navigates before its simulated IDs exist and should produce no POST.
|
|
188
|
+
|
|
189
|
+
This check uses the published 6.28.1 client pinned by the SDK; it can also be repeated with a locally built candidate. Candidate verification is recorded in `openspec/changes/sdk-relay-keepalive/verification.md`; Comporte staging is still needed for their real origin, FPJS acquisition and backend. The fixture contacts only its localhost backend and does not initialize real Mixpanel or Fingerprint services.
|