wolves-js-client 1.0.0 → 1.0.1

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.
@@ -0,0 +1,22 @@
1
+ /**
2
+ * DeviceInfo - Collects device and environment information for event metadata
3
+ * Aligns with Statsig SDK's approach: sends raw user_agent for server-side parsing
4
+ *
5
+ * Note: Browser/OS parsing is done server-side from user_agent, not client-side
6
+ */
7
+ export type DeviceInfoData = {
8
+ user_agent: string;
9
+ locale: string;
10
+ screen_width: number | null;
11
+ screen_height: number | null;
12
+ viewport_width: number | null;
13
+ viewport_height: number | null;
14
+ timezone: string;
15
+ timezone_offset: number | null;
16
+ };
17
+ export declare function getDeviceInfo(): DeviceInfoData;
18
+ /**
19
+ * Get device info as a flat record suitable for event metadata
20
+ * Only includes non-null values
21
+ */
22
+ export declare function getDeviceInfoForMetadata(): Record<string, string | number>;
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ /**
3
+ * DeviceInfo - Collects device and environment information for event metadata
4
+ * Aligns with Statsig SDK's approach: sends raw user_agent for server-side parsing
5
+ *
6
+ * Note: Browser/OS parsing is done server-side from user_agent, not client-side
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.getDeviceInfo = getDeviceInfo;
10
+ exports.getDeviceInfoForMetadata = getDeviceInfoForMetadata;
11
+ function getWindowSafe() {
12
+ if (typeof window !== 'undefined') {
13
+ return window;
14
+ }
15
+ return null;
16
+ }
17
+ function getNavigatorSafe() {
18
+ var _a;
19
+ const win = getWindowSafe();
20
+ return (_a = win === null || win === void 0 ? void 0 : win.navigator) !== null && _a !== void 0 ? _a : null;
21
+ }
22
+ function getSafeTimezone() {
23
+ try {
24
+ return Intl.DateTimeFormat().resolvedOptions().timeZone || '';
25
+ }
26
+ catch (_a) {
27
+ return '';
28
+ }
29
+ }
30
+ function getSafeTimezoneOffset() {
31
+ try {
32
+ return new Date().getTimezoneOffset();
33
+ }
34
+ catch (_a) {
35
+ return null;
36
+ }
37
+ }
38
+ let cachedDeviceInfo = null;
39
+ function getDeviceInfo() {
40
+ var _a, _b, _c, _d, _e, _f;
41
+ // Return cached info if available
42
+ if (cachedDeviceInfo) {
43
+ return cachedDeviceInfo;
44
+ }
45
+ const win = getWindowSafe();
46
+ const nav = getNavigatorSafe();
47
+ if (!win || !nav) {
48
+ // Return empty values for server-side or non-browser environments
49
+ return {
50
+ user_agent: '',
51
+ locale: '',
52
+ screen_width: null,
53
+ screen_height: null,
54
+ viewport_width: null,
55
+ viewport_height: null,
56
+ timezone: '',
57
+ timezone_offset: null,
58
+ };
59
+ }
60
+ const userAgent = nav.userAgent || '';
61
+ cachedDeviceInfo = {
62
+ // Send raw user_agent - server will parse browser/os info
63
+ user_agent: userAgent.length > 500 ? userAgent.substring(0, 500) : userAgent,
64
+ locale: nav.language || '',
65
+ screen_width: (_b = (_a = win.screen) === null || _a === void 0 ? void 0 : _a.width) !== null && _b !== void 0 ? _b : null,
66
+ screen_height: (_d = (_c = win.screen) === null || _c === void 0 ? void 0 : _c.height) !== null && _d !== void 0 ? _d : null,
67
+ viewport_width: (_e = win.innerWidth) !== null && _e !== void 0 ? _e : null,
68
+ viewport_height: (_f = win.innerHeight) !== null && _f !== void 0 ? _f : null,
69
+ timezone: getSafeTimezone(),
70
+ timezone_offset: getSafeTimezoneOffset(),
71
+ };
72
+ return cachedDeviceInfo;
73
+ }
74
+ /**
75
+ * Get device info as a flat record suitable for event metadata
76
+ * Only includes non-null values
77
+ */
78
+ function getDeviceInfoForMetadata() {
79
+ const info = getDeviceInfo();
80
+ const result = {};
81
+ if (info.user_agent)
82
+ result['user_agent'] = info.user_agent;
83
+ if (info.locale)
84
+ result['locale'] = info.locale;
85
+ if (info.screen_width !== null)
86
+ result['screen_width'] = info.screen_width;
87
+ if (info.screen_height !== null)
88
+ result['screen_height'] = info.screen_height;
89
+ if (info.viewport_width !== null)
90
+ result['viewport_width'] = info.viewport_width;
91
+ if (info.viewport_height !== null)
92
+ result['viewport_height'] = info.viewport_height;
93
+ if (info.timezone)
94
+ result['timezone'] = info.timezone;
95
+ if (info.timezone_offset !== null)
96
+ result['timezone_offset'] = info.timezone_offset;
97
+ return result;
98
+ }
@@ -9,5 +9,5 @@ export declare class EventLogger {
9
9
  enqueue(event: WolvesEvent): void;
10
10
  flush(): Promise<void>;
11
11
  private start;
12
- stop(): void;
12
+ stop(): Promise<void>;
13
13
  }
