@symbo.ls/sdk 3.2.3 → 3.2.6

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 (183) hide show
  1. package/README.md +141 -0
  2. package/dist/cjs/config/environment.js +94 -10
  3. package/dist/cjs/index.js +152 -12
  4. package/dist/cjs/services/AdminService.js +351 -0
  5. package/dist/cjs/services/AuthService.js +738 -305
  6. package/dist/cjs/services/BaseService.js +158 -6
  7. package/dist/cjs/services/BranchService.js +484 -0
  8. package/dist/cjs/services/CollabService.js +439 -116
  9. package/dist/cjs/services/DnsService.js +340 -0
  10. package/dist/cjs/services/FeatureFlagService.js +175 -0
  11. package/dist/cjs/services/FileService.js +201 -0
  12. package/dist/cjs/services/IntegrationService.js +538 -0
  13. package/dist/cjs/services/MetricsService.js +62 -0
  14. package/dist/cjs/services/PaymentService.js +271 -0
  15. package/dist/cjs/services/PlanService.js +426 -0
  16. package/dist/cjs/services/ProjectService.js +1207 -0
  17. package/dist/cjs/services/PullRequestService.js +503 -0
  18. package/dist/cjs/services/ScreenshotService.js +304 -0
  19. package/dist/cjs/services/SubscriptionService.js +396 -0
  20. package/dist/cjs/services/TrackingService.js +661 -0
  21. package/dist/cjs/services/WaitlistService.js +148 -0
  22. package/dist/cjs/services/index.js +60 -4
  23. package/dist/cjs/state/RootStateManager.js +2 -23
  24. package/dist/cjs/state/rootEventBus.js +9 -0
  25. package/dist/cjs/utils/CollabClient.js +78 -12
  26. package/dist/cjs/utils/TokenManager.js +16 -3
  27. package/dist/cjs/utils/changePreprocessor.js +199 -0
  28. package/dist/cjs/utils/jsonDiff.js +46 -4
  29. package/dist/cjs/utils/ordering.js +309 -0
  30. package/dist/cjs/utils/services.js +285 -128
  31. package/dist/cjs/utils/validation.js +0 -3
  32. package/dist/esm/config/environment.js +94 -10
  33. package/dist/esm/index.js +47862 -18248
  34. package/dist/esm/services/AdminService.js +1132 -0
  35. package/dist/esm/services/AuthService.js +1493 -386
  36. package/dist/esm/services/BaseService.js +757 -6
  37. package/dist/esm/services/BranchService.js +1265 -0
  38. package/dist/esm/services/CollabService.js +24956 -16089
  39. package/dist/esm/services/DnsService.js +1121 -0
  40. package/dist/esm/services/FeatureFlagService.js +956 -0
  41. package/dist/esm/services/FileService.js +982 -0
  42. package/dist/esm/services/IntegrationService.js +1319 -0
  43. package/dist/esm/services/MetricsService.js +843 -0
  44. package/dist/esm/services/PaymentService.js +1052 -0
  45. package/dist/esm/services/PlanService.js +1207 -0
  46. package/dist/esm/services/ProjectService.js +2526 -0
  47. package/dist/esm/services/PullRequestService.js +1284 -0
  48. package/dist/esm/services/ScreenshotService.js +1085 -0
  49. package/dist/esm/services/SubscriptionService.js +1177 -0
  50. package/dist/esm/services/TrackingService.js +18454 -0
  51. package/dist/esm/services/WaitlistService.js +929 -0
  52. package/dist/esm/services/index.js +47373 -18027
  53. package/dist/esm/state/RootStateManager.js +11 -23
  54. package/dist/esm/state/rootEventBus.js +9 -0
  55. package/dist/esm/utils/CollabClient.js +17526 -16120
  56. package/dist/esm/utils/TokenManager.js +16 -3
  57. package/dist/esm/utils/changePreprocessor.js +542 -0
  58. package/dist/esm/utils/jsonDiff.js +958 -43
  59. package/dist/esm/utils/ordering.js +291 -0
  60. package/dist/esm/utils/services.js +285 -128
  61. package/dist/esm/utils/validation.js +116 -50
  62. package/dist/node/config/environment.js +94 -10
  63. package/dist/node/index.js +183 -16
  64. package/dist/node/services/AdminService.js +332 -0
  65. package/dist/node/services/AuthService.js +742 -310
  66. package/dist/node/services/BaseService.js +148 -6
  67. package/dist/node/services/BranchService.js +465 -0
  68. package/dist/node/services/CollabService.js +439 -116
  69. package/dist/node/services/DnsService.js +321 -0
  70. package/dist/node/services/FeatureFlagService.js +156 -0
  71. package/dist/node/services/FileService.js +182 -0
  72. package/dist/node/services/IntegrationService.js +519 -0
  73. package/dist/node/services/MetricsService.js +43 -0
  74. package/dist/node/services/PaymentService.js +252 -0
  75. package/dist/node/services/PlanService.js +407 -0
  76. package/dist/node/services/ProjectService.js +1188 -0
  77. package/dist/node/services/PullRequestService.js +484 -0
  78. package/dist/node/services/ScreenshotService.js +285 -0
  79. package/dist/node/services/SubscriptionService.js +377 -0
  80. package/dist/node/services/TrackingService.js +632 -0
  81. package/dist/node/services/WaitlistService.js +129 -0
  82. package/dist/node/services/index.js +60 -4
  83. package/dist/node/state/RootStateManager.js +2 -23
  84. package/dist/node/state/rootEventBus.js +9 -0
  85. package/dist/node/utils/CollabClient.js +77 -11
  86. package/dist/node/utils/TokenManager.js +16 -3
  87. package/dist/node/utils/changePreprocessor.js +180 -0
  88. package/dist/node/utils/jsonDiff.js +46 -4
  89. package/dist/node/utils/ordering.js +290 -0
  90. package/dist/node/utils/services.js +285 -128
  91. package/dist/node/utils/validation.js +0 -3
  92. package/package.json +30 -18
  93. package/src/config/environment.js +95 -10
  94. package/src/index.js +190 -23
  95. package/src/services/AdminService.js +374 -0
  96. package/src/services/AuthService.js +874 -328
  97. package/src/services/BaseService.js +166 -6
  98. package/src/services/BranchService.js +536 -0
  99. package/src/services/CollabService.js +557 -148
  100. package/src/services/DnsService.js +366 -0
  101. package/src/services/FeatureFlagService.js +174 -0
  102. package/src/services/FileService.js +213 -0
  103. package/src/services/IntegrationService.js +548 -0
  104. package/src/services/MetricsService.js +40 -0
  105. package/src/services/PaymentService.js +287 -0
  106. package/src/services/PlanService.js +468 -0
  107. package/src/services/ProjectService.js +1366 -0
  108. package/src/services/PullRequestService.js +537 -0
  109. package/src/services/ScreenshotService.js +258 -0
  110. package/src/services/SubscriptionService.js +425 -0
  111. package/src/services/TrackingService.js +853 -0
  112. package/src/services/WaitlistService.js +130 -0
  113. package/src/services/index.js +79 -5
  114. package/src/services/tests/BranchService/createBranch.test.js +153 -0
  115. package/src/services/tests/BranchService/deleteBranch.test.js +173 -0
  116. package/src/services/tests/BranchService/getBranchChanges.test.js +146 -0
  117. package/src/services/tests/BranchService/listBranches.test.js +87 -0
  118. package/src/services/tests/BranchService/mergeBranch.test.js +210 -0
  119. package/src/services/tests/BranchService/publishVersion.test.js +183 -0
  120. package/src/services/tests/BranchService/renameBranch.test.js +240 -0
  121. package/src/services/tests/BranchService/resetBranch.test.js +152 -0
  122. package/src/services/tests/FeatureFlagService/adminFeatureFlags.test.js +67 -0
  123. package/src/services/tests/FeatureFlagService/getFeatureFlags.test.js +75 -0
  124. package/src/services/tests/FileService/createFileFormData.test.js +74 -0
  125. package/src/services/tests/FileService/getFileUrl.test.js +69 -0
  126. package/src/services/tests/FileService/updateProjectIcon.test.js +109 -0
  127. package/src/services/tests/FileService/uploadDocument.test.js +36 -0
  128. package/src/services/tests/FileService/uploadFile.test.js +78 -0
  129. package/src/services/tests/FileService/uploadFileWithValidation.test.js +114 -0
  130. package/src/services/tests/FileService/uploadImage.test.js +36 -0
  131. package/src/services/tests/FileService/uploadMultipleFiles.test.js +111 -0
  132. package/src/services/tests/FileService/validateFile.test.js +63 -0
  133. package/src/services/tests/PlanService/createPlan.test.js +104 -0
  134. package/src/services/tests/PlanService/createPlanWithValidation.test.js +523 -0
  135. package/src/services/tests/PlanService/deletePlan.test.js +92 -0
  136. package/src/services/tests/PlanService/getActivePlans.test.js +123 -0
  137. package/src/services/tests/PlanService/getAdminPlans.test.js +84 -0
  138. package/src/services/tests/PlanService/getPlan.test.js +50 -0
  139. package/src/services/tests/PlanService/getPlanByKey.test.js +109 -0
  140. package/src/services/tests/PlanService/getPlanWithValidation.test.js +85 -0
  141. package/src/services/tests/PlanService/getPlans.test.js +53 -0
  142. package/src/services/tests/PlanService/getPlansByPriceRange.test.js +109 -0
  143. package/src/services/tests/PlanService/getPlansWithValidation.test.js +48 -0
  144. package/src/services/tests/PlanService/initializePlans.test.js +75 -0
  145. package/src/services/tests/PlanService/updatePlan.test.js +111 -0
  146. package/src/services/tests/PlanService/updatePlanWithValidation.test.js +556 -0
  147. package/src/state/RootStateManager.js +37 -32
  148. package/src/state/rootEventBus.js +19 -0
  149. package/src/utils/CollabClient.js +99 -12
  150. package/src/utils/TokenManager.js +20 -3
  151. package/src/utils/changePreprocessor.js +239 -0
  152. package/src/utils/jsonDiff.js +40 -5
  153. package/src/utils/ordering.js +271 -0
  154. package/src/utils/services.js +306 -139
  155. package/src/utils/validation.js +0 -3
  156. package/dist/cjs/services/AIService.js +0 -155
  157. package/dist/cjs/services/BasedService.js +0 -1185
  158. package/dist/cjs/services/CoreService.js +0 -2295
  159. package/dist/cjs/services/SocketService.js +0 -309
  160. package/dist/cjs/services/SymstoryService.js +0 -571
  161. package/dist/cjs/utils/basedQuerys.js +0 -181
  162. package/dist/cjs/utils/symstoryClient.js +0 -259
  163. package/dist/esm/services/AIService.js +0 -185
  164. package/dist/esm/services/BasedService.js +0 -5262
  165. package/dist/esm/services/CoreService.js +0 -2827
  166. package/dist/esm/services/SocketService.js +0 -456
  167. package/dist/esm/services/SymstoryService.js +0 -7025
  168. package/dist/esm/utils/basedQuerys.js +0 -163
  169. package/dist/esm/utils/symstoryClient.js +0 -354
  170. package/dist/node/services/AIService.js +0 -136
  171. package/dist/node/services/BasedService.js +0 -1156
  172. package/dist/node/services/CoreService.js +0 -2266
  173. package/dist/node/services/SocketService.js +0 -280
  174. package/dist/node/services/SymstoryService.js +0 -542
  175. package/dist/node/utils/basedQuerys.js +0 -162
  176. package/dist/node/utils/symstoryClient.js +0 -230
  177. package/src/services/AIService.js +0 -150
  178. package/src/services/BasedService.js +0 -1302
  179. package/src/services/CoreService.js +0 -2548
  180. package/src/services/SocketService.js +0 -336
  181. package/src/services/SymstoryService.js +0 -649
  182. package/src/utils/basedQuerys.js +0 -164
  183. package/src/utils/symstoryClient.js +0 -252
