Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@segment/analytics-node

Package Overview
Dependencies
Maintainers
240
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@segment/analytics-node - npm Package Compare versions

Comparing version 0.0.1-beta.9 to 0.0.1-beta.10

2

dist/cjs/app/analytics-node.js

@@ -31,3 +31,3 @@ "use strict";

flushInterval,
});
}, this);
this._publisher = publisher;

@@ -34,0 +34,0 @@ this.ready = this.register(plugin).then(() => undefined);

@@ -5,3 +5,3 @@ "use strict";

// This file is generated.
exports.version = '0.0.1-beta.9';
exports.version = '0.0.1-beta.10';
//# sourceMappingURL=version.js.map

@@ -36,4 +36,4 @@ "use strict";

exports.createNodePlugin = createNodePlugin;
const createConfiguredNodePlugin = (props) => {
const publisher = new publisher_1.Publisher(props);
const createConfiguredNodePlugin = (props, emitter) => {
const publisher = new publisher_1.Publisher(props, emitter);
return {

@@ -40,0 +40,0 @@ publisher: publisher,

@@ -18,3 +18,4 @@ "use strict";

class Publisher {
constructor({ host, path, maxRetries, maxEventsInBatch, flushInterval, writeKey, httpRequestTimeout, }) {
constructor({ host, path, maxRetries, maxEventsInBatch, flushInterval, writeKey, httpRequestTimeout, }, emitter) {
this._emitter = emitter;
this._maxRetries = maxRetries;

@@ -132,3 +133,3 @@ this._maxEventsInBatch = Math.max(maxEventsInBatch, 1);

try {
const response = await (0, fetch_1.fetch)(this._url, {
const requestInit = {
signal: signal,

@@ -142,3 +143,10 @@ method: 'POST',

body: payload,
};
this._emitter.emit('http_request', {
url: this._url,
method: requestInit.method,
headers: requestInit.headers,
body: requestInit.body,
});
const response = await (0, fetch_1.fetch)(this._url, requestInit);
clearTimeout(timeoutId);

@@ -145,0 +153,0 @@ if (response.ok) {

@@ -28,3 +28,3 @@ import { bindAll, pTimeout } from '@segment/analytics-core';

flushInterval,
});
}, this);
this._publisher = publisher;

@@ -31,0 +31,0 @@ this.ready = this.register(plugin).then(() => undefined);

// This file is generated.
export const version = '0.0.1-beta.9';
export const version = '0.0.1-beta.10';
//# sourceMappingURL=version.js.map

@@ -32,4 +32,4 @@ import { Publisher } from './publisher';

}
export const createConfiguredNodePlugin = (props) => {
const publisher = new Publisher(props);
export const createConfiguredNodePlugin = (props, emitter) => {
const publisher = new Publisher(props, emitter);
return {

@@ -36,0 +36,0 @@ publisher: publisher,

@@ -15,3 +15,4 @@ import { backoff } from '@segment/analytics-core';

export class Publisher {
constructor({ host, path, maxRetries, maxEventsInBatch, flushInterval, writeKey, httpRequestTimeout, }) {
constructor({ host, path, maxRetries, maxEventsInBatch, flushInterval, writeKey, httpRequestTimeout, }, emitter) {
this._emitter = emitter;
this._maxRetries = maxRetries;

@@ -129,3 +130,3 @@ this._maxEventsInBatch = Math.max(maxEventsInBatch, 1);

try {
const response = await fetch(this._url, {
const requestInit = {
signal: signal,

@@ -139,3 +140,10 @@ method: 'POST',

body: payload,
};
this._emitter.emit('http_request', {
url: this._url,
method: requestInit.method,
headers: requestInit.headers,
body: requestInit.body,
});
const response = await fetch(this._url, requestInit);
clearTimeout(timeoutId);

@@ -142,0 +150,0 @@ if (response.ok) {

@@ -8,5 +8,13 @@ import { CoreEmitterContract, Emitter } from '@segment/analytics-core';

*/
declare type NodeEmitterEvents = CoreEmitterContract<Context> & {
export declare type NodeEmitterEvents = CoreEmitterContract<Context> & {
initialize: [AnalyticsSettings];
call_after_close: [SegmentEvent];
http_request: [
{
url: string;
method: string;
headers: Record<string, string>;
body: string;
}
];
drained: [];

@@ -16,3 +24,2 @@ };

}
export {};
//# sourceMappingURL=emitter.d.ts.map

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

export declare const version = "0.0.1-beta.9";
export declare const version = "0.0.1-beta.10";
//# sourceMappingURL=version.d.ts.map
import { Publisher, PublisherProps } from './publisher';
import { Plugin } from '../../app/types';
import { NodeEmitter } from '../../app/emitter';
declare type DefinedPluginFields = 'name' | 'type' | 'version' | 'isLoaded' | 'load' | 'alias' | 'group' | 'identify' | 'page' | 'screen' | 'track';

@@ -7,3 +8,3 @@ declare type SegmentNodePlugin = Plugin & Required<Pick<Plugin, DefinedPluginFields>>;

export declare function createNodePlugin(publisher: Publisher): SegmentNodePlugin;
export declare const createConfiguredNodePlugin: (props: ConfigureNodePluginProps) => {
export declare const createConfiguredNodePlugin: (props: ConfigureNodePluginProps, emitter: NodeEmitter) => {
publisher: Publisher;

@@ -10,0 +11,0 @@ plugin: SegmentNodePlugin;

import type { Context } from '../../app/context';
import { NodeEmitter } from '../../app/emitter';
export interface PublisherProps {

@@ -24,3 +25,4 @@ host?: string;

private _httpRequestTimeout;
constructor({ host, path, maxRetries, maxEventsInBatch, flushInterval, writeKey, httpRequestTimeout, }: PublisherProps);
private _emitter;
constructor({ host, path, maxRetries, maxEventsInBatch, flushInterval, writeKey, httpRequestTimeout, }: PublisherProps, emitter: NodeEmitter);
private createBatch;

@@ -27,0 +29,0 @@ private clearBatch;

{
"name": "@segment/analytics-node",
"version": "0.0.1-beta.9",
"version": "0.0.1-beta.10",
"main": "./dist/cjs/index.js",

@@ -5,0 +5,0 @@ "module": "./dist/esm/index.js",

# @segment/analytics-node
> ### Warning: Until 1.x release, use this library at your own risk!
> ### Warning: This library is in [public beta](https://segment.com/legal/first-access-beta-preview) ⚠️

@@ -18,3 +18,3 @@ ## Requirements

### Usage
### Usage
Assuming some express-like web framework.

@@ -46,15 +46,37 @@ ```ts

```
## Regional configuration
For Business plans with access to Regional Segment, you can use the host configuration parameter to send data to the desired region:
Oregon (Default) — api.segment.io/v1
Dublin — events.eu1.segmentapis.com
An example of setting the host to the EU endpoint using the Node library would be:
## Graceful Exit
Avoid losing events on exit!
* Call `.closeAndFlush()` to stop collecting new events and flush all existing events.
* If a callback on an event call is included, this also waits for all callbacks to be called, and any of their subsequent promises to be resolved.
```ts
await analytics.closeAndFlush()
// or
await analytics.closeAndFlush({ timeout: 5000 }) // force resolve after 5000ms
```
#### Advanced Example
```ts
const app = express()
const server = app.listen(3000)
const onExit = async () => {
await analytics.closeAndFlush()
server.close(() => {
console.log("Gracefully closing server...")
process.exit()
})
}
['SIGINT', 'SIGTERM'].forEach((code) => process.on(code, onExit))
```
#### Collecting unflushed events
If you absolutely need to preserve all possible events in the event of a forced timeout, even ones that came in after `analytics.closeAndFlush()` was called, you can collect those events.
```ts
const analytics = new Analytics({
...
host: "https://events.eu1.segmentapis.com"
});
const unflushedEvents = []
analytics.on('call_after_close', (event) => unflushedEvents.push(events))
await analytics.closeAndFlush()
console.log(unflushedEvents) // all events that came in after closeAndFlush was called
```

@@ -75,3 +97,17 @@

```
## Regional configuration
For Business plans with access to Regional Segment, you can use the host configuration parameter to send data to the desired region:
Oregon (Default) — api.segment.io/v1
Dublin — events.eu1.segmentapis.com
An example of setting the host to the EU endpoint using the Node library would be:
```ts
const analytics = new Analytics({
...
host: "https://events.eu1.segmentapis.com"
});
```
## Batching

@@ -84,3 +120,2 @@ Our libraries are built to support high performance environments. That means it is safe to use our Node library on a web server that’s serving thousands of requests per second.

- The very first time it gets a message.
- Every 15 messages (controlled by `settings.maxEventsInBatch`).

@@ -119,38 +154,5 @@ - If 10 seconds has passed since the last flush (controlled by `settings.flushInterval`)

## Graceful Exit
Avoid losing events on exit!
* Call `.closeAndFlush()` to stop collecting new events and flush all existing events.
* If a callback on an event call is included, this also waits for all callbacks to be called, and any of their subsequent promises to be resolved.
```ts
await analytics.closeAndFlush()
// or
await analytics.closeAndFlush({ timeout: 5000 }) // force resolve after 5000ms
```
#### Advanced Example
```ts
const app = express()
const server = app.listen(3000)
const onExit = async () => {
await analytics.closeAndFlush()
server.close(() => {
console.log("Gracefully closing server...")
process.exit()
})
}
['SIGINT', 'SIGTERM'].forEach((code) => process.on(code, onExit))
```
#### Collecting unflushed events
If you absolutely need to preserve all possible events in the event of a forced timeout, even ones that came in after `analytics.closeAndFlush()` was called, you can collect those events.
```ts
const unflushedEvents = []
analytics.on('call_after_close', (event) => unflushedEvents.push(events))
await analytics.closeAndFlush()
console.log(unflushedEvents) // all events that came in after closeAndFlush was called
```
## Event Emitter Interface
You can see the complete list of emitted events in [emitter.ts](src/app/emitter.ts)
```ts

@@ -162,4 +164,22 @@ analytics.on('error', (err) => console.error(err))

analytics.on('track', (ctx) => console.log(ctx))
```
#### You can use the emitter to log all HTTP Requests
```ts
analytics.on('http_request', (event) => console.log(event))
// when triggered, emits an event of the shape:
{
url: 'https://api.segment.io/v1/batch',
method: 'POST',
headers: {
'Content-Type': 'application/json',
...
},
body: '...',
}
```
## Multiple Clients

@@ -244,3 +264,20 @@ Different parts of your application may require different types of batching, or even sending to multiple Segment sources. In that case, you can initialize multiple instances of Analytics with different settings:

```
- Undocumented behavior around `track` properties have been removed.
```ts
// old, undocumented behavior
analytics.track({
...
event: 'Ultimate Played',
myProp: 'abc'
})
// new
analytics.track({
...
event: 'Ultimate Played',
properties: {
myProp: 'abc'
}
})
```

@@ -247,0 +284,0 @@ ## Plugin Architecture

@@ -44,11 +44,14 @@ import { CoreAnalytics, bindAll, pTimeout } from '@segment/analytics-core'

const { plugin, publisher } = createConfiguredNodePlugin({
writeKey: settings.writeKey,
host: settings.host,
path: settings.path,
maxRetries: settings.maxRetries ?? 3,
maxEventsInBatch: settings.maxEventsInBatch ?? 15,
httpRequestTimeout: settings.httpRequestTimeout,
flushInterval,
})
const { plugin, publisher } = createConfiguredNodePlugin(
{
writeKey: settings.writeKey,
host: settings.host,
path: settings.path,
maxRetries: settings.maxRetries ?? 3,
maxEventsInBatch: settings.maxEventsInBatch ?? 15,
httpRequestTimeout: settings.httpRequestTimeout,
flushInterval,
},
this as NodeEmitter
)
this._publisher = publisher

@@ -55,0 +58,0 @@ this.ready = this.register(plugin).then(() => undefined)

@@ -9,5 +9,13 @@ import { CoreEmitterContract, Emitter } from '@segment/analytics-core'

*/
type NodeEmitterEvents = CoreEmitterContract<Context> & {
export type NodeEmitterEvents = CoreEmitterContract<Context> & {
initialize: [AnalyticsSettings]
call_after_close: [SegmentEvent] // any event that did not get dispatched due to close
http_request: [
{
url: string
method: string
headers: Record<string, string>
body: string
}
]
drained: []

@@ -14,0 +22,0 @@ }

// This file is generated.
export const version = '0.0.1-beta.9'
export const version = '0.0.1-beta.10'

@@ -6,2 +6,3 @@ import { Publisher, PublisherProps } from './publisher'

import { Context } from '../../app/context'
import { NodeEmitter } from '../../app/emitter'

@@ -56,4 +57,7 @@ function normalizeEvent(ctx: Context) {

export const createConfiguredNodePlugin = (props: ConfigureNodePluginProps) => {
const publisher = new Publisher(props)
export const createConfiguredNodePlugin = (
props: ConfigureNodePluginProps,
emitter: NodeEmitter
) => {
const publisher = new Publisher(props, emitter)
return {

@@ -60,0 +64,0 @@ publisher: publisher,

@@ -8,2 +8,3 @@ import { backoff } from '@segment/analytics-core'

import { ContextBatch } from './context-batch'
import { NodeEmitter } from '../../app/emitter'

@@ -45,12 +46,16 @@ function sleep(timeoutInMs: number): Promise<void> {

private _httpRequestTimeout: number
constructor({
host,
path,
maxRetries,
maxEventsInBatch,
flushInterval,
writeKey,
httpRequestTimeout,
}: PublisherProps) {
private _emitter: NodeEmitter
constructor(
{
host,
path,
maxRetries,
maxEventsInBatch,
flushInterval,
writeKey,
httpRequestTimeout,
}: PublisherProps,
emitter: NodeEmitter
) {
this._emitter = emitter
this._maxRetries = maxRetries

@@ -190,3 +195,3 @@ this._maxEventsInBatch = Math.max(maxEventsInBatch, 1)

try {
const response = await fetch(this._url, {
const requestInit = {
signal: signal,

@@ -200,3 +205,13 @@ method: 'POST',

body: payload,
}
this._emitter.emit('http_request', {
url: this._url,
method: requestInit.method,
headers: requestInit.headers,
body: requestInit.body,
})
const response = await fetch(this._url, requestInit)
clearTimeout(timeoutId)

@@ -203,0 +218,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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