@symbo.ls/sdk 2.32.11 → 2.32.13

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.
Files changed (50) hide show
  1. package/README.md +141 -0
  2. package/dist/cjs/config/environment.js +18 -7
  3. package/dist/cjs/index.js +38 -12
  4. package/dist/cjs/services/BaseService.js +46 -0
  5. package/dist/cjs/services/DnsService.js +6 -5
  6. package/dist/cjs/services/TrackingService.js +661 -0
  7. package/dist/cjs/services/index.js +5 -5
  8. package/dist/cjs/utils/changePreprocessor.js +8 -1
  9. package/dist/cjs/utils/services.js +27 -3
  10. package/dist/esm/config/environment.js +18 -7
  11. package/dist/esm/index.js +20747 -5912
  12. package/dist/esm/services/AdminService.js +64 -7
  13. package/dist/esm/services/AuthService.js +64 -7
  14. package/dist/esm/services/BaseService.js +64 -7
  15. package/dist/esm/services/BranchService.js +64 -7
  16. package/dist/esm/services/CollabService.js +72 -8
  17. package/dist/esm/services/DnsService.js +70 -12
  18. package/dist/esm/services/FileService.js +64 -7
  19. package/dist/esm/services/PaymentService.js +64 -7
  20. package/dist/esm/services/PlanService.js +64 -7
  21. package/dist/esm/services/ProjectService.js +72 -8
  22. package/dist/esm/services/PullRequestService.js +64 -7
  23. package/dist/esm/services/ScreenshotService.js +64 -7
  24. package/dist/esm/services/SubscriptionService.js +64 -7
  25. package/dist/esm/services/TrackingService.js +18321 -0
  26. package/dist/esm/services/index.js +20667 -5882
  27. package/dist/esm/utils/CollabClient.js +18 -7
  28. package/dist/esm/utils/changePreprocessor.js +8 -1
  29. package/dist/esm/utils/services.js +27 -3
  30. package/dist/node/config/environment.js +18 -7
  31. package/dist/node/index.js +42 -16
  32. package/dist/node/services/BaseService.js +46 -0
  33. package/dist/node/services/DnsService.js +6 -5
  34. package/dist/node/services/TrackingService.js +632 -0
  35. package/dist/node/services/index.js +5 -5
  36. package/dist/node/utils/changePreprocessor.js +8 -1
  37. package/dist/node/utils/services.js +27 -3
  38. package/package.json +8 -6
  39. package/src/config/environment.js +19 -11
  40. package/src/index.js +44 -14
  41. package/src/services/BaseService.js +43 -0
  42. package/src/services/DnsService.js +5 -5
  43. package/src/services/TrackingService.js +853 -0
  44. package/src/services/index.js +6 -5
  45. package/src/utils/changePreprocessor.js +25 -1
  46. package/src/utils/services.js +28 -4
  47. package/dist/cjs/services/CoreService.js +0 -2818
  48. package/dist/esm/services/CoreService.js +0 -3513
  49. package/dist/node/services/CoreService.js +0 -2789
  50. package/src/services/CoreService.js +0 -3208
