@@ -12,17 +12,21 @@ import type {
12
12
FinishedCheckIn ,
13
13
MonitorConfig ,
14
14
Primitive ,
15
+ Session ,
16
+ SessionContext ,
15
17
Severity ,
16
18
SeverityLevel ,
17
19
TransactionContext ,
18
20
User ,
19
21
} from '@sentry/types' ;
20
- import { isThenable , logger , timestampInSeconds , uuid4 } from '@sentry/utils' ;
22
+ import { GLOBAL_OBJ , isThenable , logger , timestampInSeconds , uuid4 } from '@sentry/utils' ;
21
23
24
+ import { DEFAULT_ENVIRONMENT } from './constants' ;
22
25
import { DEBUG_BUILD } from './debug-build' ;
23
26
import type { Hub } from './hub' ;
24
- import { getCurrentHub } from './hub' ;
27
+ import { getCurrentHub , getIsolationScope } from './hub' ;
25
28
import type { Scope } from './scope' ;
29
+ import { closeSession , makeSession , updateSession } from './session' ;
26
30
import type { ExclusiveEventHintOrCaptureContext } from './utils/prepareEvent' ;
27
31
import { parseEventHintOrCaptureContext } from './utils/prepareEvent' ;
28
32
@@ -322,3 +326,99 @@ export function getClient<C extends Client>(): C | undefined {
322
326
export function getCurrentScope ( ) : Scope {
323
327
return getCurrentHub ( ) . getScope ( ) ;
324
328
}
329
+
330
+ /**
331
+ * Start a session on the current isolation scope.
332
+ *
333
+ * @param context (optional) additional properties to be applied to the returned session object
334
+ *
335
+ * @returns the new active session
336
+ */
337
+ export function startSession ( context ?: SessionContext ) : Session {
338
+ const client = getClient ( ) ;
339
+ const isolationScope = getIsolationScope ( ) ;
340
+ const currentScope = getCurrentScope ( ) ;
341
+
342
+ const { release, environment = DEFAULT_ENVIRONMENT } = ( client && client . getOptions ( ) ) || { } ;
343
+
344
+ // Will fetch userAgent if called from browser sdk
345
+ const { userAgent } = GLOBAL_OBJ . navigator || { } ;
346
+
347
+ const session = makeSession ( {
348
+ release,
349
+ environment,
350
+ user : isolationScope . getUser ( ) ,
351
+ ...( userAgent && { userAgent } ) ,
352
+ ...context ,
353
+ } ) ;
354
+
355
+ // End existing session if there's one
356
+ const currentSession = isolationScope . getSession ( ) ;
357
+ if ( currentSession && currentSession . status === 'ok' ) {
358
+ updateSession ( currentSession , { status : 'exited' } ) ;
359
+ }
360
+
361
+ endSession ( ) ;
362
+
363
+ // Afterwards we set the new session on the scope
364
+ isolationScope . setSession ( session ) ;
365
+
366
+ // TODO (v8): Remove this and only use the isolation scope(?).
367
+ // For v7 though, we can't "soft-break" people using getCurrentHub().getScope().setSession()
368
+ currentScope . setSession ( session ) ;
369
+
370
+ return session ;
371
+ }
372
+
373
+ /**
374
+ * End the session on the current isolation scope.
375
+ */
376
+ export function endSession ( ) : void {
377
+ const isolationScope = getIsolationScope ( ) ;
378
+ const currentScope = getCurrentScope ( ) ;
379
+
380
+ const session = isolationScope . getSession ( ) ;
381
+ if ( session ) {
382
+ closeSession ( session ) ;
383
+ }
384
+ _sendSessionUpdate ( ) ;
385
+
386
+ // the session is over; take it off of the scope
387
+ isolationScope . setSession ( ) ;
388
+
389
+ // TODO (v8): Remove this and only use the isolation scope(?).
390
+ // For v7 though, we can't "soft-break" people using getCurrentHub().getScope().setSession()
391
+ currentScope . setSession ( ) ;
392
+ }
393
+
394
+ /**
395
+ * Sends the current Session on the scope
396
+ */
397
+ function _sendSessionUpdate ( ) : void {
398
+ const isolationScope = getIsolationScope ( ) ;
399
+ const currentScope = getCurrentScope ( ) ;
400
+ const client = getClient ( ) ;
401
+ // TODO (v8): Remove currentScope and only use the isolation scope(?).
402
+ // For v7 though, we can't "soft-break" people using getCurrentHub().getScope().setSession()
403
+ const session = currentScope . getSession ( ) || isolationScope . getSession ( ) ;
404
+ if ( session && client && client . captureSession ) {
405
+ client . captureSession ( session ) ;
406
+ }
407
+ }
408
+
409
+ /**
410
+ * Sends the current session on the scope to Sentry
411
+ *
412
+ * @param end If set the session will be marked as exited and removed from the scope.
413
+ * Defaults to `false`.
414
+ */
415
+ export function captureSession ( end : boolean = false ) : void {
416
+ // both send the update and pull the session from the scope
417
+ if ( end ) {
418
+ endSession ( ) ;
419
+ return ;
420
+ }
421
+
422
+ // only send the update
423
+ _sendSessionUpdate ( ) ;
424
+ }
0 commit comments