@leanbase-giangnd/js 0.1.0 → 0.1.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leanbase-giangnd/js",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Leanbase browser SDK - event tracking, autocapture, and session replay",
5
5
  "repository": {
6
6
  "type": "git",
@@ -0,0 +1,35 @@
1
+ import { window as win } from '../../utils'
2
+ import { record as rrwebRecord } from '@rrweb/record'
3
+ import { LazyLoadedSessionRecording } from './external/lazy-loaded-session-recorder'
4
+ import { getRecordNetworkPlugin } from './external/network-plugin'
5
+
6
+ // Use a safe global target (prefer `win`, fallback to globalThis)
7
+ const _target: any = (win as any) ?? (globalThis as any)
8
+
9
+ _target.__PosthogExtensions__ = _target.__PosthogExtensions__ || {}
10
+
11
+ // Expose rrweb.record under the same contract
12
+ _target.__PosthogExtensions__.rrweb = _target.__PosthogExtensions__.rrweb || {
13
+ record: rrwebRecord,
14
+ }
15
+
16
+ // Provide initSessionRecording if not present — return a new LazyLoadedSessionRecording when called
17
+ _target.__PosthogExtensions__.initSessionRecording =
18
+ _target.__PosthogExtensions__.initSessionRecording ||
19
+ ((instance: any) => {
20
+ return new LazyLoadedSessionRecording(instance)
21
+ })
22
+
23
+ // Provide a no-op loadExternalDependency that calls the callback immediately (since rrweb is bundled)
24
+ _target.__PosthogExtensions__.loadExternalDependency =
25
+ _target.__PosthogExtensions__.loadExternalDependency ||
26
+ ((instance: any, scriptName: string, cb?: (err?: any) => void) => {
27
+ if (cb) cb(undefined)
28
+ })
29
+
30
+ // Provide rrwebPlugins object with network plugin factory if not present
31
+ _target.__PosthogExtensions__.rrwebPlugins = _target.__PosthogExtensions__.rrwebPlugins || {}
32
+ _target.__PosthogExtensions__.rrwebPlugins.getRecordNetworkPlugin =
33
+ _target.__PosthogExtensions__.rrwebPlugins.getRecordNetworkPlugin || (() => getRecordNetworkPlugin)
34
+
35
+ export {}
@@ -1,4 +1,5 @@
1
1
  import { record as rrwebRecord } from '@rrweb/record'
2
+ import '../extension-shim'
2
3
  import { clampToRange, includes, isBoolean, isNullish, isNumber, isObject, isString, isUndefined } from '@posthog/core'
3
4
  import type { recordOptions, rrwebRecord as rrwebRecordType } from '../types/rrweb'
4
5
  import {
@@ -118,6 +119,16 @@ const newQueuedEvent = (rrwebMethod: () => void): QueuedRRWebEvent => ({
118
119
  })
119
120
 
120
121
  function getRRWebRecord(): rrwebRecordType | undefined {
122
+ try {
123
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
124
+ const ext = (globalThis as any).__PosthogExtensions__
125
+ if (ext && ext.rrweb && ext.rrweb.record) {
126
+ return ext.rrweb.record as unknown as rrwebRecordType
127
+ }
128
+ } catch {
129
+ // ignore
130
+ }
131
+
121
132
  return rrwebRecord as unknown as rrwebRecordType
122
133
  }
123
134
 
@@ -1022,7 +1033,7 @@ export class LazyLoadedSessionRecording {
1022
1033
  private _captureSnapshot(properties: Properties) {
1023
1034
  // :TRICKY: Make sure we batch these requests, use a custom endpoint and don't truncate the strings.
1024
1035
  this._instance.capture('$snapshot', properties, {
1025
- _url: this._snapshotUrl(),
1036
+ _url: this._instance.requestRouter.endpointFor('api', this._endpoint),
1026
1037
  _noTruncate: true,
1027
1038
  _batchKey: SESSION_RECORDING_BATCH_KEY,
1028
1039
  skip_client_rate_limiting: true,
@@ -57,42 +57,24 @@ export class SessionRecording {
57
57
  }
58
58
 
59
59
  private get _isRecordingEnabled() {
60
- if (!window) {
61
- return false
62
- }
63
-
64
- if (!this._serverRecordingEnabled) {
65
- return false
66
- }
67
-
68
- if (this._instance.config.disable_session_recording) {
69
- return false
70
- }
71
-
72
- return true
60
+ const enabled_server_side = !!this._instance.get_property(SESSION_RECORDING_REMOTE_CONFIG)?.enabled
61
+ const enabled_client_side = !this._instance.config.disable_session_recording
62
+ const isDisabled = this._instance.config.disable_session_recording || this._instance.consent?.isOptedOut?.()
63
+ return window && enabled_server_side && enabled_client_side && !isDisabled
73
64
  }
74
65
 
75
66
  startIfEnabledOrStop(startReason?: SessionStartReason) {
76
- const canRunReplay = !isUndefined(Object.assign) && !isUndefined(Array.from)
77
-
78
- if (!this._isRecordingEnabled || !canRunReplay) {
79
- this.stopRecording()
67
+ if (this._isRecordingEnabled && this._lazyLoadedSessionRecording?.isStarted) {
80
68
  return
81
69
  }
82
70
 
83
- if (this._lazyLoadedSessionRecording?.isStarted) {
84
- return
71
+ const canRunReplay = !isUndefined(Object.assign) && !isUndefined(Array.from)
72
+ if (this._isRecordingEnabled && canRunReplay) {
73
+ this._lazyLoadAndStart(startReason)
74
+ log.info('starting')
75
+ } else {
76
+ this.stopRecording()
85
77
  }
86
-
87
- // According to the rrweb docs, rrweb is not supported on IE11 and below:
88
- // "rrweb does not support IE11 and below because it uses the MutationObserver API, which was supported by these browsers."
89
- // https://github.com/rrweb-io/rrweb/blob/master/guide.md#compatibility-note
90
- //
91
- // However, MutationObserver does exist on IE11, it just doesn't work well and does not detect all changes.
92
- // Instead, when we load "recorder.js", the first JS error is about "Object.assign" and "Array.from" being undefined.
93
- // Thus instead of MutationObserver, we look for this function and block recording if it's undefined.
94
- this._lazyLoadAndStart(startReason)
95
- log.info('starting')
96
78
  }
97
79
 
98
80
  /**
package/src/leanbase.ts CHANGED
@@ -43,6 +43,8 @@ import { PageViewManager } from './page-view'
43
43
  import { ScrollManager } from './scroll-manager'
44
44
  import { isLikelyBot } from './utils/blocked-uas'
45
45
  import { SessionRecording } from './extensions/replay/session-recording'
46
+ import type { RequestRouter } from '../../browser/lib/src/utils/request-router'
47
+ import type { ConsentManager } from '../../browser/lib/src/consent'
46
48
 
47
49
  const defaultConfig = (): LeanbaseConfig => ({
48
50
  host: 'https://i.leanbase.co',
@@ -87,6 +89,8 @@ export class Leanbase extends PostHogCore {
87
89
  sessionPersistence?: LeanbasePersistence
88
90
  sessionManager?: SessionIdManager
89
91
  sessionPropsManager?: SessionPropsManager
92
+ requestRouter!: RequestRouter
93
+ consent!: ConsentManager
90
94
  sessionRecording?: SessionRecording
91
95
  isRemoteConfigLoaded?: boolean
92
96
  personProcessingSetOncePropertiesSent = false
@@ -221,6 +225,10 @@ export class Leanbase extends PostHogCore {
221
225
  const oldConfig = { ...this.config }
222
226
  if (isObject(config)) {
223
227
  extend(this.config, config)
228
+ if (!this.config.api_host && this.config.host) {
229
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
230
+ ;(this.config as any).api_host = this.config.host
231
+ }
224
232
  this.persistence?.update_config(this.config, oldConfig)
225
233
  this.replayAutocapture?.startIfEnabled()
226
234
  this.sessionRecording?.startIfEnabledOrStop()
package/src/types.ts CHANGED
@@ -101,6 +101,15 @@ export interface LeanbaseConfig extends Partial<PostHogCoreOptions> {
101
101
  * @default 'https://i.leanbase.co'
102
102
  */
103
103
  host?: string
104
+ /**
105
+ * API host (alias) used by some modules; kept for compatibility with upstream
106
+ */
107
+ api_host?: string
108
+
109
+ /**
110
+ * UI host override
111
+ */
112
+ ui_host?: string
104
113
 
105
114
  /**
106
115
  * The token for your Leanbase project.
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = '0.1.0'
1
+ export const version = '0.1.1'