@@ -222,8 +222,6 @@ const SERVICE_METHODS = {
222
222
  suspendUser: "admin",
223
223
  promoteToAdmin: "admin",
224
224
  demoteFromAdmin: "admin",
225
- // Utility methods
226
- getHealthStatus: "core",
227
225
  // Screenshot methods
228
226
  createScreenshotProject: "screenshot",
229
227
  getProjectScreenshots: "screenshot",
@@ -236,7 +234,33 @@ const SERVICE_METHODS = {
236
234
  getComponentScreenshot: "screenshot",
237
235
  getScreenshotByKey: "screenshot",
238
236
  getQueueStatistics: "screenshot",
239
- refreshThumbnail: "screenshot"
237
+ refreshThumbnail: "screenshot",
238
+ // Tracking methods
239
+ configureTracking: "tracking",
240
+ trackEvent: "tracking",
241
+ trackError: "tracking",
242
+ captureException: "tracking",
243
+ logMessage: "tracking",
244
+ logDebug: "tracking",
245
+ logInfo: "tracking",
246
+ logWarning: "tracking",
247
+ logWarn: "tracking",
248
+ logErrorMessage: "tracking",
249
+ logError: "tracking",
250
+ addBreadcrumb: "tracking",
251
+ trackMeasurement: "tracking",
252
+ trackView: "tracking",
253
+ setUser: "tracking",
254
+ clearUser: "tracking",
255
+ setSession: "tracking",
256
+ clearSession: "tracking",
257
+ setGlobalAttributes: "tracking",
258
+ setGlobalAttribute: "tracking",
259
+ removeGlobalAttribute: "tracking",
260
+ flushQueue: "tracking",
261
+ getClient: "tracking",
262
+ isEnabled: "tracking",
263
+ isInitialized: "tracking"
240
264
  };
241
265
  export {
242
266
  SERVICE_METHODS
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@symbo.ls/sdk",
3
- "version": "2.32.11",
3
+ "version": "2.32.13",
4
4
  "type": "module",
5
5
  "main": "dist/esm/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -46,10 +46,12 @@
46
46
  "test:user": "cross-env NODE_ENV=$NODE_ENV npx tape integration-tests/index.js integration-tests/user/*.test.js | tap-spec"
47
47
  },
48
48
  "dependencies": {
49
- "@domql/element": "^2.32.11",
50
- "@domql/utils": "^2.32.11",
51
- "@symbo.ls/router": "^2.32.11",
52
- "@symbo.ls/socket": "^2.32.11",
49
+ "@domql/element": "^2.32.13",
50
+ "@domql/utils": "^2.32.13",
51
+ "@grafana/faro-web-sdk": "^1.19.0",
52
+ "@grafana/faro-web-tracing": "^1.19.0",
53
+ "@symbo.ls/router": "^2.32.13",
54
+ "@symbo.ls/socket": "^2.32.13",
53
55
  "acorn": "^8.14.0",
54
56
  "acorn-walk": "^8.3.4",
55
57
  "dexie": "^4.0.11",
@@ -71,5 +73,5 @@
71
73
  "tap-spec": "^5.0.0",
72
74
  "tape": "^5.9.0"
73
75
  },
74
- "gitHead": "45bd289bc2a652a700941e7743f1066ac5312430"
76
+ "gitHead": "c9fa0cbf09841fd8c586d525a1f4e96f3ba11569"
75
77
  }
@@ -10,7 +10,9 @@ const CONFIG = {
10
10
  // Feature toggles that apply across all environments by default
11
11
  features: {
12
12
  newUserOnboarding: true,
13
- betaFeatures: false
13
+ betaFeatures: false,
14
+ // Tracking is enabled by default unless overridden per environment
15
+ trackingEnabled: true
14
16
  }
15
17
  },
16
18
 