package/README.md CHANGED
@@ -377,6 +377,147 @@ const ai = sdk.getService('ai')
377
377
  const response = await ai.prompt(query, options)
378
378
  ```
379
379
 
380
+ ### Tracking Service (Grafana Faro)
381
+ ```javascript
382
+ // 1) Initialize SDK with tracking config (early in app startup)
383
+ const sdk = new SDK({
384
+ useNewServices: true,
385
+ apiUrl: 'https://api.symbols.app',
386
+ // Tracking configuration mirrors TrackingService options
387
+ tracking: {
388
+ url: 'https://<your-faro-receiver-url>', // FO ingest/collector URL
389
+ appName: 'Symbols Platform',
390
+ environment: 'development', // 'production' | 'staging' | 'testing' | 'development'
391
+ appVersion: '1.0.0',
392
+ sessionTracking: true,
393
+ enableTracing: true, // adds browser tracing when available
394
+ globalAttributes: { region: 'us-east-1' }
395
+ }
396
+ })
397
+ await sdk.initialize()
398
+
399
+ // 2) Get the tracking service
400
+ const tracking = sdk.getService('tracking')
401
+
402
+ // 3) Send signals
403
+ tracking.trackEvent('purchase', { amount: 42, currency: 'USD' })
404
+ tracking.trackMeasurement('cart_value', { value: 42 })
405
+ tracking.logError('checkout failed', { step: 'payment' })
406
+ tracking.trackView('Checkout', { stage: 'payment' })
407
+ tracking.setUser({ id: 'u_123', email: 'user@example.com' })
408
+ ```
409
+
410
+ #### Configuration
411
+ Provide these under `tracking` when creating the `SDK` (or later via `tracking.configureTracking()`):
412
+
413
+ - `url` string: Frontend Observability/Faro ingestion URL. If omitted and no custom transports are provided, tracking is disabled.
414
+ - `appName` string: Logical application name used in Grafana dashboards.
415
+ - `appVersion` string: App version shown in Grafana.
416
+ - `environment` string: One of your environments; default resolves from runtime (`production`, `staging`, `testing`, `development`).
417
+ - `sessionTracking` boolean: Enable Faro session tracking. Default: `true`.
418
+ - `enableTracing` boolean: Enable web tracing and send to Tempo (if collector configured). Default: `true`.
419
+ - `globalAttributes` object: Key/values merged into every signal.
420
+ - `user` object: Initial user attributes.
421
+ - `maxQueueSize` number: Max queued calls before client setup. Default: `100`.
422
+ - `isolate` boolean: Create an isolated Faro instance.
423
+ - `transports` array | `transport` any: Custom transports (advanced).
424
+ - `instrumentations` array | `instrumentationsFactory(runtime) => Promise<array>` | `webInstrumentationOptions` object: Control Faro web instrumentations.
425
+
426
+ Note:
427
+ - Tracking is automatically disabled in non‑browser environments.
428
+ - Calls are queued until the Faro client is ready. For specific calls, pass `{ queue: false }` to skip queuing.
429
+
430
+ #### Method reference
431
+ The following methods are available via `sdk.getService('tracking')` and map to `utils/services.js`:
432
+
433
+ - `configureTracking(trackingOptions)` / `configure(trackingOptions)`: Merge/override runtime tracking options (supports all config keys above).
434
+ - `trackEvent(name, attributes?, options?)`
435
+ - `name` string (required)
436
+ - `attributes` object merged with global attributes
437
+ - `options` object:
438
+ - `domain` string | null
439
+ - `queue` boolean (whether to queue if client not ready)
440
+ - Additional transport options are forwarded to Faro
441
+ - Example:
442
+ ```javascript
443
+ tracking.trackEvent('signup_attempt', { method: 'email' }, { domain: 'auth' })
444
+ ```
445
+ - `trackError(error, options?)` / `captureException(error, options?)`
446
+ - `error` Error | string
447
+ - `options` can be:
448
+ - object with Faro error options (`context`, `type`, `stackFrames`, `skipDedupe`, `timestampOverwriteMs`, etc.)
449
+ - or a plain context object (shorthand)
450
+ - `queue` boolean supported
451
+ - Example:
452
+ ```javascript
453
+ tracking.trackError(new Error('Login failed'), { context: { screen: 'Login' } })
454
+ ```
455
+ - `logMessage(message, level='info', context?)`
456
+ - Convenience wrappers: `logDebug`, `logInfo`, `logWarning`/`logWarn`, `logErrorMessage`/`logError`
457
+ - `message` string | string[]
458
+ - `context` object merged with global attributes
459
+ - Example:
460
+ ```javascript
461
+ tracking.logWarning('Slow response', { route: '/checkout', ttfbMs: 900 })
462
+ ```
463
+ - `addBreadcrumb(message, attributes?)`
464
+ - Adds a low‑cost breadcrumb via `trackEvent('breadcrumb', ...)`
465
+ - Example:
466
+ ```javascript
467
+ tracking.addBreadcrumb('Open modal', { id: 'planLimits' })
468
+ ```
469
+ - `trackMeasurement(type, values, options?)`
470
+ - `type` string (required)
471
+ - `values` object | number. If number, it becomes `{ value: <number> }`.
472
+ - `options`:
473
+ - `attributes` object (merged into payload.attributes)
474
+ - `context` object (transport context)
475
+ - `queue` boolean
476
+ - Any additional transport options
477
+ - Example:
478
+ ```javascript
479
+ tracking.trackMeasurement('cart_value', 42, { context: { currency: 'USD' } })
480
+ ```
481
+ - `trackView(name, attributes?)`
482
+ - Sets the current view/page in Faro
483
+ - Example:
484
+ ```javascript
485
+ tracking.trackView('Dashboard', { section: 'Analytics' })
486
+ ```
487
+ - `setUser(user, options?)` / `clearUser()`
488
+ - `user` object with arbitrary attributes; supports `{ queue: boolean }`
489
+ - Example:
490
+ ```javascript
491
+ tracking.setUser({ id: 'u_123', role: 'admin' })
492
+ ```
493
+ - `setSession(session, options?)` / `clearSession()`
494
+ - Attach custom session data; supports `{ queue: boolean, ...sessionOptions }`
495
+ - `setGlobalAttributes(attributes)` / `setGlobalAttribute(key, value)` / `removeGlobalAttribute(key)`
496
+ - Manage the global attributes merged into every signal
497
+ - `flushQueue()`
498
+ - Immediately runs all queued calls (no‑op if client not ready)
499
+ - `getClient()`
500
+ - Returns the underlying Faro client (or `null` if not ready)
501
+ - `isEnabled()` / `isInitialized()`
502
+ - Status helpers
503
+
504
+ #### Example: auth error tracking from services
505
+ The SDK’s services automatically send errors to tracking:
506
+ ```javascript
507
+ try {
508
+ await auth.login(email, password)
509
+ } catch (error) {
510
+ // BaseService forwards details to tracking.trackError(...)
511
+ }
512
+ ```
513
+
514
+ #### Visualizing in Grafana
515
+ - Use the Frontend Observability (Faro) data source and pick:
516
+ - Service = your `appName`
517
+ - Environment = your `environment`
518
+ - Panels for page loads and Web Vitals require web instrumentations and real page traffic.
519
+ - If self‑hosting with a Faro collector → Loki/Tempo, ensure the FO app is installed and the dashboard uses the FO data source; otherwise create custom panels with LogQL over Loki.
520
+
380
521
  ## Error Handling
381
522
  ```javascript
