@summalytics/js 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/dist/index.js ADDED
@@ -0,0 +1,75 @@
1
+ function createSessionId() {
2
+ if (typeof crypto !== 'undefined' && crypto.randomUUID) {
3
+ return crypto.randomUUID()
4
+ }
5
+
6
+ return `session_${Math.random().toString(36).slice(2)}`
7
+ }
8
+
9
+ function createRequestId() {
10
+ if (typeof crypto !== 'undefined' && crypto.randomUUID) {
11
+ return crypto.randomUUID()
12
+ }
13
+
14
+ return `req_${Math.random().toString(36).slice(2)}`
15
+ }
16
+
17
+ export function createSummalytics(config) {
18
+ const sessionId = createSessionId()
19
+
20
+ const send = async (payload) => {
21
+ const body = JSON.stringify(payload)
22
+
23
+ if (typeof navigator !== 'undefined' && navigator.sendBeacon) {
24
+ const beaconUrl = `${config.endpoint}${config.endpoint.includes('?') ? '&' : '?'}key=${encodeURIComponent(config.writeKey)}`
25
+ const blob = new Blob([body], { type: 'application/json' })
26
+ const accepted = navigator.sendBeacon(beaconUrl, blob)
27
+ if (accepted) {
28
+ return
29
+ }
30
+ }
31
+
32
+ await fetch(config.endpoint, {
33
+ method: 'POST',
34
+ headers: {
35
+ 'Content-Type': 'application/json',
36
+ 'x-summalytics-key': config.writeKey,
37
+ },
38
+ body,
39
+ keepalive: true,
40
+ })
41
+ }
42
+
43
+ const track = async (eventName, payload = {}) => {
44
+ await send({
45
+ requestId: payload.requestId ?? createRequestId(),
46
+ eventName,
47
+ timestamp: payload.timestamp,
48
+ path: payload.path,
49
+ referrer: payload.referrer,
50
+ sessionId: payload.sessionId ?? sessionId,
51
+ value: payload.value,
52
+ properties: payload.properties,
53
+ })
54
+ }
55
+
56
+ const pageview = async (payload = {}) => {
57
+ const path = payload.path ?? (typeof window !== 'undefined' ? window.location.pathname : '/')
58
+ const referrer = payload.referrer ?? (typeof document !== 'undefined' ? document.referrer : '')
59
+
60
+ await track('pageview', {
61
+ ...payload,
62
+ path,
63
+ referrer,
64
+ })
65
+ }
66
+
67
+ if (config.autoPageview !== false && typeof window !== 'undefined') {
68
+ void pageview()
69
+ }
70
+
71
+ return {
72
+ track,
73
+ pageview,
74
+ }
75
+ }
package/package.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "@summalytics/js",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "exports": {
7
+ ".": "./dist/index.js"
8
+ },
9
+ "publishConfig": {
10
+ "access": "public"
11
+ },
12
+ "files": [
13
+ "dist",
14
+ "src"
15
+ ]
16
+ }
package/src/index.ts ADDED
@@ -0,0 +1,94 @@
1
+ export interface SummalyticsConfig {
2
+ endpoint?: string
3
+ writeKey: string
4
+ autoPageview?: boolean
5
+ }
6
+
7
+ const DEFAULT_ENDPOINT = 'https://summalytics.ai/api/ingest'
8
+
9
+ export interface TrackPayload {
10
+ value?: number
11
+ properties?: Record<string, unknown>
12
+ timestamp?: string
13
+ path?: string
14
+ referrer?: string
15
+ sessionId?: string
16
+ requestId?: string
17
+ }
18
+
19
+ function createSessionId() {
20
+ if (typeof crypto !== 'undefined' && crypto.randomUUID) {
21
+ return crypto.randomUUID()
22
+ }
23
+
24
+ return `session_${Math.random().toString(36).slice(2)}`
25
+ }
26
+
27
+ function createRequestId() {
28
+ if (typeof crypto !== 'undefined' && crypto.randomUUID) {
29
+ return crypto.randomUUID()
30
+ }
31
+
32
+ return `req_${Math.random().toString(36).slice(2)}`
33
+ }
34
+
35
+ export function createSummalytics(config: SummalyticsConfig) {
36
+ const sessionId = createSessionId()
37
+ const endpoint = config.endpoint ?? DEFAULT_ENDPOINT
38
+
39
+ const send = async (payload: Record<string, unknown>) => {
40
+ const body = JSON.stringify(payload)
41
+
42
+ if (typeof navigator !== 'undefined' && navigator.sendBeacon) {
43
+ const beaconUrl = `${endpoint}${endpoint.includes('?') ? '&' : '?'}key=${encodeURIComponent(config.writeKey)}`
44
+ const blob = new Blob([body], { type: 'application/json' })
45
+ const accepted = navigator.sendBeacon(beaconUrl, blob)
46
+ if (accepted) {
47
+ return
48
+ }
49
+ }
50
+
51
+ await fetch(endpoint, {
52
+ method: 'POST',
53
+ headers: {
54
+ 'Content-Type': 'application/json',
55
+ 'x-summalytics-key': config.writeKey,
56
+ },
57
+ body,
58
+ keepalive: true,
59
+ })
60
+ }
61
+
62
+ const track = async (eventName: string, payload: TrackPayload = {}) => {
63
+ await send({
64
+ requestId: payload.requestId ?? createRequestId(),
65
+ eventName,
66
+ timestamp: payload.timestamp,
67
+ path: payload.path,
68
+ referrer: payload.referrer,
69
+ sessionId: payload.sessionId ?? sessionId,
70
+ value: payload.value,
71
+ properties: payload.properties,
72
+ })
73
+ }
74
+
75
+ const pageview = async (payload: Omit<TrackPayload, 'value'> = {}) => {
76
+ const path = payload.path ?? (typeof window !== 'undefined' ? window.location.pathname : '/')
77
+ const referrer = payload.referrer ?? (typeof document !== 'undefined' ? document.referrer : '')
78
+
79
+ await track('pageview', {
80
+ ...payload,
81
+ path,
82
+ referrer,
83
+ })
84
+ }
85
+
86
+ if (config.autoPageview !== false && typeof window !== 'undefined') {
87
+ void pageview()
88
+ }
89
+
90
+ return {
91
+ track,
92
+ pageview,
93
+ }
94
+ }