Socket
Socket
Sign inDemoInstall

posthog-node

Package Overview
Dependencies
Maintainers
4
Versions
66
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

posthog-node - npm Package Compare versions

Comparing version 4.0.0-beta.1 to 4.0.0-beta.2

6

CHANGELOG.md

@@ -0,1 +1,7 @@

# 4.0.0-beta.2 - 2024-03-12
- `flushAsync` and `shutdownAsync` are removed with `flush` and `shutdown` now being the async methods.
- Fixed an issue where `shutdown` would potentially exit early if a flush was already in progress
- Flushes will now try to flush up to `maxBatchSize` (default 100) in one go
# 4.0.0-beta.1 - 2024-03-04

@@ -2,0 +8,0 @@

22

lib/index.d.ts

@@ -9,2 +9,4 @@ /// <reference types="node" />

flushInterval?: number;
/** The maximum number of queued messages to be flushed as part of a single batch (must be higher than `flushAt`) */
maxBatchSize?: number;
/** If set to true the SDK is essentially disabled (useful for local environments where you don't want to track anything) */

@@ -126,3 +128,5 @@ disabled?: boolean;

private flushAt;
private maxBatchSize;
private flushInterval;
private flushPromise;
private requestTimeout;

@@ -157,3 +161,3 @@ private featureFlagsRequestTimeoutMs;

private buildPayload;
protected addPendingPromise(promise: Promise<any>): void;
protected addPendingPromise<T>(promise: Promise<T>): Promise<T>;
/***

@@ -190,7 +194,12 @@ *** TRACKING

protected enqueue(type: string, _message: any, options?: PostHogCaptureOptions): void;
flushAsync(): Promise<any>;
flush(callback?: (err?: any, data?: any) => void): void;
private clearFlushTimer;
/**
* Helper for flushing the queue in the background
* Avoids unnecessary promise errors
*/
private flushBackground;
flush(): Promise<any[]>;
private _flush;
private fetchWithRetry;
shutdownAsync(shutdownTimeoutMs?: number): Promise<void>;
shutdown(shutdownTimeoutMs?: number): void;
shutdown(shutdownTimeoutMs?: number): Promise<void>;
}

@@ -409,4 +418,3 @@

reloadFeatureFlags(): Promise<void>;
shutdown(shutdownTimeoutMs?: number): void;
shutdownAsync(shutdownTimeoutMs?: number): Promise<void>;
shutdown(shutdownTimeoutMs?: number): Promise<void>;
private addLocalPersonAndGroupProperties;

@@ -413,0 +421,0 @@ }

@@ -10,3 +10,5 @@ import { PostHogFetchOptions, PostHogFetchResponse, PostHogAutocaptureElement, PostHogDecideResponse, PostHogCoreOptions, PostHogEventProperties, PostHogPersistedProperty, PostHogCaptureOptions, JsonType } from './types';

private flushAt;
private maxBatchSize;
private flushInterval;
private flushPromise;
private requestTimeout;

@@ -41,3 +43,3 @@ private featureFlagsRequestTimeoutMs;

private buildPayload;
protected addPendingPromise(promise: Promise<any>): void;
protected addPendingPromise<T>(promise: Promise<T>): Promise<T>;
/***

@@ -74,7 +76,12 @@ *** TRACKING

protected enqueue(type: string, _message: any, options?: PostHogCaptureOptions): void;
flushAsync(): Promise<any>;
flush(callback?: (err?: any, data?: any) => void): void;
private clearFlushTimer;
/**
* Helper for flushing the queue in the background
* Avoids unnecessary promise errors
*/
private flushBackground;
flush(): Promise<any[]>;
private _flush;
private fetchWithRetry;
shutdownAsync(shutdownTimeoutMs?: number): Promise<void>;
shutdown(shutdownTimeoutMs?: number): void;
shutdown(shutdownTimeoutMs?: number): Promise<void>;
}

