@studio-vaai/js-tracking 0.1.3
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/LICENSE +21 -0
- package/README.md +71 -0
- package/dist/base.d.ts +52 -0
- package/dist/base.d.ts.map +1 -0
- package/dist/client.d.ts +28 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +10 -0
- package/dist/errors.d.ts +6 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +11 -0
- package/dist/events.d.ts +127 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/impl/fetch-umami-tracking-client.d.ts +69 -0
- package/dist/impl/fetch-umami-tracking-client.d.ts.map +1 -0
- package/dist/impl/fetch-umami-tracking-client.js +154 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/steps.d.ts +11 -0
- package/dist/steps.d.ts.map +1 -0
- package/package.json +28 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) studio vaai GmbH
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# @studio-vaai/js-tracking
|
|
2
|
+
|
|
3
|
+
Typed analytics events for studio vaai, plus a beacon-based [Umami](https://umami.is)
|
|
4
|
+
transport.
|
|
5
|
+
|
|
6
|
+
## Public surface
|
|
7
|
+
|
|
8
|
+
```ts
|
|
9
|
+
interface TrackingClient {
|
|
10
|
+
trackEvent(event: TrackingEvent, options?: TrackOptions): TrackResult;
|
|
11
|
+
}
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Synchronous and fire-and-forget — the default transport dispatches via
|
|
15
|
+
`navigator.sendBeacon` so events survive page unload and navigation. The
|
|
16
|
+
returned `TrackResult` reflects whether the browser accepted the beacon (or
|
|
17
|
+
the event was queued for later flush), not whether the server acknowledged it.
|
|
18
|
+
|
|
19
|
+
Event-specific by design: every event must appear in `TrackingEvent` (see
|
|
20
|
+
[`src/events.ts`](src/events.ts)). Until the first variant lands, `trackEvent`
|
|
21
|
+
is uncallable — which forces a central declaration of every event the SDK can
|
|
22
|
+
send.
|
|
23
|
+
|
|
24
|
+
The Umami-script-style `track()` / `identify()` overloads live as
|
|
25
|
+
closure-private helpers inside the transport in
|
|
26
|
+
[`src/impl/fetch-umami-tracking-client.ts`](src/impl/fetch-umami-tracking-client.ts);
|
|
27
|
+
they are not part of the public API.
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import { createFetchUmamiTrackingClient } from "@studio-vaai/js-tracking";
|
|
33
|
+
|
|
34
|
+
// Static config: websiteId known at construction.
|
|
35
|
+
const tracking = createFetchUmamiTrackingClient({
|
|
36
|
+
sdkVersion: "@studio-vaai/react-components@0.1.3",
|
|
37
|
+
websiteId: "00000000-0000-0000-0000-000000000000",
|
|
38
|
+
// baseUrl defaults to https://a.studio-vaai.com
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Once you've declared the event in src/events.ts:
|
|
42
|
+
tracking.trackEvent({ name: "try_on_started", data: { productId } });
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Lazy resolver (per-shop config)
|
|
46
|
+
|
|
47
|
+
Pass `resolveConfig` instead of `websiteId` when the Umami website is only
|
|
48
|
+
known after an async lookup (e.g. fetched via `client.tracking.getTracking()`).
|
|
49
|
+
Events fired before the resolver settles are buffered internally and flushed
|
|
50
|
+
in order on success.
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
const tracking = createFetchUmamiTrackingClient({
|
|
54
|
+
sdkVersion: "@studio-vaai/react-components@0.1.3",
|
|
55
|
+
resolveConfig: async () => {
|
|
56
|
+
const r = await client.tracking.getTracking({});
|
|
57
|
+
if (!r.ok) throw new ApiFailureError(r.error);
|
|
58
|
+
return { websiteId: r.data.umamiWebsiteId, baseUrl: r.data.umamiBaseUrl };
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Adding an event
|
|
64
|
+
|
|
65
|
+
Declare it in [`src/events.ts`](src/events.ts) as a new `TrackingEvent` union
|
|
66
|
+
variant (snake_case `name`, flat-primitive `data`). Call sites then get full
|
|
67
|
+
autocomplete + type-checking on `name` and `data`.
|
|
68
|
+
|
|
69
|
+
## License
|
|
70
|
+
|
|
71
|
+
MIT
|
package/dist/base.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export type TrackErrorKind = "network" | "rejected" | "unknown";
|
|
2
|
+
export interface TrackError {
|
|
3
|
+
kind: TrackErrorKind;
|
|
4
|
+
message: string;
|
|
5
|
+
details?: unknown;
|
|
6
|
+
}
|
|
7
|
+
export interface TrackSuccess {
|
|
8
|
+
ok: true;
|
|
9
|
+
}
|
|
10
|
+
export interface TrackFailure {
|
|
11
|
+
ok: false;
|
|
12
|
+
error: TrackError;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Fire-and-mostly-forget result. Tracking is best-effort: callers should not
|
|
16
|
+
* branch product behaviour on `ok`, but may surface a warning in dev.
|
|
17
|
+
*
|
|
18
|
+
* Returned synchronously from {@link TrackingClient.trackEvent} — reflects
|
|
19
|
+
* whether the event was queued for delivery (via the Beacon API or a buffer
|
|
20
|
+
* waiting on a lazy resolver), not whether the server received it.
|
|
21
|
+
*/
|
|
22
|
+
export type TrackResult = TrackSuccess | TrackFailure;
|
|
23
|
+
/**
|
|
24
|
+
* Ambient page/session metadata that decorates every event. Mirrors the Umami
|
|
25
|
+
* `/api/send` payload so transports can pass it through unchanged.
|
|
26
|
+
*
|
|
27
|
+
* Browser transports auto-populate these from `window`/`document`/`navigator`
|
|
28
|
+
* when fields are absent; pass overrides via {@link TrackOptions.context} for
|
|
29
|
+
* SSR, web workers, or tests.
|
|
30
|
+
*/
|
|
31
|
+
export interface EventContext {
|
|
32
|
+
/** Page URL path + query, e.g. `/products/abc?ref=hero`. */
|
|
33
|
+
url?: string;
|
|
34
|
+
/** Document title. */
|
|
35
|
+
title?: string;
|
|
36
|
+
/** Hostname seen by the visitor, e.g. `shop.example.com`. */
|
|
37
|
+
hostname?: string;
|
|
38
|
+
/** HTTP `Referer` (sic) — origin page that linked to the current one. */
|
|
39
|
+
referrer?: string;
|
|
40
|
+
/** BCP-47 language tag, e.g. `en-US`. */
|
|
41
|
+
language?: string;
|
|
42
|
+
/** Screen size as `"<width>x<height>"`, e.g. `"1920x1080"`. */
|
|
43
|
+
screen?: string;
|
|
44
|
+
}
|
|
45
|
+
export interface TrackOptions {
|
|
46
|
+
/**
|
|
47
|
+
* Per-call overrides merged on top of whatever the transport auto-derives.
|
|
48
|
+
* Use this to attach SSR-known values or to scrub a field for a single event.
|
|
49
|
+
*/
|
|
50
|
+
context?: EventContext;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;AAEhE,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,IAAI,CAAC;CACV;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,UAAU,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,YAAY,CAAC;AAEtD;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,4DAA4D;IAC5D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sBAAsB;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { TrackOptions, TrackResult } from "./base.js";
|
|
2
|
+
import type { TrackingEvent } from "./events.js";
|
|
3
|
+
/** Npm package id. */
|
|
4
|
+
export declare const SDK_PACKAGE_ID: "@studio-vaai/js-tracking";
|
|
5
|
+
/** Marker config every transport extends. */
|
|
6
|
+
export type TrackingClientConfig = Record<never, never>;
|
|
7
|
+
/**
|
|
8
|
+
* Transport-agnostic event sender. Implementations live under `impl/` (e.g.
|
|
9
|
+
* the Umami beacon transport) — consumers depend on this interface so the
|
|
10
|
+
* underlying analytics backend can be swapped without touching call sites.
|
|
11
|
+
*/
|
|
12
|
+
export interface TrackingClient {
|
|
13
|
+
/**
|
|
14
|
+
* Send a single typed event. Synchronous and fire-and-forget — implementations
|
|
15
|
+
* dispatch via the page-unload-safe Beacon API. Returns a {@link TrackResult}
|
|
16
|
+
* reflecting whether the event was successfully queued for delivery, NOT
|
|
17
|
+
* whether the server acknowledged it. Never throws — analytics must not
|
|
18
|
+
* break the host app.
|
|
19
|
+
*
|
|
20
|
+
* Buffered events (e.g. while a lazy resolver is in flight) return
|
|
21
|
+
* `{ ok: true }` immediately; if the eventual flush fails, the caller is
|
|
22
|
+
* not notified — that's the price of fire-and-forget analytics.
|
|
23
|
+
*/
|
|
24
|
+
trackEvent(event: TrackingEvent, options?: TrackOptions): TrackResult;
|
|
25
|
+
}
|
|
26
|
+
/** Contract-only stub — throws; a transport package supplies a real implementation. */
|
|
27
|
+
export declare function createTrackingClient(_config: TrackingClientConfig): TrackingClient;
|
|
28
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD,sBAAsB;AACtB,eAAO,MAAM,cAAc,EAAG,0BAAmC,CAAC;AAElE,6CAA6C;AAC7C,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAExD;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;;;;;OAUG;IACH,UAAU,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,WAAW,CAAC;CACvE;AAED,uFAAuF;AACvF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,oBAAoB,GAAG,cAAc,CAElF"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { TrackingClientNotImplementedError } from "./errors.js";
|
|
2
|
+
//#region src/client.ts
|
|
3
|
+
/** Npm package id. */
|
|
4
|
+
var SDK_PACKAGE_ID = "@studio-vaai/js-tracking";
|
|
5
|
+
/** Contract-only stub — throws; a transport package supplies a real implementation. */
|
|
6
|
+
function createTrackingClient(_config) {
|
|
7
|
+
throw new TrackingClientNotImplementedError();
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
export { SDK_PACKAGE_ID, createTrackingClient };
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,qBAAa,iCAAkC,SAAQ,KAAK;IAC1D,QAAQ,CAAC,IAAI,EAAG,iCAAiC,CAAU;IAE3D,cAKC;CACF"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/errors.ts
|
|
2
|
+
/** Thrown by the contract-only {@link createTrackingClient} stub. */
|
|
3
|
+
var TrackingClientNotImplementedError = class extends Error {
|
|
4
|
+
code = "tracking_client_not_implemented";
|
|
5
|
+
constructor() {
|
|
6
|
+
super("@studio-vaai/js-tracking: createTrackingClient has no runtime implementation; use a transport like createFetchUmamiTrackingClient.");
|
|
7
|
+
this.name = "TrackingClientNotImplementedError";
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
//#endregion
|
|
11
|
+
export { TrackingClientNotImplementedError };
|
package/dist/events.d.ts
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import type { Step } from "./steps.js";
|
|
2
|
+
/**
|
|
3
|
+
* Shape every tracked event must satisfy. The `name` field is the
|
|
4
|
+
* discriminator Umami uses for the event name; `data` becomes Umami's event
|
|
5
|
+
* `data` payload — each variant declares its own concrete data shape so call
|
|
6
|
+
* sites get field-level autocomplete.
|
|
7
|
+
*
|
|
8
|
+
* Wire convention: event names and `data` keys are kebab-case so they read
|
|
9
|
+
* cleanly in Umami's event-data viewer. Values must be string/number/boolean
|
|
10
|
+
* primitives — the transport doesn't recursively serialize nested objects.
|
|
11
|
+
*/
|
|
12
|
+
export interface TrackingEventBase {
|
|
13
|
+
/** Stable event name (kebab-case). Becomes the Umami event name. */
|
|
14
|
+
readonly name: string;
|
|
15
|
+
/** Flat primitive payload. Each variant tightens this to a concrete shape. */
|
|
16
|
+
readonly data?: object;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Fields present on every event's `data`. The transport additionally injects
|
|
20
|
+
* `sdk-version` from {@link FetchUmamiTrackingClientConfig.sdkVersion}, so
|
|
21
|
+
* callers never set that themselves.
|
|
22
|
+
*/
|
|
23
|
+
interface CommonData {
|
|
24
|
+
readonly "product-id": string;
|
|
25
|
+
}
|
|
26
|
+
interface EntrypointImpressionEvent extends TrackingEventBase {
|
|
27
|
+
readonly name: "entrypoint-impression";
|
|
28
|
+
readonly data: CommonData & {
|
|
29
|
+
/** Merchant-defined identifier for the entrypoint placement. */
|
|
30
|
+
readonly entry: string;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
interface EntrypointClickedEvent extends TrackingEventBase {
|
|
34
|
+
readonly name: "entrypoint-clicked";
|
|
35
|
+
readonly data: CommonData & {
|
|
36
|
+
readonly entry: string;
|
|
37
|
+
/**
|
|
38
|
+
* Optional finer-grained placement classifier within `entry` (e.g.
|
|
39
|
+
* `entry: "pdp-button"` + `subentry: "size-row"`). Merchant-defined.
|
|
40
|
+
*/
|
|
41
|
+
readonly subentry?: string;
|
|
42
|
+
readonly "current-step": Step;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
interface IntroOpenedEvent extends TrackingEventBase {
|
|
46
|
+
readonly name: "intro-opened";
|
|
47
|
+
readonly data: CommonData & {
|
|
48
|
+
/** Typically `entry` | `image-rejection` | `image-record`. */
|
|
49
|
+
readonly source: Step;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
interface ConsentGrantedEvent extends TrackingEventBase {
|
|
53
|
+
readonly name: "consent-granted";
|
|
54
|
+
readonly data: CommonData;
|
|
55
|
+
}
|
|
56
|
+
interface ImageRecordInitiatedEvent extends TrackingEventBase {
|
|
57
|
+
readonly name: "image-record-initiated";
|
|
58
|
+
readonly data: CommonData & {
|
|
59
|
+
/** Typically `intro` | `height`. */
|
|
60
|
+
readonly source: Step;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
interface ImageUploadInitiatedEvent extends TrackingEventBase {
|
|
64
|
+
readonly name: "image-upload-initiated";
|
|
65
|
+
readonly data: CommonData & {
|
|
66
|
+
/** Typically `intro` | `height`. */
|
|
67
|
+
readonly source: Step;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
interface ImageUploadAbortedEvent extends TrackingEventBase {
|
|
71
|
+
readonly name: "image-upload-aborted";
|
|
72
|
+
readonly data: CommonData;
|
|
73
|
+
}
|
|
74
|
+
interface ImageUploadedEvent extends TrackingEventBase {
|
|
75
|
+
readonly name: "image-uploaded";
|
|
76
|
+
readonly data: CommonData & {
|
|
77
|
+
readonly "image-source": "record-self-timer" | "record-system-dialog" | "select";
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
interface HeightEnteredEvent extends TrackingEventBase {
|
|
81
|
+
readonly name: "height-entered";
|
|
82
|
+
readonly data: CommonData & {
|
|
83
|
+
/** Typically `image-upload` | `variant-selection`. */
|
|
84
|
+
readonly source: Step;
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
interface VariantSelectionInitiatedEvent extends TrackingEventBase {
|
|
88
|
+
readonly name: "variant-selection-initiated";
|
|
89
|
+
readonly data: CommonData & {
|
|
90
|
+
/** Typically `height` | `try-on`. */
|
|
91
|
+
readonly source: Step;
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Selected variant axes carried by events that fire after the user has chosen
|
|
96
|
+
* a specific variant (try-on, cart add, order). Emitted as flat
|
|
97
|
+
* `variant-<axis>` keys (e.g. `variant-color`, `variant-size`,
|
|
98
|
+
* `variant-length`). Axis names are open so merchants can configure new axes
|
|
99
|
+
* without an SDK change.
|
|
100
|
+
*/
|
|
101
|
+
type VariantData = Readonly<Partial<Record<`variant-${string}`, string>>>;
|
|
102
|
+
interface TryOnInitiatedEvent extends TrackingEventBase {
|
|
103
|
+
readonly name: "try-on-initiated";
|
|
104
|
+
readonly data: CommonData & VariantData;
|
|
105
|
+
}
|
|
106
|
+
interface CartItemAddedEvent extends TrackingEventBase {
|
|
107
|
+
readonly name: "cart-item-added";
|
|
108
|
+
readonly data: CommonData & VariantData;
|
|
109
|
+
}
|
|
110
|
+
interface OrderPlacedEvent extends TrackingEventBase {
|
|
111
|
+
readonly name: "order-placed";
|
|
112
|
+
readonly data: CommonData & VariantData;
|
|
113
|
+
}
|
|
114
|
+
interface ViewClosedEvent extends TrackingEventBase {
|
|
115
|
+
readonly name: "view-closed";
|
|
116
|
+
readonly data: CommonData & {
|
|
117
|
+
readonly "current-step": Step;
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Discriminated union of every event the SDK can send. Add new events by
|
|
122
|
+
* declaring a variant interface above and appending it to the union — call
|
|
123
|
+
* sites get full autocomplete + type-checking on `name` and `data`.
|
|
124
|
+
*/
|
|
125
|
+
export type TrackingEvent = EntrypointImpressionEvent | EntrypointClickedEvent | IntroOpenedEvent | ConsentGrantedEvent | ImageRecordInitiatedEvent | ImageUploadInitiatedEvent | ImageUploadAbortedEvent | ImageUploadedEvent | HeightEnteredEvent | VariantSelectionInitiatedEvent | TryOnInitiatedEvent | CartItemAddedEvent | OrderPlacedEvent | ViewClosedEvent;
|
|
126
|
+
export {};
|
|
127
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { EventContext } from "../base.js";
|
|
2
|
+
import type { TrackingClient, TrackingClientConfig } from "../client.js";
|
|
3
|
+
/** Default Umami base URL (int/prod Umami). */
|
|
4
|
+
export declare const DEFAULT_UMAMI_BASE_URL: "https://a.studio-vaai.com";
|
|
5
|
+
/** Per-shop Umami config the {@link FetchUmamiTrackingClientConfig.resolveConfig} resolver returns. */
|
|
6
|
+
export interface ResolvedUmamiConfig {
|
|
7
|
+
/** Umami website UUID for this shop. */
|
|
8
|
+
websiteId: string;
|
|
9
|
+
/** Optional override; defaults to {@link DEFAULT_UMAMI_BASE_URL} when omitted. */
|
|
10
|
+
baseUrl?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Sync sender used by the transport. The default delegates to
|
|
14
|
+
* `navigator.sendBeacon` — the page-unload-safe analytics primitive. Tests
|
|
15
|
+
* inject their own recorder.
|
|
16
|
+
*/
|
|
17
|
+
export type SendBeaconFn = (url: string, data: BodyInit) => boolean;
|
|
18
|
+
export interface FetchUmamiTrackingClientConfig extends TrackingClientConfig {
|
|
19
|
+
/**
|
|
20
|
+
* Stamped on every event as the `sdk-version` field. Higher SDK layers
|
|
21
|
+
* (e.g. `@studio-vaai/react-components`) pass their own
|
|
22
|
+
* `"<pkg>@<version>"` here so the analytics view shows the version of the
|
|
23
|
+
* SDK merchants actually install — not this internal tracking package.
|
|
24
|
+
*/
|
|
25
|
+
sdkVersion: string;
|
|
26
|
+
/**
|
|
27
|
+
* Static Umami website UUID. Provide this OR {@link resolveConfig}, not both.
|
|
28
|
+
* Use the static form when the website id is known at client construction.
|
|
29
|
+
*/
|
|
30
|
+
websiteId?: string;
|
|
31
|
+
/** Static Umami base URL. Used together with {@link websiteId}. Defaults to {@link DEFAULT_UMAMI_BASE_URL}. */
|
|
32
|
+
baseUrl?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Lazy resolver for per-shop Umami config. Provide this OR {@link websiteId},
|
|
35
|
+
* not both. Runs once when the client is constructed; events fired before
|
|
36
|
+
* the promise settles are buffered internally and flushed (in order) the
|
|
37
|
+
* moment the resolver returns. Buffered events have already returned
|
|
38
|
+
* `{ ok: true }` to the caller — if the eventual flush fails (resolver
|
|
39
|
+
* rejected or sendBeacon refused) the caller is not notified.
|
|
40
|
+
*/
|
|
41
|
+
resolveConfig?: () => Promise<ResolvedUmamiConfig>;
|
|
42
|
+
/**
|
|
43
|
+
* Override the beacon sender. Defaults to `navigator.sendBeacon` bound to
|
|
44
|
+
* `navigator` when available; falls back to a no-op that reports `false`
|
|
45
|
+
* (so the call site can surface `{ ok: false }` in SSR / older browsers).
|
|
46
|
+
*/
|
|
47
|
+
sendBeacon?: SendBeaconFn;
|
|
48
|
+
/**
|
|
49
|
+
* Ambient context applied to every payload, before per-call overrides. Useful
|
|
50
|
+
* for SSR-known fields or to pin a hostname different from `window.location`.
|
|
51
|
+
*/
|
|
52
|
+
defaultContext?: EventContext;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Umami `/api/send` transport for {@link TrackingClient}. Dispatches via the
|
|
56
|
+
* Beacon API so events survive page unload and navigation; the return value
|
|
57
|
+
* reports whether the browser accepted the beacon, not whether the server
|
|
58
|
+
* acknowledged it. Errors are never thrown — analytics cannot break the host app.
|
|
59
|
+
*
|
|
60
|
+
* Supports two configuration modes:
|
|
61
|
+
* - **Static**: pass `websiteId` (and optionally `baseUrl`) at construction.
|
|
62
|
+
* Events fire immediately.
|
|
63
|
+
* - **Lazy**: pass `resolveConfig` for per-shop Umami config that's only known
|
|
64
|
+
* asynchronously (e.g. fetched via `client.tracking.getTracking()`). Events
|
|
65
|
+
* fired before the resolver settles are buffered in order and flushed once
|
|
66
|
+
* the config is available.
|
|
67
|
+
*/
|
|
68
|
+
export declare function createFetchUmamiTrackingClient(config: FetchUmamiTrackingClientConfig): TrackingClient;
|
|
69
|
+
//# sourceMappingURL=fetch-umami-tracking-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-umami-tracking-client.d.ts","sourceRoot":"","sources":["../../src/impl/fetch-umami-tracking-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAyC,MAAM,YAAY,CAAC;AACtF,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGzE,+CAA+C;AAC/C,eAAO,MAAM,sBAAsB,EAAG,2BAAoC,CAAC;AAE3E,uGAAuG;AACvG,MAAM,WAAW,mBAAmB;IAClC,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,kFAAkF;IAClF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,KAAK,OAAO,CAAC;AAEpE,MAAM,WAAW,8BAA+B,SAAQ,oBAAoB;IAC1E;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+GAA+G;IAC/G,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACnD;;;;OAIG;IACH,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B;;;OAGG;IACH,cAAc,CAAC,EAAE,YAAY,CAAC;CAC/B;AAkHD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,8BAA8B,GACrC,cAAc,CAgJhB"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
//#region src/impl/fetch-umami-tracking-client.ts
|
|
2
|
+
/** Default Umami base URL (int/prod Umami). */
|
|
3
|
+
var DEFAULT_UMAMI_BASE_URL = "https://a.studio-vaai.com";
|
|
4
|
+
function deriveBrowserContext() {
|
|
5
|
+
const ctx = {};
|
|
6
|
+
if (typeof globalThis === "undefined") return ctx;
|
|
7
|
+
const w = globalThis.window;
|
|
8
|
+
if (typeof w === "undefined") return ctx;
|
|
9
|
+
const loc = w.location;
|
|
10
|
+
if (typeof loc !== "undefined") {
|
|
11
|
+
ctx.hostname = loc.hostname;
|
|
12
|
+
ctx.url = `${loc.pathname}${loc.search}`;
|
|
13
|
+
}
|
|
14
|
+
const doc = w.document;
|
|
15
|
+
if (typeof doc !== "undefined") {
|
|
16
|
+
ctx.title = doc.title;
|
|
17
|
+
if (doc.referrer !== "") ctx.referrer = doc.referrer;
|
|
18
|
+
}
|
|
19
|
+
const nav = w.navigator;
|
|
20
|
+
if (typeof nav !== "undefined") ctx.language = nav.language;
|
|
21
|
+
const scr = w.screen;
|
|
22
|
+
if (typeof scr !== "undefined") ctx.screen = `${String(scr.width)}x${String(scr.height)}`;
|
|
23
|
+
return ctx;
|
|
24
|
+
}
|
|
25
|
+
function mergeContext(base, defaults, overrides) {
|
|
26
|
+
return {
|
|
27
|
+
...base,
|
|
28
|
+
...defaults,
|
|
29
|
+
...overrides
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function applyContext(payload, ctx) {
|
|
33
|
+
if (typeof ctx.hostname !== "undefined") payload.hostname = ctx.hostname;
|
|
34
|
+
if (typeof ctx.language !== "undefined") payload.language = ctx.language;
|
|
35
|
+
if (typeof ctx.screen !== "undefined") payload.screen = ctx.screen;
|
|
36
|
+
if (typeof ctx.title !== "undefined") payload.title = ctx.title;
|
|
37
|
+
if (typeof ctx.url !== "undefined") payload.url = ctx.url;
|
|
38
|
+
if (typeof ctx.referrer !== "undefined") payload.referrer = ctx.referrer;
|
|
39
|
+
}
|
|
40
|
+
function networkError(message, details) {
|
|
41
|
+
return details === void 0 ? {
|
|
42
|
+
kind: "network",
|
|
43
|
+
message
|
|
44
|
+
} : {
|
|
45
|
+
kind: "network",
|
|
46
|
+
message,
|
|
47
|
+
details
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function bakeState(websiteId, baseUrl) {
|
|
51
|
+
return {
|
|
52
|
+
endpoint: `${(baseUrl ?? "https://a.studio-vaai.com").replace(/\/$/, "")}/api/send`,
|
|
53
|
+
websiteId
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function defaultSendBeacon() {
|
|
57
|
+
return (url, data) => {
|
|
58
|
+
if (typeof navigator === "undefined" || typeof navigator.sendBeacon !== "function") return false;
|
|
59
|
+
return navigator.sendBeacon.bind(navigator)(url, data);
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Umami `/api/send` transport for {@link TrackingClient}. Dispatches via the
|
|
64
|
+
* Beacon API so events survive page unload and navigation; the return value
|
|
65
|
+
* reports whether the browser accepted the beacon, not whether the server
|
|
66
|
+
* acknowledged it. Errors are never thrown — analytics cannot break the host app.
|
|
67
|
+
*
|
|
68
|
+
* Supports two configuration modes:
|
|
69
|
+
* - **Static**: pass `websiteId` (and optionally `baseUrl`) at construction.
|
|
70
|
+
* Events fire immediately.
|
|
71
|
+
* - **Lazy**: pass `resolveConfig` for per-shop Umami config that's only known
|
|
72
|
+
* asynchronously (e.g. fetched via `client.tracking.getTracking()`). Events
|
|
73
|
+
* fired before the resolver settles are buffered in order and flushed once
|
|
74
|
+
* the config is available.
|
|
75
|
+
*/
|
|
76
|
+
function createFetchUmamiTrackingClient(config) {
|
|
77
|
+
const sendBeacon = config.sendBeacon ?? defaultSendBeacon();
|
|
78
|
+
let resolved = null;
|
|
79
|
+
let resolverError = null;
|
|
80
|
+
const pending = [];
|
|
81
|
+
const staticWebsiteId = config.websiteId;
|
|
82
|
+
const resolverFn = config.resolveConfig;
|
|
83
|
+
if (staticWebsiteId === void 0 && resolverFn === void 0) throw new Error("createFetchUmamiTrackingClient: provide either `websiteId` or `resolveConfig`");
|
|
84
|
+
if (staticWebsiteId !== void 0 && resolverFn !== void 0) throw new Error("createFetchUmamiTrackingClient: pass either `websiteId` or `resolveConfig`, not both");
|
|
85
|
+
if (staticWebsiteId !== void 0) resolved = bakeState(staticWebsiteId, config.baseUrl);
|
|
86
|
+
else if (resolverFn !== void 0) {
|
|
87
|
+
if (config.baseUrl !== void 0) throw new Error("createFetchUmamiTrackingClient: `baseUrl` is set by the resolver in lazy mode — drop the static `baseUrl`");
|
|
88
|
+
(async () => {
|
|
89
|
+
try {
|
|
90
|
+
const r = await resolverFn();
|
|
91
|
+
resolved = bakeState(r.websiteId, r.baseUrl);
|
|
92
|
+
} catch (error) {
|
|
93
|
+
resolverError = {
|
|
94
|
+
kind: "unknown",
|
|
95
|
+
message: "Failed to resolve Umami tracking config",
|
|
96
|
+
details: error
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
while (pending.length > 0) {
|
|
100
|
+
const item = pending.shift();
|
|
101
|
+
if (item === void 0) break;
|
|
102
|
+
if (resolved === null) continue;
|
|
103
|
+
sendNow(resolved, item.event, item.options);
|
|
104
|
+
}
|
|
105
|
+
})();
|
|
106
|
+
}
|
|
107
|
+
function dispatchBeacon(state, body) {
|
|
108
|
+
let blob;
|
|
109
|
+
try {
|
|
110
|
+
blob = new Blob([JSON.stringify(body)], { type: "application/json" });
|
|
111
|
+
} catch (error) {
|
|
112
|
+
return {
|
|
113
|
+
ok: false,
|
|
114
|
+
error: networkError("Failed to serialise event", error)
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
if (!sendBeacon(state.endpoint, blob)) return {
|
|
118
|
+
ok: false,
|
|
119
|
+
error: networkError("navigator.sendBeacon refused the event (quota exceeded, payload too large, or unavailable)")
|
|
120
|
+
};
|
|
121
|
+
return { ok: true };
|
|
122
|
+
}
|
|
123
|
+
function track(state, name, data, contextOverrides) {
|
|
124
|
+
const payload = { website: state.websiteId };
|
|
125
|
+
applyContext(payload, mergeContext(deriveBrowserContext(), config.defaultContext, contextOverrides));
|
|
126
|
+
if (typeof name !== "undefined") payload.name = name;
|
|
127
|
+
if (typeof data !== "undefined") payload.data = { ...data };
|
|
128
|
+
return dispatchBeacon(state, {
|
|
129
|
+
type: "event",
|
|
130
|
+
payload
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
function sendNow(state, event, options) {
|
|
134
|
+
const data = {
|
|
135
|
+
...event.data ?? {},
|
|
136
|
+
"sdk-version": config.sdkVersion
|
|
137
|
+
};
|
|
138
|
+
return track(state, event.name, data, options?.context);
|
|
139
|
+
}
|
|
140
|
+
return { trackEvent: (event, options) => {
|
|
141
|
+
if (resolved !== null) return sendNow(resolved, event, options);
|
|
142
|
+
if (resolverError !== null) return {
|
|
143
|
+
ok: false,
|
|
144
|
+
error: resolverError
|
|
145
|
+
};
|
|
146
|
+
pending.push({
|
|
147
|
+
event,
|
|
148
|
+
options
|
|
149
|
+
});
|
|
150
|
+
return { ok: true };
|
|
151
|
+
} };
|
|
152
|
+
}
|
|
153
|
+
//#endregion
|
|
154
|
+
export { DEFAULT_UMAMI_BASE_URL, createFetchUmamiTrackingClient };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type { EventContext, TrackError, TrackErrorKind, TrackFailure, TrackOptions, TrackResult, TrackSuccess, } from "./base.js";
|
|
2
|
+
export type { TrackingClient, TrackingClientConfig } from "./client.js";
|
|
3
|
+
export { createTrackingClient, SDK_PACKAGE_ID } from "./client.js";
|
|
4
|
+
export { TrackingClientNotImplementedError } from "./errors.js";
|
|
5
|
+
export type { TrackingEvent, TrackingEventBase } from "./events.js";
|
|
6
|
+
export type { Step } from "./steps.js";
|
|
7
|
+
export type { FetchUmamiTrackingClientConfig, ResolvedUmamiConfig, } from "./impl/fetch-umami-tracking-client.js";
|
|
8
|
+
export { createFetchUmamiTrackingClient, DEFAULT_UMAMI_BASE_URL, } from "./impl/fetch-umami-tracking-client.js";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,UAAU,EACV,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,YAAY,GACb,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,iCAAiC,EAAE,MAAM,aAAa,CAAC;AAChE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACpE,YAAY,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACvC,YAAY,EACV,8BAA8B,EAC9B,mBAAmB,GACpB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,8BAA8B,EAC9B,sBAAsB,GACvB,MAAM,uCAAuC,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { TrackingClientNotImplementedError } from "./errors.js";
|
|
2
|
+
import { SDK_PACKAGE_ID, createTrackingClient } from "./client.js";
|
|
3
|
+
import { DEFAULT_UMAMI_BASE_URL, createFetchUmamiTrackingClient } from "./impl/fetch-umami-tracking-client.js";
|
|
4
|
+
export { DEFAULT_UMAMI_BASE_URL, SDK_PACKAGE_ID, TrackingClientNotImplementedError, createFetchUmamiTrackingClient, createTrackingClient };
|
package/dist/steps.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every distinct step in the studio vaai try-on flow state machine. Used as
|
|
3
|
+
* the `source` and `current-step` value type on tracking events.
|
|
4
|
+
*
|
|
5
|
+
* This union is the analytics view of the flow — it doesn't have to match the
|
|
6
|
+
* exact XState state IDs in `@studio-vaai/js-machine` 1:1. Callers translate
|
|
7
|
+
* from machine state to {@link Step} at the event-emit site. Extend the union
|
|
8
|
+
* here when a new flow step needs to appear in analytics.
|
|
9
|
+
*/
|
|
10
|
+
export type Step = "entry" | "intro" | "consent" | "image-record" | "image-upload" | "image-rejection" | "height" | "variant-selection" | "try-on" | "cart" | "order";
|
|
11
|
+
//# sourceMappingURL=steps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"steps.d.ts","sourceRoot":"","sources":["../src/steps.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,MAAM,IAAI,GACZ,OAAO,GACP,OAAO,GACP,SAAS,GACT,cAAc,GACd,cAAc,GACd,iBAAiB,GACjB,QAAQ,GACR,mBAAmB,GACnB,QAAQ,GACR,MAAM,GACN,OAAO,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@studio-vaai/js-tracking",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "Typed analytics events for studio vaai, plus a fetch-based Umami transport.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"type": "module",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "vite build --config vite.lib.config.ts && rm -f tsconfig.tsbuildinfo && tsgo --emitDeclarationOnly",
|
|
21
|
+
"clean": "rm -rf dist tsconfig.tsbuildinfo",
|
|
22
|
+
"test": "vitest run --config ../../vitest.config.ts",
|
|
23
|
+
"test:watch": "vitest --config ../../vitest.config.ts"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"vite": "8.0.5"
|
|
27
|
+
}
|
|
28
|
+
}
|