382
523
  try {
@@ -30,7 +30,9 @@ const CONFIG = {
30
30
  // Feature toggles that apply across all environments by default
31
31
  features: {
32
32
  newUserOnboarding: true,
33
- betaFeatures: false
33
+ betaFeatures: false,
34
+ // Tracking is enabled by default unless overridden per environment
35
+ trackingEnabled: true
34
36
  }
35
37
  },
36
38
  // Environment-specific configurations
@@ -46,18 +48,38 @@ const CONFIG = {
46
48
  // For based api
47
49
  basedOrg: "symbols",
48
50
  // For based api
49
- githubClientId: "Ov23liHxyWFBxS8f1gnF",
51
+ githubClientId: "Ov23liAFrsR0StbAO6PO",
50
52
  // For github api
53
+ grafanaUrl: "",
54
+ // For grafana tracing
55
+ grafanaAppName: "Symbols Localhost",
51
56
  // Environment-specific feature toggles (override common)
52
57
  features: {
53
- betaFeatures: true
58
+ // Disable tracking by default on localhost/dev machines
59
+ trackingEnabled: false,
54
60
  // Enable beta features in local dev
55
- }
61
+ betaFeatures: true,
62
+ // Preserve common defaults explicitly for local
63
+ newUserOnboarding: true
64
+ },
65
+ typesenseCollectionName: "docs",
66
+ typesenseApiKey: "vZya3L2zpq8L6iI5WWMUZJZABvT63VDb",
67
+ typesenseHost: "localhost",
68
+ typesensePort: "8108",
69
+ typesenseProtocol: "http"
56
70
  },