@@ -24,12 +26,16 @@ const CONFIG = {
24
26
  basedProject: 'platform-v2-sm', // For based api
25
27
  basedOrg: 'symbols', // For based api
26
28
  githubClientId: 'Ov23liAFrsR0StbAO6PO', // For github api
27
- grafanaUrl:
28
- 'https://faro-collector-prod-us-east-0.grafana.net/collect/aef64330db80bdfeaac084317bf72f99', // For grafana tracing
29
- grafanaAppName: 'Localhost Symbols',
29
+ grafanaUrl: '', // For grafana tracing
30
+ grafanaAppName: 'Symbols Localhost',
30
31
  // Environment-specific feature toggles (override common)
31
32
  features: {
32
- betaFeatures: true // Enable beta features in local dev
33
+ // Disable tracking by default on localhost/dev machines
34
+ trackingEnabled: false,
35
+ // Enable beta features in local dev
36
+ betaFeatures: true,
37
+ // Preserve common defaults explicitly for local
38
+ newUserOnboarding: true
33
39
  },
34
40
  typesenseCollectionName: 'docs',
35
41
  typesenseApiKey: 'vZya3L2zpq8L6iI5WWMUZJZABvT63VDb',
@@ -57,8 +63,7 @@ const CONFIG = {
57
63
  basedProject: 'platform-v2-sm',
58
64
  basedOrg: 'symbols',
59
65
  githubClientId: 'Ov23liHxyWFBxS8f1gnF',
60
- grafanaUrl:
61
- 'https://faro-collector-prod-us-east-0.grafana.net/collect/7a3ba473cee2025c68513667024316b8', // For grafana tracing
66
+ grafanaUrl: '', // For grafana tracing
62
67
  grafanaAppName: 'Symbols Test',
63
68
  typesenseCollectionName: 'docs',
64
69
  typesenseApiKey: 'awmcVpbWqZi9IUgmvslp1C5LKDU8tMjA',
@@ -70,8 +75,7 @@ const CONFIG = {
70
75
  socketUrl: 'https://upcoming.api.symbols.app',
71
76
  apiUrl: 'https://upcoming.api.symbols.app',
72
77
  githubClientId: 'Ov23liWF7NvdZ056RV5J',
73
- grafanaUrl:
74
- 'https://faro-collector-prod-us-east-0.grafana.net/collect/7a3ba473cee2025c68513667024316b8', // For grafana tracing
78
+ grafanaUrl: '', // For grafana tracing
75
79
  grafanaAppName: 'Symbols Upcoming',
76
80
  typesenseCollectionName: 'docs',
77
81
  typesenseApiKey: 'awmcVpbWqZi9IUgmvslp1C5LKDU8tMjA',
@@ -86,8 +90,7 @@ const CONFIG = {
86
90
  basedProject: 'platform-v2-sm',
87
91
  basedOrg: 'symbols',
88
92
  githubClientId: 'Ov23ligwZDQVD0VfuWNa',
89
- grafanaUrl:
90
- 'https://faro-collector-prod-us-east-0.grafana.net/collect/7a3ba473cee2025c68513667024316b8', // For grafana tracing
93
+ grafanaUrl: '', // For grafana tracing
91
94
  grafanaAppName: 'Symbols Staging',
92
95
  typesenseCollectionName: 'docs',
93
96
  typesenseApiKey: 'awmcVpbWqZi9IUgmvslp1C5LKDU8tMjA',
@@ -135,6 +138,11 @@ export const getConfig = () => {
135
138
  // Create the final config with environment variable overrides
136
139
  const finalConfig = {
137
140
  ...envConfig,
141
+ // Deep-merge feature flags so env-specific overrides don't drop common defaults
142
+ features: {
143
+ ...(CONFIG.common.features || {}),
144
+ ...((CONFIG[env] && CONFIG[env].features) || {})
145
+ },
138
146
  socketUrl: process.env.SYMBOLS_APP_SOCKET_URL || envConfig.socketUrl,
139
147
  apiUrl: process.env.SYMBOLS_APP_API_URL || envConfig.apiUrl,
140
148
  basedEnv: process.env.SYMBOLS_APP_BASED_ENV || envConfig.basedEnv,
package/src/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  createAuthService,
3
- createCoreService,
4
3
  createCollabService,
5
4
  createProjectService,
6
5
  createPlanService,
@@ -11,13 +10,24 @@ import {
11
10
  createPullRequestService,
12
11
  createAdminService,
13
12
  createSubscriptionService,
14
- createScreenshotService
13
+ createScreenshotService,
14
+ createTrackingService
15
15
  } from './services/index.js'
16
16
 
17
17
  import { SERVICE_METHODS } from './utils/services.js'
18
18
  import environment from './config/environment.js'
19
19
  import { rootBus } from './state/rootEventBus.js'
20
20
 
21
+ const isBrowserEnvironment = () => typeof window !== 'undefined'
22
+
23
+ export const isLocalhost = () => {
24
+ if (!isBrowserEnvironment()) {
25
+ return false
26
+ }
27
+ const host = window.location && window.location.hostname
28
+ return host === 'localhost' || host === '127.0.0.1' || host === '::1' || host === '' || !host
29
+ }
30
+
21
31
  export class SDK {
22
32
  constructor(options = {}) {
23
33
  this._services = new Map()
@@ -48,13 +58,6 @@ export class SDK {
48
58
  options: this._options
49
59
  })
50
60
  ),
51
- this._initService(
52
- 'core',
53
- createCoreService({
54
- context: this._context,
55
- options: this._options
56
- })
57
- ),
58
61
  this._initService(
59
62
  'collab',
60
63
  createCollabService({
@@ -132,6 +135,13 @@ export class SDK {
132
135
  context: this._context,
133
136
  options: this._options
134
137
  })
138
+ ),
139
+ this._initService(
140
+ 'tracking',
141
+ createTrackingService({
142
+ context: this._context,
143
+ options: this._options
144
+ })
135
145
  )
136
146
  ])
137
147
 
@@ -156,16 +166,36 @@ export class SDK {
156
166
  }
157
167
 
158
168
  _validateOptions(options) {
169
+ const onLocalhost = isLocalhost()
170
+ const hasGrafanaUrl = Boolean(environment.grafanaUrl)
159
171
  const defaults = {
160
172
  useNewServices: true, // Use new service implementations by default
161
173
  apiUrl: environment.apiUrl,
162
174
  socketUrl: environment.socketUrl,
163
175
  timeout: 30000,
164
176
  retryAttempts: 3,
165
- debug: false
177
+ debug: false,
178
+ tracking: {
179
+ // Force-disabled on localhost or when no Grafana URL is configured
180
+ enabled: onLocalhost ? false : (hasGrafanaUrl ? environment.features.trackingEnabled : false),
181
+ }
182
+ }
183
+
184
+ const merged = {
185
+ ...defaults,
186
+ ...options,
187
+ tracking: {
188
+ ...defaults.tracking,
189
+ ...(options.tracking || {})
190
+ }
166
191
  }
167
192
 
168
- return { ...defaults, ...options }
193
+ // Enforce disabled tracking on localhost or when no Grafana URL configured, even if overridden
194
+ if (onLocalhost || !hasGrafanaUrl) {
195
+ merged.tracking.enabled = false
196
+ }
197
+
198
+ return merged
169
199
  }
170
200
 
171
201
  // Get service instance
@@ -179,7 +209,7 @@ export class SDK {
179
209
  // Update context
180
210
  updateContext(newContext) {
181
211
  // Do not persist authToken in SDK context; TokenManager is the source of truth
182
- const { authToken, ...sanitized } = newContext || {}
212
+ const { ...sanitized } = newContext || {}
183
213
 
184
214
  this._context = {
185
215
  ...this._context,
@@ -265,7 +295,6 @@ export default SDK
265
295
  // Export services for direct usage
266
296
  export {
267
297
  createAuthService,
268
- createCoreService,
269
298
  createCollabService,
270
299
  createProjectService,
271
300
  createPlanService,
@@ -275,7 +304,8 @@ export {
275
304
  createBranchService,
276
305
  createPullRequestService,
277
306
  createAdminService,
278
- createSubscriptionService
307
+ createSubscriptionService,
308
+ createTrackingService
279
309
  } from './services/index.js'
280
310
 
281
311
  // Export environment configuration
@@ -71,6 +71,34 @@ export class BaseService {
71
71
  this._error = error
72
72
  }
73
73
 
74
+ _getTrackingService () {
75
+ const services = this._context?.services
76
+ const tracking = services?.tracking
77
+ if (!tracking || typeof tracking.trackError !== 'function') {return null}
78
+ return tracking
79
+ }
80
+
81
+ _shouldTrackErrors () {
82
+ const name = this?.constructor?.name
83
+ return name !== 'TrackingService'
84
+ }
85
+
86
+ _trackServiceError (error, details = {}) {
87
+ if (!this._shouldTrackErrors()) {return}
88
+ try {
89
+ const tracking = this._getTrackingService()
90
+ if (!tracking) {return}
91
+ const context = {
92
+ service: this?.constructor?.name || 'UnknownService',
93
+ apiUrl: this._apiUrl || null,
94
+ ...details
95
+ }
96
+ tracking.trackError(error instanceof Error ? error : new Error(String(error)), context)
97
+ } catch {
98
+ // Do not let tracking failures affect service flow
99
+ }
100
+ }
101
+
74
102
  _requireAuth () {
75
103
  if (!this._context.authToken) {
76
104
  throw new Error('Authentication required')
@@ -132,11 +160,26 @@ export class BaseService {
132
160
  } catch {
133
161
  // Use default error message
134
162
  }
163
+ // Track HTTP error before throwing
164
+ this._trackServiceError(
165
+ new Error(error.message || error.error || `HTTP ${response.status}: ${response.statusText}`),
166
+ {
167
+ endpoint,
168
+ methodName: options.methodName,
169
+ status: response.status,
170
+ statusText: response.statusText
171
+ }
172
+ )
135
173
  throw new Error(error.message || error.error || 'Request failed', { cause: error })
136
174
  }
137
175
 
138
176
  return response.status === 204 ? null : response.json()
139
177
  } catch (error) {
178
+ // Track network/other request errors before rethrowing
179
+ this._trackServiceError(error, {
180
+ endpoint,
181
+ methodName: options.methodName
182
+ })
140
183
  throw new Error(`Request failed: ${error.message}`, { cause: error })
141
184
  }
142
185
  }
@@ -57,7 +57,7 @@ export class DnsService extends BaseService {
57
57
  }
58
58
  throw new Error(response.message)
59
59
  } catch (error) {
60
- throw new Error(`Failed to get custom host: ${error.message}`)
60
+ throw new Error(`Failed to get custom host: ${error.message}`, { cause: error })
61
61
  }
62
62
  }
63
63
 
@@ -136,7 +136,7 @@ export class DnsService extends BaseService {
136
136
  throw new Error(response.message)
137
137
  } catch (error) {
138
138
  throw new Error(
139
- `Failed to update project custom domains: ${error.message}`
139
+ `Failed to update project custom domains: ${error.message}`, { cause: error }
140
140
  )
141
141
  }
142
142
  }
@@ -325,7 +325,7 @@ export class DnsService extends BaseService {
325
325
  needsVerification: false
326
326
  }
327
327
  } catch (error) {
328
- throw new Error(`Failed to verify domain ownership: ${error.message}`)
328
+ throw new Error(`Failed to verify domain ownership: ${error.message}`, { cause: error })
329
329
  }
330
330
  }
331
331
 
@@ -348,7 +348,7 @@ export class DnsService extends BaseService {
348
348
  }
349
349
  throw new Error(response.message)
350
350
  } catch (error) {
351
- throw new Error(`Failed to get project domains: ${error.message}`)
351
+ throw new Error(`Failed to get project domains: ${error.message}`, { cause: error })
352
352
  }
353
353
  }
354
354
 
@@ -374,7 +374,7 @@ export class DnsService extends BaseService {
374
374
  }
375
375
  throw new Error(response.message)
376
376
  } catch (error) {
377
- throw new Error(`Failed to remove project custom domain: ${error.message}`)
377
+ throw new Error(`Failed to remove project custom domain: ${error.message}`, { cause: error })
378
378
  }
379
379
  }
380
380