posthog-js-lite 0.0.3 → 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.
Files changed (62) hide show
  1. package/README.md +2 -14
  2. package/index.ts +5 -0
  3. package/lib/index.cjs.js +1473 -0
  4. package/lib/index.cjs.js.map +1 -0
  5. package/lib/index.d.ts +177 -0
  6. package/lib/index.esm.js +1468 -0
  7. package/lib/index.esm.js.map +1 -0
  8. package/lib/node_modules/tslib/tslib.es6.d.ts +35 -0
  9. package/lib/posthog-core/src/eventemitter.d.ts +8 -0
  10. package/lib/posthog-core/src/index.d.ts +84 -0
  11. package/lib/posthog-core/src/lz-string.d.ts +8 -0
  12. package/lib/posthog-core/src/types.d.ts +68 -0
  13. package/lib/posthog-core/src/utils.d.ts +13 -0
  14. package/lib/posthog-web/index.d.ts +3 -0
  15. package/lib/posthog-web/src/context.d.ts +1 -0
  16. package/lib/posthog-web/src/posthog-web.d.ts +18 -0
  17. package/lib/posthog-web/src/storage.d.ts +12 -0
  18. package/package.json +5 -42
  19. package/src/context.ts +168 -0
  20. package/src/posthog-web.ts +70 -0
  21. package/src/storage.ts +115 -0
  22. package/test/posthog-web.spec.ts +32 -0
  23. package/tsconfig.json +4 -17
  24. package/.prettierrc +0 -7
  25. package/babel.config.js +0 -4
  26. package/dist/babel.config.d.ts +0 -5
  27. package/dist/babel.config.js +0 -5
  28. package/dist/babel.config.js.map +0 -1
  29. package/dist/package.json +0 -44
  30. package/dist/src/__tests__/index.d.ts +0 -1
  31. package/dist/src/__tests__/index.js +0 -39
  32. package/dist/src/__tests__/index.js.map +0 -1
  33. package/dist/src/index.d.ts +0 -19
  34. package/dist/src/index.js +0 -110
  35. package/dist/src/index.js.map +0 -1
  36. package/dist/src/targets/browser.d.ts +0 -19
  37. package/dist/src/targets/browser.js +0 -14
  38. package/dist/src/targets/browser.js.map +0 -1
  39. package/dist/src/targets/node.d.ts +0 -19
  40. package/dist/src/targets/node.js +0 -9
  41. package/dist/src/targets/node.js.map +0 -1
  42. package/dist/src/types.d.ts +0 -20
  43. package/dist/src/types.js +0 -3
  44. package/dist/src/types.js.map +0 -1
  45. package/dist/src/utils/context.d.ts +0 -18
  46. package/dist/src/utils/context.js +0 -182
  47. package/dist/src/utils/context.js.map +0 -1
  48. package/dist/src/utils/lz-string.d.ts +0 -14
  49. package/dist/src/utils/lz-string.js +0 -467
  50. package/dist/src/utils/lz-string.js.map +0 -1
  51. package/dist/src/utils/utils.d.ts +0 -3
  52. package/dist/src/utils/utils.js +0 -29
  53. package/dist/src/utils/utils.js.map +0 -1
  54. package/dist/tsconfig.tsbuildinfo +0 -2718
  55. package/src/__tests__/index.js +0 -47
  56. package/src/index.ts +0 -127
  57. package/src/targets/browser.ts +0 -17
  58. package/src/targets/node.ts +0 -6
  59. package/src/types.ts +0 -22
  60. package/src/utils/context.ts +0 -158
  61. package/src/utils/lz-string.js +0 -511
  62. package/src/utils/utils.ts +0 -27
