@storybook/instrumenter 6.5.7 → 7.0.0-alpha.0
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/esm/instrumenter.js +485 -654
- package/dist/esm/types.js +1 -1
- package/dist/{ts3.9 → types}/index.d.ts +0 -0
- package/dist/{ts3.9 → types}/instrumenter.d.ts +0 -0
- package/dist/{ts3.9 → types}/types.d.ts +0 -0
- package/package.json +6 -7
- package/dist/modern/index.js +0 -2
- package/dist/modern/instrumenter.js +0 -710
- package/dist/modern/types.js +0 -8
- package/dist/ts3.4/index.d.ts +0 -2
- package/dist/ts3.4/instrumenter.d.ts +0 -46
- package/dist/ts3.4/types.d.ts +0 -73
package/dist/esm/instrumenter.js
CHANGED
|
@@ -1,74 +1,8 @@
|
|
|
1
|
-
import "core-js/modules/es.symbol.js";
|
|
2
|
-
import "core-js/modules/es.symbol.description.js";
|
|
3
|
-
import "core-js/modules/es.symbol.iterator.js";
|
|
4
|
-
import "core-js/modules/es.regexp.exec.js";
|
|
5
|
-
import "core-js/modules/es.symbol.to-primitive.js";
|
|
6
|
-
import "core-js/modules/es.date.to-primitive.js";
|
|
7
|
-
import "core-js/modules/es.number.constructor.js";
|
|
8
|
-
|
|
9
|
-
var _global$FEATURES;
|
|
10
|
-
|
|
11
|
-
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
|
12
|
-
|
|
13
|
-
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
14
|
-
|
|
15
1
|
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
16
2
|
|
|
17
|
-
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return
|
|
18
|
-
|
|
19
|
-
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
20
|
-
|
|
21
|
-
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
22
|
-
|
|
23
|
-
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
24
|
-
|
|
25
|
-
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
26
|
-
|
|
27
|
-
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
28
|
-
|
|
29
|
-
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
30
|
-
|
|
31
|
-
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
3
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
32
4
|
|
|
33
|
-
function
|
|
34
|
-
|
|
35
|
-
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
36
|
-
|
|
37
|
-
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
38
|
-
|
|
39
|
-
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
40
|
-
|
|
41
|
-
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
42
|
-
|
|
43
|
-
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
44
|
-
|
|
45
|
-
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
46
|
-
|
|
47
|
-
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
48
|
-
|
|
49
|
-
import "core-js/modules/es.object.to-string.js";
|
|
50
|
-
import "core-js/modules/es.array.iterator.js";
|
|
51
|
-
import "core-js/modules/es.map.js";
|
|
52
|
-
import "core-js/modules/es.string.iterator.js";
|
|
53
|
-
import "core-js/modules/web.dom-collections.iterator.js";
|
|
54
|
-
import "core-js/modules/es.set.js";
|
|
55
|
-
import "core-js/modules/es.array.filter.js";
|
|
56
|
-
import "core-js/modules/es.array.from.js";
|
|
57
|
-
import "core-js/modules/es.object.assign.js";
|
|
58
|
-
import "core-js/modules/es.array.map.js";
|
|
59
|
-
import "core-js/modules/es.array.find-index.js";
|
|
60
|
-
import "core-js/modules/es.array.slice.js";
|
|
61
|
-
import "core-js/modules/es.array.find.js";
|
|
62
|
-
import "core-js/modules/es.object.values.js";
|
|
63
|
-
import "core-js/modules/web.dom-collections.for-each.js";
|
|
64
|
-
import "core-js/modules/es.object.entries.js";
|
|
65
|
-
import "core-js/modules/es.object.keys.js";
|
|
66
|
-
import "core-js/modules/es.array.concat.js";
|
|
67
|
-
import "core-js/modules/es.promise.js";
|
|
68
|
-
import "core-js/modules/es.function.name.js";
|
|
69
|
-
import "core-js/modules/es.array.includes.js";
|
|
70
|
-
import "core-js/modules/es.array.sort.js";
|
|
71
|
-
import "core-js/modules/es.string.includes.js";
|
|
5
|
+
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
72
6
|
|
|
73
7
|
/* eslint-disable no-underscore-dangle */
|
|
74
8
|
import { addons } from '@storybook/addons';
|
|
@@ -76,7 +10,7 @@ import { once } from '@storybook/client-logger';
|
|
|
76
10
|
import { FORCE_REMOUNT, IGNORED_EXCEPTION, SET_CURRENT_STORY, STORY_RENDER_PHASE_CHANGED } from '@storybook/core-events';
|
|
77
11
|
import global from 'global';
|
|
78
12
|
import { CallStates } from './types';
|
|
79
|
-
export
|
|
13
|
+
export const EVENTS = {
|
|
80
14
|
CALL: 'instrumenter/call',
|
|
81
15
|
SYNC: 'instrumenter/sync',
|
|
82
16
|
START: 'instrumenter/start',
|
|
@@ -85,8 +19,8 @@ export var EVENTS = {
|
|
|
85
19
|
NEXT: 'instrumenter/next',
|
|
86
20
|
END: 'instrumenter/end'
|
|
87
21
|
};
|
|
88
|
-
|
|
89
|
-
|
|
22
|
+
const debuggerDisabled = global.FEATURES?.interactionsDebugger !== true;
|
|
23
|
+
const controlsDisabled = {
|
|
90
24
|
debugger: !debuggerDisabled,
|
|
91
25
|
start: false,
|
|
92
26
|
back: false,
|
|
@@ -94,26 +28,22 @@ var controlsDisabled = {
|
|
|
94
28
|
next: false,
|
|
95
29
|
end: false
|
|
96
30
|
};
|
|
97
|
-
|
|
31
|
+
const alreadyCompletedException = new Error(`This function ran after the play function completed. Did you forget to \`await\` it?`);
|
|
98
32
|
|
|
99
|
-
|
|
100
|
-
return Object.prototype.toString.call(o) === '[object Object]';
|
|
101
|
-
};
|
|
33
|
+
const isObject = o => Object.prototype.toString.call(o) === '[object Object]';
|
|
102
34
|
|
|
103
|
-
|
|
104
|
-
return Object.prototype.toString.call(o) === '[object Module]';
|
|
105
|
-
};
|
|
35
|
+
const isModule = o => Object.prototype.toString.call(o) === '[object Module]';
|
|
106
36
|
|
|
107
|
-
|
|
37
|
+
const isInstrumentable = o => {
|
|
108
38
|
if (!isObject(o) && !isModule(o)) return false;
|
|
109
39
|
if (o.constructor === undefined) return true;
|
|
110
|
-
|
|
40
|
+
const proto = o.constructor.prototype;
|
|
111
41
|
if (!isObject(proto)) return false;
|
|
112
42
|
if (Object.prototype.hasOwnProperty.call(proto, 'isPrototypeOf') === false) return false;
|
|
113
43
|
return true;
|
|
114
44
|
};
|
|
115
45
|
|
|
116
|
-
|
|
46
|
+
const construct = obj => {
|
|
117
47
|
try {
|
|
118
48
|
return new obj.constructor();
|
|
119
49
|
} catch (e) {
|
|
@@ -121,41 +51,31 @@ var construct = function construct(obj) {
|
|
|
121
51
|
}
|
|
122
52
|
};
|
|
123
53
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
var getRetainedState = function getRetainedState(state) {
|
|
144
|
-
var isDebugging = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
145
|
-
var calls = (isDebugging ? state.shadowCalls : state.calls).filter(function (call) {
|
|
146
|
-
return call.retain;
|
|
147
|
-
});
|
|
54
|
+
const getInitialState = () => ({
|
|
55
|
+
renderPhase: undefined,
|
|
56
|
+
isDebugging: false,
|
|
57
|
+
isPlaying: false,
|
|
58
|
+
isLocked: false,
|
|
59
|
+
cursor: 0,
|
|
60
|
+
calls: [],
|
|
61
|
+
shadowCalls: [],
|
|
62
|
+
callRefsByResult: new Map(),
|
|
63
|
+
chainedCallIds: new Set(),
|
|
64
|
+
parentId: undefined,
|
|
65
|
+
playUntil: undefined,
|
|
66
|
+
resolvers: {},
|
|
67
|
+
syncTimeout: undefined,
|
|
68
|
+
forwardedException: undefined
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const getRetainedState = (state, isDebugging = false) => {
|
|
72
|
+
const calls = (isDebugging ? state.shadowCalls : state.calls).filter(call => call.retain);
|
|
148
73
|
if (!calls.length) return undefined;
|
|
149
|
-
|
|
150
|
-
var _ref2 = _slicedToArray(_ref, 2),
|
|
151
|
-
ref = _ref2[1];
|
|
152
|
-
|
|
153
|
-
return ref.retain;
|
|
154
|
-
}));
|
|
74
|
+
const callRefsByResult = new Map(Array.from(state.callRefsByResult.entries()).filter(([, ref]) => ref.retain));
|
|
155
75
|
return {
|
|
156
76
|
cursor: calls.length,
|
|
157
|
-
calls
|
|
158
|
-
callRefsByResult
|
|
77
|
+
calls,
|
|
78
|
+
callRefsByResult
|
|
159
79
|
};
|
|
160
80
|
};
|
|
161
81
|
/**
|
|
@@ -163,13 +83,9 @@ var getRetainedState = function getRetainedState(state) {
|
|
|
163
83
|
*/
|
|
164
84
|
|
|
165
85
|
|
|
166
|
-
export
|
|
86
|
+
export class Instrumenter {
|
|
167
87
|
// State is tracked per story to deal with multiple stories on the same canvas (i.e. docs mode)
|
|
168
|
-
|
|
169
|
-
var _this = this;
|
|
170
|
-
|
|
171
|
-
_classCallCheck(this, Instrumenter);
|
|
172
|
-
|
|
88
|
+
constructor() {
|
|
173
89
|
this.channel = void 0;
|
|
174
90
|
this.initialized = false;
|
|
175
91
|
this.state = void 0;
|
|
@@ -177,202 +93,167 @@ export var Instrumenter = /*#__PURE__*/function () {
|
|
|
177
93
|
|
|
178
94
|
this.state = global.window.parent.__STORYBOOK_ADDON_INTERACTIONS_INSTRUMENTER_STATE__ || {}; // When called from `start`, isDebugging will be true
|
|
179
95
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
var state = _this.getState(storyId);
|
|
188
|
-
|
|
189
|
-
_this.setState(storyId, Object.assign({}, getInitialState(), getRetainedState(state, isDebugging), {
|
|
96
|
+
const resetState = ({
|
|
97
|
+
storyId,
|
|
98
|
+
isPlaying = true,
|
|
99
|
+
isDebugging = false
|
|
100
|
+
}) => {
|
|
101
|
+
const state = this.getState(storyId);
|
|
102
|
+
this.setState(storyId, Object.assign({}, getInitialState(), getRetainedState(state, isDebugging), {
|
|
190
103
|
shadowCalls: isDebugging ? state.shadowCalls : [],
|
|
191
104
|
chainedCallIds: isDebugging ? state.chainedCallIds : new Set(),
|
|
192
105
|
playUntil: isDebugging ? state.playUntil : undefined,
|
|
193
|
-
isPlaying
|
|
194
|
-
isDebugging
|
|
106
|
+
isPlaying,
|
|
107
|
+
isDebugging
|
|
195
108
|
})); // Don't sync while debugging, as it'll cause flicker.
|
|
196
109
|
|
|
197
|
-
|
|
198
|
-
if (!isDebugging) _this.sync(storyId);
|
|
110
|
+
if (!isDebugging) this.sync(storyId);
|
|
199
111
|
}; // A forceRemount might be triggered for debugging (on `start`), or elsewhere in Storybook.
|
|
200
112
|
|
|
201
113
|
|
|
202
114
|
this.channel.on(FORCE_REMOUNT, resetState); // Start with a clean slate before playing after a remount, and stop debugging when done.
|
|
203
115
|
|
|
204
|
-
this.channel.on(STORY_RENDER_PHASE_CHANGED,
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
116
|
+
this.channel.on(STORY_RENDER_PHASE_CHANGED, ({
|
|
117
|
+
storyId,
|
|
118
|
+
newPhase
|
|
119
|
+
}) => {
|
|
120
|
+
const {
|
|
121
|
+
isDebugging,
|
|
122
|
+
forwardedException
|
|
123
|
+
} = this.getState(storyId);
|
|
124
|
+
this.setState(storyId, {
|
|
213
125
|
renderPhase: newPhase
|
|
214
126
|
});
|
|
215
127
|
|
|
216
128
|
if (newPhase === 'playing') {
|
|
217
129
|
resetState({
|
|
218
|
-
storyId
|
|
219
|
-
isDebugging
|
|
130
|
+
storyId,
|
|
131
|
+
isDebugging
|
|
220
132
|
});
|
|
221
133
|
}
|
|
222
134
|
|
|
223
135
|
if (newPhase === 'played') {
|
|
224
|
-
|
|
136
|
+
this.setState(storyId, {
|
|
225
137
|
isLocked: false,
|
|
226
138
|
isPlaying: false,
|
|
227
139
|
isDebugging: false,
|
|
228
140
|
forwardedException: undefined
|
|
229
141
|
}); // Rethrow any unhandled forwarded exception so it doesn't go unnoticed.
|
|
230
142
|
|
|
231
|
-
|
|
232
143
|
if (forwardedException) throw forwardedException;
|
|
233
144
|
}
|
|
234
145
|
}); // Trash non-retained state and clear the log when switching stories, but not on initial boot.
|
|
235
146
|
|
|
236
|
-
this.channel.on(SET_CURRENT_STORY,
|
|
237
|
-
if (
|
|
147
|
+
this.channel.on(SET_CURRENT_STORY, () => {
|
|
148
|
+
if (this.initialized) this.cleanup();else this.initialized = true;
|
|
238
149
|
});
|
|
239
150
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
if (!
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
isDebugging: true
|
|
255
|
-
};
|
|
256
|
-
});
|
|
151
|
+
const start = ({
|
|
152
|
+
storyId,
|
|
153
|
+
playUntil
|
|
154
|
+
}) => {
|
|
155
|
+
if (!this.getState(storyId).isDebugging) {
|
|
156
|
+
this.setState(storyId, ({
|
|
157
|
+
calls
|
|
158
|
+
}) => ({
|
|
159
|
+
calls: [],
|
|
160
|
+
shadowCalls: calls.map(call => Object.assign({}, call, {
|
|
161
|
+
status: CallStates.WAITING
|
|
162
|
+
})),
|
|
163
|
+
isDebugging: true
|
|
164
|
+
}));
|
|
257
165
|
}
|
|
258
166
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
var shadowCalls = _ref7.shadowCalls;
|
|
265
|
-
var firstRowIndex = shadowCalls.findIndex(function (call) {
|
|
266
|
-
return call.id === log[0].callId;
|
|
267
|
-
});
|
|
167
|
+
const log = this.getLog(storyId);
|
|
168
|
+
this.setState(storyId, ({
|
|
169
|
+
shadowCalls
|
|
170
|
+
}) => {
|
|
171
|
+
const firstRowIndex = shadowCalls.findIndex(call => call.id === log[0].callId);
|
|
268
172
|
return {
|
|
269
|
-
playUntil: playUntil ||
|
|
270
|
-
return call.interceptable;
|
|
271
|
-
}).slice(-1)[0]) === null || _shadowCalls$slice$fi === void 0 ? void 0 : _shadowCalls$slice$fi.id)
|
|
173
|
+
playUntil: playUntil || shadowCalls.slice(0, firstRowIndex).filter(call => call.interceptable).slice(-1)[0]?.id
|
|
272
174
|
};
|
|
273
175
|
}); // Force remount may trigger a page reload if the play function can't be aborted.
|
|
274
176
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
storyId: storyId,
|
|
177
|
+
this.channel.emit(FORCE_REMOUNT, {
|
|
178
|
+
storyId,
|
|
278
179
|
isDebugging: true
|
|
279
180
|
});
|
|
280
181
|
};
|
|
281
182
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
var next = isDebugging ? log.findIndex(function (_ref9) {
|
|
293
|
-
var status = _ref9.status;
|
|
294
|
-
return status === CallStates.WAITING;
|
|
295
|
-
}) : log.length;
|
|
183
|
+
const back = ({
|
|
184
|
+
storyId
|
|
185
|
+
}) => {
|
|
186
|
+
const {
|
|
187
|
+
isDebugging
|
|
188
|
+
} = this.getState(storyId);
|
|
189
|
+
const log = this.getLog(storyId);
|
|
190
|
+
const next = isDebugging ? log.findIndex(({
|
|
191
|
+
status
|
|
192
|
+
}) => status === CallStates.WAITING) : log.length;
|
|
296
193
|
start({
|
|
297
|
-
storyId
|
|
298
|
-
playUntil:
|
|
194
|
+
storyId,
|
|
195
|
+
playUntil: log[next - 2]?.callId
|
|
299
196
|
});
|
|
300
197
|
};
|
|
301
198
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
return id === callId;
|
|
318
|
-
});
|
|
199
|
+
const goto = ({
|
|
200
|
+
storyId,
|
|
201
|
+
callId
|
|
202
|
+
}) => {
|
|
203
|
+
const {
|
|
204
|
+
calls,
|
|
205
|
+
shadowCalls,
|
|
206
|
+
resolvers
|
|
207
|
+
} = this.getState(storyId);
|
|
208
|
+
const call = calls.find(({
|
|
209
|
+
id
|
|
210
|
+
}) => id === callId);
|
|
211
|
+
const shadowCall = shadowCalls.find(({
|
|
212
|
+
id
|
|
213
|
+
}) => id === callId);
|
|
319
214
|
|
|
320
215
|
if (!call && shadowCall && Object.values(resolvers).length > 0) {
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
var nextId = (_this$getLog$find = _this.getLog(storyId).find(function (c) {
|
|
324
|
-
return c.status === CallStates.WAITING;
|
|
325
|
-
})) === null || _this$getLog$find === void 0 ? void 0 : _this$getLog$find.callId;
|
|
326
|
-
if (shadowCall.id !== nextId) _this.setState(storyId, {
|
|
216
|
+
const nextId = this.getLog(storyId).find(c => c.status === CallStates.WAITING)?.callId;
|
|
217
|
+
if (shadowCall.id !== nextId) this.setState(storyId, {
|
|
327
218
|
playUntil: shadowCall.id
|
|
328
219
|
});
|
|
329
|
-
Object.values(resolvers).forEach(
|
|
330
|
-
return resolve();
|
|
331
|
-
});
|
|
220
|
+
Object.values(resolvers).forEach(resolve => resolve());
|
|
332
221
|
} else {
|
|
333
222
|
start({
|
|
334
|
-
storyId
|
|
223
|
+
storyId,
|
|
335
224
|
playUntil: callId
|
|
336
225
|
});
|
|
337
226
|
}
|
|
338
227
|
};
|
|
339
228
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
229
|
+
const next = ({
|
|
230
|
+
storyId
|
|
231
|
+
}) => {
|
|
232
|
+
const {
|
|
233
|
+
resolvers
|
|
234
|
+
} = this.getState(storyId);
|
|
345
235
|
|
|
346
236
|
if (Object.values(resolvers).length > 0) {
|
|
347
|
-
Object.values(resolvers).forEach(
|
|
348
|
-
return resolve();
|
|
349
|
-
});
|
|
237
|
+
Object.values(resolvers).forEach(resolve => resolve());
|
|
350
238
|
} else {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
var nextId = (_this$getLog$find2 = _this.getLog(storyId).find(function (c) {
|
|
354
|
-
return c.status === CallStates.WAITING;
|
|
355
|
-
})) === null || _this$getLog$find2 === void 0 ? void 0 : _this$getLog$find2.callId;
|
|
239
|
+
const nextId = this.getLog(storyId).find(c => c.status === CallStates.WAITING)?.callId;
|
|
356
240
|
if (nextId) start({
|
|
357
|
-
storyId
|
|
241
|
+
storyId,
|
|
358
242
|
playUntil: nextId
|
|
359
243
|
});else end({
|
|
360
|
-
storyId
|
|
244
|
+
storyId
|
|
361
245
|
});
|
|
362
246
|
}
|
|
363
247
|
};
|
|
364
248
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
249
|
+
const end = ({
|
|
250
|
+
storyId
|
|
251
|
+
}) => {
|
|
252
|
+
this.setState(storyId, {
|
|
369
253
|
playUntil: undefined,
|
|
370
254
|
isDebugging: false
|
|
371
255
|
});
|
|
372
|
-
|
|
373
|
-
Object.values(_this.getState(storyId).resolvers).forEach(function (resolve) {
|
|
374
|
-
return resolve();
|
|
375
|
-
});
|
|
256
|
+
Object.values(this.getState(storyId).resolvers).forEach(resolve => resolve());
|
|
376
257
|
};
|
|
377
258
|
|
|
378
259
|
this.channel.on(EVENTS.START, start);
|
|
@@ -382,460 +263,412 @@ export var Instrumenter = /*#__PURE__*/function () {
|
|
|
382
263
|
this.channel.on(EVENTS.END, end);
|
|
383
264
|
}
|
|
384
265
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
return this.state[storyId] || getInitialState();
|
|
389
|
-
}
|
|
390
|
-
}, {
|
|
391
|
-
key: "setState",
|
|
392
|
-
value: function setState(storyId, update) {
|
|
393
|
-
var state = this.getState(storyId);
|
|
394
|
-
var patch = typeof update === 'function' ? update(state) : update;
|
|
395
|
-
this.state = Object.assign({}, this.state, _defineProperty({}, storyId, Object.assign({}, state, patch))); // Track state on the parent window so we can reload the iframe without losing state.
|
|
396
|
-
|
|
397
|
-
global.window.parent.__STORYBOOK_ADDON_INTERACTIONS_INSTRUMENTER_STATE__ = this.state;
|
|
398
|
-
}
|
|
399
|
-
}, {
|
|
400
|
-
key: "cleanup",
|
|
401
|
-
value: function cleanup() {
|
|
402
|
-
// Reset stories with retained state to their initial state, and drop the rest.
|
|
403
|
-
this.state = Object.entries(this.state).reduce(function (acc, _ref15) {
|
|
404
|
-
var _ref16 = _slicedToArray(_ref15, 2),
|
|
405
|
-
storyId = _ref16[0],
|
|
406
|
-
state = _ref16[1];
|
|
407
|
-
|
|
408
|
-
var retainedState = getRetainedState(state);
|
|
409
|
-
if (!retainedState) return acc;
|
|
410
|
-
acc[storyId] = Object.assign(getInitialState(), retainedState);
|
|
411
|
-
return acc;
|
|
412
|
-
}, {});
|
|
413
|
-
this.channel.emit(EVENTS.SYNC, {
|
|
414
|
-
controlStates: controlsDisabled,
|
|
415
|
-
logItems: []
|
|
416
|
-
});
|
|
417
|
-
global.window.parent.__STORYBOOK_ADDON_INTERACTIONS_INSTRUMENTER_STATE__ = this.state;
|
|
418
|
-
}
|
|
419
|
-
}, {
|
|
420
|
-
key: "getLog",
|
|
421
|
-
value: function getLog(storyId) {
|
|
422
|
-
var _this$getState5 = this.getState(storyId),
|
|
423
|
-
calls = _this$getState5.calls,
|
|
424
|
-
shadowCalls = _this$getState5.shadowCalls;
|
|
266
|
+
getState(storyId) {
|
|
267
|
+
return this.state[storyId] || getInitialState();
|
|
268
|
+
}
|
|
425
269
|
|
|
426
|
-
|
|
270
|
+
setState(storyId, update) {
|
|
271
|
+
const state = this.getState(storyId);
|
|
272
|
+
const patch = typeof update === 'function' ? update(state) : update;
|
|
273
|
+
this.state = Object.assign({}, this.state, {
|
|
274
|
+
[storyId]: Object.assign({}, state, patch)
|
|
275
|
+
}); // Track state on the parent window so we can reload the iframe without losing state.
|
|
427
276
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
});
|
|
431
|
-
var seen = new Set();
|
|
432
|
-
return merged.reduceRight(function (acc, call) {
|
|
433
|
-
call.args.forEach(function (arg) {
|
|
434
|
-
if (arg !== null && arg !== void 0 && arg.__callId__) {
|
|
435
|
-
seen.add(arg.__callId__);
|
|
436
|
-
}
|
|
437
|
-
});
|
|
438
|
-
call.path.forEach(function (node) {
|
|
439
|
-
if (node.__callId__) {
|
|
440
|
-
seen.add(node.__callId__);
|
|
441
|
-
}
|
|
442
|
-
});
|
|
277
|
+
global.window.parent.__STORYBOOK_ADDON_INTERACTIONS_INSTRUMENTER_STATE__ = this.state;
|
|
278
|
+
}
|
|
443
279
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
280
|
+
cleanup() {
|
|
281
|
+
// Reset stories with retained state to their initial state, and drop the rest.
|
|
282
|
+
this.state = Object.entries(this.state).reduce((acc, [storyId, state]) => {
|
|
283
|
+
const retainedState = getRetainedState(state);
|
|
284
|
+
if (!retainedState) return acc;
|
|
285
|
+
acc[storyId] = Object.assign(getInitialState(), retainedState);
|
|
286
|
+
return acc;
|
|
287
|
+
}, {});
|
|
288
|
+
this.channel.emit(EVENTS.SYNC, {
|
|
289
|
+
controlStates: controlsDisabled,
|
|
290
|
+
logItems: []
|
|
291
|
+
});
|
|
292
|
+
global.window.parent.__STORYBOOK_ADDON_INTERACTIONS_INSTRUMENTER_STATE__ = this.state;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
getLog(storyId) {
|
|
296
|
+
const {
|
|
297
|
+
calls,
|
|
298
|
+
shadowCalls
|
|
299
|
+
} = this.getState(storyId);
|
|
300
|
+
const merged = [...shadowCalls];
|
|
301
|
+
calls.forEach((call, index) => {
|
|
302
|
+
merged[index] = call;
|
|
303
|
+
});
|
|
304
|
+
const seen = new Set();
|
|
305
|
+
return merged.reduceRight((acc, call) => {
|
|
306
|
+
call.args.forEach(arg => {
|
|
307
|
+
if (arg?.__callId__) {
|
|
308
|
+
seen.add(arg.__callId__);
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
call.path.forEach(node => {
|
|
312
|
+
if (node.__callId__) {
|
|
313
|
+
seen.add(node.__callId__);
|
|
450
314
|
}
|
|
315
|
+
});
|
|
451
316
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
key: "instrument",
|
|
460
|
-
value: function instrument(obj, options) {
|
|
461
|
-
var _this2 = this;
|
|
462
|
-
|
|
463
|
-
if (!isInstrumentable(obj)) return obj;
|
|
464
|
-
var _options$mutate = options.mutate,
|
|
465
|
-
mutate = _options$mutate === void 0 ? false : _options$mutate,
|
|
466
|
-
_options$path = options.path,
|
|
467
|
-
path = _options$path === void 0 ? [] : _options$path;
|
|
468
|
-
return Object.keys(obj).reduce(function (acc, key) {
|
|
469
|
-
var value = obj[key]; // Nothing to patch, but might be instrumentable, so we recurse
|
|
470
|
-
|
|
471
|
-
if (typeof value !== 'function') {
|
|
472
|
-
acc[key] = _this2.instrument(value, Object.assign({}, options, {
|
|
473
|
-
path: path.concat(key)
|
|
474
|
-
}));
|
|
475
|
-
return acc;
|
|
476
|
-
} // Already patched, so we pass through unchanged
|
|
317
|
+
if (call.interceptable && !seen.has(call.id)) {
|
|
318
|
+
acc.unshift({
|
|
319
|
+
callId: call.id,
|
|
320
|
+
status: call.status
|
|
321
|
+
});
|
|
322
|
+
seen.add(call.id);
|
|
323
|
+
}
|
|
477
324
|
|
|
325
|
+
return acc;
|
|
326
|
+
}, []);
|
|
327
|
+
} // Traverses the object structure to recursively patch all function properties.
|
|
328
|
+
// Returns the original object, or a new object with the same constructor,
|
|
329
|
+
// depending on whether it should mutate.
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
instrument(obj, options) {
|
|
333
|
+
if (!isInstrumentable(obj)) return obj;
|
|
334
|
+
const {
|
|
335
|
+
mutate = false,
|
|
336
|
+
path = []
|
|
337
|
+
} = options;
|
|
338
|
+
return Object.keys(obj).reduce((acc, key) => {
|
|
339
|
+
const value = obj[key]; // Nothing to patch, but might be instrumentable, so we recurse
|
|
340
|
+
|
|
341
|
+
if (typeof value !== 'function') {
|
|
342
|
+
acc[key] = this.instrument(value, Object.assign({}, options, {
|
|
343
|
+
path: path.concat(key)
|
|
344
|
+
}));
|
|
345
|
+
return acc;
|
|
346
|
+
} // Already patched, so we pass through unchanged
|
|
478
347
|
|
|
479
|
-
if (typeof value.__originalFn__ === 'function') {
|
|
480
|
-
acc[key] = value;
|
|
481
|
-
return acc;
|
|
482
|
-
} // Patch the function and mark it "patched" by adding a reference to the original function
|
|
483
348
|
|
|
349
|
+
if (typeof value.__originalFn__ === 'function') {
|
|
350
|
+
acc[key] = value;
|
|
351
|
+
return acc;
|
|
352
|
+
} // Patch the function and mark it "patched" by adding a reference to the original function
|
|
484
353
|
|
|
485
|
-
acc[key] = function () {
|
|
486
|
-
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
487
|
-
args[_key] = arguments[_key];
|
|
488
|
-
}
|
|
489
354
|
|
|
490
|
-
|
|
491
|
-
};
|
|
355
|
+
acc[key] = (...args) => this.track(key, value, args, options);
|
|
492
356
|
|
|
493
|
-
|
|
357
|
+
acc[key].__originalFn__ = value; // Reuse the original name as the patched function's name
|
|
494
358
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
359
|
+
Object.defineProperty(acc[key], 'name', {
|
|
360
|
+
value: key,
|
|
361
|
+
writable: false
|
|
362
|
+
}); // Deal with functions that also act like an object
|
|
499
363
|
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
364
|
+
if (Object.keys(value).length > 0) {
|
|
365
|
+
Object.assign(acc[key], this.instrument(Object.assign({}, value), Object.assign({}, options, {
|
|
366
|
+
path: path.concat(key)
|
|
367
|
+
})));
|
|
368
|
+
}
|
|
505
369
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
370
|
+
return acc;
|
|
371
|
+
}, mutate ? obj : construct(obj));
|
|
372
|
+
} // Monkey patch an object method to record calls.
|
|
373
|
+
// Returns a function that invokes the original function, records the invocation ("call") and
|
|
374
|
+
// returns the original result.
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
track(method, fn, args, options) {
|
|
378
|
+
const storyId = args?.[0]?.__storyId__ || global.window.__STORYBOOK_PREVIEW__?.urlStore?.selection?.storyId;
|
|
379
|
+
const {
|
|
380
|
+
cursor,
|
|
381
|
+
parentId
|
|
382
|
+
} = this.getState(storyId);
|
|
383
|
+
this.setState(storyId, {
|
|
384
|
+
cursor: cursor + 1
|
|
385
|
+
});
|
|
386
|
+
const id = `${parentId || storyId} [${cursor}] ${method}`;
|
|
387
|
+
const {
|
|
388
|
+
path = [],
|
|
389
|
+
intercept = false,
|
|
390
|
+
retain = false
|
|
391
|
+
} = options;
|
|
392
|
+
const interceptable = typeof intercept === 'function' ? intercept(method, path) : intercept;
|
|
393
|
+
const call = {
|
|
394
|
+
id,
|
|
395
|
+
parentId,
|
|
396
|
+
storyId,
|
|
397
|
+
cursor,
|
|
398
|
+
path,
|
|
399
|
+
method,
|
|
400
|
+
args,
|
|
401
|
+
interceptable,
|
|
402
|
+
retain
|
|
403
|
+
};
|
|
404
|
+
const result = (interceptable ? this.intercept : this.invoke).call(this, fn, call, options);
|
|
405
|
+
return this.instrument(result, Object.assign({}, options, {
|
|
406
|
+
mutate: true,
|
|
407
|
+
path: [{
|
|
408
|
+
__callId__: call.id
|
|
409
|
+
}]
|
|
410
|
+
}));
|
|
411
|
+
}
|
|
511
412
|
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
413
|
+
intercept(fn, call, options) {
|
|
414
|
+
const {
|
|
415
|
+
chainedCallIds,
|
|
416
|
+
isDebugging,
|
|
417
|
+
playUntil
|
|
418
|
+
} = this.getState(call.storyId); // For a "jump to step" action, continue playing until we hit a call by that ID.
|
|
419
|
+
// For chained calls, we can only return a Promise for the last call in the chain.
|
|
516
420
|
|
|
517
|
-
|
|
421
|
+
const isChainedUpon = chainedCallIds.has(call.id);
|
|
518
422
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
423
|
+
if (!isDebugging || isChainedUpon || playUntil) {
|
|
424
|
+
if (playUntil === call.id) {
|
|
425
|
+
this.setState(call.storyId, {
|
|
426
|
+
playUntil: undefined
|
|
427
|
+
});
|
|
428
|
+
}
|
|
522
429
|
|
|
523
|
-
this.
|
|
524
|
-
|
|
525
|
-
});
|
|
526
|
-
var id = "".concat(parentId || storyId, " [").concat(cursor, "] ").concat(method);
|
|
527
|
-
var _options$path2 = options.path,
|
|
528
|
-
path = _options$path2 === void 0 ? [] : _options$path2,
|
|
529
|
-
_options$intercept = options.intercept,
|
|
530
|
-
intercept = _options$intercept === void 0 ? false : _options$intercept,
|
|
531
|
-
_options$retain = options.retain,
|
|
532
|
-
retain = _options$retain === void 0 ? false : _options$retain;
|
|
533
|
-
var interceptable = typeof intercept === 'function' ? intercept(method, path) : intercept;
|
|
534
|
-
var call = {
|
|
535
|
-
id: id,
|
|
536
|
-
parentId: parentId,
|
|
537
|
-
storyId: storyId,
|
|
538
|
-
cursor: cursor,
|
|
539
|
-
path: path,
|
|
540
|
-
method: method,
|
|
541
|
-
args: args,
|
|
542
|
-
interceptable: interceptable,
|
|
543
|
-
retain: retain
|
|
544
|
-
};
|
|
545
|
-
var result = (interceptable ? this.intercept : this.invoke).call(this, fn, call, options);
|
|
546
|
-
return this.instrument(result, Object.assign({}, options, {
|
|
547
|
-
mutate: true,
|
|
548
|
-
path: [{
|
|
549
|
-
__callId__: call.id
|
|
550
|
-
}]
|
|
551
|
-
}));
|
|
552
|
-
}
|
|
553
|
-
}, {
|
|
554
|
-
key: "intercept",
|
|
555
|
-
value: function intercept(fn, call, options) {
|
|
556
|
-
var _this3 = this;
|
|
430
|
+
return this.invoke(fn, call, options);
|
|
431
|
+
} // Instead of invoking the function, defer the function call until we continue playing.
|
|
557
432
|
|
|
558
|
-
var _this$getState7 = this.getState(call.storyId),
|
|
559
|
-
chainedCallIds = _this$getState7.chainedCallIds,
|
|
560
|
-
isDebugging = _this$getState7.isDebugging,
|
|
561
|
-
playUntil = _this$getState7.playUntil; // For a "jump to step" action, continue playing until we hit a call by that ID.
|
|
562
|
-
// For chained calls, we can only return a Promise for the last call in the chain.
|
|
563
433
|
|
|
434
|
+
return new Promise(resolve => {
|
|
435
|
+
this.setState(call.storyId, ({
|
|
436
|
+
resolvers
|
|
437
|
+
}) => ({
|
|
438
|
+
isLocked: false,
|
|
439
|
+
resolvers: Object.assign({}, resolvers, {
|
|
440
|
+
[call.id]: resolve
|
|
441
|
+
})
|
|
442
|
+
}));
|
|
443
|
+
}).then(() => {
|
|
444
|
+
this.setState(call.storyId, state => {
|
|
445
|
+
const _state$resolvers = state.resolvers,
|
|
446
|
+
_call$id = call.id,
|
|
447
|
+
resolvers = _objectWithoutPropertiesLoose(_state$resolvers, [_call$id].map(_toPropertyKey));
|
|
564
448
|
|
|
565
|
-
|
|
449
|
+
return {
|
|
450
|
+
isLocked: true,
|
|
451
|
+
resolvers
|
|
452
|
+
};
|
|
453
|
+
});
|
|
454
|
+
return this.invoke(fn, call, options);
|
|
455
|
+
});
|
|
456
|
+
}
|
|
566
457
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
458
|
+
invoke(fn, call, options) {
|
|
459
|
+
// TODO this doesnt work because the abortSignal we have here is the newly created one
|
|
460
|
+
// const { abortSignal } = global.window.__STORYBOOK_PREVIEW__ || {};
|
|
461
|
+
// if (abortSignal && abortSignal.aborted) throw IGNORED_EXCEPTION;
|
|
462
|
+
const {
|
|
463
|
+
callRefsByResult,
|
|
464
|
+
forwardedException,
|
|
465
|
+
renderPhase
|
|
466
|
+
} = this.getState(call.storyId);
|
|
467
|
+
const info = Object.assign({}, call, {
|
|
468
|
+
// Map args that originate from a tracked function call to a call reference to enable nesting.
|
|
469
|
+
// These values are often not fully serializable anyway (e.g. HTML elements).
|
|
470
|
+
args: call.args.map(arg => {
|
|
471
|
+
if (callRefsByResult.has(arg)) {
|
|
472
|
+
return callRefsByResult.get(arg);
|
|
572
473
|
}
|
|
573
474
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
475
|
+
if (arg instanceof global.window.HTMLElement) {
|
|
476
|
+
const {
|
|
477
|
+
prefix,
|
|
478
|
+
localName,
|
|
479
|
+
id,
|
|
480
|
+
classList,
|
|
481
|
+
innerText
|
|
482
|
+
} = arg;
|
|
483
|
+
const classNames = Array.from(classList);
|
|
581
484
|
return {
|
|
582
|
-
|
|
583
|
-
|
|
485
|
+
__element__: {
|
|
486
|
+
prefix,
|
|
487
|
+
localName,
|
|
488
|
+
id,
|
|
489
|
+
classNames,
|
|
490
|
+
innerText
|
|
491
|
+
}
|
|
584
492
|
};
|
|
585
|
-
});
|
|
586
|
-
}).then(function () {
|
|
587
|
-
_this3.setState(call.storyId, function (state) {
|
|
588
|
-
var _state$resolvers = state.resolvers,
|
|
589
|
-
_call$id = call.id,
|
|
590
|
-
_ = _state$resolvers[_call$id],
|
|
591
|
-
resolvers = _objectWithoutProperties(_state$resolvers, [_call$id].map(_toPropertyKey));
|
|
592
|
-
|
|
593
|
-
return {
|
|
594
|
-
isLocked: true,
|
|
595
|
-
resolvers: resolvers
|
|
596
|
-
};
|
|
597
|
-
});
|
|
598
|
-
|
|
599
|
-
return _this3.invoke(fn, call, options);
|
|
600
|
-
});
|
|
601
|
-
}
|
|
602
|
-
}, {
|
|
603
|
-
key: "invoke",
|
|
604
|
-
value: function invoke(fn, call, options) {
|
|
605
|
-
var _this4 = this;
|
|
606
|
-
|
|
607
|
-
// TODO this doesnt work because the abortSignal we have here is the newly created one
|
|
608
|
-
// const { abortSignal } = global.window.__STORYBOOK_PREVIEW__ || {};
|
|
609
|
-
// if (abortSignal && abortSignal.aborted) throw IGNORED_EXCEPTION;
|
|
610
|
-
var _this$getState8 = this.getState(call.storyId),
|
|
611
|
-
callRefsByResult = _this$getState8.callRefsByResult,
|
|
612
|
-
forwardedException = _this$getState8.forwardedException,
|
|
613
|
-
renderPhase = _this$getState8.renderPhase;
|
|
614
|
-
|
|
615
|
-
var info = Object.assign({}, call, {
|
|
616
|
-
// Map args that originate from a tracked function call to a call reference to enable nesting.
|
|
617
|
-
// These values are often not fully serializable anyway (e.g. HTML elements).
|
|
618
|
-
args: call.args.map(function (arg) {
|
|
619
|
-
if (callRefsByResult.has(arg)) {
|
|
620
|
-
return callRefsByResult.get(arg);
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
if (arg instanceof global.window.HTMLElement) {
|
|
624
|
-
var prefix = arg.prefix,
|
|
625
|
-
localName = arg.localName,
|
|
626
|
-
id = arg.id,
|
|
627
|
-
classList = arg.classList,
|
|
628
|
-
innerText = arg.innerText;
|
|
629
|
-
var classNames = Array.from(classList);
|
|
630
|
-
return {
|
|
631
|
-
__element__: {
|
|
632
|
-
prefix: prefix,
|
|
633
|
-
localName: localName,
|
|
634
|
-
id: id,
|
|
635
|
-
classNames: classNames,
|
|
636
|
-
innerText: innerText
|
|
637
|
-
}
|
|
638
|
-
};
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
return arg;
|
|
642
|
-
})
|
|
643
|
-
}); // Mark any ancestor calls as "chained upon" so we won't attempt to defer it later.
|
|
644
|
-
|
|
645
|
-
call.path.forEach(function (ref) {
|
|
646
|
-
if (ref !== null && ref !== void 0 && ref.__callId__) {
|
|
647
|
-
_this4.setState(call.storyId, function (_ref18) {
|
|
648
|
-
var chainedCallIds = _ref18.chainedCallIds;
|
|
649
|
-
return {
|
|
650
|
-
chainedCallIds: new Set(Array.from(chainedCallIds).concat(ref.__callId__))
|
|
651
|
-
};
|
|
652
|
-
});
|
|
653
493
|
}
|
|
654
|
-
});
|
|
655
494
|
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
message = e.message,
|
|
660
|
-
stack = e.stack;
|
|
661
|
-
var exception = {
|
|
662
|
-
name: name,
|
|
663
|
-
message: message,
|
|
664
|
-
stack: stack
|
|
665
|
-
};
|
|
495
|
+
return arg;
|
|
496
|
+
})
|
|
497
|
+
}); // Mark any ancestor calls as "chained upon" so we won't attempt to defer it later.
|
|
666
498
|
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
__callId__: call.id,
|
|
677
|
-
retain: call.retain
|
|
678
|
-
}]]))
|
|
679
|
-
};
|
|
680
|
-
}); // We need to throw to break out of the play function, but we don't want to trigger a redbox
|
|
681
|
-
// so we throw an ignoredException, which is caught and silently ignored by Storybook.
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
if (call.interceptable && e !== alreadyCompletedException) {
|
|
685
|
-
throw IGNORED_EXCEPTION;
|
|
686
|
-
} // Non-interceptable calls need their exceptions forwarded to the next interceptable call.
|
|
687
|
-
// In case no interceptable call picks it up, it'll get rethrown in the "completed" phase.
|
|
499
|
+
call.path.forEach(ref => {
|
|
500
|
+
if (ref?.__callId__) {
|
|
501
|
+
this.setState(call.storyId, ({
|
|
502
|
+
chainedCallIds
|
|
503
|
+
}) => ({
|
|
504
|
+
chainedCallIds: new Set(Array.from(chainedCallIds).concat(ref.__callId__))
|
|
505
|
+
}));
|
|
506
|
+
}
|
|
507
|
+
});
|
|
688
508
|
|
|
509
|
+
const handleException = e => {
|
|
510
|
+
if (e instanceof Error) {
|
|
511
|
+
const {
|
|
512
|
+
name,
|
|
513
|
+
message,
|
|
514
|
+
stack
|
|
515
|
+
} = e;
|
|
516
|
+
const exception = {
|
|
517
|
+
name,
|
|
518
|
+
message,
|
|
519
|
+
stack
|
|
520
|
+
};
|
|
521
|
+
this.update(Object.assign({}, info, {
|
|
522
|
+
status: CallStates.ERROR,
|
|
523
|
+
exception
|
|
524
|
+
})); // Always track errors to their originating call.
|
|
525
|
+
|
|
526
|
+
this.setState(call.storyId, state => ({
|
|
527
|
+
callRefsByResult: new Map([...Array.from(state.callRefsByResult.entries()), [e, {
|
|
528
|
+
__callId__: call.id,
|
|
529
|
+
retain: call.retain
|
|
530
|
+
}]])
|
|
531
|
+
})); // We need to throw to break out of the play function, but we don't want to trigger a redbox
|
|
532
|
+
// so we throw an ignoredException, which is caught and silently ignored by Storybook.
|
|
533
|
+
|
|
534
|
+
if (call.interceptable && e !== alreadyCompletedException) {
|
|
535
|
+
throw IGNORED_EXCEPTION;
|
|
536
|
+
} // Non-interceptable calls need their exceptions forwarded to the next interceptable call.
|
|
537
|
+
// In case no interceptable call picks it up, it'll get rethrown in the "completed" phase.
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
this.setState(call.storyId, {
|
|
541
|
+
forwardedException: e
|
|
542
|
+
});
|
|
543
|
+
return e;
|
|
544
|
+
}
|
|
689
545
|
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
});
|
|
546
|
+
throw e;
|
|
547
|
+
};
|
|
693
548
|
|
|
694
|
-
|
|
695
|
-
|
|
549
|
+
try {
|
|
550
|
+
// An earlier, non-interceptable call might have forwarded an exception.
|
|
551
|
+
if (forwardedException) {
|
|
552
|
+
this.setState(call.storyId, {
|
|
553
|
+
forwardedException: undefined
|
|
554
|
+
});
|
|
555
|
+
throw forwardedException;
|
|
556
|
+
}
|
|
696
557
|
|
|
697
|
-
|
|
698
|
-
|
|
558
|
+
if (renderPhase === 'played' && !call.retain) {
|
|
559
|
+
throw alreadyCompletedException;
|
|
560
|
+
}
|
|
699
561
|
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
562
|
+
const finalArgs = options.getArgs ? options.getArgs(call, this.getState(call.storyId)) : call.args;
|
|
563
|
+
const result = fn( // Wrap any callback functions to provide a way to access their "parent" call.
|
|
564
|
+
// This is picked up in the `track` function and used for call metadata.
|
|
565
|
+
...finalArgs.map(arg => {
|
|
566
|
+
if (typeof arg !== 'function' || Object.keys(arg).length) return arg;
|
|
567
|
+
return (...args) => {
|
|
568
|
+
const {
|
|
569
|
+
cursor,
|
|
570
|
+
parentId
|
|
571
|
+
} = this.getState(call.storyId);
|
|
703
572
|
this.setState(call.storyId, {
|
|
704
|
-
|
|
573
|
+
cursor: 0,
|
|
574
|
+
parentId: call.id
|
|
705
575
|
});
|
|
706
|
-
throw forwardedException;
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
if (renderPhase === 'played' && !call.retain) {
|
|
710
|
-
throw alreadyCompletedException;
|
|
711
|
-
}
|
|
712
576
|
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
return function () {
|
|
717
|
-
var _this4$getState = _this4.getState(call.storyId),
|
|
718
|
-
cursor = _this4$getState.cursor,
|
|
719
|
-
parentId = _this4$getState.parentId;
|
|
720
|
-
|
|
721
|
-
_this4.setState(call.storyId, {
|
|
722
|
-
cursor: 0,
|
|
723
|
-
parentId: call.id
|
|
724
|
-
});
|
|
725
|
-
|
|
726
|
-
var restore = function restore() {
|
|
727
|
-
return _this4.setState(call.storyId, {
|
|
728
|
-
cursor: cursor,
|
|
729
|
-
parentId: parentId
|
|
730
|
-
});
|
|
731
|
-
};
|
|
732
|
-
|
|
733
|
-
var res = arg.apply(void 0, arguments);
|
|
734
|
-
if (res instanceof Promise) res.then(restore, restore);else restore();
|
|
735
|
-
return res;
|
|
736
|
-
};
|
|
737
|
-
}))); // Track the result so we can trace later uses of it back to the originating call.
|
|
738
|
-
// Primitive results (undefined, null, boolean, string, number, BigInt) are ignored.
|
|
739
|
-
|
|
740
|
-
if (result && ['object', 'function', 'symbol'].includes(_typeof(result))) {
|
|
741
|
-
this.setState(call.storyId, function (state) {
|
|
742
|
-
return {
|
|
743
|
-
callRefsByResult: new Map([].concat(_toConsumableArray(Array.from(state.callRefsByResult.entries())), [[result, {
|
|
744
|
-
__callId__: call.id,
|
|
745
|
-
retain: call.retain
|
|
746
|
-
}]]))
|
|
747
|
-
};
|
|
577
|
+
const restore = () => this.setState(call.storyId, {
|
|
578
|
+
cursor,
|
|
579
|
+
parentId
|
|
748
580
|
});
|
|
749
|
-
}
|
|
750
581
|
|
|
751
|
-
|
|
752
|
-
|
|
582
|
+
const res = arg(...args);
|
|
583
|
+
if (res instanceof Promise) res.then(restore, restore);else restore();
|
|
584
|
+
return res;
|
|
585
|
+
};
|
|
586
|
+
})); // Track the result so we can trace later uses of it back to the originating call.
|
|
587
|
+
// Primitive results (undefined, null, boolean, string, number, BigInt) are ignored.
|
|
588
|
+
|
|
589
|
+
if (result && ['object', 'function', 'symbol'].includes(typeof result)) {
|
|
590
|
+
this.setState(call.storyId, state => ({
|
|
591
|
+
callRefsByResult: new Map([...Array.from(state.callRefsByResult.entries()), [result, {
|
|
592
|
+
__callId__: call.id,
|
|
593
|
+
retain: call.retain
|
|
594
|
+
}]])
|
|
753
595
|
}));
|
|
596
|
+
}
|
|
754
597
|
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
status: CallStates.DONE
|
|
759
|
-
}));
|
|
760
|
-
|
|
761
|
-
return value;
|
|
762
|
-
}, handleException);
|
|
763
|
-
}
|
|
598
|
+
this.update(Object.assign({}, info, {
|
|
599
|
+
status: result instanceof Promise ? CallStates.ACTIVE : CallStates.DONE
|
|
600
|
+
}));
|
|
764
601
|
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
602
|
+
if (result instanceof Promise) {
|
|
603
|
+
return result.then(value => {
|
|
604
|
+
this.update(Object.assign({}, info, {
|
|
605
|
+
status: CallStates.DONE
|
|
606
|
+
}));
|
|
607
|
+
return value;
|
|
608
|
+
}, handleException);
|
|
768
609
|
}
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
key: "update",
|
|
774
|
-
value: function update(call) {
|
|
775
|
-
var _this5 = this;
|
|
776
|
-
|
|
777
|
-
clearTimeout(this.getState(call.storyId).syncTimeout);
|
|
778
|
-
this.channel.emit(EVENTS.CALL, call);
|
|
779
|
-
this.setState(call.storyId, function (_ref19) {
|
|
780
|
-
var calls = _ref19.calls;
|
|
781
|
-
// Omit earlier calls for the same ID, which may have been superceded by a later invocation.
|
|
782
|
-
// This typically happens when calls are part of a callback which runs multiple times.
|
|
783
|
-
var callsById = calls.concat(call).reduce(function (a, c) {
|
|
784
|
-
return Object.assign(a, _defineProperty({}, c.id, c));
|
|
785
|
-
}, {});
|
|
786
|
-
return {
|
|
787
|
-
// Calls are sorted to ensure parent calls always come before calls in their callback.
|
|
788
|
-
calls: Object.values(callsById).sort(function (a, b) {
|
|
789
|
-
return a.id.localeCompare(b.id, undefined, {
|
|
790
|
-
numeric: true
|
|
791
|
-
});
|
|
792
|
-
}),
|
|
793
|
-
syncTimeout: setTimeout(function () {
|
|
794
|
-
return _this5.sync(call.storyId);
|
|
795
|
-
}, 0)
|
|
796
|
-
};
|
|
797
|
-
});
|
|
610
|
+
|
|
611
|
+
return result;
|
|
612
|
+
} catch (e) {
|
|
613
|
+
return handleException(e);
|
|
798
614
|
}
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
615
|
+
} // Sends the call info and log to the manager.
|
|
616
|
+
// Uses a 0ms debounce because this might get called many times in one tick.
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
update(call) {
|
|
620
|
+
clearTimeout(this.getState(call.storyId).syncTimeout);
|
|
621
|
+
this.channel.emit(EVENTS.CALL, call);
|
|
622
|
+
this.setState(call.storyId, ({
|
|
623
|
+
calls
|
|
624
|
+
}) => {
|
|
625
|
+
// Omit earlier calls for the same ID, which may have been superceded by a later invocation.
|
|
626
|
+
// This typically happens when calls are part of a callback which runs multiple times.
|
|
627
|
+
const callsById = calls.concat(call).reduce((a, c) => Object.assign(a, {
|
|
628
|
+
[c.id]: c
|
|
629
|
+
}), {});
|
|
630
|
+
return {
|
|
631
|
+
// Calls are sorted to ensure parent calls always come before calls in their callback.
|
|
632
|
+
calls: Object.values(callsById).sort((a, b) => a.id.localeCompare(b.id, undefined, {
|
|
633
|
+
numeric: true
|
|
634
|
+
})),
|
|
635
|
+
syncTimeout: setTimeout(() => this.sync(call.storyId), 0)
|
|
636
|
+
};
|
|
637
|
+
});
|
|
638
|
+
}
|
|
810
639
|
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
640
|
+
sync(storyId) {
|
|
641
|
+
const {
|
|
642
|
+
isLocked,
|
|
643
|
+
isPlaying
|
|
644
|
+
} = this.getState(storyId);
|
|
645
|
+
const logItems = this.getLog(storyId);
|
|
646
|
+
const hasActive = logItems.some(item => item.status === CallStates.ACTIVE);
|
|
818
647
|
|
|
819
|
-
|
|
820
|
-
return [CallStates.DONE, CallStates.ERROR].includes(item.status);
|
|
821
|
-
});
|
|
822
|
-
var controlStates = {
|
|
823
|
-
debugger: true,
|
|
824
|
-
start: hasPrevious,
|
|
825
|
-
back: hasPrevious,
|
|
826
|
-
goto: true,
|
|
827
|
-
next: isPlaying,
|
|
828
|
-
end: isPlaying
|
|
829
|
-
};
|
|
648
|
+
if (debuggerDisabled || isLocked || hasActive || logItems.length === 0) {
|
|
830
649
|
this.channel.emit(EVENTS.SYNC, {
|
|
831
|
-
controlStates:
|
|
832
|
-
logItems
|
|
650
|
+
controlStates: controlsDisabled,
|
|
651
|
+
logItems
|
|
833
652
|
});
|
|
653
|
+
return;
|
|
834
654
|
}
|
|
835
|
-
}]);
|
|
836
655
|
|
|
837
|
-
|
|
838
|
-
|
|
656
|
+
const hasPrevious = logItems.some(item => [CallStates.DONE, CallStates.ERROR].includes(item.status));
|
|
657
|
+
const controlStates = {
|
|
658
|
+
debugger: true,
|
|
659
|
+
start: hasPrevious,
|
|
660
|
+
back: hasPrevious,
|
|
661
|
+
goto: true,
|
|
662
|
+
next: isPlaying,
|
|
663
|
+
end: isPlaying
|
|
664
|
+
};
|
|
665
|
+
this.channel.emit(EVENTS.SYNC, {
|
|
666
|
+
controlStates,
|
|
667
|
+
logItems
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
}
|
|
839
672
|
/**
|
|
840
673
|
* Instruments an object or module by traversing its properties, patching any functions (methods)
|
|
841
674
|
* to enable debugging. Patched functions will emit a `call` event when invoked.
|
|
@@ -843,9 +676,7 @@ export var Instrumenter = /*#__PURE__*/function () {
|
|
|
843
676
|
* this function. As such, "interceptable" functions will have to be `await`-ed.
|
|
844
677
|
*/
|
|
845
678
|
|
|
846
|
-
export function instrument(obj) {
|
|
847
|
-
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
848
|
-
|
|
679
|
+
export function instrument(obj, options = {}) {
|
|
849
680
|
try {
|
|
850
681
|
// Don't do any instrumentation if not loaded in an iframe.
|
|
851
682
|
if (global.window.parent === global.window) return obj; // Only create an instance if we don't have one (singleton) yet.
|
|
@@ -854,7 +685,7 @@ export function instrument(obj) {
|
|
|
854
685
|
global.window.__STORYBOOK_ADDON_INTERACTIONS_INSTRUMENTER__ = new Instrumenter();
|
|
855
686
|
}
|
|
856
687
|
|
|
857
|
-
|
|
688
|
+
const instrumenter = global.window.__STORYBOOK_ADDON_INTERACTIONS_INSTRUMENTER__;
|
|
858
689
|
return instrumenter.instrument(obj, options);
|
|
859
690
|
} catch (e) {
|
|
860
691
|
// Access to the parent window might fail due to CORS restrictions.
|