@fullstory/browser 2.0.6 → 2.0.8
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/dist/index.d.ts +6 -4
- package/dist/index.esm.js +3 -0
- package/dist/index.js +3 -0
- package/package.json +7 -14
- package/src/index.test.ts +33 -24
- package/src/index.ts +12 -4
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { FSApi } from '@fullstory/snippet';
|
|
|
11
11
|
* - recordCrossDomainIFrames: FullStory can record cross-domain iFrames. Defaults to `false`. Certain limitations apply and can be found [here](https://help.fullstory.com/hc/en-us/articles/360020622514-Can-FullStory-capture-content-that-is-presented-in-iframes-#h_01F1G333PYKPGZ4B42WDBV3YKV).
|
|
12
12
|
* - recordOnlyThisIFrame: FullStory can record the iFrame as its own unique session. Defaults to `false`. Additional conditions apply and can be found [here](https://help.fullstory.com/hc/en-us/articles/360020622514-Can-FullStory-capture-content-that-is-presented-in-iframes-#h_01F1G33B40Q2TPQA8MA7SF8Y5P).
|
|
13
13
|
* - devMode: In dev mode FullStory won't record sessions. Any calls to SDK methods will `console.warn` that FullStory is in `devMode`. Defaults to `false`.
|
|
14
|
+
* - sessionUid (beta): Sets the session UID passed to the `FS('init', ...)` v2 operation.
|
|
14
15
|
*/
|
|
15
16
|
export interface SnippetOptions {
|
|
16
17
|
orgId: string;
|
|
@@ -23,6 +24,7 @@ export interface SnippetOptions {
|
|
|
23
24
|
namespace?: string;
|
|
24
25
|
recordCrossDomainIFrames?: boolean;
|
|
25
26
|
recordOnlyThisIFrame?: boolean;
|
|
27
|
+
sessionUid?: string;
|
|
26
28
|
script?: string;
|
|
27
29
|
startCaptureManually?: boolean;
|
|
28
30
|
}
|
|
@@ -53,7 +55,7 @@ declare global {
|
|
|
53
55
|
_fs_script?: string;
|
|
54
56
|
}
|
|
55
57
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
export {};
|
|
58
|
+
declare const init: (inputOptions: SnippetOptions, readyCallback?: ReadyCallback) => void;
|
|
59
|
+
declare const isInitialized: () => boolean;
|
|
60
|
+
declare const FullStory: FSApi;
|
|
61
|
+
export { FullStory, init, isInitialized };
|
package/dist/index.esm.js
CHANGED
|
@@ -83,6 +83,9 @@ var _init = function (inputOptions, readyCallback) {
|
|
|
83
83
|
console.warn('Failed to initialize FS snippet');
|
|
84
84
|
return;
|
|
85
85
|
}
|
|
86
|
+
if (options.sessionUid) {
|
|
87
|
+
fs('init', { env: { sessionUid: options.sessionUid } });
|
|
88
|
+
}
|
|
86
89
|
if (readyCallback) {
|
|
87
90
|
fs('observe', { type: 'start', callback: readyCallback });
|
|
88
91
|
}
|
package/dist/index.js
CHANGED
|
@@ -85,6 +85,9 @@ var _init = function (inputOptions, readyCallback) {
|
|
|
85
85
|
console.warn('Failed to initialize FS snippet');
|
|
86
86
|
return;
|
|
87
87
|
}
|
|
88
|
+
if (options.sessionUid) {
|
|
89
|
+
fs('init', { env: { sessionUid: options.sessionUid } });
|
|
90
|
+
}
|
|
88
91
|
if (readyCallback) {
|
|
89
92
|
fs('observe', { type: 'start', callback: readyCallback });
|
|
90
93
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fullstory/browser",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.8",
|
|
4
4
|
"description": "The official Fullstory browser SDK",
|
|
5
5
|
"repository": "git://github.com/fullstorydev/fullstory-browser-sdk.git",
|
|
6
6
|
"homepage": "https://github.com/fullstorydev/fullstory-browser-sdk",
|
|
@@ -11,8 +11,7 @@
|
|
|
11
11
|
"types": "./dist/index.d.ts",
|
|
12
12
|
"scripts": {
|
|
13
13
|
"clean": "rimraf dist",
|
|
14
|
-
"
|
|
15
|
-
"test": "npm run lint && karma start --single-run --browsers ChromeHeadless karma.conf.js",
|
|
14
|
+
"test": "npm run lint && jest",
|
|
16
15
|
"lint": "eslint src",
|
|
17
16
|
"build": "rollup -c"
|
|
18
17
|
},
|
|
@@ -26,7 +25,7 @@
|
|
|
26
25
|
"sdk"
|
|
27
26
|
],
|
|
28
27
|
"dependencies": {
|
|
29
|
-
"@fullstory/snippet": "2.0.
|
|
28
|
+
"@fullstory/snippet": "2.0.6"
|
|
30
29
|
},
|
|
31
30
|
"devDependencies": {
|
|
32
31
|
"@babel/core": "^7.8.7",
|
|
@@ -34,26 +33,20 @@
|
|
|
34
33
|
"@babel/preset-env": "^7.10.4",
|
|
35
34
|
"@babel/register": "^7.8.6",
|
|
36
35
|
"@rollup/plugin-typescript": "^11.1.0",
|
|
37
|
-
"@types/
|
|
38
|
-
"@types/mocha": "^10.0.1",
|
|
36
|
+
"@types/jest": "^29.5.0",
|
|
39
37
|
"@types/node": "^18.15.11",
|
|
40
38
|
"@typescript-eslint/eslint-plugin": "^5.58.0",
|
|
41
39
|
"@typescript-eslint/parser": "^5.58.0",
|
|
42
|
-
"chai": "^4.1.2",
|
|
43
40
|
"eslint": "^8.6.0",
|
|
44
41
|
"eslint-config-airbnb": "^19.0.4",
|
|
45
42
|
"eslint-plugin-import": "^2.20.1",
|
|
46
43
|
"eslint-plugin-jsx-a11y": "^6.5.1",
|
|
47
44
|
"eslint-plugin-react": "^7.28.0",
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"karma-chrome-launcher": "^3.1.0",
|
|
51
|
-
"karma-mocha": "^2.0.1",
|
|
52
|
-
"karma-spec-reporter": "0.0.32",
|
|
53
|
-
"karma-webpack": "^5.0.0",
|
|
54
|
-
"mocha": "^9.2.0",
|
|
45
|
+
"jest": "^29.7.0",
|
|
46
|
+
"jest-environment-jsdom": "^30.3.0",
|
|
55
47
|
"rimraf": "^2.7.1",
|
|
56
48
|
"rollup": "^3.21.0",
|
|
49
|
+
"ts-jest": "^29.1.0",
|
|
57
50
|
"tslib": "^2.5.0",
|
|
58
51
|
"typescript": "^4.2.4",
|
|
59
52
|
"webpack": "^5.76.1"
|
package/src/index.test.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { assert, expect } from 'chai';
|
|
2
1
|
import {
|
|
3
2
|
FullStory as FS,
|
|
4
3
|
init,
|
|
@@ -19,23 +18,23 @@ beforeEach(() => {
|
|
|
19
18
|
|
|
20
19
|
describe('init', () => {
|
|
21
20
|
it('should throw error if not initialized with an orgId', () => {
|
|
22
|
-
expect(() => { init({} as SnippetOptions); }).
|
|
21
|
+
expect(() => { init({} as SnippetOptions); }).toThrow();
|
|
23
22
|
});
|
|
24
23
|
|
|
25
24
|
it('should throw error if API called before init', () => {
|
|
26
25
|
try {
|
|
27
26
|
FS('log', { msg: 'my log' });
|
|
28
|
-
|
|
27
|
+
throw new Error('this should have thrown');
|
|
29
28
|
} catch (error) {
|
|
30
|
-
expect((error as Error).message).
|
|
29
|
+
expect((error as Error).message).toMatch(/FullStory is not loaded/);
|
|
31
30
|
}
|
|
32
31
|
init({ orgId: testOrg });
|
|
33
|
-
expect(() => { FS('log', { msg: 'my log' }); }).
|
|
32
|
+
expect(() => { FS('log', { msg: 'my log' }); }).not.toThrow();
|
|
34
33
|
});
|
|
35
34
|
|
|
36
35
|
it('should add _fs_org value to window object', () => {
|
|
37
36
|
init({ orgId: testOrg });
|
|
38
|
-
expect(window._fs_org).
|
|
37
|
+
expect(window._fs_org).toBe(testOrg);
|
|
39
38
|
});
|
|
40
39
|
|
|
41
40
|
it('should add _fs_run_in_iframe value to window object', () => {
|
|
@@ -43,7 +42,7 @@ describe('init', () => {
|
|
|
43
42
|
orgId: testOrg,
|
|
44
43
|
recordCrossDomainIFrames: true,
|
|
45
44
|
});
|
|
46
|
-
expect(window._fs_run_in_iframe).
|
|
45
|
+
expect(window._fs_run_in_iframe).toBe(true);
|
|
47
46
|
});
|
|
48
47
|
|
|
49
48
|
it('should add _fs_is_outer_script value to window object', () => {
|
|
@@ -51,7 +50,7 @@ describe('init', () => {
|
|
|
51
50
|
orgId: testOrg,
|
|
52
51
|
recordOnlyThisIFrame: true,
|
|
53
52
|
});
|
|
54
|
-
expect(window._fs_is_outer_script).
|
|
53
|
+
expect(window._fs_is_outer_script).toBe(true);
|
|
55
54
|
});
|
|
56
55
|
|
|
57
56
|
it('should add _fs_dev_mode value to window when initialized with devMode', () => {
|
|
@@ -60,19 +59,19 @@ describe('init', () => {
|
|
|
60
59
|
devMode: true,
|
|
61
60
|
});
|
|
62
61
|
|
|
63
|
-
expect(window._fs_dev_mode).
|
|
62
|
+
expect(window._fs_dev_mode).toBe(true);
|
|
64
63
|
});
|
|
65
64
|
|
|
66
65
|
it('should return whether initialized', () => {
|
|
67
66
|
let isInit = isInitialized();
|
|
68
|
-
expect(isInit).
|
|
67
|
+
expect(isInit).toBe(false);
|
|
69
68
|
|
|
70
69
|
init({
|
|
71
70
|
orgId: testOrg,
|
|
72
71
|
});
|
|
73
72
|
|
|
74
73
|
isInit = isInitialized();
|
|
75
|
-
expect(isInit).
|
|
74
|
+
expect(isInit).toBe(true);
|
|
76
75
|
});
|
|
77
76
|
|
|
78
77
|
it('should load fs-debug.js when debug is set', () => {
|
|
@@ -81,7 +80,22 @@ describe('init', () => {
|
|
|
81
80
|
debug: true,
|
|
82
81
|
});
|
|
83
82
|
|
|
84
|
-
expect(window._fs_script).
|
|
83
|
+
expect(window._fs_script).toMatch(/fs-debug.js$/);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('should pass sessionUid to FS init', () => {
|
|
87
|
+
const sessionUid = 'session-123';
|
|
88
|
+
|
|
89
|
+
init({
|
|
90
|
+
orgId: testOrg,
|
|
91
|
+
sessionUid,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const queue = (window[window._fs_namespace ?? 'FS'] as unknown as { q?: unknown[][] }).q;
|
|
95
|
+
const initCall = queue?.find((call) => call[0] === 'init');
|
|
96
|
+
const initOptions = initCall?.[1] as { env?: { sessionUid?: string } } | undefined;
|
|
97
|
+
|
|
98
|
+
expect(initOptions?.env?.sessionUid).toBe(sessionUid);
|
|
85
99
|
});
|
|
86
100
|
});
|
|
87
101
|
|
|
@@ -98,17 +112,17 @@ describe('devMode', () => {
|
|
|
98
112
|
});
|
|
99
113
|
|
|
100
114
|
it('should return a message for functions invoked when in devMode', () => {
|
|
101
|
-
expect(consoleWarnedMessage).
|
|
115
|
+
expect(consoleWarnedMessage).toBeUndefined();
|
|
102
116
|
init({
|
|
103
117
|
orgId: testOrg,
|
|
104
118
|
devMode: true,
|
|
105
119
|
});
|
|
106
120
|
|
|
107
|
-
expect(consoleWarnedMessage).
|
|
121
|
+
expect(consoleWarnedMessage).toMatch(/FullStory was initialized in devMode/);
|
|
108
122
|
|
|
109
123
|
FS('log', { msg: 'hello world' });
|
|
110
124
|
|
|
111
|
-
expect(consoleWarnedMessage).
|
|
125
|
+
expect(consoleWarnedMessage).toBe('FullStory is in dev mode and is not capturing: log not executed');
|
|
112
126
|
});
|
|
113
127
|
});
|
|
114
128
|
|
|
@@ -118,11 +132,7 @@ describe('getCurrentSessionURL', () => {
|
|
|
118
132
|
// in theory, this is a race condition - assuming that fs.js
|
|
119
133
|
// can't load by the time the following statement is executed
|
|
120
134
|
const url = FS('getSession');
|
|
121
|
-
|
|
122
|
-
url,
|
|
123
|
-
null,
|
|
124
|
-
'FullStory.getCurrentSessionURL() should return null if executed before fs.js is fully bootstrapped'
|
|
125
|
-
);
|
|
135
|
+
expect(url).toBeNull();
|
|
126
136
|
});
|
|
127
137
|
});
|
|
128
138
|
|
|
@@ -177,7 +187,7 @@ describe('typescript safety', () => {
|
|
|
177
187
|
FS.event(42, { product_id: 'asdf' });
|
|
178
188
|
|
|
179
189
|
// Assertion for posterity's sake...
|
|
180
|
-
expect(true).
|
|
190
|
+
expect(true).toBe(true);
|
|
181
191
|
});
|
|
182
192
|
|
|
183
193
|
it('allows the optional "source" param', () => {
|
|
@@ -212,7 +222,7 @@ describe('typescript safety', () => {
|
|
|
212
222
|
});
|
|
213
223
|
|
|
214
224
|
// NOTE: don't run this test, it will hang since fs.js isn't really running. It's only for typescript safety checks.
|
|
215
|
-
|
|
225
|
+
it.skip('provides type assistance for the async api', async () => {
|
|
216
226
|
init({ orgId: testOrg });
|
|
217
227
|
|
|
218
228
|
const disconnector = await FS('observeAsync', { type: 'start', callback: () => console.log('STARTED') });
|
|
@@ -220,7 +230,6 @@ describe('typescript safety', () => {
|
|
|
220
230
|
disconnector.disconnect();
|
|
221
231
|
|
|
222
232
|
const url = await FS('getSessionAsync');
|
|
223
|
-
|
|
224
|
-
console.log(url.trim());
|
|
233
|
+
expect(url === null || typeof url === 'string' || typeof url === 'object').toBe(true); // type-check only
|
|
225
234
|
});
|
|
226
235
|
});
|
package/src/index.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { initFS, FSApi } from '@fullstory/snippet';
|
|
|
12
12
|
* - recordCrossDomainIFrames: FullStory can record cross-domain iFrames. Defaults to `false`. Certain limitations apply and can be found [here](https://help.fullstory.com/hc/en-us/articles/360020622514-Can-FullStory-capture-content-that-is-presented-in-iframes-#h_01F1G333PYKPGZ4B42WDBV3YKV).
|
|
13
13
|
* - recordOnlyThisIFrame: FullStory can record the iFrame as its own unique session. Defaults to `false`. Additional conditions apply and can be found [here](https://help.fullstory.com/hc/en-us/articles/360020622514-Can-FullStory-capture-content-that-is-presented-in-iframes-#h_01F1G33B40Q2TPQA8MA7SF8Y5P).
|
|
14
14
|
* - devMode: In dev mode FullStory won't record sessions. Any calls to SDK methods will `console.warn` that FullStory is in `devMode`. Defaults to `false`.
|
|
15
|
+
* - sessionUid (beta): Sets the session UID passed to the `FS('init', ...)` v2 operation.
|
|
15
16
|
*/
|
|
16
17
|
export interface SnippetOptions {
|
|
17
18
|
orgId: string;
|
|
@@ -24,6 +25,7 @@ export interface SnippetOptions {
|
|
|
24
25
|
namespace?: string;
|
|
25
26
|
recordCrossDomainIFrames?: boolean;
|
|
26
27
|
recordOnlyThisIFrame?: boolean;
|
|
28
|
+
sessionUid?: string;
|
|
27
29
|
script?: string;
|
|
28
30
|
startCaptureManually?: boolean;
|
|
29
31
|
}
|
|
@@ -124,6 +126,10 @@ const _init = (inputOptions: SnippetOptions, readyCallback?: ReadyCallback) => {
|
|
|
124
126
|
return;
|
|
125
127
|
}
|
|
126
128
|
|
|
129
|
+
if (options.sessionUid) {
|
|
130
|
+
fs('init', { env: { sessionUid: options.sessionUid } });
|
|
131
|
+
}
|
|
132
|
+
|
|
127
133
|
if (readyCallback) {
|
|
128
134
|
fs('observe', { type: 'start', callback: readyCallback });
|
|
129
135
|
}
|
|
@@ -151,10 +157,10 @@ const initOnce = (message) => (inputOptions: SnippetOptions, readyCallback?: Rea
|
|
|
151
157
|
window._fs_initialized = true;
|
|
152
158
|
};
|
|
153
159
|
|
|
154
|
-
|
|
160
|
+
const init = initOnce('FullStory init has already been called once, additional invocations are ignored');
|
|
155
161
|
|
|
156
162
|
// normalize undefined into boolean
|
|
157
|
-
|
|
163
|
+
const isInitialized = () => !!window._fs_initialized;
|
|
158
164
|
|
|
159
165
|
const hasFullStoryWithFunction = (...testNames) => {
|
|
160
166
|
const fs = ensureSnippetLoaded();
|
|
@@ -201,7 +207,9 @@ const buildFullStoryShim = (): FSApi => {
|
|
|
201
207
|
FS.setVars = guard('setVars');
|
|
202
208
|
FS.shutdown = guard('shutdown');
|
|
203
209
|
|
|
204
|
-
return FS;
|
|
210
|
+
return FS as FSApi;
|
|
205
211
|
};
|
|
206
212
|
|
|
207
|
-
|
|
213
|
+
const FullStory: FSApi = buildFullStoryShim();
|
|
214
|
+
|
|
215
|
+
export { FullStory, init, isInitialized };
|