@storybook/instrumenter 6.4.0-alpha.35
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/README.md +3 -0
- package/dist/cjs/index.js +41 -0
- package/dist/cjs/instrumenter.js +725 -0
- package/dist/cjs/types.js +15 -0
- package/dist/cjs/typings.d.js +1 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/instrumenter.js +684 -0
- package/dist/esm/types.js +8 -0
- package/dist/esm/typings.d.js +0 -0
- package/dist/modern/index.js +2 -0
- package/dist/modern/instrumenter.js +547 -0
- package/dist/modern/types.js +8 -0
- package/dist/modern/typings.d.js +0 -0
- package/dist/ts3.4/index.d.ts +2 -0
- package/dist/ts3.4/instrumenter.d.ts +53 -0
- package/dist/ts3.4/types.d.ts +37 -0
- package/dist/ts3.9/index.d.ts +2 -0
- package/dist/ts3.9/instrumenter.d.ts +53 -0
- package/dist/ts3.9/types.d.ts +37 -0
- package/package.json +52 -0
|
@@ -0,0 +1,725 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
require("core-js/modules/es.symbol.js");
|
|
4
|
+
|
|
5
|
+
require("core-js/modules/es.symbol.description.js");
|
|
6
|
+
|
|
7
|
+
require("core-js/modules/es.symbol.iterator.js");
|
|
8
|
+
|
|
9
|
+
require("core-js/modules/es.symbol.to-primitive.js");
|
|
10
|
+
|
|
11
|
+
require("core-js/modules/es.date.to-primitive.js");
|
|
12
|
+
|
|
13
|
+
require("core-js/modules/es.number.constructor.js");
|
|
14
|
+
|
|
15
|
+
Object.defineProperty(exports, "__esModule", {
|
|
16
|
+
value: true
|
|
17
|
+
});
|
|
18
|
+
exports.instrument = exports.Instrumenter = exports.EVENTS = void 0;
|
|
19
|
+
|
|
20
|
+
require("core-js/modules/es.object.to-string.js");
|
|
21
|
+
|
|
22
|
+
require("core-js/modules/es.map.js");
|
|
23
|
+
|
|
24
|
+
require("core-js/modules/es.string.iterator.js");
|
|
25
|
+
|
|
26
|
+
require("core-js/modules/es.array.iterator.js");
|
|
27
|
+
|
|
28
|
+
require("core-js/modules/web.dom-collections.iterator.js");
|
|
29
|
+
|
|
30
|
+
require("core-js/modules/es.set.js");
|
|
31
|
+
|
|
32
|
+
require("core-js/modules/es.array.filter.js");
|
|
33
|
+
|
|
34
|
+
require("core-js/modules/es.array.from.js");
|
|
35
|
+
|
|
36
|
+
require("core-js/modules/es.object.assign.js");
|
|
37
|
+
|
|
38
|
+
require("core-js/modules/es.array.map.js");
|
|
39
|
+
|
|
40
|
+
require("core-js/modules/es.array.find-index.js");
|
|
41
|
+
|
|
42
|
+
require("core-js/modules/es.array.slice.js");
|
|
43
|
+
|
|
44
|
+
require("core-js/modules/es.array.find.js");
|
|
45
|
+
|
|
46
|
+
require("core-js/modules/web.dom-collections.for-each.js");
|
|
47
|
+
|
|
48
|
+
require("core-js/modules/es.object.values.js");
|
|
49
|
+
|
|
50
|
+
require("core-js/modules/es.object.keys.js");
|
|
51
|
+
|
|
52
|
+
require("core-js/modules/es.array.concat.js");
|
|
53
|
+
|
|
54
|
+
require("core-js/modules/es.promise.js");
|
|
55
|
+
|
|
56
|
+
require("core-js/modules/es.function.name.js");
|
|
57
|
+
|
|
58
|
+
require("core-js/modules/es.array.includes.js");
|
|
59
|
+
|
|
60
|
+
var _addons = require("@storybook/addons");
|
|
61
|
+
|
|
62
|
+
var _coreEvents = require("@storybook/core-events");
|
|
63
|
+
|
|
64
|
+
var _global = _interopRequireDefault(require("global"));
|
|
65
|
+
|
|
66
|
+
var _types = require("./types");
|
|
67
|
+
|
|
68
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
69
|
+
|
|
70
|
+
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
|
71
|
+
|
|
72
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
|
|
73
|
+
|
|
74
|
+
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); }
|
|
75
|
+
|
|
76
|
+
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; }
|
|
77
|
+
|
|
78
|
+
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; }
|
|
79
|
+
|
|
80
|
+
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; }
|
|
81
|
+
|
|
82
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
83
|
+
|
|
84
|
+
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."); }
|
|
85
|
+
|
|
86
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
|
|
87
|
+
|
|
88
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
89
|
+
|
|
90
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
91
|
+
|
|
92
|
+
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."); }
|
|
93
|
+
|
|
94
|
+
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); }
|
|
95
|
+
|
|
96
|
+
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; }
|
|
97
|
+
|
|
98
|
+
function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_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; }
|
|
99
|
+
|
|
100
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
101
|
+
|
|
102
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
103
|
+
|
|
104
|
+
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
|
105
|
+
|
|
106
|
+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
|
107
|
+
|
|
108
|
+
var EVENTS = {
|
|
109
|
+
CALL: 'instrumenter/call',
|
|
110
|
+
SYNC: 'instrumenter/sync',
|
|
111
|
+
START: 'instrumenter/start',
|
|
112
|
+
BACK: 'instrumenter/back',
|
|
113
|
+
GOTO: 'instrumenter/goto',
|
|
114
|
+
NEXT: 'instrumenter/next',
|
|
115
|
+
END: 'instrumenter/end'
|
|
116
|
+
};
|
|
117
|
+
exports.EVENTS = EVENTS;
|
|
118
|
+
|
|
119
|
+
var isObject = function isObject(o) {
|
|
120
|
+
return Object.prototype.toString.call(o) === '[object Object]';
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
var isModule = function isModule(o) {
|
|
124
|
+
return Object.prototype.toString.call(o) === '[object Module]';
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
var isInstrumentable = function isInstrumentable(o) {
|
|
128
|
+
if (!isObject(o) && !isModule(o)) return false;
|
|
129
|
+
if (o.constructor === undefined) return true;
|
|
130
|
+
var proto = o.constructor.prototype;
|
|
131
|
+
if (!isObject(proto)) return false;
|
|
132
|
+
if (Object.prototype.hasOwnProperty.call(proto, 'isPrototypeOf') === false) return false;
|
|
133
|
+
return true;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
var construct = function construct(obj) {
|
|
137
|
+
try {
|
|
138
|
+
return new obj.constructor();
|
|
139
|
+
} catch (e) {
|
|
140
|
+
return {};
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
var getInitialState = function getInitialState() {
|
|
145
|
+
return {
|
|
146
|
+
isDebugging: false,
|
|
147
|
+
cursor: 0,
|
|
148
|
+
calls: [],
|
|
149
|
+
shadowCalls: [],
|
|
150
|
+
callRefsByResult: new Map(),
|
|
151
|
+
chainedCallIds: new Set(),
|
|
152
|
+
parentCallId: undefined,
|
|
153
|
+
playUntil: undefined,
|
|
154
|
+
resolvers: {},
|
|
155
|
+
syncTimeout: undefined,
|
|
156
|
+
forwardedException: undefined
|
|
157
|
+
};
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
var Instrumenter = /*#__PURE__*/function () {
|
|
161
|
+
function Instrumenter() {
|
|
162
|
+
var _this = this;
|
|
163
|
+
|
|
164
|
+
_classCallCheck(this, Instrumenter);
|
|
165
|
+
|
|
166
|
+
this.channel = void 0;
|
|
167
|
+
this.state = void 0;
|
|
168
|
+
this.channel = _addons.addons.getChannel();
|
|
169
|
+
this.state = // Restore state from the parent window in case the iframe was reloaded.
|
|
170
|
+
_global.default.window.parent.__STORYBOOK_ADDON_INTERACTIONS_INSTRUMENTER_STATE__ || getInitialState(); // When called from `start`, isDebugging will be true
|
|
171
|
+
|
|
172
|
+
var resetState = function resetState() {
|
|
173
|
+
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
|
174
|
+
_ref$isDebugging = _ref.isDebugging,
|
|
175
|
+
isDebugging = _ref$isDebugging === void 0 ? false : _ref$isDebugging;
|
|
176
|
+
|
|
177
|
+
var _this$state = _this.state,
|
|
178
|
+
calls = _this$state.calls,
|
|
179
|
+
shadowCalls = _this$state.shadowCalls,
|
|
180
|
+
callRefsByResult = _this$state.callRefsByResult,
|
|
181
|
+
chainedCallIds = _this$state.chainedCallIds,
|
|
182
|
+
playUntil = _this$state.playUntil;
|
|
183
|
+
var retainedCalls = (isDebugging ? shadowCalls : calls).filter(function (call) {
|
|
184
|
+
return call.retain;
|
|
185
|
+
});
|
|
186
|
+
var retainedCallRefs = new Map(Array.from(callRefsByResult.entries()).filter(function (_ref2) {
|
|
187
|
+
var _ref3 = _slicedToArray(_ref2, 2),
|
|
188
|
+
ref = _ref3[1];
|
|
189
|
+
|
|
190
|
+
return ref.retain;
|
|
191
|
+
}));
|
|
192
|
+
|
|
193
|
+
_this.setState(Object.assign({}, getInitialState(), {
|
|
194
|
+
cursor: retainedCalls.length,
|
|
195
|
+
calls: retainedCalls,
|
|
196
|
+
callRefsByResult: retainedCallRefs,
|
|
197
|
+
shadowCalls: isDebugging ? shadowCalls : [],
|
|
198
|
+
chainedCallIds: isDebugging ? chainedCallIds : new Set(),
|
|
199
|
+
playUntil: isDebugging ? playUntil : undefined,
|
|
200
|
+
isDebugging: isDebugging
|
|
201
|
+
})); // Don't sync while debugging, as it'll cause flicker.
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
if (!isDebugging) _this.channel.emit(EVENTS.SYNC, _this.getLog());
|
|
205
|
+
}; // A forceRemount might be triggered for debugging (on `start`), or elsewhere in Storybook.
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
this.channel.on(_coreEvents.FORCE_REMOUNT, resetState); // Start with a clean slate before playing, but also clean up when switching to a story that
|
|
209
|
+
// doesn't have a play function (in which case there is no 'playing' phase).
|
|
210
|
+
// Invocation of the play function is guaranteed to always be preceded by the 'rendering' phase.
|
|
211
|
+
|
|
212
|
+
this.channel.on(_coreEvents.STORY_RENDER_PHASE_CHANGED, function (_ref4) {
|
|
213
|
+
var storyId = _ref4.storyId,
|
|
214
|
+
newPhase = _ref4.newPhase;
|
|
215
|
+
|
|
216
|
+
// TODO keep state per story
|
|
217
|
+
if (newPhase === 'loading') {
|
|
218
|
+
resetState({
|
|
219
|
+
isDebugging: _this.state.isDebugging
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (newPhase === 'completed') {
|
|
224
|
+
_this.setState({
|
|
225
|
+
isDebugging: false
|
|
226
|
+
}); // Rethrow any unhandled forwarded exception so it doesn't go unnoticed.
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
if (_this.state.forwardedException) throw _this.state.forwardedException;
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
var start = function start(_ref5) {
|
|
234
|
+
var storyId = _ref5.storyId,
|
|
235
|
+
playUntil = _ref5.playUntil;
|
|
236
|
+
|
|
237
|
+
if (!_this.state.isDebugging) {
|
|
238
|
+
_this.setState(function (_ref6) {
|
|
239
|
+
var calls = _ref6.calls;
|
|
240
|
+
return {
|
|
241
|
+
calls: [],
|
|
242
|
+
shadowCalls: calls.map(function (call) {
|
|
243
|
+
return Object.assign({}, call, {
|
|
244
|
+
state: _types.CallStates.WAITING
|
|
245
|
+
});
|
|
246
|
+
}),
|
|
247
|
+
isDebugging: true
|
|
248
|
+
};
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
var log = _this.getLog();
|
|
253
|
+
|
|
254
|
+
var firstRowIndex = _this.state.shadowCalls.findIndex(function (call) {
|
|
255
|
+
return call.id === log[0].callId;
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
_this.setState(function (_ref7) {
|
|
259
|
+
var _shadowCalls$slice$fi;
|
|
260
|
+
|
|
261
|
+
var shadowCalls = _ref7.shadowCalls;
|
|
262
|
+
return {
|
|
263
|
+
playUntil: playUntil || ((_shadowCalls$slice$fi = shadowCalls.slice(0, firstRowIndex).filter(function (call) {
|
|
264
|
+
return call.interceptable;
|
|
265
|
+
}).slice(-1)[0]) === null || _shadowCalls$slice$fi === void 0 ? void 0 : _shadowCalls$slice$fi.id)
|
|
266
|
+
};
|
|
267
|
+
}); // Force remount may trigger a page reload if the play function can't be aborted.
|
|
268
|
+
// global.window.location.reload();
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
_this.channel.emit(_coreEvents.FORCE_REMOUNT, {
|
|
272
|
+
storyId: storyId,
|
|
273
|
+
isDebugging: true
|
|
274
|
+
});
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
var back = function back(_ref8) {
|
|
278
|
+
var _log, _log$slice$;
|
|
279
|
+
|
|
280
|
+
var storyId = _ref8.storyId;
|
|
281
|
+
var isDebugging = _this.state.isDebugging;
|
|
282
|
+
|
|
283
|
+
var log = _this.getLog();
|
|
284
|
+
|
|
285
|
+
var next = log.findIndex(function (_ref9) {
|
|
286
|
+
var state = _ref9.state;
|
|
287
|
+
return state === _types.CallStates.WAITING;
|
|
288
|
+
});
|
|
289
|
+
var playUntil = ((_log = log[next - 2]) === null || _log === void 0 ? void 0 : _log.callId) || (isDebugging ? null : (_log$slice$ = log.slice(-2)[0]) === null || _log$slice$ === void 0 ? void 0 : _log$slice$.callId);
|
|
290
|
+
start({
|
|
291
|
+
storyId: storyId,
|
|
292
|
+
playUntil: playUntil
|
|
293
|
+
});
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
var goto = function goto(_ref10) {
|
|
297
|
+
var storyId = _ref10.storyId,
|
|
298
|
+
callId = _ref10.callId;
|
|
299
|
+
var _this$state2 = _this.state,
|
|
300
|
+
calls = _this$state2.calls,
|
|
301
|
+
shadowCalls = _this$state2.shadowCalls,
|
|
302
|
+
resolvers = _this$state2.resolvers;
|
|
303
|
+
var call = calls.find(function (_ref11) {
|
|
304
|
+
var id = _ref11.id;
|
|
305
|
+
return id === callId;
|
|
306
|
+
});
|
|
307
|
+
var shadowCall = shadowCalls.find(function (_ref12) {
|
|
308
|
+
var id = _ref12.id;
|
|
309
|
+
return id === callId;
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
if (!call && shadowCall) {
|
|
313
|
+
var _this$getLog$find;
|
|
314
|
+
|
|
315
|
+
var nextCallId = (_this$getLog$find = _this.getLog().find(function (_ref13) {
|
|
316
|
+
var state = _ref13.state;
|
|
317
|
+
return state === _types.CallStates.WAITING;
|
|
318
|
+
})) === null || _this$getLog$find === void 0 ? void 0 : _this$getLog$find.callId;
|
|
319
|
+
if (shadowCall.id !== nextCallId) _this.setState({
|
|
320
|
+
playUntil: shadowCall.id
|
|
321
|
+
});
|
|
322
|
+
Object.values(resolvers).forEach(function (resolve) {
|
|
323
|
+
return resolve();
|
|
324
|
+
});
|
|
325
|
+
} else {
|
|
326
|
+
start({
|
|
327
|
+
storyId: storyId,
|
|
328
|
+
playUntil: callId
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
var next = function next() {
|
|
334
|
+
Object.values(_this.state.resolvers).forEach(function (resolve) {
|
|
335
|
+
return resolve();
|
|
336
|
+
});
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
var end = function end() {
|
|
340
|
+
_this.setState({
|
|
341
|
+
playUntil: undefined,
|
|
342
|
+
isDebugging: false
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
Object.values(_this.state.resolvers).forEach(function (resolve) {
|
|
346
|
+
return resolve();
|
|
347
|
+
});
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
this.channel.on(EVENTS.START, start);
|
|
351
|
+
this.channel.on(EVENTS.BACK, back);
|
|
352
|
+
this.channel.on(EVENTS.GOTO, goto);
|
|
353
|
+
this.channel.on(EVENTS.NEXT, next);
|
|
354
|
+
this.channel.on(EVENTS.END, end);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
_createClass(Instrumenter, [{
|
|
358
|
+
key: "setState",
|
|
359
|
+
value: function setState(update) {
|
|
360
|
+
this.state = Object.assign({}, this.state, typeof update === 'function' ? update(this.state) : update); // Track state on the parent window so we can reload the iframe without losing state.
|
|
361
|
+
|
|
362
|
+
_global.default.window.parent.__STORYBOOK_ADDON_INTERACTIONS_INSTRUMENTER_STATE__ = this.state;
|
|
363
|
+
}
|
|
364
|
+
}, {
|
|
365
|
+
key: "getLog",
|
|
366
|
+
value: function getLog() {
|
|
367
|
+
var merged = _toConsumableArray(this.state.shadowCalls);
|
|
368
|
+
|
|
369
|
+
this.state.calls.forEach(function (call, index) {
|
|
370
|
+
merged[index] = call;
|
|
371
|
+
});
|
|
372
|
+
var seen = new Set();
|
|
373
|
+
return merged.reduceRight(function (acc, call) {
|
|
374
|
+
call.args.forEach(function (arg) {
|
|
375
|
+
if (arg !== null && arg !== void 0 && arg.__callId__) {
|
|
376
|
+
seen.add(arg.__callId__);
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
call.path.forEach(function (node) {
|
|
380
|
+
if (node.__callId__) {
|
|
381
|
+
seen.add(node.__callId__);
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
if (call.interceptable && !seen.has(call.id) && !seen.has(call.parentId)) {
|
|
386
|
+
acc.unshift({
|
|
387
|
+
callId: call.id,
|
|
388
|
+
state: call.state
|
|
389
|
+
});
|
|
390
|
+
seen.add(call.id);
|
|
391
|
+
|
|
392
|
+
if (call.parentId) {
|
|
393
|
+
seen.add(call.parentId);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
return acc;
|
|
398
|
+
}, []);
|
|
399
|
+
} // Traverses the object structure to recursively patch all function properties.
|
|
400
|
+
// Returns the original object, or a new object with the same constructor,
|
|
401
|
+
// depending on whether it should mutate.
|
|
402
|
+
|
|
403
|
+
}, {
|
|
404
|
+
key: "instrument",
|
|
405
|
+
value: function instrument(obj) {
|
|
406
|
+
var _this2 = this;
|
|
407
|
+
|
|
408
|
+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
409
|
+
if (!isInstrumentable(obj)) return obj;
|
|
410
|
+
var _options$mutate = options.mutate,
|
|
411
|
+
mutate = _options$mutate === void 0 ? false : _options$mutate,
|
|
412
|
+
_options$path = options.path,
|
|
413
|
+
path = _options$path === void 0 ? [] : _options$path;
|
|
414
|
+
return Object.keys(obj).reduce(function (acc, key) {
|
|
415
|
+
var value = obj[key]; // Nothing to patch, but might be instrumentable, so we recurse
|
|
416
|
+
|
|
417
|
+
if (typeof value !== 'function') {
|
|
418
|
+
acc[key] = _this2.instrument(value, Object.assign({}, options, {
|
|
419
|
+
path: path.concat(key)
|
|
420
|
+
}));
|
|
421
|
+
return acc;
|
|
422
|
+
} // Already patched, so we pass through unchanged
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
if (typeof value._original === 'function') {
|
|
426
|
+
acc[key] = value;
|
|
427
|
+
return acc;
|
|
428
|
+
} // Patch the function and mark it "patched" by adding a reference to the original function
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
acc[key] = _this2.patch(key, value, options);
|
|
432
|
+
acc[key]._original = value; // Deal with functions that also act like an object
|
|
433
|
+
|
|
434
|
+
if (Object.keys(value).length > 0) {
|
|
435
|
+
Object.assign(acc[key], _this2.instrument(Object.assign({}, value), Object.assign({}, options, {
|
|
436
|
+
path: path.concat(key)
|
|
437
|
+
})));
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
return acc;
|
|
441
|
+
}, mutate ? obj : construct(obj));
|
|
442
|
+
}
|
|
443
|
+
}, {
|
|
444
|
+
key: "patch",
|
|
445
|
+
value: function patch(method, fn, options) {
|
|
446
|
+
var _this3 = this;
|
|
447
|
+
|
|
448
|
+
var patched = function patched() {
|
|
449
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
450
|
+
args[_key] = arguments[_key];
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
return _this3.track(method, fn, args, options);
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
Object.defineProperty(patched, 'name', {
|
|
457
|
+
value: method,
|
|
458
|
+
writable: false
|
|
459
|
+
});
|
|
460
|
+
return patched;
|
|
461
|
+
} // Monkey patch an object method to record calls.
|
|
462
|
+
// Returns a function that invokes the original function, records the invocation ("call") and
|
|
463
|
+
// returns the original result.
|
|
464
|
+
|
|
465
|
+
}, {
|
|
466
|
+
key: "track",
|
|
467
|
+
value: function track(method, fn, args, _ref14) {
|
|
468
|
+
var _ref14$path = _ref14.path,
|
|
469
|
+
path = _ref14$path === void 0 ? [] : _ref14$path,
|
|
470
|
+
options = _objectWithoutProperties(_ref14, ["path"]);
|
|
471
|
+
|
|
472
|
+
var index = this.state.cursor;
|
|
473
|
+
this.setState({
|
|
474
|
+
cursor: this.state.cursor + 1
|
|
475
|
+
});
|
|
476
|
+
var id = "".concat(index, "-").concat(method);
|
|
477
|
+
var _options$intercept = options.intercept,
|
|
478
|
+
intercept = _options$intercept === void 0 ? false : _options$intercept,
|
|
479
|
+
_options$retain = options.retain,
|
|
480
|
+
retain = _options$retain === void 0 ? false : _options$retain;
|
|
481
|
+
var interceptable = typeof intercept === 'function' ? intercept(method, path) : intercept;
|
|
482
|
+
var call = {
|
|
483
|
+
id: id,
|
|
484
|
+
path: path,
|
|
485
|
+
method: method,
|
|
486
|
+
args: args,
|
|
487
|
+
interceptable: interceptable,
|
|
488
|
+
retain: retain
|
|
489
|
+
};
|
|
490
|
+
var result = (interceptable ? this.intercept : this.invoke).call(this, fn, call);
|
|
491
|
+
return this.instrument(result, Object.assign({}, options, {
|
|
492
|
+
mutate: true,
|
|
493
|
+
path: [{
|
|
494
|
+
__callId__: call.id
|
|
495
|
+
}]
|
|
496
|
+
}));
|
|
497
|
+
}
|
|
498
|
+
}, {
|
|
499
|
+
key: "intercept",
|
|
500
|
+
value: function intercept(fn, call) {
|
|
501
|
+
var _this4 = this;
|
|
502
|
+
|
|
503
|
+
// For a "jump to step" action, continue playing until we hit a call by that ID.
|
|
504
|
+
// For chained calls, we can only return a Promise for the last call in the chain.
|
|
505
|
+
var isChainedUpon = this.state.chainedCallIds.has(call.id);
|
|
506
|
+
|
|
507
|
+
if (!this.state.isDebugging || isChainedUpon || this.state.playUntil) {
|
|
508
|
+
if (this.state.playUntil === call.id) {
|
|
509
|
+
this.setState({
|
|
510
|
+
playUntil: undefined
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
return this.invoke(fn, call);
|
|
515
|
+
} // Instead of invoking the function, defer the function call until we continue playing.
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
return new Promise(function (resolve) {
|
|
519
|
+
_this4.setState(function (_ref15) {
|
|
520
|
+
var resolvers = _ref15.resolvers;
|
|
521
|
+
return {
|
|
522
|
+
resolvers: Object.assign({}, resolvers, _defineProperty({}, call.id, resolve))
|
|
523
|
+
};
|
|
524
|
+
});
|
|
525
|
+
}).then(function () {
|
|
526
|
+
var _this4$state$resolver = _this4.state.resolvers,
|
|
527
|
+
_call$id = call.id,
|
|
528
|
+
_ = _this4$state$resolver[_call$id],
|
|
529
|
+
resolvers = _objectWithoutProperties(_this4$state$resolver, [_call$id].map(_toPropertyKey));
|
|
530
|
+
|
|
531
|
+
_this4.setState({
|
|
532
|
+
resolvers: resolvers
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
return _this4.invoke(fn, call);
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
}, {
|
|
539
|
+
key: "invoke",
|
|
540
|
+
value: function invoke(fn, call) {
|
|
541
|
+
var _this5 = this;
|
|
542
|
+
|
|
543
|
+
var _this$state3 = this.state,
|
|
544
|
+
parentCallId = _this$state3.parentCallId,
|
|
545
|
+
callRefsByResult = _this$state3.callRefsByResult,
|
|
546
|
+
forwardedException = _this$state3.forwardedException;
|
|
547
|
+
var info = Object.assign({}, call, {
|
|
548
|
+
parentId: parentCallId,
|
|
549
|
+
// Map args that originate from a tracked function call to a call reference to enable nesting.
|
|
550
|
+
// These values are often not fully serializable anyway (e.g. HTML elements).
|
|
551
|
+
args: call.args.map(function (arg) {
|
|
552
|
+
if (callRefsByResult.has(arg)) {
|
|
553
|
+
return callRefsByResult.get(arg);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
if (arg instanceof _global.default.window.HTMLElement) {
|
|
557
|
+
var prefix = arg.prefix,
|
|
558
|
+
localName = arg.localName,
|
|
559
|
+
id = arg.id,
|
|
560
|
+
classList = arg.classList,
|
|
561
|
+
innerText = arg.innerText;
|
|
562
|
+
var classNames = Array.from(classList);
|
|
563
|
+
return {
|
|
564
|
+
__element__: {
|
|
565
|
+
prefix: prefix,
|
|
566
|
+
localName: localName,
|
|
567
|
+
id: id,
|
|
568
|
+
classNames: classNames,
|
|
569
|
+
innerText: innerText
|
|
570
|
+
}
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
return arg;
|
|
575
|
+
})
|
|
576
|
+
}); // Mark any ancestor calls as "chained upon" so we won't attempt to defer it later.
|
|
577
|
+
|
|
578
|
+
call.path.forEach(function (ref) {
|
|
579
|
+
if (ref !== null && ref !== void 0 && ref.__callId__) {
|
|
580
|
+
_this5.setState(function (_ref16) {
|
|
581
|
+
var chainedCallIds = _ref16.chainedCallIds;
|
|
582
|
+
return {
|
|
583
|
+
chainedCallIds: new Set(Array.from(chainedCallIds).concat(ref.__callId__))
|
|
584
|
+
};
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
});
|
|
588
|
+
|
|
589
|
+
var handleException = function handleException(e) {
|
|
590
|
+
if (e instanceof Error) {
|
|
591
|
+
var name = e.name,
|
|
592
|
+
message = e.message,
|
|
593
|
+
stack = e.stack;
|
|
594
|
+
var exception = {
|
|
595
|
+
name: name,
|
|
596
|
+
message: message,
|
|
597
|
+
stack: stack,
|
|
598
|
+
callId: call.id
|
|
599
|
+
};
|
|
600
|
+
|
|
601
|
+
_this5.sync(Object.assign({}, info, {
|
|
602
|
+
state: _types.CallStates.ERROR,
|
|
603
|
+
exception: exception
|
|
604
|
+
})); // Always track errors to their originating call.
|
|
605
|
+
|
|
606
|
+
|
|
607
|
+
_this5.setState(function (state) {
|
|
608
|
+
return {
|
|
609
|
+
callRefsByResult: new Map([].concat(_toConsumableArray(Array.from(state.callRefsByResult.entries())), [[e, {
|
|
610
|
+
__callId__: call.id,
|
|
611
|
+
retain: call.retain
|
|
612
|
+
}]]))
|
|
613
|
+
};
|
|
614
|
+
}); // We need to throw to break out of the play function, but we don't want to trigger a redbox
|
|
615
|
+
// so we throw an ignoredException, which is caught and silently ignored by Storybook.
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
if (call.interceptable) {
|
|
619
|
+
throw _coreEvents.IGNORED_EXCEPTION;
|
|
620
|
+
} // Non-interceptable calls need their exceptions forwarded to the next interceptable call.
|
|
621
|
+
// In case no interceptable call picks it up, it'll get rethrown in the "completed" phase.
|
|
622
|
+
|
|
623
|
+
|
|
624
|
+
_this5.setState({
|
|
625
|
+
forwardedException: e
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
return e;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
throw e;
|
|
632
|
+
};
|
|
633
|
+
|
|
634
|
+
try {
|
|
635
|
+
// An earlier, non-interceptable call might have forwarded an exception.
|
|
636
|
+
if (forwardedException) {
|
|
637
|
+
this.setState({
|
|
638
|
+
forwardedException: undefined
|
|
639
|
+
});
|
|
640
|
+
throw forwardedException;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
var result = fn.apply(void 0, _toConsumableArray(call.args.map(function (arg) {
|
|
644
|
+
if (typeof arg !== 'function' || Object.keys(arg).length) return arg;
|
|
645
|
+
return function () {
|
|
646
|
+
var prev = _this5.state.parentCallId;
|
|
647
|
+
|
|
648
|
+
_this5.setState({
|
|
649
|
+
parentCallId: call.id
|
|
650
|
+
});
|
|
651
|
+
|
|
652
|
+
var res = arg.apply(void 0, arguments);
|
|
653
|
+
|
|
654
|
+
_this5.setState({
|
|
655
|
+
parentCallId: prev
|
|
656
|
+
});
|
|
657
|
+
|
|
658
|
+
return res;
|
|
659
|
+
};
|
|
660
|
+
}))); // Track the result so we can trace later uses of it back to the originating call.
|
|
661
|
+
// Primitive results (undefined, null, boolean, string, number, BigInt) are ignored.
|
|
662
|
+
|
|
663
|
+
if (result && ['object', 'function', 'symbol'].includes(_typeof(result))) {
|
|
664
|
+
this.setState(function (state) {
|
|
665
|
+
return {
|
|
666
|
+
callRefsByResult: new Map([].concat(_toConsumableArray(Array.from(state.callRefsByResult.entries())), [[result, {
|
|
667
|
+
__callId__: call.id,
|
|
668
|
+
retain: call.retain
|
|
669
|
+
}]]))
|
|
670
|
+
};
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
this.sync(Object.assign({}, info, {
|
|
675
|
+
state: result instanceof Promise ? _types.CallStates.ACTIVE : _types.CallStates.DONE
|
|
676
|
+
}));
|
|
677
|
+
|
|
678
|
+
if (result instanceof Promise) {
|
|
679
|
+
return result.then(function (value) {
|
|
680
|
+
_this5.sync(Object.assign({}, info, {
|
|
681
|
+
state: _types.CallStates.DONE
|
|
682
|
+
}));
|
|
683
|
+
|
|
684
|
+
return value;
|
|
685
|
+
}, handleException);
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
return result;
|
|
689
|
+
} catch (e) {
|
|
690
|
+
return handleException(e);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
}, {
|
|
694
|
+
key: "sync",
|
|
695
|
+
value: function sync(call) {
|
|
696
|
+
var _this6 = this;
|
|
697
|
+
|
|
698
|
+
clearTimeout(this.state.syncTimeout);
|
|
699
|
+
this.channel.emit(EVENTS.CALL, call);
|
|
700
|
+
this.setState(function (_ref17) {
|
|
701
|
+
var calls = _ref17.calls;
|
|
702
|
+
return {
|
|
703
|
+
calls: calls.concat(call),
|
|
704
|
+
syncTimeout: setTimeout(function () {
|
|
705
|
+
return _this6.channel.emit(EVENTS.SYNC, _this6.getLog());
|
|
706
|
+
}, 0)
|
|
707
|
+
};
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
}]);
|
|
711
|
+
|
|
712
|
+
return Instrumenter;
|
|
713
|
+
}();
|
|
714
|
+
|
|
715
|
+
exports.Instrumenter = Instrumenter;
|
|
716
|
+
var instrument = _global.default.window.parent === _global.default.window ? function (obj) {
|
|
717
|
+
return obj;
|
|
718
|
+
} // Don't do anything if not loaded in an iframe.
|
|
719
|
+
: function (obj) {
|
|
720
|
+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
721
|
+
if (!_global.default.window.__STORYBOOK_ADDON_INTERACTIONS_INSTRUMENTER__) _global.default.window.__STORYBOOK_ADDON_INTERACTIONS_INSTRUMENTER__ = new Instrumenter();
|
|
722
|
+
var instrumenter = _global.default.window.__STORYBOOK_ADDON_INTERACTIONS_INSTRUMENTER__;
|
|
723
|
+
return instrumenter.instrument(obj, options);
|
|
724
|
+
};
|
|
725
|
+
exports.instrument = instrument;
|