@@ -24,7 +24,9 @@ class EventLogger {
24
24
  enqueue(event) {
25
25
  this.queue.push(event);
26
26
  if (this.queue.length >= this.maxQueueSize) {
27
- this.flush();
27
+ this.flush().catch((e) => {
28
+ Log_1.Log.error('Failed to flush events', e);
29
+ });
28
30
  }
29
31
  }
30
32
  flush() {
@@ -57,11 +59,13 @@ class EventLogger {
57
59
  }, DEFAULT_FLUSH_INTERVAL_MS);
58
60
  }
59
61
  stop() {
60
- if (this.flushIntervalId) {
61
- clearInterval(this.flushIntervalId);
62
- this.flushIntervalId = null;
63
- }
64
- this.flush();
62
+ return __awaiter(this, void 0, void 0, function* () {
63
+ if (this.flushIntervalId) {
64
+ clearInterval(this.flushIntervalId);
65
+ this.flushIntervalId = null;
66
+ }
67
+ yield this.flush();
68
+ });
65
69
  }
66
70
  }
67
71
  exports.EventLogger = EventLogger;
package/dist/Network.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  import { WolvesUser } from './WolvesUser';
2
+ export declare const API_LOCAL = "http://localhost:8000/api";
3
+ export declare const API_DEV = "https://wolves-nova-dev.azurewebsites.net/api";
2
4
  export declare class Network {
3
5
  private sdkKey;
4
6
  private api;
package/dist/Network.js CHANGED
@@ -9,11 +9,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.Network = void 0;
12
+ exports.Network = exports.API_DEV = exports.API_LOCAL = void 0;
13
13
  const Log_1 = require("./Log");
14
+ const WolvesMetadata_1 = require("./WolvesMetadata");
14
15
  const RETRYABLE_CODES = [408, 500, 502, 503, 504, 522, 524, 599];
16
+ // API endpoints - switch between local and production
17
+ exports.API_LOCAL = 'http://localhost:8000/api';
18
+ exports.API_DEV = 'https://wolves-nova-dev.azurewebsites.net/api';
15
19
  class Network {
16
- constructor(sdkKey, api = 'https://wolves-nova-dev.azurewebsites.net/api') {
20
+ constructor(sdkKey, api = exports.API_LOCAL) {
17
21
  this.sdkKey = sdkKey;
18
22
  this.api = api;
19
23
  }
@@ -57,6 +61,7 @@ class Network {
57
61
  }
58
62
  sendEvents(events_1) {
59
63
  return __awaiter(this, arguments, void 0, function* (events, retries = 3, backoff = 1000) {
64
+ const sdkMetadata = WolvesMetadata_1.WolvesMetadataProvider.get();
60
65
  const apiEvents = events.map(e => {
61
66
  var _a, _b;
62
67
  return ({
@@ -68,6 +73,10 @@ class Network {
68
73
  metadata: e.metadata
69
74
  });
70
75
  });
76
+ const requestBody = {
77
+ events: apiEvents,
78
+ wolvesMetadata: sdkMetadata,
79
+ };
71
80
  try {
72
81
  const controller = new AbortController();
73
82
  const timeoutId = setTimeout(() => controller.abort(), 10000); // 10s timeout
@@ -77,7 +86,7 @@ class Network {
77
86
  'Content-Type': 'application/json',
78
87
  'wolves-api-key': this.sdkKey,
79
88
  },
80
- body: JSON.stringify({ events: apiEvents }),
89
+ body: JSON.stringify(requestBody),
81
90
  signal: controller.signal,
82
91
  }).finally(() => clearTimeout(timeoutId));
83
92
  if (!response.ok) {
@@ -20,6 +20,6 @@ export declare class WolvesClient {
20
20
  */
21
21
  getExperimentForTest(experimentName: string, groupName: string): Experiment;
22
22
  logEvent(eventName: string, value?: string | number, metadata?: Record<string, string>): void;
23
- shutdown(): void;
23
+ shutdown(): Promise<void>;
24
24
  private logExposure;
25
25
  }
@@ -122,7 +122,9 @@ class WolvesClient {
122
122
  this.logger.enqueue(event);
123
123
  }
124
124
  shutdown() {
125
- this.logger.stop();
125
+ return __awaiter(this, void 0, void 0, function* () {
126
+ yield this.logger.stop();
127
+ });
126
128
  }
127
129
  logExposure(experimentName, experiment) {
128
130
  var _a, _b, _c;
@@ -0,0 +1,13 @@
1
+ export declare const SDK_VERSION = "1.0.0";
2
+ export declare const SDK_TYPE = "wolves-js-client";
3
+ export type WolvesMetadata = {
4
+ readonly [key: string]: string | undefined | null;
5
+ readonly sdkVersion: string;
6
+ readonly sdkType: string;
7
+ };
8
+ export declare const WolvesMetadataProvider: {
9
+ get: () => WolvesMetadata;
10
+ add: (additions: {
11
+ [key: string]: string | undefined;
12
+ }) => void;
13
+ };
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WolvesMetadataProvider = exports.SDK_TYPE = exports.SDK_VERSION = void 0;
4
+ exports.SDK_VERSION = '1.0.0';
5
+ exports.SDK_TYPE = 'wolves-js-client';
6
+ let metadata = {
7
+ sdkVersion: exports.SDK_VERSION,
8
+ sdkType: exports.SDK_TYPE,
9
+ };
10
+ exports.WolvesMetadataProvider = {
11
+ get: () => metadata,
12
+ add: (additions) => {
13
+ metadata = Object.assign(Object.assign({}, metadata), additions);
14
+ },
15
+ };
package/dist/index.d.ts CHANGED
@@ -2,3 +2,5 @@ export { WolvesClient } from './WolvesClient';
2
2
  export { WolvesUser } from './WolvesUser';
3
3
  export { Experiment } from './Types';
4
4
  export { Log, LogLevel } from './Log';
5
+ export { SDK_VERSION, SDK_TYPE, WolvesMetadataProvider } from './WolvesMetadata';
6
+ export type { WolvesMetadata } from './WolvesMetadata';
package/dist/index.js CHANGED
@@ -1,8 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LogLevel = exports.Log = exports.WolvesClient = void 0;
3
+ exports.WolvesMetadataProvider = exports.SDK_TYPE = exports.SDK_VERSION = exports.LogLevel = exports.Log = exports.WolvesClient = void 0;
4
4
  var WolvesClient_1 = require("./WolvesClient");
5
5
  Object.defineProperty(exports, "WolvesClient", { enumerable: true, get: function () { return WolvesClient_1.WolvesClient; } });
6
6
  var Log_1 = require("./Log");
7
7
  Object.defineProperty(exports, "Log", { enumerable: true, get: function () { return Log_1.Log; } });
8
8
  Object.defineProperty(exports, "LogLevel", { enumerable: true, get: function () { return Log_1.LogLevel; } });
9
+ var WolvesMetadata_1 = require("./WolvesMetadata");
10
+ Object.defineProperty(exports, "SDK_VERSION", { enumerable: true, get: function () { return WolvesMetadata_1.SDK_VERSION; } });
11
+ Object.defineProperty(exports, "SDK_TYPE", { enumerable: true, get: function () { return WolvesMetadata_1.SDK_TYPE; } });
12
+ Object.defineProperty(exports, "WolvesMetadataProvider", { enumerable: true, get: function () { return WolvesMetadata_1.WolvesMetadataProvider; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wolves-js-client",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "A Wolves JavaScript Client SDK",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",