Skip to content

Commit acecb4e

Browse files
committed
feat: Location change auto transaction
1 parent 41b552c commit acecb4e

File tree

1 file changed

+44
-13
lines changed

1 file changed

+44
-13
lines changed

packages/integrations/src/transactionactivity.ts

+44-13
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@ import { EventProcessor, Hub, Integration, Scope, Span, SpanContext } from '@sen
22

33
/** JSDoc */
44
interface TransactionActivityOptions {
5-
// onLocationChange: (info) => {
6-
// // info holds the location change api.
7-
// // if this returns `null` there is no transaction started.
8-
// return info.state.transaction || info.url;
9-
// },
10-
// onActivity?: (info) => {
11-
// return info.type !== 'xhr' || !info.url.match(/zendesk/);
12-
// },
135
idleTimeout: number;
6+
patchHistory: boolean;
7+
/**
8+
* Called when an history change happend
9+
*/
10+
onLocationChange(state: any): string;
11+
startTransactionOnLocationChange: boolean;
1412
}
1513

1614
/** JSDoc */
@@ -53,6 +51,9 @@ export class TransactionActivity implements Integration {
5351
public constructor(
5452
public readonly _options: TransactionActivityOptions = {
5553
idleTimeout: 500,
54+
onLocationChange: () => window.location.href,
55+
patchHistory: true,
56+
startTransactionOnLocationChange: true,
5657
},
5758
) {
5859
TransactionActivity._options = _options;
@@ -63,6 +64,31 @@ export class TransactionActivity implements Integration {
6364
*/
6465
public setupOnce(_: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void {
6566
TransactionActivity._getCurrentHub = getCurrentHub;
67+
if (this._options.patchHistory) {
68+
// tslint:disable: no-unsafe-any
69+
// tslint:disable-next-line: typedef only-arrow-functions
70+
(function(history: any) {
71+
const pushState = history.pushState;
72+
// tslint:disable-next-line: typedef only-arrow-functions
73+
history.pushState = function(state: any) {
74+
if (typeof history.onpushstate === 'function') {
75+
history.onpushstate({ state });
76+
}
77+
// ... whatever else you want to do
78+
// maybe call onhashchange e.handler
79+
return pushState.apply(history, arguments);
80+
};
81+
})(window.history);
82+
window.onpopstate = (history as any).onpushstate = (_state: any) => {
83+
if (this._options.startTransactionOnLocationChange) {
84+
TransactionActivity.startIdleTransaction(`${window.location.href}`, {
85+
op: 'navigation',
86+
sampled: true,
87+
});
88+
}
89+
};
90+
// tslint:enable: no-unsafe-any
91+
}
6692
}
6793

6894
/**
@@ -124,6 +150,14 @@ export class TransactionActivity implements Integration {
124150
(activeTransaction as any).transaction = name;
125151
}
126152

153+
public static finishIdleTransaction(): void {
154+
const active = TransactionActivity._activeTransaction;
155+
if (active) {
156+
// true = use timestamp of last span
157+
active.finish(true);
158+
}
159+
}
160+
127161
/**
128162
* Starts tracking for a specifc activity
129163
*/
@@ -165,11 +199,8 @@ export class TransactionActivity implements Integration {
165199
if (count === 0) {
166200
const timeout = TransactionActivity._options && TransactionActivity._options.idleTimeout;
167201
TransactionActivity._debounce = (setTimeout(() => {
168-
const active = TransactionActivity._activeTransaction;
169-
if (active) {
170-
active.finish(true);
171-
}
172-
}, timeout) as any) as number; // TODO 500
202+
TransactionActivity.finishIdleTransaction();
203+
}, timeout) as any) as number;
173204
}
174205
}
175206
}

0 commit comments

Comments
 (0)