@amplitude/segment-session-replay-plugin 0.0.0-beta.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/LICENSE +21 -0
- package/README.md +58 -0
- package/lib/cjs/constants.d.ts +6 -0
- package/lib/cjs/constants.d.ts.map +1 -0
- package/lib/cjs/constants.js +9 -0
- package/lib/cjs/constants.js.map +1 -0
- package/lib/cjs/helpers.d.ts +5 -0
- package/lib/cjs/helpers.d.ts.map +1 -0
- package/lib/cjs/helpers.js +53 -0
- package/lib/cjs/helpers.js.map +1 -0
- package/lib/cjs/index.d.ts +3 -0
- package/lib/cjs/index.d.ts.map +1 -0
- package/lib/cjs/index.js +98 -0
- package/lib/cjs/index.js.map +1 -0
- package/lib/cjs/typings/wrapper.d.ts +12 -0
- package/lib/cjs/typings/wrapper.d.ts.map +1 -0
- package/lib/cjs/typings/wrapper.js +3 -0
- package/lib/cjs/typings/wrapper.js.map +1 -0
- package/lib/cjs/version.d.ts +2 -0
- package/lib/cjs/version.d.ts.map +1 -0
- package/lib/cjs/version.js +6 -0
- package/lib/cjs/version.js.map +1 -0
- package/lib/esm/constants.d.ts +6 -0
- package/lib/esm/constants.d.ts.map +1 -0
- package/lib/esm/constants.js +6 -0
- package/lib/esm/constants.js.map +1 -0
- package/lib/esm/helpers.d.ts +5 -0
- package/lib/esm/helpers.d.ts.map +1 -0
- package/lib/esm/helpers.js +47 -0
- package/lib/esm/helpers.js.map +1 -0
- package/lib/esm/index.d.ts +3 -0
- package/lib/esm/index.d.ts.map +1 -0
- package/lib/esm/index.js +94 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/typings/wrapper.d.ts +12 -0
- package/lib/esm/typings/wrapper.d.ts.map +1 -0
- package/lib/esm/typings/wrapper.js +2 -0
- package/lib/esm/typings/wrapper.js.map +1 -0
- package/lib/esm/version.d.ts +2 -0
- package/lib/esm/version.d.ts.map +1 -0
- package/lib/esm/version.js +3 -0
- package/lib/esm/version.js.map +1 -0
- package/lib/scripts/rrweb-plugin-console-record-min.js +2 -0
- package/lib/scripts/rrweb-plugin-console-record-min.js.gz +0 -0
- package/lib/scripts/rrweb-plugin-console-record-min.js.map +1 -0
- package/lib/scripts/segment-session-replay-wrapper-esm.js +2 -0
- package/lib/scripts/segment-session-replay-wrapper-esm.js.gz +0 -0
- package/lib/scripts/segment-session-replay-wrapper-esm.js.map +1 -0
- package/package.json +65 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Amplitude Analytics
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://amplitude.com" target="_blank" align="center">
|
|
3
|
+
<img src="https://static.amplitude.com/lightning/46c85bfd91905de8047f1ee65c7c93d6fa9ee6ea/static/media/amplitude-logo-with-text.4fb9e463.svg" width="280">
|
|
4
|
+
</a>
|
|
5
|
+
<br />
|
|
6
|
+
</p>
|
|
7
|
+
|
|
8
|
+
# @amplitude/segment-session-replay-plugin
|
|
9
|
+
|
|
10
|
+
This package is a wrapper to facilitate integration between Segment and [Amplitude's Session Replay SDK](https://amplitude.com/docs/session-replay/session-replay-standalone-sdk). This package currently only supports the [Segment Amplitude (Actions) destination](https://segment.com/docs/connections/destinations/catalog/actions-amplitude/).
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
This package is published on NPM registry and is available to be installed using `npm` and `yarn`. Amplitude's Session
|
|
15
|
+
Replay SDK is included in this package, and does not need to be installed separately.
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
# npm
|
|
19
|
+
npm install @amplitude/segment-session-replay-plugin" --save
|
|
20
|
+
|
|
21
|
+
# yarn
|
|
22
|
+
yarn add @amplitude/segment-session-replay-plugin"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { AnalyticsBrowser } from '@segment/analytics-next';
|
|
29
|
+
import { createSegmentActionsPlugin } from '@amplitude/segment-session-replay-plugin';
|
|
30
|
+
|
|
31
|
+
export const SegmentAnalytics = AnalyticsBrowser.load({
|
|
32
|
+
writeKey: SEGMENT_API_KEY,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
createSegmentActionsPlugin({
|
|
36
|
+
segmentInstance: SegmentAnalytics,
|
|
37
|
+
amplitudeApiKey: AMPLITUDE_API_KEY,
|
|
38
|
+
sessionReplayOptions: {
|
|
39
|
+
logLevel: 4,
|
|
40
|
+
sampleRate: 1,
|
|
41
|
+
debugMode: true,
|
|
42
|
+
},
|
|
43
|
+
enableWrapperDebug: true,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
SegmentAnalytics.track("Immediate Event");
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The `sessionReplayOptions` parameter properties match those documented for the [Session Replay Standalone SDK](https://amplitude.com/docs/session-replay/session-replay-standalone-sdk#configuration).
|
|
50
|
+
|
|
51
|
+
## Segment Plugin Architecture
|
|
52
|
+
|
|
53
|
+
This wrapper makes use of Segment's plugin architecture, which ensures that all `track` and `page` events are decorated
|
|
54
|
+
with the Session Replay ID event property.
|
|
55
|
+
|
|
56
|
+
## User ID to Device ID mapping
|
|
57
|
+
|
|
58
|
+
Following Segment's documentation, the wrapper maps the Segment user id to the Amplitude device id. To determine the device id for session replay captures, the wrapper uses the `anonymousId` unless `sessionReplayOptions.deviceId` is provided.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const COOKIE_NAME = "amp_session_id";
|
|
2
|
+
export declare const DEBUG_LOG_PREFIX = "Amplitude Session Replay Segment Plugin [Debug]:";
|
|
3
|
+
export declare const INITIAL_EVENT_NAME = "Immediate Event";
|
|
4
|
+
export declare const PLUGIN_NAME = "Session Replay Events";
|
|
5
|
+
export declare const PLUGIN_TYPE = "enrichment";
|
|
6
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,mBAAmB,CAAC;AAC5C,eAAO,MAAM,gBAAgB,qDAAqD,CAAC;AACnF,eAAO,MAAM,kBAAkB,oBAAoB,CAAC;AACpD,eAAO,MAAM,WAAW,0BAA0B,CAAC;AACnD,eAAO,MAAM,WAAW,eAAe,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PLUGIN_TYPE = exports.PLUGIN_NAME = exports.INITIAL_EVENT_NAME = exports.DEBUG_LOG_PREFIX = exports.COOKIE_NAME = void 0;
|
|
4
|
+
exports.COOKIE_NAME = 'amp_session_id';
|
|
5
|
+
exports.DEBUG_LOG_PREFIX = 'Amplitude Session Replay Segment Plugin [Debug]:';
|
|
6
|
+
exports.INITIAL_EVENT_NAME = 'Immediate Event';
|
|
7
|
+
exports.PLUGIN_NAME = 'Session Replay Events';
|
|
8
|
+
exports.PLUGIN_TYPE = 'enrichment'; // https://github.com/segmentio/analytics-next/blob/c45d445/packages/core/src/plugins/index.ts#L11
|
|
9
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,WAAW,GAAG,gBAAgB,CAAC;AAC/B,QAAA,gBAAgB,GAAG,kDAAkD,CAAC;AACtE,QAAA,kBAAkB,GAAG,iBAAiB,CAAC;AACvC,QAAA,WAAW,GAAG,uBAAuB,CAAC;AACtC,QAAA,WAAW,GAAG,YAAY,CAAC,CAAC,kGAAkG","sourcesContent":["export const COOKIE_NAME = 'amp_session_id';\nexport const DEBUG_LOG_PREFIX = 'Amplitude Session Replay Segment Plugin [Debug]:';\nexport const INITIAL_EVENT_NAME = 'Immediate Event';\nexport const PLUGIN_NAME = 'Session Replay Events';\nexport const PLUGIN_TYPE = 'enrichment'; // https://github.com/segmentio/analytics-next/blob/c45d445/packages/core/src/plugins/index.ts#L11\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Context } from '@segment/analytics-next';
|
|
2
|
+
export declare const getSessionId: () => number | undefined;
|
|
3
|
+
export declare const setSessionId: (sessionId: number, deviceId: string | undefined) => Promise<void>;
|
|
4
|
+
export declare const updateSessionIdAndAddProperties: (ctx: Context, deviceId: string | undefined) => Promise<Context>;
|
|
5
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAKlD,eAAO,MAAM,YAAY,QAAO,MAAM,GAAG,SAcxC,CAAC;AAEF,eAAO,MAAM,YAAY,cAAe,MAAM,YAAY,MAAM,GAAG,SAAS,KAAG,QAAQ,IAAI,CAM1F,CAAC;AAEF,eAAO,MAAM,+BAA+B,QAAe,OAAO,YAAY,MAAM,GAAG,SAAS,KAAG,QAAQ,OAAO,CA0BjH,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.updateSessionIdAndAddProperties = exports.setSessionId = exports.getSessionId = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
var sessionReplay = tslib_1.__importStar(require("@amplitude/session-replay-browser"));
|
|
6
|
+
var js_cookie_1 = tslib_1.__importDefault(require("js-cookie"));
|
|
7
|
+
var constants_1 = require("./constants");
|
|
8
|
+
var getSessionId = function () {
|
|
9
|
+
// First try to get the sessionId from the Session Replay SDK
|
|
10
|
+
// If that fails, try to get the sessionId from the persistent storage
|
|
11
|
+
var sessionId = sessionReplay.getSessionId() || js_cookie_1.default.get(constants_1.COOKIE_NAME);
|
|
12
|
+
if (sessionId) {
|
|
13
|
+
var result = parseInt(sessionId.toString(), 10);
|
|
14
|
+
if (isNaN(result)) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
// If sessionId is not found in either the Session Replay SDK nor persistent storage, return undefined
|
|
20
|
+
return undefined;
|
|
21
|
+
};
|
|
22
|
+
exports.getSessionId = getSessionId;
|
|
23
|
+
var setSessionId = function (sessionId, deviceId) {
|
|
24
|
+
// Set the sessionId in the persistent storage
|
|
25
|
+
js_cookie_1.default.set(constants_1.COOKIE_NAME, sessionId.toString());
|
|
26
|
+
// Set the sessionId in the Session Replay SDK
|
|
27
|
+
return sessionReplay.setSessionId(sessionId, deviceId).promise;
|
|
28
|
+
};
|
|
29
|
+
exports.setSessionId = setSessionId;
|
|
30
|
+
var updateSessionIdAndAddProperties = function (ctx, deviceId) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
31
|
+
var sessionId, nextSessionId, sessionReplayProperties, properties;
|
|
32
|
+
return tslib_1.__generator(this, function (_a) {
|
|
33
|
+
switch (_a.label) {
|
|
34
|
+
case 0:
|
|
35
|
+
sessionId = (0, exports.getSessionId)() || 0;
|
|
36
|
+
if (ctx.event.integrations && ctx.event.integrations['Actions Amplitude']) {
|
|
37
|
+
nextSessionId = ctx.event.integrations['Actions Amplitude'].session_id;
|
|
38
|
+
}
|
|
39
|
+
if (!(nextSessionId && sessionId < nextSessionId)) return [3 /*break*/, 2];
|
|
40
|
+
return [4 /*yield*/, (0, exports.setSessionId)(nextSessionId, deviceId)];
|
|
41
|
+
case 1:
|
|
42
|
+
_a.sent();
|
|
43
|
+
_a.label = 2;
|
|
44
|
+
case 2:
|
|
45
|
+
sessionReplayProperties = sessionReplay.getSessionReplayProperties();
|
|
46
|
+
properties = tslib_1.__assign(tslib_1.__assign({}, sessionReplayProperties), ctx.event.properties);
|
|
47
|
+
ctx.updateEvent('properties', properties);
|
|
48
|
+
return [2 /*return*/, ctx];
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}); };
|
|
52
|
+
exports.updateSessionIdAndAddProperties = updateSessionIdAndAddProperties;
|
|
53
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":";;;;AAAA,uFAAmE;AAEnE,gEAA+B;AAC/B,yCAA0C;AAGnC,IAAM,YAAY,GAAG;IAC1B,6DAA6D;IAC7D,sEAAsE;IACtE,IAAM,SAAS,GAAgC,aAAa,CAAC,YAAY,EAAE,IAAI,mBAAM,CAAC,GAAG,CAAC,uBAAW,CAAC,CAAC;IACvG,IAAI,SAAS,EAAE;QACb,IAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;QAClD,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE;YACjB,OAAO,SAAS,CAAC;SAClB;QACD,OAAO,MAAM,CAAC;KACf;IAED,sGAAsG;IACtG,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAdW,QAAA,YAAY,gBAcvB;AAEK,IAAM,YAAY,GAAG,UAAC,SAAiB,EAAE,QAA4B;IAC1E,8CAA8C;IAC9C,mBAAM,CAAC,GAAG,CAAC,uBAAW,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;IAE9C,8CAA8C;IAC9C,OAAO,aAAa,CAAC,YAAY,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC;AACjE,CAAC,CAAC;AANW,QAAA,YAAY,gBAMvB;AAEK,IAAM,+BAA+B,GAAG,UAAO,GAAY,EAAE,QAA4B;;;;;gBAExF,SAAS,GAAW,IAAA,oBAAY,GAAE,IAAI,CAAC,CAAC;gBAI9C,IAAI,GAAG,CAAC,KAAK,CAAC,YAAY,IAAK,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,mBAAmB,CAA8B,EAAE;oBACvG,aAAa,GAAI,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,mBAAmB,CAA8B,CAAC,UAAU,CAAC;iBACtG;qBAGG,CAAA,aAAa,IAAI,SAAS,GAAG,aAAa,CAAA,EAA1C,wBAA0C;gBAC5C,qBAAM,IAAA,oBAAY,EAAC,aAAa,EAAE,QAAQ,CAAC,EAAA;;gBAA3C,SAA2C,CAAC;;;gBAKxC,uBAAuB,GAAG,aAAa,CAAC,0BAA0B,EAAE,CAAC;gBACrE,UAAU,yCACX,uBAAuB,GACvB,GAAG,CAAC,KAAK,CAAC,UAAU,CACxB,CAAC;gBAEF,GAAG,CAAC,WAAW,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;gBAE1C,sBAAO,GAAG,EAAC;;;KACZ,CAAC;AA1BW,QAAA,+BAA+B,mCA0B1C","sourcesContent":["import * as sessionReplay from '@amplitude/session-replay-browser';\nimport { Context } from '@segment/analytics-next';\nimport Cookie from 'js-cookie';\nimport { COOKIE_NAME } from './constants';\nimport { AmplitudeIntegrationData } from './typings/wrapper';\n\nexport const getSessionId = (): number | undefined => {\n // First try to get the sessionId from the Session Replay SDK\n // If that fails, try to get the sessionId from the persistent storage\n const sessionId: string | number | undefined = sessionReplay.getSessionId() || Cookie.get(COOKIE_NAME);\n if (sessionId) {\n const result = parseInt(sessionId.toString(), 10);\n if (isNaN(result)) {\n return undefined;\n }\n return result;\n }\n\n // If sessionId is not found in either the Session Replay SDK nor persistent storage, return undefined\n return undefined;\n};\n\nexport const setSessionId = (sessionId: number, deviceId: string | undefined): Promise<void> => {\n // Set the sessionId in the persistent storage\n Cookie.set(COOKIE_NAME, sessionId.toString());\n\n // Set the sessionId in the Session Replay SDK\n return sessionReplay.setSessionId(sessionId, deviceId).promise;\n};\n\nexport const updateSessionIdAndAddProperties = async (ctx: Context, deviceId: string | undefined): Promise<Context> => {\n // Get the current session id or default to 0 if it does not exist\n const sessionId: number = getSessionId() || 0;\n\n // Get the next session id from the event, if it exists\n let nextSessionId: number | undefined;\n if (ctx.event.integrations && (ctx.event.integrations['Actions Amplitude'] as AmplitudeIntegrationData)) {\n nextSessionId = (ctx.event.integrations['Actions Amplitude'] as AmplitudeIntegrationData).session_id;\n }\n\n // Update the session id if it is new\n if (nextSessionId && sessionId < nextSessionId) {\n await setSessionId(nextSessionId, deviceId);\n }\n\n // Enrich the event with the session replay properties\n // NOTE: This is what will add the `[Amplitude] Session Replay ID` attribute to the event\n const sessionReplayProperties = sessionReplay.getSessionReplayProperties();\n const properties = {\n ...sessionReplayProperties,\n ...ctx.event.properties,\n };\n\n ctx.updateEvent('properties', properties);\n\n return ctx;\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,eAAO,MAAM,0BAA0B,oFAKpC,aAAa,KAAG,QAAQ,IAAI,CAuE9B,CAAC"}
|
package/lib/cjs/index.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createSegmentActionsPlugin = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
var sessionReplay = tslib_1.__importStar(require("@amplitude/session-replay-browser"));
|
|
6
|
+
var constants_1 = require("./constants");
|
|
7
|
+
var helpers_1 = require("./helpers");
|
|
8
|
+
var version_1 = require("./version");
|
|
9
|
+
var createSegmentActionsPlugin = function (_a) {
|
|
10
|
+
var amplitudeApiKey = _a.amplitudeApiKey, sessionReplayOptions = _a.sessionReplayOptions, segmentInstance = _a.segmentInstance, _b = _a.enableWrapperDebug, enableWrapperDebug = _b === void 0 ? false : _b;
|
|
11
|
+
return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
12
|
+
var initPromise, isInitialized, deviceId, _plugin;
|
|
13
|
+
return tslib_1.__generator(this, function (_c) {
|
|
14
|
+
switch (_c.label) {
|
|
15
|
+
case 0:
|
|
16
|
+
isInitialized = false;
|
|
17
|
+
deviceId = sessionReplayOptions === null || sessionReplayOptions === void 0 ? void 0 : sessionReplayOptions.deviceId;
|
|
18
|
+
_plugin = {
|
|
19
|
+
name: constants_1.PLUGIN_NAME,
|
|
20
|
+
type: constants_1.PLUGIN_TYPE,
|
|
21
|
+
version: version_1.VERSION,
|
|
22
|
+
isLoaded: function () { return isInitialized; },
|
|
23
|
+
load: function (_ctx, ajs) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
24
|
+
var user, sessionId;
|
|
25
|
+
return tslib_1.__generator(this, function (_a) {
|
|
26
|
+
switch (_a.label) {
|
|
27
|
+
case 0:
|
|
28
|
+
// If the deviceId is not provided via the plugin parameters,
|
|
29
|
+
// default to use the anonymousId from the user
|
|
30
|
+
if (!deviceId) {
|
|
31
|
+
user = ajs.user();
|
|
32
|
+
deviceId = user.anonymousId() || undefined;
|
|
33
|
+
}
|
|
34
|
+
sessionId = (0, helpers_1.getSessionId)();
|
|
35
|
+
// Initialize the session replay plugin
|
|
36
|
+
enableWrapperDebug &&
|
|
37
|
+
console.log("".concat(constants_1.DEBUG_LOG_PREFIX, " initializing session replay with sessionId=").concat(sessionId !== null && sessionId !== void 0 ? sessionId : 'undefined', " and deviceId=").concat(deviceId !== null && deviceId !== void 0 ? deviceId : 'undefined'));
|
|
38
|
+
initPromise = sessionReplay.init(amplitudeApiKey, tslib_1.__assign(tslib_1.__assign({}, sessionReplayOptions), { sessionId: sessionId, deviceId: deviceId || undefined, version: { type: 'segment', version: version_1.VERSION } })).promise;
|
|
39
|
+
return [4 /*yield*/, initPromise];
|
|
40
|
+
case 1:
|
|
41
|
+
_a.sent();
|
|
42
|
+
isInitialized = true;
|
|
43
|
+
return [2 /*return*/];
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}); },
|
|
47
|
+
track: function (ctx) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
48
|
+
return tslib_1.__generator(this, function (_a) {
|
|
49
|
+
switch (_a.label) {
|
|
50
|
+
case 0: return [4 /*yield*/, initPromise];
|
|
51
|
+
case 1:
|
|
52
|
+
_a.sent();
|
|
53
|
+
return [4 /*yield*/, (0, helpers_1.updateSessionIdAndAddProperties)(ctx, deviceId)];
|
|
54
|
+
case 2: return [2 /*return*/, _a.sent()];
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}); },
|
|
58
|
+
page: function (ctx) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
59
|
+
return tslib_1.__generator(this, function (_a) {
|
|
60
|
+
switch (_a.label) {
|
|
61
|
+
case 0: return [4 /*yield*/, initPromise];
|
|
62
|
+
case 1:
|
|
63
|
+
_a.sent();
|
|
64
|
+
return [4 /*yield*/, (0, helpers_1.updateSessionIdAndAddProperties)(ctx, deviceId)];
|
|
65
|
+
case 2: return [2 /*return*/, _a.sent()];
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}); },
|
|
69
|
+
identify: function (ctx) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
70
|
+
var sessionId;
|
|
71
|
+
return tslib_1.__generator(this, function (_a) {
|
|
72
|
+
switch (_a.label) {
|
|
73
|
+
case 0: return [4 /*yield*/, initPromise];
|
|
74
|
+
case 1:
|
|
75
|
+
_a.sent();
|
|
76
|
+
sessionId = (0, helpers_1.getSessionId)();
|
|
77
|
+
if (!sessionId) return [3 /*break*/, 3];
|
|
78
|
+
enableWrapperDebug &&
|
|
79
|
+
console.log("".concat(constants_1.DEBUG_LOG_PREFIX, " calling setSessionId() with sessionId=").concat(sessionId, " and deviceId=").concat(deviceId !== null && deviceId !== void 0 ? deviceId : 'undefined'));
|
|
80
|
+
return [4 /*yield*/, (0, helpers_1.setSessionId)(sessionId, deviceId)];
|
|
81
|
+
case 2:
|
|
82
|
+
_a.sent();
|
|
83
|
+
_a.label = 3;
|
|
84
|
+
case 3: return [2 /*return*/, ctx];
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}); },
|
|
88
|
+
};
|
|
89
|
+
return [4 /*yield*/, segmentInstance.register(_plugin)];
|
|
90
|
+
case 1:
|
|
91
|
+
_c.sent();
|
|
92
|
+
return [2 /*return*/];
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
exports.createSegmentActionsPlugin = createSegmentActionsPlugin;
|
|
98
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;AAAA,uFAAmE;AAGnE,yCAAyE;AACzE,qCAAwF;AAExF,qCAAoC;AAE7B,IAAM,0BAA0B,GAAG,UAAO,EAKjC;QAJd,eAAe,qBAAA,EACf,oBAAoB,0BAAA,EACpB,eAAe,qBAAA,EACf,0BAA0B,EAA1B,kBAAkB,mBAAG,KAAK,KAAA;;;;;;oBAGtB,aAAa,GAAG,KAAK,CAAC;oBACtB,QAAQ,GAAuB,oBAAoB,aAApB,oBAAoB,uBAApB,oBAAoB,CAAE,QAAQ,CAAC;oBAE5D,OAAO,GAAW;wBACtB,IAAI,EAAE,uBAAW;wBACjB,IAAI,EAAE,uBAAW;wBACjB,OAAO,EAAE,iBAAO;wBAEhB,QAAQ,EAAE,cAAe,OAAA,aAAa,EAAb,CAAa;wBAEtC,IAAI,EAAE,UAAO,IAAa,EAAE,GAAc;;;;;wCACxC,6DAA6D;wCAC7D,+CAA+C;wCAC/C,IAAI,CAAC,QAAQ,EAAE;4CACP,IAAI,GAAS,GAAG,CAAC,IAAI,EAAE,CAAC;4CAC9B,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,SAAS,CAAC;yCAC5C;wCAEK,SAAS,GAAuB,IAAA,sBAAY,GAAE,CAAC;wCAErD,uCAAuC;wCACvC,kBAAkB;4CAChB,OAAO,CAAC,GAAG,CACT,UAAG,4BAAgB,yDAA+C,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,WAAW,2BACxF,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,WAAW,CACvB,CACH,CAAC;wCAEJ,WAAW,GAAG,aAAa,CAAC,IAAI,CAAC,eAAe,wCAC3C,oBAAoB,KACvB,SAAS,WAAA,EACT,QAAQ,EAAE,QAAQ,IAAI,SAAS,EAC/B,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,iBAAO,EAAE,IAC9C,CAAC,OAAO,CAAC;wCAEX,qBAAM,WAAW,EAAA;;wCAAjB,SAAiB,CAAC;wCAClB,aAAa,GAAG,IAAI,CAAC;;;;6BACtB;wBAED,KAAK,EAAE,UAAO,GAAY;;;4CACxB,qBAAM,WAAW,EAAA;;wCAAjB,SAAiB,CAAC;wCACX,qBAAM,IAAA,yCAA+B,EAAC,GAAG,EAAE,QAAQ,CAAC,EAAA;4CAA3D,sBAAO,SAAoD,EAAC;;;6BAC7D;wBAED,IAAI,EAAE,UAAO,GAAY;;;4CACvB,qBAAM,WAAW,EAAA;;wCAAjB,SAAiB,CAAC;wCACX,qBAAM,IAAA,yCAA+B,EAAC,GAAG,EAAE,QAAQ,CAAC,EAAA;4CAA3D,sBAAO,SAAoD,EAAC;;;6BAC7D;wBAED,QAAQ,EAAE,UAAO,GAAY;;;;4CAC3B,qBAAM,WAAW,EAAA;;wCAAjB,SAAiB,CAAC;wCAEZ,SAAS,GAAuB,IAAA,sBAAY,GAAE,CAAC;6CAEjD,SAAS,EAAT,wBAAS;wCACX,kBAAkB;4CAChB,OAAO,CAAC,GAAG,CACT,UAAG,4BAAgB,oDAA0C,SAAS,2BACpE,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,WAAW,CACvB,CACH,CAAC;wCACJ,qBAAM,IAAA,sBAAY,EAAC,SAAS,EAAE,QAAQ,CAAC,EAAA;;wCAAvC,SAAuC,CAAC;;4CAG1C,sBAAO,GAAG,EAAC;;;6BACZ;qBACF,CAAC;oBAEF,qBAAM,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAA;;oBAAvC,SAAuC,CAAC;;;;;CACzC,CAAC;AA5EW,QAAA,0BAA0B,8BA4ErC","sourcesContent":["import * as sessionReplay from '@amplitude/session-replay-browser';\nimport { Analytics, Context, Plugin, User } from '@segment/analytics-next';\n\nimport { DEBUG_LOG_PREFIX, PLUGIN_NAME, PLUGIN_TYPE } from './constants';\nimport { getSessionId, setSessionId, updateSessionIdAndAddProperties } from './helpers';\nimport { PluginOptions } from './typings/wrapper';\nimport { VERSION } from './version';\n\nexport const createSegmentActionsPlugin = async ({\n amplitudeApiKey,\n sessionReplayOptions,\n segmentInstance,\n enableWrapperDebug = false,\n}: PluginOptions): Promise<void> => {\n let initPromise: Promise<void>;\n let isInitialized = false;\n let deviceId: string | undefined = sessionReplayOptions?.deviceId;\n\n const _plugin: Plugin = {\n name: PLUGIN_NAME,\n type: PLUGIN_TYPE,\n version: VERSION,\n\n isLoaded: (): boolean => isInitialized,\n\n load: async (_ctx: Context, ajs: Analytics): Promise<void> => {\n // If the deviceId is not provided via the plugin parameters,\n // default to use the anonymousId from the user\n if (!deviceId) {\n const user: User = ajs.user();\n deviceId = user.anonymousId() || undefined;\n }\n\n const sessionId: number | undefined = getSessionId();\n\n // Initialize the session replay plugin\n enableWrapperDebug &&\n console.log(\n `${DEBUG_LOG_PREFIX} initializing session replay with sessionId=${sessionId ?? 'undefined'} and deviceId=${\n deviceId ?? 'undefined'\n }`,\n );\n\n initPromise = sessionReplay.init(amplitudeApiKey, {\n ...sessionReplayOptions,\n sessionId,\n deviceId: deviceId || undefined,\n version: { type: 'segment', version: VERSION },\n }).promise;\n\n await initPromise;\n isInitialized = true;\n },\n\n track: async (ctx: Context): Promise<Context> => {\n await initPromise;\n return await updateSessionIdAndAddProperties(ctx, deviceId);\n },\n\n page: async (ctx: Context): Promise<Context> => {\n await initPromise;\n return await updateSessionIdAndAddProperties(ctx, deviceId);\n },\n\n identify: async (ctx: Context): Promise<Context> => {\n await initPromise;\n\n const sessionId: number | undefined = getSessionId();\n\n if (sessionId) {\n enableWrapperDebug &&\n console.log(\n `${DEBUG_LOG_PREFIX} calling setSessionId() with sessionId=${sessionId} and deviceId=${\n deviceId ?? 'undefined'\n }`,\n );\n await setSessionId(sessionId, deviceId);\n }\n\n return ctx;\n },\n };\n\n await segmentInstance.register(_plugin);\n};\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { SessionReplayOptions } from '@amplitude/session-replay-browser';
|
|
2
|
+
import { AnalyticsBrowser } from '@segment/analytics-next';
|
|
3
|
+
export interface PluginOptions {
|
|
4
|
+
segmentInstance: AnalyticsBrowser;
|
|
5
|
+
amplitudeApiKey: string;
|
|
6
|
+
sessionReplayOptions?: SessionReplayOptions;
|
|
7
|
+
enableWrapperDebug?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export type AmplitudeIntegrationData = {
|
|
10
|
+
session_id: number;
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=wrapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrapper.d.ts","sourceRoot":"","sources":["../../../src/typings/wrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,MAAM,WAAW,aAAa;IAC5B,eAAe,EAAE,gBAAgB,CAAC;IAClC,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,MAAM,wBAAwB,GAAG;IAErC,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrapper.js","sourceRoot":"","sources":["../../../src/typings/wrapper.ts"],"names":[],"mappings":"","sourcesContent":["import { SessionReplayOptions } from '@amplitude/session-replay-browser';\nimport { AnalyticsBrowser } from '@segment/analytics-next';\n\nexport interface PluginOptions {\n segmentInstance: AnalyticsBrowser;\n amplitudeApiKey: string;\n sessionReplayOptions?: SessionReplayOptions;\n enableWrapperDebug?: boolean;\n}\n\nexport type AmplitudeIntegrationData = {\n // https://github.com/segmentio/analytics-next/blob/3f15dfae034d101fb1847bc7228c0354b414d68a/packages/browser-integration-tests/src/index.test.ts#L64-L66\n session_id: number;\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,OAAO,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":";;;AAAA,oDAAoD;AACvC,QAAA,OAAO,GAAG,cAAc,CAAC","sourcesContent":["// Autogenerated by `yarn version-file`. DO NOT EDIT\nexport const VERSION = '0.0.0-beta.1';\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const COOKIE_NAME = "amp_session_id";
|
|
2
|
+
export declare const DEBUG_LOG_PREFIX = "Amplitude Session Replay Segment Plugin [Debug]:";
|
|
3
|
+
export declare const INITIAL_EVENT_NAME = "Immediate Event";
|
|
4
|
+
export declare const PLUGIN_NAME = "Session Replay Events";
|
|
5
|
+
export declare const PLUGIN_TYPE = "enrichment";
|
|
6
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,mBAAmB,CAAC;AAC5C,eAAO,MAAM,gBAAgB,qDAAqD,CAAC;AACnF,eAAO,MAAM,kBAAkB,oBAAoB,CAAC;AACpD,eAAO,MAAM,WAAW,0BAA0B,CAAC;AACnD,eAAO,MAAM,WAAW,eAAe,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export var COOKIE_NAME = 'amp_session_id';
|
|
2
|
+
export var DEBUG_LOG_PREFIX = 'Amplitude Session Replay Segment Plugin [Debug]:';
|
|
3
|
+
export var INITIAL_EVENT_NAME = 'Immediate Event';
|
|
4
|
+
export var PLUGIN_NAME = 'Session Replay Events';
|
|
5
|
+
export var PLUGIN_TYPE = 'enrichment'; // https://github.com/segmentio/analytics-next/blob/c45d445/packages/core/src/plugins/index.ts#L11
|
|
6
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,IAAM,WAAW,GAAG,gBAAgB,CAAC;AAC5C,MAAM,CAAC,IAAM,gBAAgB,GAAG,kDAAkD,CAAC;AACnF,MAAM,CAAC,IAAM,kBAAkB,GAAG,iBAAiB,CAAC;AACpD,MAAM,CAAC,IAAM,WAAW,GAAG,uBAAuB,CAAC;AACnD,MAAM,CAAC,IAAM,WAAW,GAAG,YAAY,CAAC,CAAC,kGAAkG","sourcesContent":["export const COOKIE_NAME = 'amp_session_id';\nexport const DEBUG_LOG_PREFIX = 'Amplitude Session Replay Segment Plugin [Debug]:';\nexport const INITIAL_EVENT_NAME = 'Immediate Event';\nexport const PLUGIN_NAME = 'Session Replay Events';\nexport const PLUGIN_TYPE = 'enrichment'; // https://github.com/segmentio/analytics-next/blob/c45d445/packages/core/src/plugins/index.ts#L11\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Context } from '@segment/analytics-next';
|
|
2
|
+
export declare const getSessionId: () => number | undefined;
|
|
3
|
+
export declare const setSessionId: (sessionId: number, deviceId: string | undefined) => Promise<void>;
|
|
4
|
+
export declare const updateSessionIdAndAddProperties: (ctx: Context, deviceId: string | undefined) => Promise<Context>;
|
|
5
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAKlD,eAAO,MAAM,YAAY,QAAO,MAAM,GAAG,SAcxC,CAAC;AAEF,eAAO,MAAM,YAAY,cAAe,MAAM,YAAY,MAAM,GAAG,SAAS,KAAG,QAAQ,IAAI,CAM1F,CAAC;AAEF,eAAO,MAAM,+BAA+B,QAAe,OAAO,YAAY,MAAM,GAAG,SAAS,KAAG,QAAQ,OAAO,CA0BjH,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { __assign, __awaiter, __generator } from "tslib";
|
|
2
|
+
import * as sessionReplay from '@amplitude/session-replay-browser';
|
|
3
|
+
import Cookie from 'js-cookie';
|
|
4
|
+
import { COOKIE_NAME } from './constants';
|
|
5
|
+
export var getSessionId = function () {
|
|
6
|
+
// First try to get the sessionId from the Session Replay SDK
|
|
7
|
+
// If that fails, try to get the sessionId from the persistent storage
|
|
8
|
+
var sessionId = sessionReplay.getSessionId() || Cookie.get(COOKIE_NAME);
|
|
9
|
+
if (sessionId) {
|
|
10
|
+
var result = parseInt(sessionId.toString(), 10);
|
|
11
|
+
if (isNaN(result)) {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
// If sessionId is not found in either the Session Replay SDK nor persistent storage, return undefined
|
|
17
|
+
return undefined;
|
|
18
|
+
};
|
|
19
|
+
export var setSessionId = function (sessionId, deviceId) {
|
|
20
|
+
// Set the sessionId in the persistent storage
|
|
21
|
+
Cookie.set(COOKIE_NAME, sessionId.toString());
|
|
22
|
+
// Set the sessionId in the Session Replay SDK
|
|
23
|
+
return sessionReplay.setSessionId(sessionId, deviceId).promise;
|
|
24
|
+
};
|
|
25
|
+
export var updateSessionIdAndAddProperties = function (ctx, deviceId) { return __awaiter(void 0, void 0, void 0, function () {
|
|
26
|
+
var sessionId, nextSessionId, sessionReplayProperties, properties;
|
|
27
|
+
return __generator(this, function (_a) {
|
|
28
|
+
switch (_a.label) {
|
|
29
|
+
case 0:
|
|
30
|
+
sessionId = getSessionId() || 0;
|
|
31
|
+
if (ctx.event.integrations && ctx.event.integrations['Actions Amplitude']) {
|
|
32
|
+
nextSessionId = ctx.event.integrations['Actions Amplitude'].session_id;
|
|
33
|
+
}
|
|
34
|
+
if (!(nextSessionId && sessionId < nextSessionId)) return [3 /*break*/, 2];
|
|
35
|
+
return [4 /*yield*/, setSessionId(nextSessionId, deviceId)];
|
|
36
|
+
case 1:
|
|
37
|
+
_a.sent();
|
|
38
|
+
_a.label = 2;
|
|
39
|
+
case 2:
|
|
40
|
+
sessionReplayProperties = sessionReplay.getSessionReplayProperties();
|
|
41
|
+
properties = __assign(__assign({}, sessionReplayProperties), ctx.event.properties);
|
|
42
|
+
ctx.updateEvent('properties', properties);
|
|
43
|
+
return [2 /*return*/, ctx];
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}); };
|
|
47
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,aAAa,MAAM,mCAAmC,CAAC;AAEnE,OAAO,MAAM,MAAM,WAAW,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1C,MAAM,CAAC,IAAM,YAAY,GAAG;IAC1B,6DAA6D;IAC7D,sEAAsE;IACtE,IAAM,SAAS,GAAgC,aAAa,CAAC,YAAY,EAAE,IAAI,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACvG,IAAI,SAAS,EAAE;QACb,IAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;QAClD,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE;YACjB,OAAO,SAAS,CAAC;SAClB;QACD,OAAO,MAAM,CAAC;KACf;IAED,sGAAsG;IACtG,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF,MAAM,CAAC,IAAM,YAAY,GAAG,UAAC,SAAiB,EAAE,QAA4B;IAC1E,8CAA8C;IAC9C,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;IAE9C,8CAA8C;IAC9C,OAAO,aAAa,CAAC,YAAY,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC;AACjE,CAAC,CAAC;AAEF,MAAM,CAAC,IAAM,+BAA+B,GAAG,UAAO,GAAY,EAAE,QAA4B;;;;;gBAExF,SAAS,GAAW,YAAY,EAAE,IAAI,CAAC,CAAC;gBAI9C,IAAI,GAAG,CAAC,KAAK,CAAC,YAAY,IAAK,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,mBAAmB,CAA8B,EAAE;oBACvG,aAAa,GAAI,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,mBAAmB,CAA8B,CAAC,UAAU,CAAC;iBACtG;qBAGG,CAAA,aAAa,IAAI,SAAS,GAAG,aAAa,CAAA,EAA1C,wBAA0C;gBAC5C,qBAAM,YAAY,CAAC,aAAa,EAAE,QAAQ,CAAC,EAAA;;gBAA3C,SAA2C,CAAC;;;gBAKxC,uBAAuB,GAAG,aAAa,CAAC,0BAA0B,EAAE,CAAC;gBACrE,UAAU,yBACX,uBAAuB,GACvB,GAAG,CAAC,KAAK,CAAC,UAAU,CACxB,CAAC;gBAEF,GAAG,CAAC,WAAW,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;gBAE1C,sBAAO,GAAG,EAAC;;;KACZ,CAAC","sourcesContent":["import * as sessionReplay from '@amplitude/session-replay-browser';\nimport { Context } from '@segment/analytics-next';\nimport Cookie from 'js-cookie';\nimport { COOKIE_NAME } from './constants';\nimport { AmplitudeIntegrationData } from './typings/wrapper';\n\nexport const getSessionId = (): number | undefined => {\n // First try to get the sessionId from the Session Replay SDK\n // If that fails, try to get the sessionId from the persistent storage\n const sessionId: string | number | undefined = sessionReplay.getSessionId() || Cookie.get(COOKIE_NAME);\n if (sessionId) {\n const result = parseInt(sessionId.toString(), 10);\n if (isNaN(result)) {\n return undefined;\n }\n return result;\n }\n\n // If sessionId is not found in either the Session Replay SDK nor persistent storage, return undefined\n return undefined;\n};\n\nexport const setSessionId = (sessionId: number, deviceId: string | undefined): Promise<void> => {\n // Set the sessionId in the persistent storage\n Cookie.set(COOKIE_NAME, sessionId.toString());\n\n // Set the sessionId in the Session Replay SDK\n return sessionReplay.setSessionId(sessionId, deviceId).promise;\n};\n\nexport const updateSessionIdAndAddProperties = async (ctx: Context, deviceId: string | undefined): Promise<Context> => {\n // Get the current session id or default to 0 if it does not exist\n const sessionId: number = getSessionId() || 0;\n\n // Get the next session id from the event, if it exists\n let nextSessionId: number | undefined;\n if (ctx.event.integrations && (ctx.event.integrations['Actions Amplitude'] as AmplitudeIntegrationData)) {\n nextSessionId = (ctx.event.integrations['Actions Amplitude'] as AmplitudeIntegrationData).session_id;\n }\n\n // Update the session id if it is new\n if (nextSessionId && sessionId < nextSessionId) {\n await setSessionId(nextSessionId, deviceId);\n }\n\n // Enrich the event with the session replay properties\n // NOTE: This is what will add the `[Amplitude] Session Replay ID` attribute to the event\n const sessionReplayProperties = sessionReplay.getSessionReplayProperties();\n const properties = {\n ...sessionReplayProperties,\n ...ctx.event.properties,\n };\n\n ctx.updateEvent('properties', properties);\n\n return ctx;\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,eAAO,MAAM,0BAA0B,oFAKpC,aAAa,KAAG,QAAQ,IAAI,CAuE9B,CAAC"}
|
package/lib/esm/index.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { __assign, __awaiter, __generator } from "tslib";
|
|
2
|
+
import * as sessionReplay from '@amplitude/session-replay-browser';
|
|
3
|
+
import { DEBUG_LOG_PREFIX, PLUGIN_NAME, PLUGIN_TYPE } from './constants';
|
|
4
|
+
import { getSessionId, setSessionId, updateSessionIdAndAddProperties } from './helpers';
|
|
5
|
+
import { VERSION } from './version';
|
|
6
|
+
export var createSegmentActionsPlugin = function (_a) {
|
|
7
|
+
var amplitudeApiKey = _a.amplitudeApiKey, sessionReplayOptions = _a.sessionReplayOptions, segmentInstance = _a.segmentInstance, _b = _a.enableWrapperDebug, enableWrapperDebug = _b === void 0 ? false : _b;
|
|
8
|
+
return __awaiter(void 0, void 0, void 0, function () {
|
|
9
|
+
var initPromise, isInitialized, deviceId, _plugin;
|
|
10
|
+
return __generator(this, function (_c) {
|
|
11
|
+
switch (_c.label) {
|
|
12
|
+
case 0:
|
|
13
|
+
isInitialized = false;
|
|
14
|
+
deviceId = sessionReplayOptions === null || sessionReplayOptions === void 0 ? void 0 : sessionReplayOptions.deviceId;
|
|
15
|
+
_plugin = {
|
|
16
|
+
name: PLUGIN_NAME,
|
|
17
|
+
type: PLUGIN_TYPE,
|
|
18
|
+
version: VERSION,
|
|
19
|
+
isLoaded: function () { return isInitialized; },
|
|
20
|
+
load: function (_ctx, ajs) { return __awaiter(void 0, void 0, void 0, function () {
|
|
21
|
+
var user, sessionId;
|
|
22
|
+
return __generator(this, function (_a) {
|
|
23
|
+
switch (_a.label) {
|
|
24
|
+
case 0:
|
|
25
|
+
// If the deviceId is not provided via the plugin parameters,
|
|
26
|
+
// default to use the anonymousId from the user
|
|
27
|
+
if (!deviceId) {
|
|
28
|
+
user = ajs.user();
|
|
29
|
+
deviceId = user.anonymousId() || undefined;
|
|
30
|
+
}
|
|
31
|
+
sessionId = getSessionId();
|
|
32
|
+
// Initialize the session replay plugin
|
|
33
|
+
enableWrapperDebug &&
|
|
34
|
+
console.log("".concat(DEBUG_LOG_PREFIX, " initializing session replay with sessionId=").concat(sessionId !== null && sessionId !== void 0 ? sessionId : 'undefined', " and deviceId=").concat(deviceId !== null && deviceId !== void 0 ? deviceId : 'undefined'));
|
|
35
|
+
initPromise = sessionReplay.init(amplitudeApiKey, __assign(__assign({}, sessionReplayOptions), { sessionId: sessionId, deviceId: deviceId || undefined, version: { type: 'segment', version: VERSION } })).promise;
|
|
36
|
+
return [4 /*yield*/, initPromise];
|
|
37
|
+
case 1:
|
|
38
|
+
_a.sent();
|
|
39
|
+
isInitialized = true;
|
|
40
|
+
return [2 /*return*/];
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}); },
|
|
44
|
+
track: function (ctx) { return __awaiter(void 0, void 0, void 0, function () {
|
|
45
|
+
return __generator(this, function (_a) {
|
|
46
|
+
switch (_a.label) {
|
|
47
|
+
case 0: return [4 /*yield*/, initPromise];
|
|
48
|
+
case 1:
|
|
49
|
+
_a.sent();
|
|
50
|
+
return [4 /*yield*/, updateSessionIdAndAddProperties(ctx, deviceId)];
|
|
51
|
+
case 2: return [2 /*return*/, _a.sent()];
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}); },
|
|
55
|
+
page: function (ctx) { return __awaiter(void 0, void 0, void 0, function () {
|
|
56
|
+
return __generator(this, function (_a) {
|
|
57
|
+
switch (_a.label) {
|
|
58
|
+
case 0: return [4 /*yield*/, initPromise];
|
|
59
|
+
case 1:
|
|
60
|
+
_a.sent();
|
|
61
|
+
return [4 /*yield*/, updateSessionIdAndAddProperties(ctx, deviceId)];
|
|
62
|
+
case 2: return [2 /*return*/, _a.sent()];
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}); },
|
|
66
|
+
identify: function (ctx) { return __awaiter(void 0, void 0, void 0, function () {
|
|
67
|
+
var sessionId;
|
|
68
|
+
return __generator(this, function (_a) {
|
|
69
|
+
switch (_a.label) {
|
|
70
|
+
case 0: return [4 /*yield*/, initPromise];
|
|
71
|
+
case 1:
|
|
72
|
+
_a.sent();
|
|
73
|
+
sessionId = getSessionId();
|
|
74
|
+
if (!sessionId) return [3 /*break*/, 3];
|
|
75
|
+
enableWrapperDebug &&
|
|
76
|
+
console.log("".concat(DEBUG_LOG_PREFIX, " calling setSessionId() with sessionId=").concat(sessionId, " and deviceId=").concat(deviceId !== null && deviceId !== void 0 ? deviceId : 'undefined'));
|
|
77
|
+
return [4 /*yield*/, setSessionId(sessionId, deviceId)];
|
|
78
|
+
case 2:
|
|
79
|
+
_a.sent();
|
|
80
|
+
_a.label = 3;
|
|
81
|
+
case 3: return [2 /*return*/, ctx];
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}); },
|
|
85
|
+
};
|
|
86
|
+
return [4 /*yield*/, segmentInstance.register(_plugin)];
|
|
87
|
+
case 1:
|
|
88
|
+
_c.sent();
|
|
89
|
+
return [2 /*return*/];
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
};
|
|
94
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,aAAa,MAAM,mCAAmC,CAAC;AAGnE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,+BAA+B,EAAE,MAAM,WAAW,CAAC;AAExF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,CAAC,IAAM,0BAA0B,GAAG,UAAO,EAKjC;QAJd,eAAe,qBAAA,EACf,oBAAoB,0BAAA,EACpB,eAAe,qBAAA,EACf,0BAA0B,EAA1B,kBAAkB,mBAAG,KAAK,KAAA;;;;;;oBAGtB,aAAa,GAAG,KAAK,CAAC;oBACtB,QAAQ,GAAuB,oBAAoB,aAApB,oBAAoB,uBAApB,oBAAoB,CAAE,QAAQ,CAAC;oBAE5D,OAAO,GAAW;wBACtB,IAAI,EAAE,WAAW;wBACjB,IAAI,EAAE,WAAW;wBACjB,OAAO,EAAE,OAAO;wBAEhB,QAAQ,EAAE,cAAe,OAAA,aAAa,EAAb,CAAa;wBAEtC,IAAI,EAAE,UAAO,IAAa,EAAE,GAAc;;;;;wCACxC,6DAA6D;wCAC7D,+CAA+C;wCAC/C,IAAI,CAAC,QAAQ,EAAE;4CACP,IAAI,GAAS,GAAG,CAAC,IAAI,EAAE,CAAC;4CAC9B,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,SAAS,CAAC;yCAC5C;wCAEK,SAAS,GAAuB,YAAY,EAAE,CAAC;wCAErD,uCAAuC;wCACvC,kBAAkB;4CAChB,OAAO,CAAC,GAAG,CACT,UAAG,gBAAgB,yDAA+C,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,WAAW,2BACxF,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,WAAW,CACvB,CACH,CAAC;wCAEJ,WAAW,GAAG,aAAa,CAAC,IAAI,CAAC,eAAe,wBAC3C,oBAAoB,KACvB,SAAS,WAAA,EACT,QAAQ,EAAE,QAAQ,IAAI,SAAS,EAC/B,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,IAC9C,CAAC,OAAO,CAAC;wCAEX,qBAAM,WAAW,EAAA;;wCAAjB,SAAiB,CAAC;wCAClB,aAAa,GAAG,IAAI,CAAC;;;;6BACtB;wBAED,KAAK,EAAE,UAAO,GAAY;;;4CACxB,qBAAM,WAAW,EAAA;;wCAAjB,SAAiB,CAAC;wCACX,qBAAM,+BAA+B,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAA;4CAA3D,sBAAO,SAAoD,EAAC;;;6BAC7D;wBAED,IAAI,EAAE,UAAO,GAAY;;;4CACvB,qBAAM,WAAW,EAAA;;wCAAjB,SAAiB,CAAC;wCACX,qBAAM,+BAA+B,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAA;4CAA3D,sBAAO,SAAoD,EAAC;;;6BAC7D;wBAED,QAAQ,EAAE,UAAO,GAAY;;;;4CAC3B,qBAAM,WAAW,EAAA;;wCAAjB,SAAiB,CAAC;wCAEZ,SAAS,GAAuB,YAAY,EAAE,CAAC;6CAEjD,SAAS,EAAT,wBAAS;wCACX,kBAAkB;4CAChB,OAAO,CAAC,GAAG,CACT,UAAG,gBAAgB,oDAA0C,SAAS,2BACpE,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,WAAW,CACvB,CACH,CAAC;wCACJ,qBAAM,YAAY,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAA;;wCAAvC,SAAuC,CAAC;;4CAG1C,sBAAO,GAAG,EAAC;;;6BACZ;qBACF,CAAC;oBAEF,qBAAM,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAA;;oBAAvC,SAAuC,CAAC;;;;;CACzC,CAAC","sourcesContent":["import * as sessionReplay from '@amplitude/session-replay-browser';\nimport { Analytics, Context, Plugin, User } from '@segment/analytics-next';\n\nimport { DEBUG_LOG_PREFIX, PLUGIN_NAME, PLUGIN_TYPE } from './constants';\nimport { getSessionId, setSessionId, updateSessionIdAndAddProperties } from './helpers';\nimport { PluginOptions } from './typings/wrapper';\nimport { VERSION } from './version';\n\nexport const createSegmentActionsPlugin = async ({\n amplitudeApiKey,\n sessionReplayOptions,\n segmentInstance,\n enableWrapperDebug = false,\n}: PluginOptions): Promise<void> => {\n let initPromise: Promise<void>;\n let isInitialized = false;\n let deviceId: string | undefined = sessionReplayOptions?.deviceId;\n\n const _plugin: Plugin = {\n name: PLUGIN_NAME,\n type: PLUGIN_TYPE,\n version: VERSION,\n\n isLoaded: (): boolean => isInitialized,\n\n load: async (_ctx: Context, ajs: Analytics): Promise<void> => {\n // If the deviceId is not provided via the plugin parameters,\n // default to use the anonymousId from the user\n if (!deviceId) {\n const user: User = ajs.user();\n deviceId = user.anonymousId() || undefined;\n }\n\n const sessionId: number | undefined = getSessionId();\n\n // Initialize the session replay plugin\n enableWrapperDebug &&\n console.log(\n `${DEBUG_LOG_PREFIX} initializing session replay with sessionId=${sessionId ?? 'undefined'} and deviceId=${\n deviceId ?? 'undefined'\n }`,\n );\n\n initPromise = sessionReplay.init(amplitudeApiKey, {\n ...sessionReplayOptions,\n sessionId,\n deviceId: deviceId || undefined,\n version: { type: 'segment', version: VERSION },\n }).promise;\n\n await initPromise;\n isInitialized = true;\n },\n\n track: async (ctx: Context): Promise<Context> => {\n await initPromise;\n return await updateSessionIdAndAddProperties(ctx, deviceId);\n },\n\n page: async (ctx: Context): Promise<Context> => {\n await initPromise;\n return await updateSessionIdAndAddProperties(ctx, deviceId);\n },\n\n identify: async (ctx: Context): Promise<Context> => {\n await initPromise;\n\n const sessionId: number | undefined = getSessionId();\n\n if (sessionId) {\n enableWrapperDebug &&\n console.log(\n `${DEBUG_LOG_PREFIX} calling setSessionId() with sessionId=${sessionId} and deviceId=${\n deviceId ?? 'undefined'\n }`,\n );\n await setSessionId(sessionId, deviceId);\n }\n\n return ctx;\n },\n };\n\n await segmentInstance.register(_plugin);\n};\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { SessionReplayOptions } from '@amplitude/session-replay-browser';
|
|
2
|
+
import { AnalyticsBrowser } from '@segment/analytics-next';
|
|
3
|
+
export interface PluginOptions {
|
|
4
|
+
segmentInstance: AnalyticsBrowser;
|
|
5
|
+
amplitudeApiKey: string;
|
|
6
|
+
sessionReplayOptions?: SessionReplayOptions;
|
|
7
|
+
enableWrapperDebug?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export type AmplitudeIntegrationData = {
|
|
10
|
+
session_id: number;
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=wrapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrapper.d.ts","sourceRoot":"","sources":["../../../src/typings/wrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,MAAM,WAAW,aAAa;IAC5B,eAAe,EAAE,gBAAgB,CAAC;IAClC,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,MAAM,wBAAwB,GAAG;IAErC,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrapper.js","sourceRoot":"","sources":["../../../src/typings/wrapper.ts"],"names":[],"mappings":"","sourcesContent":["import { SessionReplayOptions } from '@amplitude/session-replay-browser';\nimport { AnalyticsBrowser } from '@segment/analytics-next';\n\nexport interface PluginOptions {\n segmentInstance: AnalyticsBrowser;\n amplitudeApiKey: string;\n sessionReplayOptions?: SessionReplayOptions;\n enableWrapperDebug?: boolean;\n}\n\nexport type AmplitudeIntegrationData = {\n // https://github.com/segmentio/analytics-next/blob/3f15dfae034d101fb1847bc7228c0354b414d68a/packages/browser-integration-tests/src/index.test.ts#L64-L66\n session_id: number;\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,OAAO,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,MAAM,CAAC,IAAM,OAAO,GAAG,cAAc,CAAC","sourcesContent":["// Autogenerated by `yarn version-file`. DO NOT EDIT\nexport const VERSION = '0.0.0-beta.1';\n"]}
|