stat18ion 0.1.2 → 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/README.md CHANGED
@@ -11,61 +11,40 @@ npm install stat18ion
11
11
 
12
12
  ## Usage
13
13
 
14
- Initialize the tracker once in your application root (e.g., `layout.tsx` or `App.js`).
14
+ ### 1. Unblockable (Server-Side) **Recommended**
15
+ This is immune to ad-blockers and requires zero client-side JavaScript. Best for Next.js, Nuxt, or any server-side framework.
16
+
17
+ ```typescript
18
+ // middleware.ts (Next.js Example)
19
+ import { NextResponse } from 'next/server';
20
+ import { trackServerEvent } from 'stat18ion';
21
+
22
+ export async function middleware(req) {
23
+ // Track the event without blocking the visitor
24
+ trackServerEvent({
25
+ siteId: 'YOUR_SITE_ID',
26
+ path: req.nextUrl.pathname,
27
+ ua: req.headers.get('user-agent') || '',
28
+ referrer: req.headers.get('referer') || '',
29
+ });
30
+
31
+ return NextResponse.next();
32
+ }
33
+ ```
34
+
35
+ ### 2. Standard (Client-Side)
36
+ Initialize once in your application root.
15
37
 
16
38
  ```javascript
17
39
  import { init } from 'stat18ion';
18
40
 
19
41
  init({
20
42
  siteId: 'YOUR_SITE_ID',
21
- debug: false, // Set to true to see logs in console
22
- trackLocal: false // Set to true to send data from localhost/dev
43
+ debug: false,
44
+ trackLocal: false
23
45
  });
24
46
  ```
25
47
 
26
- ### Configuration Options
27
- | Option | Type | Default | Description |
28
- | :--- | :--- | :--- | :--- |
29
- | `siteId` | `string` | Required | Your unique Site UUID from the dashboard. |
30
- | `endpoint` | `string` | SaaS URL | Your backend event endpoint. |
31
- | `debug` | `boolean` | `false` | Enable console logging for events. |
32
- | `trackLocal` | `boolean` | `false` | If false, data is never sent from `localhost`. |
33
-
34
- ### Next.js Integration
35
-
36
- To keep your layout as a **Server Component** (for Metadata/SEO), create a small client-side component:
37
-
38
- ```tsx
39
- // components/StatTracker.tsx
40
- 'use client';
41
- import { useEffect } from 'react';
42
- import { init } from 'stat18ion';
43
-
44
- export default function StatTracker() {
45
- useEffect(() => {
46
- init({ siteId: 'YOUR_UUID_HERE' });
47
- }, []);
48
- return null;
49
- }
50
- ```
51
-
52
- Then add it to your `app/layout.tsx`:
53
-
54
- ```tsx
55
- import StatTracker from './components/StatTracker';
56
-
57
- export default function RootLayout({ children }) {
58
- return (
59
- <html lang="en">
60
- <body>
61
- <StatTracker />
62
- {children}
63
- </body>
64
- </html>
65
- );
66
- }
67
- ```
68
-
69
48
  ## Features
70
49
  - 🚀 **Lightweight**: Zero dependencies, tiny bundle.
71
50
  - 🕵️ **Privacy Friendly**: No IP storage, no cookies.
package/dist/index.d.ts CHANGED
@@ -4,6 +4,20 @@ type Config = {
4
4
  debug?: boolean;
5
5
  trackLocal?: boolean;
6
6
  };
7
+ /**
8
+ * Initialize Client-Side Tracking
9
+ */
7
10
  export declare const init: (options: Config) => void;
11
+ /**
12
+ * Server-Side Tracking for "Plug n Play" unblockable analytics.
13
+ * Use this in Next.js Middleware or Server Actions.
14
+ */
15
+ export declare const trackServerEvent: (options: {
16
+ siteId: string;
17
+ path: string;
18
+ referrer?: string;
19
+ ua?: string;
20
+ endpoint?: string;
21
+ }) => Promise<void>;
8
22
  export declare const Analytics: () => null;
9
23
  export {};
package/dist/index.js CHANGED
@@ -1,19 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Analytics = exports.init = void 0;
3
+ exports.Analytics = exports.trackServerEvent = exports.init = void 0;
4
4
  let config = {
5
5
  siteId: '',
6
- endpoint: 'https://stats.hashboard.in/api/event', // SaaS default (Replace with your actual domain)
6
+ endpoint: 'https://stats.hashboard.in/api/event',
7
7
  };
