@wrelik/analytics 0.1.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/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ # @wrelik/analytics
2
+
3
+ ## 0.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - ad849e3: Initial release of all wrelik-kit packages.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [ad849e3]
12
+ - @wrelik/errors@0.1.0
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "@wrelik/analytics",
3
+ "version": "0.1.0",
4
+ "main": "./dist/index.js",
5
+ "types": "./dist/index.d.ts",
6
+ "dependencies": {
7
+ "posthog-node": "^3.6.3",
8
+ "@wrelik/errors": "0.1.0"
9
+ },
10
+ "devDependencies": {
11
+ "tsup": "^8.0.1",
12
+ "vitest": "^1.2.2",
13
+ "@wrelik/eslint-config": "0.1.0",
14
+ "@wrelik/tsconfig": "0.1.0"
15
+ },
16
+ "scripts": {
17
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean",
18
+ "lint": "eslint src/",
19
+ "test": "vitest run --passWithNoTests"
20
+ }
21
+ }
package/src/index.ts ADDED
@@ -0,0 +1,51 @@
1
+ import { PostHog } from 'posthog-node';
2
+ import { ValidationError } from '@wrelik/errors';
3
+
4
+ let client: PostHog | null = null;
5
+
6
+ export function initAnalytics(apiKey: string, host = 'https://app.posthog.com') {
7
+ client = new PostHog(apiKey, { host });
8
+ }
9
+
10
+ function getClient(safe = false) {
11
+ if (!client && !safe) {
12
+ throw new Error('Analytics not initialized. Call initAnalytics first.');
13
+ }
14
+ return client;
15
+ }
16
+
17
+ export function identify(userId: string, traits: Record<string, any>) {
18
+ getClient(true)?.identify({
19
+ distinctId: userId,
20
+ properties: traits,
21
+ });
22
+ }
23
+
24
+ export function capture(
25
+ event: string,
26
+ properties: Record<string, any> = {},
27
+ options?: { userId?: string },
28
+ ) {
29
+ // Validate naming convention: app.action.object
30
+ const parts = event.split('.');
31
+ if (parts.length < 3) {
32
+ throw new ValidationError(`Event name "${event}" must follow "app.action.object" format`);
33
+ }
34
+
35
+ // If no user is provided, we can't capture server-side easily without anonymous ID
36
+ // But usually servers have a userId context.
37
+ if (!options?.userId) {
38
+ console.warn('Analytics capture called without userId');
39
+ return;
40
+ }
41
+
42
+ getClient(true)?.capture({
43
+ distinctId: options.userId,
44
+ event,
45
+ properties,
46
+ });
47
+ }
48
+
49
+ export async function shutdown() {
50
+ await getClient(true)?.shutdown();
51
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": "@wrelik/tsconfig/node.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist"
5
+ },
6
+ "include": ["src"]
7
+ }