@@ -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()
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
- }
@@ -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
- }
@@ -1,6 +0,0 @@
1
- import { PostHogOptions } from '../types'
2
- import { createInternalPostHogInstance } from '../index'
3
-
4
- export function nodePostHog(apiKey: string, options: PostHogOptions = {}) {
5
- return createInternalPostHogInstance(apiKey, options, globalThis)
6
- }
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
- }
@@ -1,158 +0,0 @@
1
- import { version } from '../../package.json'
2
- import { currentTimestamp } from './utils'
3
-
4
- export function getContext(window: Window) {
5
- const userAgent = window.navigator.userAgent
6
- const context = {
7
- $os: os(window),
8
- $browser: browser(userAgent, navigator.vendor, !!(window as any).opera),
9
- $referrer: window.document.referrer,
10
- $referring_domain: referringDomain(window.document.referrer),
11
- $device: device(userAgent),
12
- $current_url: window.location.href,
13
- $host: window.location.host,
14
- $pathname: window.location.pathname,
15
- $browser_version: browserVersion(userAgent, window.navigator.vendor, !!(window as any).opera),
16
- $screen_height: window.screen.height,
17
- $screen_width: window.screen.width,
18
- $screen_dpr: window.devicePixelRatio,
19
- $lib: 'js',
20
- $lib_version: version,
21
- $insert_id: Math.random().toString(36).substring(2, 10) + Math.random().toString(36).substring(2, 10),
22
- $time: currentTimestamp() / 1000, // epoch time in seconds
23
- }
24
- return context // TODO: strip empty props?
25
- }
26
-
27
- function includes(haystack: string, needle: string) {
28
- return haystack.indexOf(needle) >= 0
29
- }
30
-
31
- function browser(userAgent: string, vendor: string, opera: boolean): string {
32
- vendor = vendor || '' // vendor is undefined for at least IE9
33
- if (opera || includes(userAgent, ' OPR/')) {
34
- if (includes(userAgent, 'Mini')) {
35
- return 'Opera Mini'
36
- }
37
- return 'Opera'
38
- } else if (/(BlackBerry|PlayBook|BB10)/i.test(userAgent)) {
39
- return 'BlackBerry'
40
- } else if (includes(userAgent, 'IEMobile') || includes(userAgent, 'WPDesktop')) {
41
- return 'Internet Explorer Mobile'
42
- } else if (includes(userAgent, 'SamsungBrowser/')) {
43
- // https://developer.samsung.com/internet/user-agent-string-format
44
- return 'Samsung Internet'
45
- } else if (includes(userAgent, 'Edge') || includes(userAgent, 'Edg/')) {
46
- return 'Microsoft Edge'
47
- } else if (includes(userAgent, 'FBIOS')) {
48
- return 'Facebook Mobile'
49
- } else if (includes(userAgent, 'Chrome')) {
50
- return 'Chrome'
51
- } else if (includes(userAgent, 'CriOS')) {
52
- return 'Chrome iOS'
53
- } else if (includes(userAgent, 'UCWEB') || includes(userAgent, 'UCBrowser')) {
54
- return 'UC Browser'
55
- } else if (includes(userAgent, 'FxiOS')) {
56
- return 'Firefox iOS'
57
- } else if (includes(vendor, 'Apple')) {
58
- if (includes(userAgent, 'Mobile')) {
59
- return 'Mobile Safari'
60
- }
61
- return 'Safari'
62
- } else if (includes(userAgent, 'Android')) {
63
- return 'Android Mobile'
64
- } else if (includes(userAgent, 'Konqueror')) {
65
- return 'Konqueror'
66
- } else if (includes(userAgent, 'Firefox')) {
67
- return 'Firefox'
68
- } else if (includes(userAgent, 'MSIE') || includes(userAgent, 'Trident/')) {
69
- return 'Internet Explorer'
70
- } else if (includes(userAgent, 'Gecko')) {
71
- return 'Mozilla'
72
- } else {
73
- return ''
74
- }
75
- }
76
-
77
- function browserVersion(userAgent: string, vendor: string, opera: boolean) {
78
- const regexList = {
79
- 'Internet Explorer Mobile': /rv:(\d+(\.\d+)?)/,
80
- 'Microsoft Edge': /Edge?\/(\d+(\.\d+)?)/,
81
- Chrome: /Chrome\/(\d+(\.\d+)?)/,
82
- 'Chrome iOS': /CriOS\/(\d+(\.\d+)?)/,
83
- 'UC Browser': /(UCBrowser|UCWEB)\/(\d+(\.\d+)?)/,
84
- Safari: /Version\/(\d+(\.\d+)?)/,
85
- 'Mobile Safari': /Version\/(\d+(\.\d+)?)/,
86
- Opera: /(Opera|OPR)\/(\d+(\.\d+)?)/,
87
- Firefox: /Firefox\/(\d+(\.\d+)?)/,
88
- 'Firefox iOS': /FxiOS\/(\d+(\.\d+)?)/,
89
- Konqueror: /Konqueror:(\d+(\.\d+)?)/,
90
- BlackBerry: /BlackBerry (\d+(\.\d+)?)/,
91
- 'Android Mobile': /android\s(\d+(\.\d+)?)/,
92
- 'Samsung Internet': /SamsungBrowser\/(\d+(\.\d+)?)/,
93
- 'Internet Explorer': /(rv:|MSIE )(\d+(\.\d+)?)/,
94
- Mozilla: /rv:(\d+(\.\d+)?)/,
95
- }
96
-
97
- const browserString = browser(userAgent, vendor, opera) as keyof typeof regexList
98
- const regex: RegExp = regexList[browserString] || undefined
99
-
100
- if (regex === undefined) {
101
- return null
102
- }
103
- var matches = userAgent.match(regex)
104
- if (!matches) {
105
- return null
106
- }
107
- return parseFloat(matches[matches.length - 2])
108
- }
109
-
110
- function os(window: Window) {
111
- var a = window.navigator.userAgent
112
- if (/Windows/i.test(a)) {
113
- if (/Phone/.test(a) || /WPDesktop/.test(a)) {
114
- return 'Windows Phone'
115
- }
116
- return 'Windows'
117
- } else if (/(iPhone|iPad|iPod)/.test(a)) {
118
- return 'iOS'
119
- } else if (/Android/.test(a)) {
120
- return 'Android'
121
- } else if (/(BlackBerry|PlayBook|BB10)/i.test(a)) {
122
- return 'BlackBerry'
123
- } else if (/Mac/i.test(a)) {
124
- return 'Mac OS X'
125
- } else if (/Linux/.test(a)) {
126
- return 'Linux'
127
- } else if (/CrOS/.test(a)) {
128
- return 'Chrome OS'
129
- } else {
130
- return ''
131
- }
132
- }
133
-
134
- function device(userAgent: string) {
135
- if (/Windows Phone/i.test(userAgent) || /WPDesktop/.test(userAgent)) {
136
- return 'Windows Phone'
137
- } else if (/iPad/.test(userAgent)) {
138
- return 'iPad'
139
- } else if (/iPod/.test(userAgent)) {
140
- return 'iPod Touch'
141
- } else if (/iPhone/.test(userAgent)) {
142
- return 'iPhone'
143
- } else if (/(BlackBerry|PlayBook|BB10)/i.test(userAgent)) {
144
- return 'BlackBerry'
145
- } else if (/Android/.test(userAgent)) {
146
- return 'Android'
147
- } else {
148
- return ''
149
- }
150
- }
151
-
152
- function referringDomain(referrer: string) {
153
- var split = referrer.split('/')
154
- if (split.length >= 3) {
155
- return split[2]
156
- }
157
- return ''
158
- }