8
8
  const log = (message, ...args) => {
9
9
  if (config.debug) {
10
10
  console.log(`[Stat18ion] ${message}`, ...args);
11
11
  }
12
12
  };
13
+ /**
14
+ * Client-side event sender
15
+ */
13
16
  const sendEvent = (payload) => {
14
17
  const url = config.endpoint;
15
18
  const body = JSON.stringify(payload);
16
- if (navigator.sendBeacon) {
19
+ if (typeof navigator !== 'undefined' && navigator.sendBeacon) {
17
20
  const blob = new Blob([body], { type: 'application/json' });
18
21
  navigator.sendBeacon(url, blob);
19
22
  }
@@ -23,17 +26,19 @@ const sendEvent = (payload) => {
23
26
  body,
24
27
  headers: { 'Content-Type': 'application/json' },
25
28
  keepalive: true,
26
- credentials: 'omit', // No cookies/auth needed for tracking
29
+ credentials: 'omit',
27
30
  }).catch((err) => console.error(err));
28
31
  }
29
32
  };
33
+ /**
34
+ * Main function to track page views (Client-side)
35
+ */
30
36
  const trackPageView = () => {
37
+ if (typeof window === 'undefined')
38
+ return;
31
39
  const isLocal = ['localhost', '127.0.0.1', '0.0.0.0'].includes(window.location.hostname);
32
- // Safety check: Don't send data from local dev unless explicitly asked
33
40
  if (isLocal && !config.trackLocal) {
34
- if (config.debug) {
35
- log('Skipping event sending on localhost. Use trackLocal: true to enable.');
36
- }
41
+ log('Skipping event sending on localhost.');
37
42
  return;
38
43
  }
39
44
  const payload = {
@@ -48,6 +53,8 @@ const trackPageView = () => {
48
53
  };
49
54
  // History API Monkey Patching
50
55
  const patchHistory = () => {
56
+ if (typeof window === 'undefined')
57
+ return;
51
58
  const originalPushState = history.pushState;
52
59
  const originalReplaceState = history.replaceState;
53
60
  history.pushState = function (...args) {
@@ -62,26 +69,46 @@ const patchHistory = () => {
62
69
  trackPageView();
63
70
  });
64
71
  };
72
+ /**
73
+ * Initialize Client-Side Tracking
74
+ */
65
75
  const init = (options) => {
66
- if (config.siteId) {
67
- console.warn('Stat18ion already initialized');
76
+ if (config.siteId)
68
77
  return;
69
- }
70
78
  config = { ...config, ...options };
71
- if (!config.endpoint) {
72
- console.error('[Stat18ion] Error: No endpoint provided. Analytics will not be sent.');
79
+ if (!config.endpoint)
73
80
  return;
74
- }
75
81
  log('Initialized', config);
76
- // Initial Page View
77
82
  trackPageView();
78
- // Route Changes
79
83
  patchHistory();
80
84
  };
81
85
  exports.init = init;
86
+ /**
87
+ * Server-Side Tracking for "Plug n Play" unblockable analytics.
88
+ * Use this in Next.js Middleware or Server Actions.
89
+ */
90
+ const trackServerEvent = async (options) => {
91
+ const payload = {
92
+ siteId: options.siteId,
93
+ path: options.path,
94
+ referrer: options.referrer || '',
95
+ ua: options.ua || '',
96
+ ts: Date.now(),
97
+ };
98
+ const endpoint = options.endpoint || 'https://stats.hashboard.in/api/event';
99
+ try {
100
+ await fetch(endpoint, {
101
+ method: 'POST',
102
+ body: JSON.stringify(payload),
103
+ headers: { 'Content-Type': 'application/json' },
104
+ });
105
+ }
106
+ catch (err) {
107
+ console.error('[Stat18ion] Server-side tracking failed:', err);
108
+ }
109
+ };
110
+ exports.trackServerEvent = trackServerEvent;
82
111
  const Analytics = () => {
83
- // Config would typically be passed via props or context in React
84
- // For now this is a placeholder if we want a Component wrapper
85
112
  return null;
86
113
  };
87
114
  exports.Analytics = Analytics;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stat18ion",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Privacy-first, lightweight analytics tracker for the modern web.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",