@stacksjs/analytics 0.70.55 → 0.70.56

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/analytics",
3
3
  "type": "module",
4
- "version": "0.70.55",
4
+ "version": "0.70.56",
5
5
  "description": "Stacks Analytics. Privacy-friendly.",
6
6
  "author": "Chris Breuer",
7
7
  "contributors": [
@@ -33,16 +33,17 @@
33
33
  ],
34
34
  "exports": {
35
35
  ".": {
36
- "bun": "./src/index.ts",
37
- "import": "./dist/index.js"
36
+ "development": "./src/index.ts",
37
+ "bun": "./dist/index.js",
38
+ "import": "./dist/index.js",
39
+ "default": "./dist/index.js"
38
40
  }
39
41
  },
40
42
  "module": "dist/index.js",
41
43
  "types": "dist/index.d.ts",
42
44
  "files": [
43
45
  "README.md",
44
- "dist",
45
- "src"
46
+ "dist"
46
47
  ],
47
48
  "scripts": {
48
49
  "build": "bun build.ts",
@@ -1 +0,0 @@
1
- export const fathomWip = 1
@@ -1,2 +0,0 @@
1
- export * from './fathom'
2
- export * from './self-hosted'
@@ -1,148 +0,0 @@
1
- /**
2
- * Self-Hosted Analytics Driver
3
- *
4
- * This driver generates a minimal, privacy-focused tracking script
5
- * that sends analytics data to your own API endpoint (powered by dynamodb-tooling analytics).
6
- *
7
- * Features:
8
- * - No cookies required
9
- * - Privacy-focused (hashed visitor IDs)
10
- * - Do Not Track support
11
- * - Page view tracking
12
- * - Custom event tracking
13
- * - Outbound link tracking (optional)
14
- * - Hash-based routing support (optional)
15
- */
16
-
17
- export interface SelfHostedConfig {
18
- /** Site ID for tracking */
19
- siteId: string
20
- /** API endpoint URL for collecting analytics */
21
- apiEndpoint: string
22
- /** Honor Do Not Track browser setting */
23
- honorDnt?: boolean
24
- /** Track hash changes as page views */
25
- trackHashChanges?: boolean
26
- /** Track outbound link clicks */
27
- trackOutboundLinks?: boolean
28
- }
29
-
30
- /**
31
- * Generate the self-hosted analytics tracking script
32
- */
33
- export function generateSelfHostedScript(config: SelfHostedConfig): string {
34
- if (!config.siteId || !config.apiEndpoint) {
35
- return ''
36
- }
37
-
38
- const siteId = escapeAttr(config.siteId)
39
- const apiEndpoint = escapeAttr(config.apiEndpoint)
40
- const honorDnt = config.honorDnt ? `if(n.doNotTrack==="1")return;` : ''
41
- const hashTracking = config.trackHashChanges ? `w.addEventListener('hashchange',pv);` : ''
42
- const outboundTracking = config.trackOutboundLinks
43
- ? `
44
- d.addEventListener('click',function(e){
45
- var a=e.target.closest('a');
46
- if(a&&a.hostname!==location.hostname){
47
- t('outbound',{url:a.href});
48
- }
49
- });`
50
- : ''
51
-
52
- return `<!-- Stacks Self-Hosted Analytics -->
53
- <script data-site="${siteId}" data-api="${apiEndpoint}" defer>
54
- (function(){
55
- 'use strict';
56
- var d=document,w=window,n=navigator,s=d.currentScript;
57
- var site=s.dataset.site,api=s.dataset.api;
58
- ${honorDnt}
59
- var q=[],sid=Math.random().toString(36).slice(2);
60
- function t(e,p){
61
- var x=new XMLHttpRequest();
62
- x.open('POST',api+'/collect',true);
63
- x.setRequestHeader('Content-Type','application/json');
64
- // Strip the URL's query string before sending. location.href includes
65
- // tokens / session IDs / search terms that shouldn't reach the
66
- // analytics backend. Same goes for document.referrer when it points
67
- // back to our own domain (path is fine, query is not).
68
- var safeUrl=location.origin+location.pathname+location.hash;
69
- var safeRef=d.referrer?d.referrer.split('?')[0]:'';
70
- x.send(JSON.stringify({
71
- s:site,sid:sid,e:e,p:p||{},
72
- u:safeUrl,r:safeRef,t:d.title,
73
- sw:screen.width,sh:screen.height
74
- }));
75
- }
76
- function pv(){t('pageview');}
77
- ${hashTracking}
78
- ${outboundTracking}
79
- if(d.readyState==='complete')pv();
80
- else w.addEventListener('load',pv);
81
- w.stacksAnalytics={track:function(n,v){t('event',{name:n,value:v});}};
82
- })();
83
- </script>`
84
- }
85
-
86
- /**
87
- * Generate the head tag for including self-hosted analytics
88
- * Compatible with Stacks docs config.ts head array format
89
- */
90
- export function getSelfHostedAnalyticsHead(config: SelfHostedConfig): [string, Record<string, string>][] {
91
- if (!config.siteId || !config.apiEndpoint) {
92
- return []
93
- }
94
-
95
- // Return as an inline script tag configuration
96
- // Note: For VitePress/Stacks docs, inline scripts need special handling
97
- return [
98
- ['script', {
99
- 'data-site': config.siteId,
100
- 'data-api': config.apiEndpoint,
101
- 'defer': '',
102
- 'innerHTML': generateInlineScript(config),
103
- }],
104
- ]
105
- }
106
-
107
- /**
108
- * Generate just the inline script content (without script tags)
109
- */
110
- function generateInlineScript(config: SelfHostedConfig): string {
111
- const honorDnt = config.honorDnt ? `if(n.doNotTrack==="1")return;` : ''
112
- const hashTracking = config.trackHashChanges ? `w.addEventListener('hashchange',pv);` : ''
113
- const outboundTracking = config.trackOutboundLinks
114
- ? `d.addEventListener('click',function(e){var a=e.target.closest('a');if(a&&a.hostname!==location.hostname){t('outbound',{url:a.href});}});`
115
- : ''
116
-
117
- return `(function(){
118
- 'use strict';
119
- var d=document,w=window,n=navigator,s=d.currentScript;
120
- var site=s.dataset.site,api=s.dataset.api;
121
- ${honorDnt}
122
- var q=[],sid=Math.random().toString(36).slice(2);
123
- function t(e,p){
124
- var x=new XMLHttpRequest();
125
- x.open('POST',api+'/collect',true);
126
- x.setRequestHeader('Content-Type','application/json');
127
- var safeUrl=location.origin+location.pathname+location.hash;var safeRef=d.referrer?d.referrer.split('?')[0]:'';x.send(JSON.stringify({s:site,sid:sid,e:e,p:p||{},u:safeUrl,r:safeRef,t:d.title,sw:screen.width,sh:screen.height}));
128
- }
129
- function pv(){t('pageview');}
130
- ${hashTracking}
131
- ${outboundTracking}
132
- if(d.readyState==='complete')pv();
133
- else w.addEventListener('load',pv);
134
- w.stacksAnalytics={track:function(n,v){t('event',{name:n,value:v});}};
135
- })();`
136
- }
137
-
138
- /**
139
- * Escape attribute value for safe HTML insertion
140
- */
141
- function escapeAttr(str: string): string {
142
- return str
143
- .replace(/&/g, '&amp;')
144
- .replace(/"/g, '&quot;')
145
- .replace(/'/g, '&#39;')
146
- .replace(/</g, '&lt;')
147
- .replace(/>/g, '&gt;')
148
- }
package/src/index.ts DELETED
@@ -1 +0,0 @@
1
- export * from './drivers'