Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/analytics-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
},
"dependencies": {
"@metamask/sdk-types": "workspace:^",
"cross-fetch": "^4.0.0"
"cross-fetch": "^4.0.0",
"openapi-fetch": "^0.13.5"
},
"devDependencies": {
"@lavamoat/allow-scripts": "^2.3.1",
Expand Down
3 changes: 3 additions & 0 deletions packages/analytics-client/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
export { SendAnalytics } from './Analytics';
export type { AnalyticsProps } from './Analytics';

export { initAnalyticsClient, trackEvent } from './v2';
export type { AnalyticsProps as V2AnalyticsProps, BaseAnalyticsProps as V2BaseAnalyticsProps } from './v2';

Check failure on line 5 in packages/analytics-client/src/index.ts

View workflow job for this annotation

GitHub Actions / Lint, build, and test / Lint (18.x)

Replace `·AnalyticsProps·as·V2AnalyticsProps,·BaseAnalyticsProps·as·V2BaseAnalyticsProps·` with `⏎··AnalyticsProps·as·V2AnalyticsProps,⏎··BaseAnalyticsProps·as·V2BaseAnalyticsProps,⏎`

// Removed re-exports from communication-layer
// export type {
// TrackingEvents,
Expand Down
121 changes: 121 additions & 0 deletions packages/analytics-client/src/v2/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import createClient from 'openapi-fetch';
import { components, paths } from './schema';
import { type OriginatorInfo } from '@metamask/sdk-types';

Check failure on line 3 in packages/analytics-client/src/v2/client.ts

View workflow job for this annotation

GitHub Actions / Lint, build, and test / Lint (18.x)

`@metamask/sdk-types` import should occur before import of `./schema`

type AnalyticsClientOptions = {
// TODO Add options

Check failure on line 6 in packages/analytics-client/src/v2/client.ts

View workflow job for this annotation

GitHub Actions / Lint, build, and test / Lint (18.x)

Replace `··//·TODO·Add·options·` with `//·TODO·Add·options`
pushInterval: number;

Check failure on line 7 in packages/analytics-client/src/v2/client.ts

View workflow job for this annotation

GitHub Actions / Lint, build, and test / Lint (18.x)

Delete `··`
analyticsUrl: string;

Check failure on line 8 in packages/analytics-client/src/v2/client.ts

View workflow job for this annotation

GitHub Actions / Lint, build, and test / Lint (18.x)

Delete `··`
};

class AnalyticsClient {
private _options: AnalyticsClientOptions | undefined = undefined;

Check failure on line 12 in packages/analytics-client/src/v2/client.ts

View workflow job for this annotation

GitHub Actions / Lint, build, and test / Lint (18.x)

Delete `··`
private _pushInterval: NodeJS.Timeout | undefined = undefined;

Check failure on line 13 in packages/analytics-client/src/v2/client.ts

View workflow job for this annotation

GitHub Actions / Lint, build, and test / Lint (18.x)

Replace `····` with `··`

Check failure on line 13 in packages/analytics-client/src/v2/client.ts

View workflow job for this annotation

GitHub Actions / Lint, build, and test / Lint (18.x)

Expected blank line between class members
private _client: ReturnType<typeof createClient> | undefined = undefined;

Check failure on line 14 in packages/analytics-client/src/v2/client.ts

View workflow job for this annotation

GitHub Actions / Lint, build, and test / Lint (18.x)

Delete `··`

Check failure on line 14 in packages/analytics-client/src/v2/client.ts

View workflow job for this annotation

GitHub Actions / Lint, build, and test / Lint (18.x)

Expected blank line between class members
private _events: components['schemas']['Event'][] = [];

public init(options?: AnalyticsClientOptions) {
if (!options) {
options = {
pushInterval: 1000,
analyticsUrl: 'http://localhost:3000',
};
}

if (this.isInitialized) {
// Nothing to do
return;
}

this._options = options;

this._client = createClient<paths>({
baseUrl: this._options.analyticsUrl,
});

this._pushInterval = setInterval(() => {
this.pushEvents();
}, this._options.pushInterval);
}

public get isInitialized() {
return this._options !== undefined && this._pushInterval !== undefined && this._client !== undefined;
}

private checkInitialized() {
if (!this.isInitialized) {
throw new Error('Analytics client is not initialized');
}
}

private useClient(): ReturnType<typeof createClient<paths>> {
this.checkInitialized();
return this._client as ReturnType<typeof createClient<paths>>;
}

private async pushEvents() {
if (this._events.length === 0) {
return;
}

const client = this.useClient();


const events = this._events as components['schemas']['Event'][];
this._events = [];

const result = await client.POST("/v1/events", {
body: events,
});

if (!result.data) {
throw new Error(`Failed to post request_initiated event: ${result.error}`);
}
}

public trackEvent<T extends components['schemas']['Event']>(event: T) {
this._events.push(event);
}
}

const GlobalAnalyticsClient = new AnalyticsClient();

export type BaseAnalyticsProps = {
id: string;
originatorInfo?: OriginatorInfo; // Now uses local type
sdkVersion?: string;
// TODO What is this?
anonId: string;
};

export type AnalyticsProps = BaseAnalyticsProps & AnalyticsClientOptions;

let globalAnalyticsProps: BaseAnalyticsProps | undefined = undefined;

export function initAnalyticsClient(options?: AnalyticsProps) {
globalAnalyticsProps = options;
GlobalAnalyticsClient.init(options);
}

export function trackEvent<T extends components['schemas']['Event']>(event: T | Partial<T>) {
if (!globalAnalyticsProps) {
throw new Error('Analytics client is not initialized');
}

const baseEventProps = {
sdk_version: globalAnalyticsProps.sdkVersion,
dapp_id: globalAnalyticsProps.originatorInfo?.dappId,
anon_id: globalAnalyticsProps.anonId,
platform: globalAnalyticsProps.originatorInfo?.platform,
integration_type: globalAnalyticsProps.originatorInfo?.source,
}

const mergedEvent = {
...baseEventProps,
...event,
} as T;

GlobalAnalyticsClient.trackEvent(mergedEvent);
}

export default GlobalAnalyticsClient;
6 changes: 6 additions & 0 deletions packages/analytics-client/src/v2/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import GlobalAnalyticsClient from './client';

export { initAnalyticsClient, trackEvent } from './client';
export type { AnalyticsProps, BaseAnalyticsProps } from './client';

export default GlobalAnalyticsClient;
Loading
Loading