posthog-js-lite 0.0.5 → 2.0.0-alpha1
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 +2 -24
- package/index.ts +5 -0
- package/lib/index.cjs.js +1473 -0
- package/lib/index.cjs.js.map +1 -0
- package/lib/index.d.ts +177 -0
- package/lib/index.esm.js +1468 -0
- package/lib/index.esm.js.map +1 -0
- package/lib/node_modules/tslib/tslib.es6.d.ts +35 -0
- package/lib/posthog-core/src/eventemitter.d.ts +8 -0
- package/lib/posthog-core/src/index.d.ts +84 -0
- package/lib/posthog-core/src/lz-string.d.ts +8 -0
- package/lib/posthog-core/src/types.d.ts +68 -0
- package/lib/posthog-core/src/utils.d.ts +13 -0
- package/lib/posthog-web/index.d.ts +3 -0
- package/lib/posthog-web/src/context.d.ts +1 -0
- package/lib/posthog-web/src/posthog-web.d.ts +18 -0
- package/lib/posthog-web/src/storage.d.ts +12 -0
- package/package.json +5 -42
- package/src/context.ts +168 -0
- package/src/posthog-web.ts +70 -0
- package/src/storage.ts +115 -0
- package/test/posthog-web.spec.ts +32 -0
- package/tsconfig.json +4 -17
- package/.prettierrc +0 -7
- package/babel.config.js +0 -4
- package/dist/babel.config.d.ts +0 -5
- package/dist/babel.config.js +0 -5
- package/dist/babel.config.js.map +0 -1
- package/dist/package.json +0 -44
- package/dist/src/__tests__/index.d.ts +0 -1
- package/dist/src/__tests__/index.js +0 -48
- package/dist/src/__tests__/index.js.map +0 -1
- package/dist/src/index.d.ts +0 -19
- package/dist/src/index.js +0 -109
- package/dist/src/index.js.map +0 -1
- package/dist/src/targets/browser.d.ts +0 -19
- package/dist/src/targets/browser.js +0 -10
- package/dist/src/targets/browser.js.map +0 -1
- package/dist/src/targets/node.d.ts +0 -19
- package/dist/src/targets/node.js +0 -9
- package/dist/src/targets/node.js.map +0 -1
- package/dist/src/types.d.ts +0 -20
- package/dist/src/types.js +0 -3
- package/dist/src/types.js.map +0 -1
- package/dist/src/utils/context.d.ts +0 -1
- package/dist/src/utils/context.js +0 -187
- package/dist/src/utils/context.js.map +0 -1
- package/dist/src/utils/lz-string.d.ts +0 -14
- package/dist/src/utils/lz-string.js +0 -467
- package/dist/src/utils/lz-string.js.map +0 -1
- package/dist/src/utils/utils.d.ts +0 -3
- package/dist/src/utils/utils.js +0 -29
- package/dist/src/utils/utils.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -2454
- package/src/__tests__/index.js +0 -47
- package/src/index.ts +0 -127
- package/src/targets/browser.ts +0 -17
- package/src/targets/node.ts +0 -6
- package/src/types.ts +0 -22
- package/src/utils/context.ts +0 -163
- package/src/utils/lz-string.js +0 -511
- package/src/utils/utils.ts +0 -28
package/src/__tests__/index.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { createInternalPostHogInstance } from '../index'
|
|
2
|
-
import { LZString } from '../utils/lz-string'
|
|
3
|
-
|
|
4
|
-
const testWindow = {
|
|
5
|
-
navigator: {
|
|
6
|
-
userAgent: 'not me / Mozilla',
|
|
7
|
-
},
|
|
8
|
-
document: {
|
|
9
|
-
referrer: '',
|
|
10
|
-
},
|
|
11
|
-
location: {
|
|
12
|
-
href: 'http://example.com/',
|
|
13
|
-
host: 'example.com',
|
|
14
|
-
pathname: '/',
|
|
15
|
-
},
|
|
16
|
-
screen: {
|
|
17
|
-
width: 640,
|
|
18
|
-
height: 480,
|
|
19
|
-
},
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
test('capture makes a window.fetch call', () => {
|
|
23
|
-
expect(true).toBe(true)
|
|
24
|
-
|
|
25
|
-
const fetchCalled = []
|
|
26
|
-
|
|
27
|
-
const postHog = createInternalPostHogInstance(
|
|
28
|
-
'API_KEY_WAS_HERE',
|
|
29
|
-
{
|
|
30
|
-
fetch: async (url, options) => {
|
|
31
|
-
fetchCalled.push({ url, options })
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
testWindow
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
postHog.capture('hi there!')
|
|
38
|
-
|
|
39
|
-
expect(fetchCalled.length).toBe(1)
|
|
40
|
-
expect(fetchCalled[0].url).toMatch(/^https:\/\/app\.posthog\.com\/e\/\?ip=1&_=[0-9]+&v=[0-9\.a-z\-]+$/)
|
|
41
|
-
expect(fetchCalled[0].options.method).toBe('POST')
|
|
42
|
-
const bodyText = decodeURIComponent(fetchCalled[0].options.body.split('&')[0].split('=')[1])
|
|
43
|
-
const body = JSON.parse(LZString.decompressFromBase64(bodyText))
|
|
44
|
-
|
|
45
|
-
expect(body.api_key).toBe('API_KEY_WAS_HERE')
|
|
46
|
-
expect(body.batch[0].event).toBe('hi there!')
|
|
47
|
-
})
|
package/src/index.ts
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import { version } from '../package.json'
|
|
2
|
-
import { PostHogAPIRequest, PostHogOptions, PostHogSession } from './types'
|
|
3
|
-
import { currentISOTime, currentTimestamp, generateUUID } from './utils/utils'
|
|
4
|
-
import { getContext } from './utils/context'
|
|
5
|
-
|
|
6
|
-
import { LZString } from './utils/lz-string.js'
|
|
7
|
-
|
|
8
|
-
const defaultOptions: PostHogOptions = {
|
|
9
|
-
apiHost: 'https://app.posthog.com',
|
|
10
|
-
maxQueueLength: 1,
|
|
11
|
-
optedIn: true,
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function createInternalPostHogInstance(apiKey: string, options: PostHogOptions, globalThis: any) {
|
|
15
|
-
const session = {} as Partial<PostHogSession> // getDataFromCookiesAndLocalStorage
|
|
16
|
-
const anonymousId = generateUUID(globalThis)
|
|
17
|
-
|
|
18
|
-
let postHogInstance = {
|
|
19
|
-
options: { ...defaultOptions, ...options, apiKey } as Required<PostHogOptions>,
|
|
20
|
-
|
|
21
|
-
session: {
|
|
22
|
-
anonymousId: anonymousId,
|
|
23
|
-
distinctId: anonymousId,
|
|
24
|
-
...session,
|
|
25
|
-
} as PostHogSession,
|
|
26
|
-
|
|
27
|
-
getDistinctId() {
|
|
28
|
-
return postHogInstance.session.distinctId
|
|
29
|
-
},
|
|
30
|
-
|
|
31
|
-
getContextProperties() {
|
|
32
|
-
return {
|
|
33
|
-
$lib: 'posthog-js-lite',
|
|
34
|
-
$lib_version: version,
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
|
-
|
|
38
|
-
optedIn() {
|
|
39
|
-
return postHogInstance.options.optedIn
|
|
40
|
-
},
|
|
41
|
-
|
|
42
|
-
optIn() {
|
|
43
|
-
postHogInstance.options.optedIn = true
|
|
44
|
-
postHogInstance.flush()
|
|
45
|
-
},
|
|
46
|
-
|
|
47
|
-
optOut() {
|
|
48
|
-
postHogInstance.options.optedIn = false
|
|
49
|
-
},
|
|
50
|
-
|
|
51
|
-
capture(event: string, properties = {}) {
|
|
52
|
-
postHogInstance.enqueue({
|
|
53
|
-
event,
|
|
54
|
-
distinct_id: postHogInstance.getDistinctId(),
|
|
55
|
-
timestamp: currentISOTime(),
|
|
56
|
-
properties: {
|
|
57
|
-
...getContext(globalThis), // TODO: debounce this, no need to do every event
|
|
58
|
-
...properties,
|
|
59
|
-
},
|
|
60
|
-
})
|
|
61
|
-
},
|
|
62
|
-
|
|
63
|
-
identify(distinctId: string | null, userProperties = {}) {
|
|
64
|
-
postHogInstance.enqueue({
|
|
65
|
-
event: '$identify',
|
|
66
|
-
distinct_id: distinctId || postHogInstance.session.anonymousId,
|
|
67
|
-
timestamp: currentISOTime(),
|
|
68
|
-
$set: {
|
|
69
|
-
...userProperties,
|
|
70
|
-
},
|
|
71
|
-
properties: {
|
|
72
|
-
...getContext(globalThis),
|
|
73
|
-
$anon_distinct_id: postHogInstance.session.anonymousId,
|
|
74
|
-
},
|
|
75
|
-
})
|
|
76
|
-
if (distinctId) {
|
|
77
|
-
postHogInstance.session.distinctId = distinctId
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
|
|
81
|
-
queue: [] as PostHogAPIRequest[],
|
|
82
|
-
enqueue(apiRequest: PostHogAPIRequest) {
|
|
83
|
-
postHogInstance.queue.push(apiRequest)
|
|
84
|
-
|
|
85
|
-
if (postHogInstance.optedIn() && postHogInstance.queue.length >= postHogInstance.options.maxQueueLength) {
|
|
86
|
-
postHogInstance.flush()
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
|
|
90
|
-
flush() {
|
|
91
|
-
let queue = postHogInstance.queue
|
|
92
|
-
postHogInstance.queue = []
|
|
93
|
-
postHogInstance.makeRequest(queue)
|
|
94
|
-
},
|
|
95
|
-
|
|
96
|
-
makeRequest: async function (events: PostHogAPIRequest[]) {
|
|
97
|
-
const requestData = {
|
|
98
|
-
api_key: postHogInstance.options.apiKey,
|
|
99
|
-
batch: events,
|
|
100
|
-
sent_at: currentISOTime(),
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const url = `${postHogInstance.options.apiHost}/e/?ip=1&_=${currentTimestamp()}&v=${version}`
|
|
104
|
-
|
|
105
|
-
const payload = JSON.stringify(requestData)
|
|
106
|
-
const compressedPayload = LZString.compressToBase64(payload)
|
|
107
|
-
|
|
108
|
-
const fetchOptions = {
|
|
109
|
-
method: 'POST',
|
|
110
|
-
mode: 'no-cors',
|
|
111
|
-
credentials: 'omit',
|
|
112
|
-
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
113
|
-
body: `data=${encodeURIComponent(compressedPayload)}&compression=lz64`,
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
try {
|
|
117
|
-
const rawResponse = await postHogInstance.options.fetch(url, fetchOptions)
|
|
118
|
-
const body = await rawResponse.text()
|
|
119
|
-
} catch (error) {
|
|
120
|
-
// TODO: retry if fails?
|
|
121
|
-
throw error
|
|
122
|
-
}
|
|
123
|
-
},
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return postHogInstance
|
|
127
|
-
}
|
package/src/targets/browser.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/* global window */
|
|
2
|
-
import { createInternalPostHogInstance } from '../index'
|
|
3
|
-
import { PostHogOptions } from '../types'
|
|
4
|
-
|
|
5
|
-
function autoCapturePlugin() {}
|
|
6
|
-
|
|
7
|
-
export function browserPostHog(apiKey: string, options: PostHogOptions = {}) {
|
|
8
|
-
return createInternalPostHogInstance(
|
|
9
|
-
apiKey,
|
|
10
|
-
{
|
|
11
|
-
...options,
|
|
12
|
-
fetch: window.fetch.bind(window),
|
|
13
|
-
plugins: [...(options.plugins || []), autoCapturePlugin()],
|
|
14
|
-
},
|
|
15
|
-
window
|
|
16
|
-
)
|
|
17
|
-
}
|
package/src/targets/node.ts
DELETED
package/src/types.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
export type PostHogOptions = {
|
|
2
|
-
plugins?: any[]
|
|
3
|
-
apiHost?: string
|
|
4
|
-
loaded?: () => any
|
|
5
|
-
fetch?: any
|
|
6
|
-
apiKey?: string
|
|
7
|
-
maxQueueLength?: number
|
|
8
|
-
optedIn?: boolean
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export type PostHogSession = {
|
|
12
|
-
distinctId: string
|
|
13
|
-
anonymousId: string
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export type PostHogAPIRequest = {
|
|
17
|
-
event: string
|
|
18
|
-
distinct_id: string
|
|
19
|
-
timestamp: string
|
|
20
|
-
properties?: Record<string, unknown>
|
|
21
|
-
$set?: Record<string, unknown>
|
|
22
|
-
}
|
package/src/utils/context.ts
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import { version } from '../../package.json'
|
|
2
|
-
import { currentTimestamp } from './utils'
|
|
3
|
-
|
|
4
|
-
export function getContext(window: Window) {
|
|
5
|
-
const context = {}
|
|
6
|
-
if (window.navigator) {
|
|
7
|
-
const userAgent = window.navigator.userAgent
|
|
8
|
-
Object.assign(context, {
|
|
9
|
-
$os: os(window),
|
|
10
|
-
$browser: browser(userAgent, window.navigator.vendor, !!(window as any).opera),
|
|
11
|
-
$referrer: window.document.referrer,
|
|
12
|
-
$referring_domain: referringDomain(window.document.referrer),
|
|
13
|
-
$device: device(userAgent),
|
|
14
|
-
$current_url: window.location.href,
|
|
15
|
-
$host: window.location.host,
|
|
16
|
-
$pathname: window.location.pathname,
|
|
17
|
-
$browser_version: browserVersion(userAgent, window.navigator.vendor, !!(window as any).opera),
|
|
18
|
-
$screen_height: window.screen.height,
|
|
19
|
-
$screen_width: window.screen.width,
|
|
20
|
-
$screen_dpr: window.devicePixelRatio,
|
|
21
|
-
})
|
|
22
|
-
}
|
|
23
|
-
Object.assign(context, {
|
|
24
|
-
$lib: 'js',
|
|
25
|
-
$lib_version: version,
|
|
26
|
-
$insert_id: Math.random().toString(36).substring(2, 10) + Math.random().toString(36).substring(2, 10),
|
|
27
|
-
$time: currentTimestamp() / 1000, // epoch time in seconds
|
|
28
|
-
})
|
|
29
|
-
return context // TODO: strip empty props?
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function includes(haystack: string, needle: string) {
|
|
33
|
-
return haystack.indexOf(needle) >= 0
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function browser(userAgent: string, vendor: string, opera: boolean): string {
|
|
37
|
-
vendor = vendor || '' // vendor is undefined for at least IE9
|
|
38
|
-
if (opera || includes(userAgent, ' OPR/')) {
|
|
39
|
-
if (includes(userAgent, 'Mini')) {
|
|
40
|
-
return 'Opera Mini'
|
|
41
|
-
}
|
|
42
|
-
return 'Opera'
|
|
43
|
-
} else if (/(BlackBerry|PlayBook|BB10)/i.test(userAgent)) {
|
|
44
|
-
return 'BlackBerry'
|
|
45
|
-
} else if (includes(userAgent, 'IEMobile') || includes(userAgent, 'WPDesktop')) {
|
|
46
|
-
return 'Internet Explorer Mobile'
|
|
47
|
-
} else if (includes(userAgent, 'SamsungBrowser/')) {
|
|
48
|
-
// https://developer.samsung.com/internet/user-agent-string-format
|
|
49
|
-
return 'Samsung Internet'
|
|
50
|
-
} else if (includes(userAgent, 'Edge') || includes(userAgent, 'Edg/')) {
|
|
51
|
-
return 'Microsoft Edge'
|
|
52
|
-
} else if (includes(userAgent, 'FBIOS')) {
|
|
53
|
-
return 'Facebook Mobile'
|
|
54
|
-
} else if (includes(userAgent, 'Chrome')) {
|
|
55
|
-
return 'Chrome'
|
|
56
|
-
} else if (includes(userAgent, 'CriOS')) {
|
|
57
|
-
return 'Chrome iOS'
|
|
58
|
-
} else if (includes(userAgent, 'UCWEB') || includes(userAgent, 'UCBrowser')) {
|
|
59
|
-
return 'UC Browser'
|
|
60
|
-
} else if (includes(userAgent, 'FxiOS')) {
|
|
61
|
-
return 'Firefox iOS'
|
|
62
|
-
} else if (includes(vendor, 'Apple')) {
|
|
63
|
-
if (includes(userAgent, 'Mobile')) {
|
|
64
|
-
return 'Mobile Safari'
|
|
65
|
-
}
|
|
66
|
-
return 'Safari'
|
|
67
|
-
} else if (includes(userAgent, 'Android')) {
|
|
68
|
-
return 'Android Mobile'
|
|
69
|
-
} else if (includes(userAgent, 'Konqueror')) {
|
|
70
|
-
return 'Konqueror'
|
|
71
|
-
} else if (includes(userAgent, 'Firefox')) {
|
|
72
|
-
return 'Firefox'
|
|
73
|
-
} else if (includes(userAgent, 'MSIE') || includes(userAgent, 'Trident/')) {
|
|
74
|
-
return 'Internet Explorer'
|
|
75
|
-
} else if (includes(userAgent, 'Gecko')) {
|
|
76
|
-
return 'Mozilla'
|
|
77
|
-
} else {
|
|
78
|
-
return ''
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function browserVersion(userAgent: string, vendor: string, opera: boolean) {
|
|
83
|
-
const regexList = {
|
|
84
|
-
'Internet Explorer Mobile': /rv:(\d+(\.\d+)?)/,
|
|
85
|
-
'Microsoft Edge': /Edge?\/(\d+(\.\d+)?)/,
|
|
86
|
-
Chrome: /Chrome\/(\d+(\.\d+)?)/,
|
|
87
|
-
'Chrome iOS': /CriOS\/(\d+(\.\d+)?)/,
|
|
88
|
-
'UC Browser': /(UCBrowser|UCWEB)\/(\d+(\.\d+)?)/,
|
|
89
|
-
Safari: /Version\/(\d+(\.\d+)?)/,
|
|
90
|
-
'Mobile Safari': /Version\/(\d+(\.\d+)?)/,
|
|
91
|
-
Opera: /(Opera|OPR)\/(\d+(\.\d+)?)/,
|
|
92
|
-
Firefox: /Firefox\/(\d+(\.\d+)?)/,
|
|
93
|
-
'Firefox iOS': /FxiOS\/(\d+(\.\d+)?)/,
|
|
94
|
-
Konqueror: /Konqueror:(\d+(\.\d+)?)/,
|
|
95
|
-
BlackBerry: /BlackBerry (\d+(\.\d+)?)/,
|
|
96
|
-
'Android Mobile': /android\s(\d+(\.\d+)?)/,
|
|
97
|
-
'Samsung Internet': /SamsungBrowser\/(\d+(\.\d+)?)/,
|
|
98
|
-
'Internet Explorer': /(rv:|MSIE )(\d+(\.\d+)?)/,
|
|
99
|
-
Mozilla: /rv:(\d+(\.\d+)?)/,
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const browserString = browser(userAgent, vendor, opera) as keyof typeof regexList
|
|
103
|
-
const regex: RegExp = regexList[browserString] || undefined
|
|
104
|
-
|
|
105
|
-
if (regex === undefined) {
|
|
106
|
-
return null
|
|
107
|
-
}
|
|
108
|
-
var matches = userAgent.match(regex)
|
|
109
|
-
if (!matches) {
|
|
110
|
-
return null
|
|
111
|
-
}
|
|
112
|
-
return parseFloat(matches[matches.length - 2])
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function os(window: Window) {
|
|
116
|
-
var a = window.navigator.userAgent
|
|
117
|
-
if (/Windows/i.test(a)) {
|
|
118
|
-
if (/Phone/.test(a) || /WPDesktop/.test(a)) {
|
|
119
|
-
return 'Windows Phone'
|
|
120
|
-
}
|
|
121
|
-
return 'Windows'
|
|
122
|
-
} else if (/(iPhone|iPad|iPod)/.test(a)) {
|
|
123
|
-
return 'iOS'
|
|
124
|
-
} else if (/Android/.test(a)) {
|
|
125
|
-
return 'Android'
|
|
126
|
-
} else if (/(BlackBerry|PlayBook|BB10)/i.test(a)) {
|
|
127
|
-
return 'BlackBerry'
|
|
128
|
-
} else if (/Mac/i.test(a)) {
|
|
129
|
-
return 'Mac OS X'
|
|
130
|
-
} else if (/Linux/.test(a)) {
|
|
131
|
-
return 'Linux'
|
|
132
|
-
} else if (/CrOS/.test(a)) {
|
|
133
|
-
return 'Chrome OS'
|
|
134
|
-
} else {
|
|
135
|
-
return ''
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function device(userAgent: string) {
|
|
140
|
-
if (/Windows Phone/i.test(userAgent) || /WPDesktop/.test(userAgent)) {
|
|
141
|
-
return 'Windows Phone'
|
|
142
|
-
} else if (/iPad/.test(userAgent)) {
|
|
143
|
-
return 'iPad'
|
|
144
|
-
} else if (/iPod/.test(userAgent)) {
|
|
145
|
-
return 'iPod Touch'
|
|
146
|
-
} else if (/iPhone/.test(userAgent)) {
|
|
147
|
-
return 'iPhone'
|
|
148
|
-
} else if (/(BlackBerry|PlayBook|BB10)/i.test(userAgent)) {
|
|
149
|
-
return 'BlackBerry'
|
|
150
|
-
} else if (/Android/.test(userAgent)) {
|
|
151
|
-
return 'Android'
|
|
152
|
-
} else {
|
|
153
|
-
return ''
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
function referringDomain(referrer: string) {
|
|
158
|
-
var split = referrer.split('/')
|
|
159
|
-
if (split.length >= 3) {
|
|
160
|
-
return split[2]
|
|
161
|
-
}
|
|
162
|
-
return ''
|
|
163
|
-
}
|