57
71
  development: {
58
72
  socketUrl: "https://dev.api.symbols.app",
59
73
  apiUrl: "https://dev.api.symbols.app",
60
- githubClientId: "Ov23liHxyWFBxS8f1gnF"
74
+ githubClientId: "Ov23liHxyWFBxS8f1gnF",
75
+ grafanaUrl: "https://faro-collector-prod-us-east-0.grafana.net/collect/7a3ba473cee2025c68513667024316b8",
76
+ // For grafana tracing
77
+ grafanaAppName: "Symbols Dev",
78
+ typesenseCollectionName: "docs",
79
+ typesenseApiKey: "awmcVpbWqZi9IUgmvslp1C5LKDU8tMjA",
80
+ typesenseHost: "tl2qpnwxev4cjm36p-1.a1.typesense.net",
81
+ typesensePort: "443",
82
+ typesenseProtocol: "https"
61
83
  },
62
84
  testing: {
63
85
  socketUrl: "https://test.api.symbols.app",
@@ -65,12 +87,28 @@ const CONFIG = {
65
87
  basedEnv: "testing",
66
88
  basedProject: "platform-v2-sm",
67
89
  basedOrg: "symbols",
68
- githubClientId: "Ov23liHxyWFBxS8f1gnF"
90
+ githubClientId: "Ov23liHxyWFBxS8f1gnF",
91
+ grafanaUrl: "",
92
+ // For grafana tracing
93
+ grafanaAppName: "Symbols Test",
94
+ typesenseCollectionName: "docs",
95
+ typesenseApiKey: "awmcVpbWqZi9IUgmvslp1C5LKDU8tMjA",
96
+ typesenseHost: "tl2qpnwxev4cjm36p-1.a1.typesense.net",
97
+ typesensePort: "443",
98
+ typesenseProtocol: "https"
69
99
  },
70
100
  upcoming: {
71
101
  socketUrl: "https://upcoming.api.symbols.app",
72
102
  apiUrl: "https://upcoming.api.symbols.app",
73
- githubClientId: "Ov23liWF7NvdZ056RV5J"
103
+ githubClientId: "Ov23liWF7NvdZ056RV5J",
104
+ grafanaUrl: "",
105
+ // For grafana tracing
106
+ grafanaAppName: "Symbols Upcoming",
107
+ typesenseCollectionName: "docs",
108
+ typesenseApiKey: "awmcVpbWqZi9IUgmvslp1C5LKDU8tMjA",
109
+ typesenseHost: "tl2qpnwxev4cjm36p-1.a1.typesense.net",
110
+ typesensePort: "443",
111
+ typesenseProtocol: "https"
74
112
  },
75
113
  staging: {
76
114
  socketUrl: "https://staging.api.symbols.app",
@@ -78,7 +116,31 @@ const CONFIG = {
78
116
  basedEnv: "staging",
79
117
  basedProject: "platform-v2-sm",
80
118
  basedOrg: "symbols",
81
- githubClientId: "Ov23ligwZDQVD0VfuWNa"
119
+ githubClientId: "Ov23ligwZDQVD0VfuWNa",
120
+ grafanaUrl: "",
121
+ // For grafana tracing
122
+ grafanaAppName: "Symbols Staging",
123
+ typesenseCollectionName: "docs",
124
+ typesenseApiKey: "awmcVpbWqZi9IUgmvslp1C5LKDU8tMjA",
125
+ typesenseHost: "tl2qpnwxev4cjm36p-1.a1.typesense.net",
126
+ typesensePort: "443",
127
+ typesenseProtocol: "https"
128
+ },
129
+ preview: {
130
+ socketUrl: "https://api.symbols.app",
131
+ apiUrl: "https://api.symbols.app",
132
+ basedEnv: "production",
133
+ basedProject: "platform-v2-sm",
134
+ basedOrg: "symbols",
135
+ githubClientId: "Ov23liFAlOEIXtX3dBtR",
136
+ grafanaUrl: "https://faro-collector-prod-us-east-0.grafana.net/collect/5c1089f3c3eea4ec5658e05c3f53baae",
137
+ // For grafana tracing
138
+ grafanaAppName: "Symbols Preview",
139
+ typesenseCollectionName: "docs",
140
+ typesenseApiKey: "awmcVpbWqZi9IUgmvslp1C5LKDU8tMjA",
141
+ typesenseHost: "tl2qpnwxev4cjm36p-1.a1.typesense.net",
142
+ typesensePort: "443",
143
+ typesenseProtocol: "https"
82
144
  },
83
145
  production: {
84
146
  socketUrl: "https://api.symbols.app",
@@ -86,7 +148,15 @@ const CONFIG = {
86
148
  basedEnv: "production",
87
149
  basedProject: "platform-v2-sm",
88
150
  basedOrg: "symbols",
89
- githubClientId: "Ov23liFAlOEIXtX3dBtR"
151
+ githubClientId: "Ov23liFAlOEIXtX3dBtR",
152
+ grafanaUrl: "https://faro-collector-prod-us-east-0.grafana.net/collect/5c1089f3c3eea4ec5658e05c3f53baae",
153
+ // For grafana tracing
154
+ grafanaAppName: "Symbols",
155
+ typesenseCollectionName: "docs",
156
+ typesenseApiKey: "awmcVpbWqZi9IUgmvslp1C5LKDU8tMjA",
157
+ typesenseHost: "tl2qpnwxev4cjm36p-1.a1.typesense.net",
158
+ typesensePort: "443",
159
+ typesenseProtocol: "https"
90
160
  }
91
161
  };
92
162
  const getEnvironment = () => {
@@ -103,15 +173,27 @@ const getConfig = () => {
103
173
  const envConfig = { ...CONFIG.common, ...CONFIG[env] };
104
174
  const finalConfig = {
105
175
  ...envConfig,
176
+ // Deep-merge feature flags so env-specific overrides don't drop common defaults
177
+ features: {
178
+ ...CONFIG.common.features || {},
179
+ ...CONFIG[env] && CONFIG[env].features || {}
180
+ },
106
181
  socketUrl: process.env.SYMBOLS_APP_SOCKET_URL || envConfig.socketUrl,
107
182
  apiUrl: process.env.SYMBOLS_APP_API_URL || envConfig.apiUrl,
108
183
  basedEnv: process.env.SYMBOLS_APP_BASED_ENV || envConfig.basedEnv,
109
184
  basedProject: process.env.SYMBOLS_APP_BASED_PROJECT || envConfig.basedProject,
110
185
  basedOrg: process.env.SYMBOLS_APP_BASED_ORG || envConfig.basedOrg,
111
186
  githubClientId: process.env.SYMBOLS_APP_GITHUB_CLIENT_ID || envConfig.githubClientId,
187
+ grafanaUrl: process.env.SYMBOLS_APP_GRAFANA_URL || envConfig.grafanaUrl,
188
+ typesenseCollectionName: process.env.TYPESENSE_COLLECTION_NAME || envConfig.typesenseCollectionName,
189
+ typesenseApiKey: process.env.TYPESENSE_API_KEY || envConfig.typesenseApiKey,
190
+ typesenseHost: process.env.TYPESENSE_HOST || envConfig.typesenseHost,
191
+ typesensePort: process.env.TYPESENSE_PORT || envConfig.typesensePort,
192
+ typesenseProtocol: process.env.TYPESENSE_PROTOCOL || envConfig.typesenseProtocol,
112
193
  isDevelopment: (0, import_utils.isDevelopment)(env),
113
194
  isTesting: env === "testing",
114
195
  isStaging: env === "staging",
196
+ isPreview: env === "preview",
115
197
  isProduction: env === "production"
116
198
  // Store all environment variables for potential future use
117
199
  };
@@ -128,11 +210,13 @@ const getConfig = () => {
128
210
  );
129
211
  }
130
212
  if (finalConfig.isDevelopment) {
131
- console.log(
213
+ console.warn(
132
214
  "environment in SDK:",
133
215
  env || process.env.NODE_ENV || process.env.NODE_ENV
134
216
  );
135
217
  console.log(finalConfig);
218
+ } else if (global.window) {
219
+ global.window.finalConfig = finalConfig;
136
220
  }
137
221
  return finalConfig;
138
222
  } catch (error) {
package/dist/cjs/index.js CHANGED
@@ -28,23 +28,48 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
28
28
  var index_exports = {};
29
29
  __export(index_exports, {
30
30
  SDK: () => SDK,
31
+ createAdminService: () => import_services3.createAdminService,
31
32
  createAuthService: () => import_services3.createAuthService,
33
+ createBranchService: () => import_services3.createBranchService,
32
34
  createCollabService: () => import_services3.createCollabService,
33
- createCoreService: () => import_services3.createCoreService,
35
+ createDnsService: () => import_services3.createDnsService,
36
+ createFeatureFlagService: () => import_services3.createFeatureFlagService,
37
+ createFileService: () => import_services3.createFileService,
38
+ createIntegrationService: () => import_services3.createIntegrationService,
39
+ createMetricsService: () => import_services3.createMetricsService,
40
+ createPaymentService: () => import_services3.createPaymentService,
41
+ createPlanService: () => import_services3.createPlanService,
42
+ createProjectService: () => import_services3.createProjectService,
43
+ createPullRequestService: () => import_services3.createPullRequestService,
44
+ createSubscriptionService: () => import_services3.createSubscriptionService,
45
+ createTrackingService: () => import_services3.createTrackingService,
46
+ createWaitlistService: () => import_services3.createWaitlistService,
34
47
  default: () => index_default,
35
- environment: () => import_environment2.default
48
+ environment: () => import_environment2.default,
49
+ isLocalhost: () => isLocalhost
36
50
  });
37
51
  module.exports = __toCommonJS(index_exports);
38
52
  var import_services = require("./services/index.js");
39
53
  var import_services2 = require("./utils/services.js");
40
54
  var import_environment = __toESM(require("./config/environment.js"), 1);
55
+ var import_rootEventBus = require("./state/rootEventBus.js");
41
56
  var import_services3 = require("./services/index.js");
42
57
  var import_environment2 = __toESM(require("./config/environment.js"), 1);
58
+ const isBrowserEnvironment = () => typeof window !== "undefined";
59
+ const isLocalhost = () => {
60
+ if (!isBrowserEnvironment()) {
61
+ return false;
62
+ }
63
+ const host = window.location && window.location.hostname;
64
+ return host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "" || !host;
65
+ };
43
66
  class SDK {
44
67
  constructor(options = {}) {
45
68
  this._services = /* @__PURE__ */ new Map();
46
69
  this._context = {};
47
70
  this._options = this._validateOptions(options);
71
+ this.environment = import_environment.default;
72
+ this.rootBus = import_rootEventBus.rootBus;
48
73
  this._createServiceProxies();
49
74
  }
50
75
  // Initialize SDK with context
@@ -62,15 +87,114 @@ class SDK {
62
87
  })
63
88
  ),
64
89
  this._initService(
65
- "core",
66
- (0, import_services.createCoreService)({
90
+ "collab",
91
+ (0, import_services.createCollabService)({
67
92
  context: this._context,
68
93
  options: this._options
69
94
  })
70
95
  ),
96
+ // Initialize new modular services
71
97
  this._initService(
72
- "collab",
73
- (0, import_services.createCollabService)({
98
+ "project",
99
+ (0, import_services.createProjectService)({
100
+ context: this._context,
101
+ options: this._options
102
+ })
103
+ ),
104
+ this._initService(
105
+ "plan",
106
+ (0, import_services.createPlanService)({
107
+ context: this._context,
108
+ options: this._options
109
+ })
110
+ ),
111
+ this._initService(
112
+ "subscription",
113
+ (0, import_services.createSubscriptionService)({
114
+ context: this._context,
115
+ options: this._options
116
+ })
117
+ ),
118
+ this._initService(
119
+ "file",
120
+ (0, import_services.createFileService)({
121
+ context: this._context,
122
+ options: this._options
123
+ })
124
+ ),
125
+ this._initService(
126
+ "payment",
127
+ (0, import_services.createPaymentService)({
128
+ context: this._context,
129
+ options: this._options
130
+ })
131
+ ),
132
+ this._initService(
133
+ "dns",
134
+ (0, import_services.createDnsService)({
135
+ context: this._context,
136
+ options: this._options
137
+ })
138
+ ),
139
+ this._initService(
140
+ "branch",
141
+ (0, import_services.createBranchService)({
142
+ context: this._context,
143
+ options: this._options
144
+ })
145
+ ),
146
+ this._initService(
147
+ "pullRequest",
148
+ (0, import_services.createPullRequestService)({
149
+ context: this._context,
150
+ options: this._options
151
+ })
152
+ ),
153
+ this._initService(
154
+ "admin",
155
+ (0, import_services.createAdminService)({
156
+ context: this._context,
157
+ options: this._options
158
+ })
159
+ ),
160
+ this._initService(
161
+ "screenshot",
162
+ (0, import_services.createScreenshotService)({
163
+ context: this._context,
164
+ options: this._options
165
+ })
166
+ ),
167
+ this._initService(
168
+ "tracking",
169
+ (0, import_services.createTrackingService)({
170
+ context: this._context,
171
+ options: this._options
172
+ })
173
+ ),
174
+ this._initService(
175
+ "waitlist",
176
+ (0, import_services.createWaitlistService)({
177
+ context: this._context,
178
+ options: this._options
179
+ })
180
+ ),
181
+ this._initService(
182
+ "metrics",
183
+ (0, import_services.createMetricsService)({
184
+ context: this._context,
185
+ options: this._options
186
+ })
187
+ ),
188
+ this._initService(
189
+ "integration",
190
+ (0, import_services.createIntegrationService)({
191
+ context: this._context,
192
+ options: this._options
193
+ })
194
+ ),
195
+ this._initService(
196
+ "featureFlag",
197
+ (0, import_services.createFeatureFlagService)({
74
198
  context: this._context,
75
199
  options: this._options
76
200
  })
@@ -91,6 +215,8 @@ class SDK {
91
215
  this._services.set(name, service);
92
216
  }
93
217
  _validateOptions(options) {
218
+ const onLocalhost = isLocalhost();
219
+ const hasGrafanaUrl = Boolean(import_environment.default.grafanaUrl);
94
220
  const defaults = {
95
221
  useNewServices: true,
96
222
  // Use new service implementations by default
@@ -98,9 +224,24 @@ class SDK {
98
224
  socketUrl: import_environment.default.socketUrl,
99
225
  timeout: 3e4,
100
226
  retryAttempts: 3,
101
- debug: false
227
+ debug: false,
228
+ tracking: {
229
+ // Force-disabled on localhost or when no Grafana URL is configured
230
+ enabled: onLocalhost ? false : hasGrafanaUrl ? import_environment.default.features.trackingEnabled : false
231
+ }
102
232
  };
103
- return { ...defaults, ...options };
233
+ const merged = {
234
+ ...defaults,
235
+ ...options,
236
+ tracking: {
237
+ ...defaults.tracking,
238
+ ...options.tracking || {}
239
+ }
240
+ };
241
+ if (onLocalhost || !hasGrafanaUrl) {
242
+ merged.tracking.enabled = false;
243
+ }
244
+ return merged;
104
245
  }
105
246
  // Get service instance
106
247
  getService(name) {
@@ -111,9 +252,10 @@ class SDK {
111
252
  }
112
253
  // Update context
113
254
  updateContext(newContext) {
255
+ const { ...sanitized } = newContext || {};
114
256
  this._context = {
115
257
  ...this._context,
116
- ...newContext
258
+ ...sanitized
117
259
  };
118
260
  for (const service of this._services.values()) {
119
261
  service.updateContext(this._context);
@@ -122,9 +264,7 @@ class SDK {
122
264
  // Check if SDK is ready
123
265
  isReady() {
124
266
  const sdkServices = Array.from(this._services.values());
125
- return sdkServices.length > 0 && sdkServices.every(
126
- (service) => service.isReady()
127
- );
267
+ return sdkServices.length > 0 && sdkServices.every((service) => service.isReady());
128
268
  }
129
269
  // Get SDK status
130
270
  getStatus() {