mytart 0.1.7 → 0.2.0

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/dist/index.d.mts CHANGED
@@ -9,12 +9,14 @@ interface BaseProviderConfig {
9
9
  enabled?: boolean;
10
10
  }
11
11
  type ProviderName = 'google-analytics' | 'mixpanel' | 'segment' | 'amplitude' | 'plausible' | 'posthog';
12
+ type GoogleAnalyticsAppType = 'browser' | 'server';
12
13
  interface GoogleAnalyticsConfig extends BaseProviderConfig {
13
14
  provider: 'google-analytics';
14
15
  measurementId: string;
15
- apiSecret: string;
16
+ apiSecret?: string;
16
17
  clientId?: string;
17
18
  debug?: boolean;
19
+ appType?: GoogleAnalyticsAppType;
18
20
  }
19
21
  interface MixpanelConfig extends BaseProviderConfig {
20
22
  provider: 'mixpanel';
@@ -118,12 +120,40 @@ declare abstract class BaseProvider {
118
120
  protected buildSuccess(statusCode?: number): TrackResult;
119
121
  }
120
122
 
123
+ declare global {
124
+ interface Window {
125
+ gtag: GtagFn;
126
+ dataLayer: unknown[];
127
+ }
128
+ }
129
+ interface GtagFn {
130
+ (command: 'config', measurementId: string, config?: GtagConfig): void;
131
+ (command: 'event', eventName: string, params?: Record<string, unknown>): void;
132
+ (command: 'set', config: Record<string, unknown>): void;
133
+ (command: string, ...args: unknown[]): void;
134
+ }
135
+ interface GtagConfig {
136
+ send_page_view?: boolean;
137
+ page_title?: string;
138
+ page_location?: string;
139
+ page_referrer?: string;
140
+ user_id?: string;
141
+ [key: string]: unknown;
142
+ }
121
143
  declare class GoogleAnalyticsProvider extends BaseProvider {
122
144
  readonly name = "google-analytics";
123
145
  private readonly config;
124
146
  private readonly http;
125
147
  private readonly endpoint;
148
+ private readonly isBrowser;
149
+ private gtagInitialized;
126
150
  constructor(config: GoogleAnalyticsConfig);
151
+ private ensureGtagLoaded;
152
+ private injectGtagScript;
153
+ private buildGtagResult;
154
+ private trackBrowser;
155
+ private identifyBrowser;
156
+ private pageBrowser;
127
157
  track({ event, properties, userId, anonymousId, timestamp }: TrackOptions): Promise<TrackResult>;
128
158
  identify({ userId, traits }: IdentifyOptions): Promise<TrackResult>;
129
159
  page({ name, url, referrer, userId, anonymousId }: PageOptions): Promise<TrackResult>;
@@ -186,4 +216,4 @@ declare class PostHogProvider extends BaseProvider {
186
216
  page({ name, url, userId, anonymousId, properties }: PageOptions): Promise<TrackResult>;
187
217
  }
188
218
 
189
- export { type AmplitudeConfig, AmplitudeProvider, BaseProvider, type BaseProviderConfig, type EventContext, type GoogleAnalyticsConfig, GoogleAnalyticsProvider, type IdentifyOptions, type MixpanelConfig, MixpanelProvider, Mytart, type MytartConfig, type MytartError, type PageOptions, type PlausibleConfig, PlausibleProvider, type PostHogConfig, PostHogProvider, type ProviderConfig, type ProviderName, type SegmentConfig, SegmentProvider, type TrackOptions, type TrackResult };
219
+ export { type AmplitudeConfig, AmplitudeProvider, BaseProvider, type BaseProviderConfig, type EventContext, type GoogleAnalyticsAppType, type GoogleAnalyticsConfig, GoogleAnalyticsProvider, type IdentifyOptions, type MixpanelConfig, MixpanelProvider, Mytart, type MytartConfig, type MytartError, type PageOptions, type PlausibleConfig, PlausibleProvider, type PostHogConfig, PostHogProvider, type ProviderConfig, type ProviderName, type SegmentConfig, SegmentProvider, type TrackOptions, type TrackResult };
package/dist/index.d.ts CHANGED
@@ -9,12 +9,14 @@ interface BaseProviderConfig {
9
9
  enabled?: boolean;
10
10
  }
11
11
  type ProviderName = 'google-analytics' | 'mixpanel' | 'segment' | 'amplitude' | 'plausible' | 'posthog';
12
+ type GoogleAnalyticsAppType = 'browser' | 'server';
12
13
  interface GoogleAnalyticsConfig extends BaseProviderConfig {
13
14
  provider: 'google-analytics';
14
15
  measurementId: string;
15
- apiSecret: string;
16
+ apiSecret?: string;
16
17
  clientId?: string;
17
18
  debug?: boolean;
19
+ appType?: GoogleAnalyticsAppType;
18
20
  }
19
21
  interface MixpanelConfig extends BaseProviderConfig {
20
22
  provider: 'mixpanel';
@@ -118,12 +120,40 @@ declare abstract class BaseProvider {
118
120
  protected buildSuccess(statusCode?: number): TrackResult;
119
121
  }
120
122
 
123
+ declare global {
124
+ interface Window {
125
+ gtag: GtagFn;
126
+ dataLayer: unknown[];
127
+ }
128
+ }
129
+ interface GtagFn {
130
+ (command: 'config', measurementId: string, config?: GtagConfig): void;
131
+ (command: 'event', eventName: string, params?: Record<string, unknown>): void;
132
+ (command: 'set', config: Record<string, unknown>): void;
133
+ (command: string, ...args: unknown[]): void;
134
+ }
135
+ interface GtagConfig {
136
+ send_page_view?: boolean;
137
+ page_title?: string;
138
+ page_location?: string;
139
+ page_referrer?: string;
140
+ user_id?: string;
141
+ [key: string]: unknown;
142
+ }
121
143
  declare class GoogleAnalyticsProvider extends BaseProvider {
122
144
  readonly name = "google-analytics";
123
145
  private readonly config;
124
146
  private readonly http;
125
147
  private readonly endpoint;
148
+ private readonly isBrowser;
149
+ private gtagInitialized;
126
150
  constructor(config: GoogleAnalyticsConfig);
151
+ private ensureGtagLoaded;
152
+ private injectGtagScript;
153
+ private buildGtagResult;
154
+ private trackBrowser;
155
+ private identifyBrowser;
156
+ private pageBrowser;
127
157
  track({ event, properties, userId, anonymousId, timestamp }: TrackOptions): Promise<TrackResult>;
128
158
  identify({ userId, traits }: IdentifyOptions): Promise<TrackResult>;
129
159
  page({ name, url, referrer, userId, anonymousId }: PageOptions): Promise<TrackResult>;
@@ -186,4 +216,4 @@ declare class PostHogProvider extends BaseProvider {
186
216
  page({ name, url, userId, anonymousId, properties }: PageOptions): Promise<TrackResult>;
187
217
  }
188
218
 
189
- export { type AmplitudeConfig, AmplitudeProvider, BaseProvider, type BaseProviderConfig, type EventContext, type GoogleAnalyticsConfig, GoogleAnalyticsProvider, type IdentifyOptions, type MixpanelConfig, MixpanelProvider, Mytart, type MytartConfig, type MytartError, type PageOptions, type PlausibleConfig, PlausibleProvider, type PostHogConfig, PostHogProvider, type ProviderConfig, type ProviderName, type SegmentConfig, SegmentProvider, type TrackOptions, type TrackResult };
219
+ export { type AmplitudeConfig, AmplitudeProvider, BaseProvider, type BaseProviderConfig, type EventContext, type GoogleAnalyticsAppType, type GoogleAnalyticsConfig, GoogleAnalyticsProvider, type IdentifyOptions, type MixpanelConfig, MixpanelProvider, Mytart, type MytartConfig, type MytartError, type PageOptions, type PlausibleConfig, PlausibleProvider, type PostHogConfig, PostHogProvider, type ProviderConfig, type ProviderName, type SegmentConfig, SegmentProvider, type TrackOptions, type TrackResult };
package/dist/index.js CHANGED
@@ -82,23 +82,104 @@ function isAxiosError(error) {
82
82
  // src/providers/google-analytics.ts
83
83
  var GA4_ENDPOINT = "https://www.google-analytics.com/mp/collect";
84
84
  var GA4_DEBUG_ENDPOINT = "https://www.google-analytics.com/debug/mp/collect";
85
+ var GTAG_URL = "https://www.googletagmanager.com/gtag/js";
85
86
  var GoogleAnalyticsProvider = class extends BaseProvider {
86
87
  constructor(config) {
87
88
  super();
88
89
  this.name = "google-analytics";
90
+ this.gtagInitialized = false;
89
91
  this.config = config;
90
92
  this.http = createHttpClient();
91
93
  this.endpoint = config.debug ? GA4_DEBUG_ENDPOINT : GA4_ENDPOINT;
94
+ this.isBrowser = config.appType === "browser";
95
+ }
96
+ async ensureGtagLoaded() {
97
+ if (typeof window === "undefined") {
98
+ return;
99
+ }
100
+ if (typeof window.gtag === "function") {
101
+ return;
102
+ }
103
+ await this.injectGtagScript();
104
+ }
105
+ injectGtagScript() {
106
+ return new Promise((resolve) => {
107
+ const script = document.createElement("script");
108
+ script.async = true;
109
+ script.src = `${GTAG_URL}?id=${this.config.measurementId}`;
110
+ const firstScript = document.getElementsByTagName("script")[0];
111
+ firstScript.parentNode?.insertBefore(script, firstScript);
112
+ window.dataLayer = window.dataLayer || [];
113
+ window.gtag = function gtag(...args) {
114
+ window.dataLayer.push(args);
115
+ };
116
+ window.gtag("config", this.config.measurementId, {
117
+ send_page_view: false
118
+ });
119
+ script.onload = () => resolve();
120
+ script.onerror = () => resolve();
121
+ });
122
+ }
123
+ buildGtagResult() {
124
+ return {
125
+ provider: this.name,
126
+ success: true,
127
+ statusCode: 200
128
+ };
129
+ }
130
+ async trackBrowser({ event, properties, userId }) {
131
+ if (typeof window === "undefined") {
132
+ return this.buildGtagResult();
133
+ }
134
+ await this.ensureGtagLoaded();
135
+ if (userId) {
136
+ window.gtag("set", { user_id: userId });
137
+ }
138
+ window.gtag("event", event, properties || {});
139
+ return this.buildGtagResult();
140
+ }
141
+ async identifyBrowser({ userId, traits }) {
142
+ if (typeof window === "undefined") {
143
+ return this.buildGtagResult();
144
+ }
145
+ await this.ensureGtagLoaded();
146
+ window.gtag("set", { user_id: userId });
147
+ if (traits) {
148
+ Object.entries(traits).forEach(([key, value]) => {
149
+ window.gtag("set", { [key]: value });
150
+ });
151
+ }
152
+ return this.buildGtagResult();
153
+ }
154
+ async pageBrowser({ name, url, referrer, userId }) {
155
+ if (typeof window === "undefined") {
156
+ return this.buildGtagResult();
157
+ }
158
+ await this.ensureGtagLoaded();
159
+ const config = {
160
+ page_title: name,
161
+ page_location: url,
162
+ page_referrer: referrer,
163
+ send_page_view: true
164
+ };
165
+ if (userId) {
166
+ config.user_id = userId;
167
+ }
168
+ window.gtag("config", this.config.measurementId, config);
169
+ return this.buildGtagResult();
92
170
  }
93
171
  async track({ event, properties, userId, anonymousId, timestamp }) {
172
+ if (this.isBrowser) {
173
+ return this.trackBrowser({ event, properties, userId, anonymousId, timestamp });
174
+ }
94
175
  try {
95
- const clientId = anonymousId ?? this.config.clientId ?? "anonymous";
176
+ const client_id = anonymousId ?? this.config.clientId ?? "anonymous";
96
177
  const params = { ...properties };
97
178
  if (timestamp) {
98
179
  params["timestamp_micros"] = timestamp.getTime() * 1e3;
99
180
  }
100
181
  const body = {
101
- client_id: clientId,
182
+ client_id,
102
183
  events: [{ name: event, params }]
103
184
  };
104
185
  if (userId) {
@@ -123,6 +204,9 @@ var GoogleAnalyticsProvider = class extends BaseProvider {
123
204
  }
124
205
  }
125
206
  async identify({ userId, traits }) {
207
+ if (this.isBrowser) {
208
+ return this.identifyBrowser({ userId, traits });
209
+ }
126
210
  try {
127
211
  const body = {
128
212
  client_id: userId,
@@ -151,6 +235,9 @@ var GoogleAnalyticsProvider = class extends BaseProvider {
151
235
  }
152
236
  }
153
237
  async page({ name, url, referrer, userId, anonymousId }) {
238
+ if (this.isBrowser) {
239
+ return this.pageBrowser({ name, url, referrer, userId, anonymousId });
240
+ }
154
241
  return this.track({
155
242
  event: "page_view",
156
243
  properties: {
package/dist/index.mjs CHANGED
@@ -39,23 +39,104 @@ function isAxiosError(error) {
39
39
  // src/providers/google-analytics.ts
40
40
  var GA4_ENDPOINT = "https://www.google-analytics.com/mp/collect";
41
41
  var GA4_DEBUG_ENDPOINT = "https://www.google-analytics.com/debug/mp/collect";
42
+ var GTAG_URL = "https://www.googletagmanager.com/gtag/js";
42
43
  var GoogleAnalyticsProvider = class extends BaseProvider {
43
44
  constructor(config) {
44
45
  super();
45
46
  this.name = "google-analytics";
47
+ this.gtagInitialized = false;
46
48
  this.config = config;
47
49
  this.http = createHttpClient();
48
50
  this.endpoint = config.debug ? GA4_DEBUG_ENDPOINT : GA4_ENDPOINT;
51
+ this.isBrowser = config.appType === "browser";
52
+ }
53
+ async ensureGtagLoaded() {
54
+ if (typeof window === "undefined") {
55
+ return;
56
+ }
57
+ if (typeof window.gtag === "function") {
58
+ return;
59
+ }
60
+ await this.injectGtagScript();
61
+ }
62
+ injectGtagScript() {
63
+ return new Promise((resolve) => {
64
+ const script = document.createElement("script");
65
+ script.async = true;
66
+ script.src = `${GTAG_URL}?id=${this.config.measurementId}`;
67
+ const firstScript = document.getElementsByTagName("script")[0];
68
+ firstScript.parentNode?.insertBefore(script, firstScript);
69
+ window.dataLayer = window.dataLayer || [];
70
+ window.gtag = function gtag(...args) {
71
+ window.dataLayer.push(args);
72
+ };
73
+ window.gtag("config", this.config.measurementId, {
74
+ send_page_view: false
75
+ });
76
+ script.onload = () => resolve();
77
+ script.onerror = () => resolve();
78
+ });
79
+ }
80
+ buildGtagResult() {
81
+ return {
82
+ provider: this.name,
83
+ success: true,
84
+ statusCode: 200
85
+ };
86
+ }
87
+ async trackBrowser({ event, properties, userId }) {
88
+ if (typeof window === "undefined") {
89
+ return this.buildGtagResult();
90
+ }
91
+ await this.ensureGtagLoaded();
92
+ if (userId) {
93
+ window.gtag("set", { user_id: userId });
94
+ }
95
+ window.gtag("event", event, properties || {});
96
+ return this.buildGtagResult();
97
+ }
98
+ async identifyBrowser({ userId, traits }) {
99
+ if (typeof window === "undefined") {
100
+ return this.buildGtagResult();
101
+ }
102
+ await this.ensureGtagLoaded();
103
+ window.gtag("set", { user_id: userId });
104
+ if (traits) {
105
+ Object.entries(traits).forEach(([key, value]) => {
106
+ window.gtag("set", { [key]: value });
107
+ });
108
+ }
109
+ return this.buildGtagResult();
110
+ }
111
+ async pageBrowser({ name, url, referrer, userId }) {
112
+ if (typeof window === "undefined") {
113
+ return this.buildGtagResult();
114
+ }
115
+ await this.ensureGtagLoaded();
116
+ const config = {
117
+ page_title: name,
118
+ page_location: url,
119
+ page_referrer: referrer,
120
+ send_page_view: true
121
+ };
122
+ if (userId) {
123
+ config.user_id = userId;
124
+ }
125
+ window.gtag("config", this.config.measurementId, config);
126
+ return this.buildGtagResult();
49
127
  }
50
128
  async track({ event, properties, userId, anonymousId, timestamp }) {
129
+ if (this.isBrowser) {
130
+ return this.trackBrowser({ event, properties, userId, anonymousId, timestamp });
131
+ }
51
132
  try {
52
- const clientId = anonymousId ?? this.config.clientId ?? "anonymous";
133
+ const client_id = anonymousId ?? this.config.clientId ?? "anonymous";
53
134
  const params = { ...properties };
54
135
  if (timestamp) {
55
136
  params["timestamp_micros"] = timestamp.getTime() * 1e3;
56
137
  }
57
138
  const body = {
58
- client_id: clientId,
139
+ client_id,
59
140
  events: [{ name: event, params }]
60
141
  };
61
142
  if (userId) {
@@ -80,6 +161,9 @@ var GoogleAnalyticsProvider = class extends BaseProvider {
80
161
  }
81
162
  }
82
163
  async identify({ userId, traits }) {
164
+ if (this.isBrowser) {
165
+ return this.identifyBrowser({ userId, traits });
166
+ }
83
167
  try {
84
168
  const body = {
85
169
  client_id: userId,
@@ -108,6 +192,9 @@ var GoogleAnalyticsProvider = class extends BaseProvider {
108
192
  }
109
193
  }
110
194
  async page({ name, url, referrer, userId, anonymousId }) {
195
+ if (this.isBrowser) {
196
+ return this.pageBrowser({ name, url, referrer, userId, anonymousId });
197
+ }
111
198
  return this.track({
112
199
  event: "page_view",
113
200
  properties: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mytart",
3
- "version": "0.1.7",
3
+ "version": "0.2.0",
4
4
  "description": "Multi-Yield Tracking & Analytics Relay Tool — framework-agnostic analytics for any project",
5
5
  "keywords": [
6
6
  "analytics",