@activescott/analytics 0.2.0 → 0.3.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 +42 -16
- package/dist/capture-client.d.ts +26 -0
- package/dist/capture-client.d.ts.map +1 -0
- package/dist/capture-client.js +35 -0
- package/dist/capture-client.js.map +1 -0
- package/dist/capture-registrar.d.ts +8 -0
- package/dist/capture-registrar.d.ts.map +1 -0
- package/dist/capture-registrar.js +20 -0
- package/dist/capture-registrar.js.map +1 -0
- package/dist/hosts.d.ts +20 -0
- package/dist/hosts.d.ts.map +1 -0
- package/dist/hosts.js +37 -0
- package/dist/hosts.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/post-hog-init.d.ts +19 -0
- package/dist/post-hog-init.d.ts.map +1 -0
- package/dist/post-hog-init.js +18 -0
- package/dist/post-hog-init.js.map +1 -0
- package/dist/post-hog-lazy-provider.d.ts +29 -0
- package/dist/post-hog-lazy-provider.d.ts.map +1 -0
- package/dist/post-hog-lazy-provider.js +23 -0
- package/dist/post-hog-lazy-provider.js.map +1 -0
- package/dist/post-hog-provider.d.ts +1 -1
- package/dist/post-hog-provider.d.ts.map +1 -1
- package/dist/post-hog-provider.js.map +1 -1
- package/dist/use-analytics-capture.d.ts +9 -0
- package/dist/use-analytics-capture.d.ts.map +1 -0
- package/dist/use-analytics-capture.js +14 -0
- package/dist/use-analytics-capture.js.map +1 -0
- package/package.json +11 -3
package/README.md
CHANGED
|
@@ -20,34 +20,52 @@ release a matching minor of this package.
|
|
|
20
20
|
|
|
21
21
|
Mount it where loader data is available (in React Router v7, that means `App`,
|
|
22
22
|
not `Layout` — `Layout` renders with undefined loader data on error
|
|
23
|
-
boundaries, and error pages intentionally get no pageview)
|
|
23
|
+
boundaries, and error pages intentionally get no pageview).
|
|
24
|
+
|
|
25
|
+
For zero bundle cost when disabled, use `LazyPostHogProvider`: it renders
|
|
26
|
+
null unless enabled with a key, otherwise suspense-loads the initialized
|
|
27
|
+
tree with posthog-js in its own chunk. Mount it as a STABLE SIBLING of your
|
|
28
|
+
UI — never as a conditional wrapper around it, which would remount the whole
|
|
29
|
+
subtree once the chunk loads:
|
|
24
30
|
|
|
25
31
|
```tsx
|
|
26
32
|
// app/root.tsx
|
|
27
|
-
import {
|
|
33
|
+
import { LazyPostHogProvider } from "@activescott/analytics"
|
|
28
34
|
|
|
29
35
|
export function App() {
|
|
30
|
-
const { posthogKey, user } = useLoaderData<typeof loader>()
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
36
|
+
const { posthogKey, isAdmin, user } = useLoaderData<typeof loader>()
|
|
37
|
+
return (
|
|
38
|
+
<>
|
|
39
|
+
<LazyPostHogProvider
|
|
40
|
+
enabled={posthogKey !== "" && !isAdmin}
|
|
41
|
+
apiKey={posthogKey || undefined}
|
|
42
|
+
options={{ api_host: "/ph", ui_host: "https://us.posthog.com" }}
|
|
43
|
+
user={user ? { distinctId: user.id } : undefined}
|
|
44
|
+
/>
|
|
45
|
+
<Outlet />
|
|
46
|
+
</>
|
|
47
|
+
)
|
|
34
48
|
}
|
|
35
49
|
```
|
|
36
50
|
|
|
37
51
|
Identify by stable id only — never pass emails, phone numbers, or other PII in
|
|
38
|
-
`properties` unless your privacy policy explicitly covers it
|
|
52
|
+
`properties` unless your privacy policy explicitly covers it.
|
|
53
|
+
|
|
54
|
+
`PostHogProvider` (same props plus `children`) remains for apps that prefer
|
|
55
|
+
a static import and a wrapping provider.
|
|
56
|
+
|
|
57
|
+
### Custom events
|
|
58
|
+
|
|
59
|
+
Capture through `captureAnalyticsEvent` or the `useAnalyticsCapture` hook —
|
|
60
|
+
both read the client the provider registers on init, so they work anywhere
|
|
61
|
+
without a provider ancestor, and drop while disabled or still loading:
|
|
39
62
|
|
|
40
63
|
```tsx
|
|
41
|
-
|
|
42
|
-
apiKey={posthogKey}
|
|
43
|
-
options={{ api_host: "/ph", ui_host: "https://us.posthog.com" }}
|
|
44
|
-
user={user ? { distinctId: user.id } : undefined}
|
|
45
|
-
>
|
|
46
|
-
...
|
|
47
|
-
</PostHogProvider>
|
|
48
|
-
```
|
|
64
|
+
import { useAnalyticsCapture } from "@activescott/analytics"
|
|
49
65
|
|
|
50
|
-
|
|
66
|
+
const capture = useAnalyticsCapture()
|
|
67
|
+
capture("search_results_shown", { result_count: 2 })
|
|
68
|
+
```
|
|
51
69
|
|
|
52
70
|
### 2. Add the reverse proxy route
|
|
53
71
|
|
|
@@ -86,6 +104,14 @@ That's it! PostHog will now:
|
|
|
86
104
|
- Identify logged-in users by id
|
|
87
105
|
- Receive events through your own domain (`/ph/*`)
|
|
88
106
|
|
|
107
|
+
### Deriving sibling origins
|
|
108
|
+
|
|
109
|
+
`@activescott/analytics/hosts` exports the pure helpers `posthogAssetsHost`
|
|
110
|
+
and `posthogUiHost`, which map a PostHog API origin to its assets and app-UI
|
|
111
|
+
siblings (`<region>.i.posthog.com` → `<region>-assets.i.posthog.com` /
|
|
112
|
+
`<region>.posthog.com`; anything else passes through unchanged) — so a
|
|
113
|
+
deployment carries one host knob instead of three.
|
|
114
|
+
|
|
89
115
|
## Versioning
|
|
90
116
|
|
|
91
117
|
Independent plain-npm versions with git tags of the form `analytics@<version>`
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry bridging the initialized posthog-js client to code that cannot
|
|
3
|
+
* (or should not) sit under the provider's React context.
|
|
4
|
+
*
|
|
5
|
+
* LazyPostHogProvider mounts childless as a stable sibling of the app UI —
|
|
6
|
+
* conditionally wrapping UI would remount the subtree when the chunk loads —
|
|
7
|
+
* so custom events cannot reach the client through context. Instead the
|
|
8
|
+
* registrar inside the initialized tree publishes the bound capture here on
|
|
9
|
+
* mount (and clears it on unmount); captureAnalyticsEvent and
|
|
10
|
+
* useAnalyticsCapture read it back. Unregistered (disabled, or not yet
|
|
11
|
+
* loaded) captures are dropped, never queued: analytics must not delay
|
|
12
|
+
* interaction.
|
|
13
|
+
*/
|
|
14
|
+
export type AnalyticsCapture = (event: string, properties?: Record<string, unknown>) => void;
|
|
15
|
+
/**
|
|
16
|
+
* Publishes (or clears, with null) the bound capture function. Called by the
|
|
17
|
+
* registrar inside the initialized provider tree; package-internal.
|
|
18
|
+
*/
|
|
19
|
+
export declare function setCaptureClient(implementation: AnalyticsCapture | null): void;
|
|
20
|
+
/**
|
|
21
|
+
* Fire-and-forget event capture. Drops when analytics is disabled or the
|
|
22
|
+
* client has not initialized yet, and never throws: a capture failure must
|
|
23
|
+
* not break the UI.
|
|
24
|
+
*/
|
|
25
|
+
export declare function captureAnalyticsEvent(event: string, properties?: Record<string, unknown>): void;
|
|
26
|
+
//# sourceMappingURL=capture-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture-client.d.ts","sourceRoot":"","sources":["../src/capture-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAC7B,KAAK,EAAE,MAAM,EACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KACjC,IAAI,CAAA;AAIT;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,cAAc,EAAE,gBAAgB,GAAG,IAAI,GACtC,IAAI,CAEN;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,EACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,IAAI,CAMN"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry bridging the initialized posthog-js client to code that cannot
|
|
3
|
+
* (or should not) sit under the provider's React context.
|
|
4
|
+
*
|
|
5
|
+
* LazyPostHogProvider mounts childless as a stable sibling of the app UI —
|
|
6
|
+
* conditionally wrapping UI would remount the subtree when the chunk loads —
|
|
7
|
+
* so custom events cannot reach the client through context. Instead the
|
|
8
|
+
* registrar inside the initialized tree publishes the bound capture here on
|
|
9
|
+
* mount (and clears it on unmount); captureAnalyticsEvent and
|
|
10
|
+
* useAnalyticsCapture read it back. Unregistered (disabled, or not yet
|
|
11
|
+
* loaded) captures are dropped, never queued: analytics must not delay
|
|
12
|
+
* interaction.
|
|
13
|
+
*/
|
|
14
|
+
let captureImplementation = null;
|
|
15
|
+
/**
|
|
16
|
+
* Publishes (or clears, with null) the bound capture function. Called by the
|
|
17
|
+
* registrar inside the initialized provider tree; package-internal.
|
|
18
|
+
*/
|
|
19
|
+
export function setCaptureClient(implementation) {
|
|
20
|
+
captureImplementation = implementation;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Fire-and-forget event capture. Drops when analytics is disabled or the
|
|
24
|
+
* client has not initialized yet, and never throws: a capture failure must
|
|
25
|
+
* not break the UI.
|
|
26
|
+
*/
|
|
27
|
+
export function captureAnalyticsEvent(event, properties) {
|
|
28
|
+
try {
|
|
29
|
+
captureImplementation?.(event, properties);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// Dropped by design.
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=capture-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture-client.js","sourceRoot":"","sources":["../src/capture-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,IAAI,qBAAqB,GAA4B,IAAI,CAAA;AAEzD;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,cAAuC;IAEvC,qBAAqB,GAAG,cAAc,CAAA;AACxC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAAa,EACb,UAAoC;IAEpC,IAAI,CAAC;QACH,qBAAqB,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,CAAA;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,qBAAqB;IACvB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Publishes the initialized client's bound capture into the module registry
|
|
3
|
+
* (and clears it on unmount) so captureAnalyticsEvent / useAnalyticsCapture
|
|
4
|
+
* work without a provider ancestor. Renders nothing; mount once inside the
|
|
5
|
+
* initialized provider tree.
|
|
6
|
+
*/
|
|
7
|
+
export declare function CaptureRegistrar(): null;
|
|
8
|
+
//# sourceMappingURL=capture-registrar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture-registrar.d.ts","sourceRoot":"","sources":["../src/capture-registrar.tsx"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,wBAAgB,gBAAgB,SAa/B"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { usePostHog } from "posthog-js/react";
|
|
3
|
+
import { setCaptureClient } from "./capture-client.js";
|
|
4
|
+
/**
|
|
5
|
+
* Publishes the initialized client's bound capture into the module registry
|
|
6
|
+
* (and clears it on unmount) so captureAnalyticsEvent / useAnalyticsCapture
|
|
7
|
+
* work without a provider ancestor. Renders nothing; mount once inside the
|
|
8
|
+
* initialized provider tree.
|
|
9
|
+
*/
|
|
10
|
+
export function CaptureRegistrar() {
|
|
11
|
+
const posthog = usePostHog();
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
setCaptureClient((event, properties) => posthog.capture(event, properties));
|
|
14
|
+
return () => {
|
|
15
|
+
setCaptureClient(null);
|
|
16
|
+
};
|
|
17
|
+
}, [posthog]);
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=capture-registrar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture-registrar.js","sourceRoot":"","sources":["../src/capture-registrar.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAEtD;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,OAAO,GAAG,UAAU,EAAE,CAAA;IAE5B,SAAS,CAAC,GAAG,EAAE;QACb,gBAAgB,CAAC,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,CACrC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC,CACnC,CAAA;QACD,OAAO,GAAG,EAAE;YACV,gBAAgB,CAAC,IAAI,CAAC,CAAA;QACxB,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;IAEb,OAAO,IAAI,CAAA;AACb,CAAC"}
|
package/dist/hosts.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derives the sibling PostHog origins from the configured API origin, so a
|
|
3
|
+
* deployment carries one host knob instead of three.
|
|
4
|
+
*
|
|
5
|
+
* PostHog cloud serves each region from `<region>.i.posthog.com` (events),
|
|
6
|
+
* `<region>-assets.i.posthog.com` (static assets) and `<region>.posthog.com`
|
|
7
|
+
* (app UI, the posthog-js `ui_host`). Any other origin — a self-hosted
|
|
8
|
+
* instance, a future region layout — is returned unchanged for both, which
|
|
9
|
+
* keeps proxy and client on the one configured host.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Returns the static-assets origin for a PostHog API origin.
|
|
13
|
+
*/
|
|
14
|
+
export declare function posthogAssetsHost(apiHost: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Returns the app-UI origin for a PostHog API origin (the `ui_host`
|
|
17
|
+
* posthog-js option).
|
|
18
|
+
*/
|
|
19
|
+
export declare function posthogUiHost(apiHost: string): string;
|
|
20
|
+
//# sourceMappingURL=hosts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosts.d.ts","sourceRoot":"","sources":["../src/hosts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGzD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGrD"}
|
package/dist/hosts.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derives the sibling PostHog origins from the configured API origin, so a
|
|
3
|
+
* deployment carries one host knob instead of three.
|
|
4
|
+
*
|
|
5
|
+
* PostHog cloud serves each region from `<region>.i.posthog.com` (events),
|
|
6
|
+
* `<region>-assets.i.posthog.com` (static assets) and `<region>.posthog.com`
|
|
7
|
+
* (app UI, the posthog-js `ui_host`). Any other origin — a self-hosted
|
|
8
|
+
* instance, a future region layout — is returned unchanged for both, which
|
|
9
|
+
* keeps proxy and client on the one configured host.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Returns the static-assets origin for a PostHog API origin.
|
|
13
|
+
*/
|
|
14
|
+
export function posthogAssetsHost(apiHost) {
|
|
15
|
+
const region = posthogCloudRegion(apiHost);
|
|
16
|
+
return region ? `https://${region}-assets.i.posthog.com` : apiHost;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Returns the app-UI origin for a PostHog API origin (the `ui_host`
|
|
20
|
+
* posthog-js option).
|
|
21
|
+
*/
|
|
22
|
+
export function posthogUiHost(apiHost) {
|
|
23
|
+
const region = posthogCloudRegion(apiHost);
|
|
24
|
+
return region ? `https://${region}.posthog.com` : apiHost;
|
|
25
|
+
}
|
|
26
|
+
function posthogCloudRegion(apiHost) {
|
|
27
|
+
let hostname;
|
|
28
|
+
try {
|
|
29
|
+
hostname = new URL(apiHost).hostname;
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
const match = /^([a-z0-9-]+)\.i\.posthog\.com$/.exec(hostname);
|
|
35
|
+
return match ? match[1] : null;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=hosts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosts.js","sourceRoot":"","sources":["../src/hosts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAA;IAC1C,OAAO,MAAM,CAAC,CAAC,CAAC,WAAW,MAAM,uBAAuB,CAAC,CAAC,CAAC,OAAO,CAAA;AACpE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAA;IAC1C,OAAO,MAAM,CAAC,CAAC,CAAC,WAAW,MAAM,cAAc,CAAC,CAAC,CAAC,OAAO,CAAA;AAC3D,CAAC;AAED,SAAS,kBAAkB,CAAC,OAAe;IACzC,IAAI,QAAgB,CAAA;IACpB,IAAI,CAAC;QACH,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAA;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;IACD,MAAM,KAAK,GAAG,iCAAiC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IAC9D,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AAChC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export { PostHogProvider } from "./post-hog-provider.js";
|
|
2
2
|
export { PostHogPageviewTracker } from "./post-hog-pageview-tracker.js";
|
|
3
3
|
export { PostHogIdentifier } from "./post-hog-identifier.js";
|
|
4
|
+
export { LazyPostHogProvider, type LazyPostHogProviderProps, } from "./post-hog-lazy-provider.js";
|
|
5
|
+
export { captureAnalyticsEvent, type AnalyticsCapture, } from "./capture-client.js";
|
|
6
|
+
export { useAnalyticsCapture } from "./use-analytics-capture.js";
|
|
4
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EACL,mBAAmB,EACnB,KAAK,wBAAwB,GAC9B,MAAM,6BAA6B,CAAA;AACpC,OAAO,EACL,qBAAqB,EACrB,KAAK,gBAAgB,GACtB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export { PostHogProvider } from "./post-hog-provider.js";
|
|
2
2
|
export { PostHogPageviewTracker } from "./post-hog-pageview-tracker.js";
|
|
3
3
|
export { PostHogIdentifier } from "./post-hog-identifier.js";
|
|
4
|
+
export { LazyPostHogProvider, } from "./post-hog-lazy-provider.js";
|
|
5
|
+
export { captureAnalyticsEvent, } from "./capture-client.js";
|
|
6
|
+
export { useAnalyticsCapture } from "./use-analytics-capture.js";
|
|
4
7
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EACL,mBAAmB,GAEpB,MAAM,6BAA6B,CAAA;AACpC,OAAO,EACL,qBAAqB,GAEtB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { PostHogConfig } from "posthog-js";
|
|
2
|
+
interface PostHogInitProps {
|
|
3
|
+
apiKey: string;
|
|
4
|
+
options?: Partial<PostHogConfig>;
|
|
5
|
+
user?: {
|
|
6
|
+
distinctId: string;
|
|
7
|
+
properties?: Record<string, unknown>;
|
|
8
|
+
};
|
|
9
|
+
children?: React.ReactNode;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The initialized PostHog tree: context provider, SPA pageview tracking,
|
|
13
|
+
* user identification, and capture registration. Lives in its own module so
|
|
14
|
+
* React.lazy splits it (and posthog-js with it) into a separate chunk —
|
|
15
|
+
* mount LazyPostHogProvider, not this, which guarantees the split point.
|
|
16
|
+
*/
|
|
17
|
+
export declare function PostHogInit({ apiKey, options, user, children, }: PostHogInitProps): import("react").JSX.Element;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=post-hog-init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post-hog-init.d.ts","sourceRoot":"","sources":["../src/post-hog-init.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAM/C,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAA;IAChC,IAAI,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAA;IACnE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC3B;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,OAAO,EACP,IAAI,EACJ,QAAQ,GACT,EAAE,gBAAgB,+BAkBlB"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { PostHogProvider as PHProvider } from "posthog-js/react";
|
|
3
|
+
import { PostHogIdentifier } from "./post-hog-identifier.js";
|
|
4
|
+
import { PostHogPageviewTracker } from "./post-hog-pageview-tracker.js";
|
|
5
|
+
import { CaptureRegistrar } from "./capture-registrar.js";
|
|
6
|
+
/**
|
|
7
|
+
* The initialized PostHog tree: context provider, SPA pageview tracking,
|
|
8
|
+
* user identification, and capture registration. Lives in its own module so
|
|
9
|
+
* React.lazy splits it (and posthog-js with it) into a separate chunk —
|
|
10
|
+
* mount LazyPostHogProvider, not this, which guarantees the split point.
|
|
11
|
+
*/
|
|
12
|
+
export function PostHogInit({ apiKey, options, user, children, }) {
|
|
13
|
+
return (_jsxs(PHProvider, { apiKey: apiKey, options: {
|
|
14
|
+
...options,
|
|
15
|
+
capture_pageview: false,
|
|
16
|
+
}, children: [_jsx(PostHogPageviewTracker, {}), _jsx(PostHogIdentifier, { distinctId: user?.distinctId, properties: user?.properties }), _jsx(CaptureRegistrar, {}), children] }));
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=post-hog-init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post-hog-init.js","sourceRoot":"","sources":["../src/post-hog-init.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,eAAe,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AASzD;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,EAC1B,MAAM,EACN,OAAO,EACP,IAAI,EACJ,QAAQ,GACS;IACjB,OAAO,CACL,MAAC,UAAU,IACT,MAAM,EAAE,MAAM,EACd,OAAO,EAAE;YACP,GAAG,OAAO;YACV,gBAAgB,EAAE,KAAK;SACxB,aAED,KAAC,sBAAsB,KAAG,EAC1B,KAAC,iBAAiB,IAChB,UAAU,EAAE,IAAI,EAAE,UAAU,EAC5B,UAAU,EAAE,IAAI,EAAE,UAAU,GAC5B,EACF,KAAC,gBAAgB,KAAG,EACnB,QAAQ,IACE,CACd,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { PostHogConfig } from "posthog-js";
|
|
2
|
+
export interface LazyPostHogProviderProps {
|
|
3
|
+
/**
|
|
4
|
+
* Whether capture runs at all. The containing app decides — typically
|
|
5
|
+
* `apiKey` presence plus its own exclusions (e.g. admin traffic). When
|
|
6
|
+
* false (or with no key) this renders null with zero PostHog code paths,
|
|
7
|
+
* and the posthog-js chunk is never fetched.
|
|
8
|
+
*/
|
|
9
|
+
enabled: boolean;
|
|
10
|
+
apiKey?: string;
|
|
11
|
+
options?: Partial<PostHogConfig>;
|
|
12
|
+
user?: {
|
|
13
|
+
distinctId: string;
|
|
14
|
+
properties?: Record<string, unknown>;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* PostHog with zero bundle cost when disabled. Renders null unless enabled
|
|
19
|
+
* with a key; otherwise suspense-loads the initialized tree — posthog-js
|
|
20
|
+
* travels in its own chunk, fetched only then.
|
|
21
|
+
*
|
|
22
|
+
* Mount as a STABLE SIBLING of your UI (e.g. beside `<Outlet/>`), never as a
|
|
23
|
+
* conditional wrapper around it: swapping a wrapper in after the chunk loads
|
|
24
|
+
* remounts the whole subtree. Custom events go through captureAnalyticsEvent
|
|
25
|
+
* / useAnalyticsCapture (registered on init), so no context ancestor is
|
|
26
|
+
* needed.
|
|
27
|
+
*/
|
|
28
|
+
export declare function LazyPostHogProvider({ enabled, apiKey, options, user, }: LazyPostHogProviderProps): import("react").JSX.Element | null;
|
|
29
|
+
//# sourceMappingURL=post-hog-lazy-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post-hog-lazy-provider.d.ts","sourceRoot":"","sources":["../src/post-hog-lazy-provider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAQ/C,MAAM,WAAW,wBAAwB;IACvC;;;;;OAKG;IACH,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAA;IAChC,IAAI,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAA;CACpE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,OAAO,EACP,MAAM,EACN,OAAO,EACP,IAAI,GACL,EAAE,wBAAwB,sCAS1B"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Suspense, lazy } from "react";
|
|
3
|
+
const PostHogInit = lazy(() => import("./post-hog-init.js").then((module) => ({
|
|
4
|
+
default: module.PostHogInit,
|
|
5
|
+
})));
|
|
6
|
+
/**
|
|
7
|
+
* PostHog with zero bundle cost when disabled. Renders null unless enabled
|
|
8
|
+
* with a key; otherwise suspense-loads the initialized tree — posthog-js
|
|
9
|
+
* travels in its own chunk, fetched only then.
|
|
10
|
+
*
|
|
11
|
+
* Mount as a STABLE SIBLING of your UI (e.g. beside `<Outlet/>`), never as a
|
|
12
|
+
* conditional wrapper around it: swapping a wrapper in after the chunk loads
|
|
13
|
+
* remounts the whole subtree. Custom events go through captureAnalyticsEvent
|
|
14
|
+
* / useAnalyticsCapture (registered on init), so no context ancestor is
|
|
15
|
+
* needed.
|
|
16
|
+
*/
|
|
17
|
+
export function LazyPostHogProvider({ enabled, apiKey, options, user, }) {
|
|
18
|
+
if (!enabled || !apiKey) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
return (_jsx(Suspense, { fallback: null, children: _jsx(PostHogInit, { apiKey: apiKey, options: options, user: user }) }));
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=post-hog-lazy-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post-hog-lazy-provider.js","sourceRoot":"","sources":["../src/post-hog-lazy-provider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AAGtC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAC5B,MAAM,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC,WAAW;CAC5B,CAAC,CAAC,CACJ,CAAA;AAeD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAClC,OAAO,EACP,MAAM,EACN,OAAO,EACP,IAAI,GACqB;IACzB,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;QACxB,OAAO,IAAI,CAAA;IACb,CAAC;IACD,OAAO,CACL,KAAC,QAAQ,IAAC,QAAQ,EAAE,IAAI,YACtB,KAAC,WAAW,IAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,GAAI,GACpD,CACZ,CAAA;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"post-hog-provider.d.ts","sourceRoot":"","sources":["../src/post-hog-provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAK/C,UAAU,oBAAoB;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAA;IAChC,IAAI,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"post-hog-provider.d.ts","sourceRoot":"","sources":["../src/post-hog-provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAK/C,UAAU,oBAAoB;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAA;IAChC,IAAI,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAA;IAKnE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC3B;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,OAAO,EACP,IAAI,EACJ,QAAQ,GACT,EAAE,oBAAoB,+BAqBtB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"post-hog-provider.js","sourceRoot":"","sources":["../src/post-hog-provider.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,eAAe,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;
|
|
1
|
+
{"version":3,"file":"post-hog-provider.js","sourceRoot":"","sources":["../src/post-hog-provider.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,eAAe,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAa5D;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,EAC9B,MAAM,EACN,OAAO,EACP,IAAI,EACJ,QAAQ,GACa;IACrB,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,4BAAG,QAAQ,GAAI,CAAA;IACxB,CAAC;IAED,OAAO,CACL,MAAC,UAAU,IACT,MAAM,EAAE,MAAM,EACd,OAAO,EAAE;YACP,GAAG,OAAO;YACV,gBAAgB,EAAE,KAAK;SACxB,aAED,KAAC,sBAAsB,KAAG,EAC1B,KAAC,iBAAiB,IAChB,UAAU,EAAE,IAAI,EAAE,UAAU,EAC5B,UAAU,EAAE,IAAI,EAAE,UAAU,GAC5B,EACD,QAAQ,IACE,CACd,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type AnalyticsCapture } from "./capture-client.js";
|
|
2
|
+
/**
|
|
3
|
+
* Returns the analytics capture function. Stable across renders; backed by
|
|
4
|
+
* the initialized provider's registered client, so it works anywhere in the
|
|
5
|
+
* app without a provider ancestor. Drops events while analytics is disabled
|
|
6
|
+
* or the client chunk is still loading.
|
|
7
|
+
*/
|
|
8
|
+
export declare function useAnalyticsCapture(): AnalyticsCapture;
|
|
9
|
+
//# sourceMappingURL=use-analytics-capture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-analytics-capture.d.ts","sourceRoot":"","sources":["../src/use-analytics-capture.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,qBAAqB,CAAA;AAE5B;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,gBAAgB,CAItD"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { captureAnalyticsEvent, } from "./capture-client.js";
|
|
3
|
+
/**
|
|
4
|
+
* Returns the analytics capture function. Stable across renders; backed by
|
|
5
|
+
* the initialized provider's registered client, so it works anywhere in the
|
|
6
|
+
* app without a provider ancestor. Drops events while analytics is disabled
|
|
7
|
+
* or the client chunk is still loading.
|
|
8
|
+
*/
|
|
9
|
+
export function useAnalyticsCapture() {
|
|
10
|
+
return useCallback((event, properties) => {
|
|
11
|
+
captureAnalyticsEvent(event, properties);
|
|
12
|
+
}, []);
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=use-analytics-capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-analytics-capture.js","sourceRoot":"","sources":["../src/use-analytics-capture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AACnC,OAAO,EACL,qBAAqB,GAEtB,MAAM,qBAAqB,CAAA;AAE5B;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,WAAW,CAAC,CAAC,KAAa,EAAE,UAAoC,EAAE,EAAE;QACzE,qBAAqB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAA;IAC1C,CAAC,EAAE,EAAE,CAAC,CAAA;AACR,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@activescott/analytics",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "PostHog analytics integration for React Router apps — provider, SPA pageview tracking, user identification, and reverse proxy helper",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -13,6 +13,10 @@
|
|
|
13
13
|
"./proxy": {
|
|
14
14
|
"types": "./dist/proxy.d.ts",
|
|
15
15
|
"import": "./dist/proxy.js"
|
|
16
|
+
},
|
|
17
|
+
"./hosts": {
|
|
18
|
+
"types": "./dist/hosts.d.ts",
|
|
19
|
+
"import": "./dist/hosts.js"
|
|
16
20
|
}
|
|
17
21
|
},
|
|
18
22
|
"files": [
|
|
@@ -35,7 +39,7 @@
|
|
|
35
39
|
"license": "MIT",
|
|
36
40
|
"repository": {
|
|
37
41
|
"type": "git",
|
|
38
|
-
"url": "https://github.com/activescott/js-utils.git",
|
|
42
|
+
"url": "git+https://github.com/activescott/js-utils.git",
|
|
39
43
|
"directory": "packages/analytics"
|
|
40
44
|
},
|
|
41
45
|
"peerDependencies": {
|
|
@@ -44,10 +48,14 @@
|
|
|
44
48
|
"react-router": "^7.0.0"
|
|
45
49
|
},
|
|
46
50
|
"devDependencies": {
|
|
51
|
+
"@testing-library/dom": "^10.4.1",
|
|
52
|
+
"@testing-library/react": "^16.3.2",
|
|
47
53
|
"@types/node": "^22",
|
|
48
54
|
"@types/react": "^19.2.14",
|
|
55
|
+
"jsdom": "^27.4.0",
|
|
49
56
|
"posthog-js": "^1.351.4",
|
|
50
|
-
"react": "
|
|
57
|
+
"react": "19.2.8",
|
|
58
|
+
"react-dom": "19.2.8",
|
|
51
59
|
"react-router": "^7.10.1",
|
|
52
60
|
"typescript": "^5.9.3",
|
|
53
61
|
"vitest": "4.1.10"
|