@@ -81,0 +88,0 @@ export declare abstract class PostHogCore extends PostHogCoreStateless {

@@ -9,2 +9,4 @@ /// <reference types="node" />

flushInterval?: number;
/** The maximum number of queued messages to be flushed as part of a single batch (must be higher than `flushAt`) */
maxBatchSize?: number;
/** If set to true the SDK is essentially disabled (useful for local environments where you don't want to track anything) */

@@ -11,0 +13,0 @@ disabled?: boolean;

@@ -73,5 +73,4 @@ import { JsonType, PostHogCoreOptions, PostHogCoreStateless, PostHogFetchOptions, PostHogFetchResponse, PostHogFlagsAndPayloadsResponse, PostHogPersistedProperty } from '../../posthog-core/src';

reloadFeatureFlags(): Promise<void>;
shutdown(shutdownTimeoutMs?: number): void;
shutdownAsync(shutdownTimeoutMs?: number): Promise<void>;
shutdown(shutdownTimeoutMs?: number): Promise<void>;
private addLocalPersonAndGroupProperties;
}
{
"name": "posthog-node",
"version": "4.0.0-beta.1",
"version": "4.0.0-beta.2",
"description": "PostHog Node.js integration",

@@ -5,0 +5,0 @@ "repository": {

@@ -456,9 +456,5 @@ import { version } from '../package.json'

shutdown(shutdownTimeoutMs?: number): void {
void this.shutdownAsync(shutdownTimeoutMs)
}
async shutdownAsync(shutdownTimeoutMs?: number): Promise<void> {
async shutdown(shutdownTimeoutMs?: number): Promise<void> {
this.featureFlagsPoller?.stopPoller()
return super.shutdownAsync(shutdownTimeoutMs)
return super.shutdown(shutdownTimeoutMs)
}

@@ -465,0 +461,0 @@

@@ -89,3 +89,3 @@ // import { PostHog } from '../'

// ensure clean shutdown & no test interdependencies
await posthog.shutdownAsync()
await posthog.shutdown()
})

@@ -113,4 +113,5 @@

await waitForPromises()
jest.runOnlyPendingTimers()
await waitForPromises() // First flush
jest.runOnlyPendingTimers() // Flush timer
await waitForPromises() // Second flush
const batchEvents = getLastBatchEvents()

@@ -117,0 +118,0 @@

@@ -1,2 +0,1 @@

// import { PostHog } from '../'
import { PostHog as PostHog } from '../src/posthog-node'

@@ -13,2 +12,10 @@ jest.mock('../src/fetch')

const waitForFlushTimer = async (): Promise<void> => {
await waitForPromises()
// To trigger the flush via the timer
jest.runOnlyPendingTimers()
// Then wait for the flush promise
await waitForPromises()
}
const getLastBatchEvents = (): any[] | undefined => {

@@ -47,4 +54,13 @@ expect(mockedFetch).toHaveBeenCalledWith('http://example.com/batch/', expect.objectContaining({ method: 'POST' }))

afterEach(async () => {
mockedFetch.mockResolvedValue({
status: 200,
text: () => Promise.resolve('ok'),
json: () =>
Promise.resolve({
status: 'ok',
}),
} as any)
// ensure clean shutdown & no test interdependencies
await posthog.shutdownAsync()
await posthog.shutdown()
})

@@ -57,4 +73,3 @@

await waitForPromises()
jest.runOnlyPendingTimers()
await waitForFlushTimer()

@@ -86,4 +101,3 @@ const batchEvents = getLastBatchEvents()

await waitForPromises()
jest.runOnlyPendingTimers()
await waitForFlushTimer()
expect(getLastBatchEvents()?.[0]).toEqual(

@@ -110,4 +124,3 @@ expect.objectContaining({

await waitForPromises()
jest.runOnlyPendingTimers()
await waitForFlushTimer()
expect(getLastBatchEvents()?.[0]).toEqual(

@@ -132,2 +145,4 @@ expect.objectContaining({

jest.runOnlyPendingTimers()
await waitForPromises()
const batchEvents = getLastBatchEvents()

@@ -152,2 +167,3 @@ expect(batchEvents).toMatchObject([

jest.runOnlyPendingTimers()
await waitForPromises()
const batchEvents = getLastBatchEvents()

@@ -172,2 +188,3 @@ expect(batchEvents).toMatchObject([

jest.runOnlyPendingTimers()
await waitForPromises()
const batchEvents = getLastBatchEvents()

@@ -190,4 +207,3 @@ expect(batchEvents).toMatchObject([

posthog.capture({ event: 'custom-time', distinctId: '123', timestamp: new Date('2021-02-03') })
await waitForPromises()
jest.runOnlyPendingTimers()
await waitForFlushTimer()
const batchEvents = getLastBatchEvents()

@@ -208,4 +224,3 @@ expect(batchEvents).toMatchObject([

posthog.capture({ event: 'custom-time', distinctId: '123', uuid })
await waitForPromises()
jest.runOnlyPendingTimers()
await waitForFlushTimer()
const batchEvents = getLastBatchEvents()

@@ -232,4 +247,3 @@ expect(batchEvents).toMatchObject([

await waitForPromises()
jest.runOnlyPendingTimers()
await waitForFlushTimer()
const batchEvents = getLastBatchEvents()

@@ -252,4 +266,3 @@ expect(batchEvents?.[0].properties).toEqual({

await waitForPromises()
jest.runOnlyPendingTimers()
await waitForFlushTimer()

@@ -272,4 +285,4 @@ let batchEvents = getLastBatchEvents()

await waitForPromises()
jest.runOnlyPendingTimers()
await waitForFlushTimer()
batchEvents = getLastBatchEvents()

@@ -292,4 +305,5 @@ expect(batchEvents?.[0].properties).toEqual({

await waitForFlushTimer()
await waitForPromises()
jest.runOnlyPendingTimers()
batchEvents = getLastBatchEvents()

@@ -303,3 +317,3 @@ expect(batchEvents?.[0].properties).toEqual({

await client.shutdownAsync()
await client.shutdown()
})

@@ -309,8 +323,11 @@ })

describe('shutdown', () => {
let warnSpy: jest.SpyInstance, logSpy: jest.SpyInstance
beforeEach(() => {
// a serverless posthog configuration
posthog = new PostHog('TEST_API_KEY', {
host: 'http://example.com',
fetchRetryCount: 0,
const actualLog = console.log
warnSpy = jest.spyOn(console, 'warn').mockImplementation((...args) => {
actualLog('spied warn:', ...args)
})
logSpy = jest.spyOn(console, 'log').mockImplementation((...args) => {
actualLog('spied log:', ...args)
})

@@ -330,6 +347,7 @@ mockedFetch.mockImplementation(async () => {

})
jest.useRealTimers()
})
afterEach(() => {
posthog.debug(false)
jest.useFakeTimers()

@@ -339,3 +357,3 @@ })

it('should shutdown cleanly', async () => {
posthog = new PostHog('TEST_API_KEY', {
const ph = new PostHog('TEST_API_KEY', {
host: 'http://example.com',

@@ -345,32 +363,37 @@ fetchRetryCount: 0,

})
ph.debug(true)
const logSpy = jest.spyOn(console, 'log').mockImplementation(() => {})
jest.useRealTimers()
// using debug mode to check console.log output
// which tells us when the flush is complete
posthog.debug(true)
for (let i = 0; i < 10; i++) {
posthog.capture({ event: 'test-event', distinctId: '123' })
// requests come 100ms apart
await wait(100)
}
// 10 capture calls to debug log
// 6 flush calls to debug log
expect(logSpy).toHaveBeenCalledTimes(16)
expect(10).toEqual(logSpy.mock.calls.filter((call) => call[1].includes('capture')).length)
expect(6).toEqual(logSpy.mock.calls.filter((call) => call[1].includes('flush')).length)
ph.capture({ event: 'test-event', distinctId: '123' })
await wait(100)
expect(logSpy).toHaveBeenCalledTimes(1)
ph.capture({ event: 'test-event', distinctId: '123' })
ph.capture({ event: 'test-event', distinctId: '123' })
await wait(100)
expect(logSpy).toHaveBeenCalledTimes(3)
await wait(400) // The flush will resolve in this time
ph.capture({ event: 'test-event', distinctId: '123' })
ph.capture({ event: 'test-event', distinctId: '123' })
await wait(100)
expect(logSpy).toHaveBeenCalledTimes(6) // 5 captures and 1 flush
expect(5).toEqual(logSpy.mock.calls.filter((call) => call[1].includes('capture')).length)
expect(1).toEqual(logSpy.mock.calls.filter((call) => call[1].includes('flush')).length)
logSpy.mockClear()
expect(logSpy).toHaveBeenCalledTimes(0)
await posthog.shutdownAsync()
// remaining 4 flush calls to debug log
// happen during shutdown
expect(4).toEqual(logSpy.mock.calls.filter((call) => call[1].includes('flush')).length)
jest.useFakeTimers()
console.warn('YOO!!')
await ph.shutdown()
// 1 final flush for the events that were queued during shutdown
expect(1).toEqual(logSpy.mock.calls.filter((call) => call[1].includes('flush')).length)
logSpy.mockRestore()
warnSpy.mockRestore()
})
it('should shutdown cleanly with pending capture flag promises', async () => {
posthog = new PostHog('TEST_API_KEY', {
const ph = new PostHog('TEST_API_KEY', {
host: 'http://example.com',

@@ -380,15 +403,12 @@ fetchRetryCount: 0,

})
ph.debug(true)
const logSpy = jest.spyOn(console, 'log').mockImplementation(() => {})
jest.useRealTimers()
posthog.debug(true)
for (let i = 0; i < 10; i++) {
posthog.capture({ event: 'test-event', distinctId: `${i}`, sendFeatureFlags: true })
ph.capture({ event: 'test-event', distinctId: `${i}`, sendFeatureFlags: true })
}
await posthog.shutdownAsync()
await ph.shutdown()
// all capture calls happen during shutdown
const batchEvents = getLastBatchEvents()
expect(batchEvents?.length).toEqual(2)
expect(batchEvents?.length).toEqual(6)
expect(batchEvents?.[batchEvents?.length - 1]).toMatchObject({

@@ -409,4 +429,4 @@ // last event in batch

expect(10).toEqual(logSpy.mock.calls.filter((call) => call[1].includes('capture')).length)
expect(3).toEqual(logSpy.mock.calls.filter((call) => call[1].includes('flush')).length)
jest.useFakeTimers()
// 1 for the captured events, 1 for the final flush of feature flag called events
expect(2).toEqual(logSpy.mock.calls.filter((call) => call[1].includes('flush')).length)
logSpy.mockRestore()

@@ -420,3 +440,3 @@ })

jest.runOnlyPendingTimers()
await posthog.flushAsync()
await posthog.flush()
const batchEvents = getLastBatchEvents()

@@ -446,3 +466,3 @@ expect(batchEvents).toMatchObject([

jest.runOnlyPendingTimers()
await posthog.flushAsync()
await posthog.flush()
const batchEvents = getLastBatchEvents()

@@ -681,3 +701,3 @@ expect(batchEvents).toMatchObject([

await posthog.shutdownAsync()
await posthog.shutdown()
})

@@ -755,4 +775,3 @@

await waitForPromises()
jest.runOnlyPendingTimers()
await waitForFlushTimer()

@@ -885,3 +904,3 @@ expect(mockedFetch).toHaveBeenCalledWith(

await waitForPromises()
await posthog.flushAsync()
await posthog.flush()

@@ -915,3 +934,3 @@ expect(mockedFetch).toHaveBeenCalledWith('http://example.com/batch/', expect.any(Object))

await waitForPromises()
await posthog.flushAsync()
await posthog.flush()

@@ -930,3 +949,3 @@ expect(mockedFetch).not.toHaveBeenCalledWith('http://example.com/batch/', expect.any(Object))

await waitForPromises()
await posthog.flushAsync()
await posthog.flush()
expect(mockedFetch).toHaveBeenCalledWith('http://example.com/batch/', expect.any(Object))

@@ -960,3 +979,3 @@

await waitForPromises()
await posthog.flushAsync()
await posthog.flush()
expect(mockedFetch).not.toHaveBeenCalledWith('http://example.com/batch/', expect.any(Object))

@@ -973,3 +992,3 @@

await waitForPromises()
await posthog.flushAsync()
await posthog.flush()
// one to decide, one to batch

@@ -1004,3 +1023,3 @@ expect(mockedFetch).toHaveBeenCalledWith(...anyDecideCall)

await waitForPromises()
await posthog.flushAsync()
await posthog.flush()
// call decide, but not batch

@@ -1007,0 +1026,0 @@ expect(mockedFetch).toHaveBeenCalledWith(...anyDecideCall)

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc