@miso.ai/client-sdk-dev-tool 1.13.2-beta.1 → 1.14.0-beta.3
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/cjs/debug.js +66 -8
- package/dist/cjs/dry-run.js +23 -1
- package/dist/cjs/lorem.js +18 -3
- package/package.json +6 -6
- package/src/debug.js +57 -8
- package/src/dry-run.js +16 -2
- package/src/lorem.js +15 -2
package/dist/cjs/debug.js
CHANGED
|
@@ -8,6 +8,12 @@ var _logs = require("./logs.js");
|
|
|
8
8
|
const _excluded = ["groupName", "apiName", "url", "bulk"];
|
|
9
9
|
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
10
10
|
const ID = 'std:debug';
|
|
11
|
+
|
|
12
|
+
// the item subworkflow contexts emit per item (one workflow per thread of
|
|
13
|
+
// the list, per message of the conversation), which floods the console.
|
|
14
|
+
// Muted paths stay out of the console only: they are still preserved for
|
|
15
|
+
// the log dump. Configurable via the `mute` option (`mute: []` shows all)
|
|
16
|
+
const DEFAULT_MUTE = Object.freeze(['workflow/thread-items', 'workflow/message-items']);
|
|
11
17
|
class DebugPlugin {
|
|
12
18
|
constructor(options = {}) {
|
|
13
19
|
this._options = options;
|
|
@@ -56,6 +62,10 @@ class DebugPlugin {
|
|
|
56
62
|
}));
|
|
57
63
|
return;
|
|
58
64
|
}
|
|
65
|
+
if (path.length === 1 && (name === 'workflow' || name === 'postworkflow')) {
|
|
66
|
+
this._handleClientWorkflowEvent(name, data);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
59
69
|
break;
|
|
60
70
|
case 'plugins':
|
|
61
71
|
if (path.length === 1) {
|
|
@@ -80,7 +90,12 @@ class DebugPlugin {
|
|
|
80
90
|
const pathname = new URL(url).pathname;
|
|
81
91
|
const args = ['api', eventName];
|
|
82
92
|
bulk && args.push(`(bulk ${bulk.bulkId})`);
|
|
83
|
-
|
|
93
|
+
|
|
94
|
+
// the api helpers' fetch defaults to POST when no method is specified
|
|
95
|
+
const {
|
|
96
|
+
method = 'POST'
|
|
97
|
+
} = data.options || {};
|
|
98
|
+
args.push(`${method} ${pathname}`);
|
|
84
99
|
if (groupName === 'interactions') {
|
|
85
100
|
// TODO: handle multiple interactions
|
|
86
101
|
const record = data.payload.data[0];
|
|
@@ -109,8 +124,18 @@ class DebugPlugin {
|
|
|
109
124
|
}
|
|
110
125
|
this._log('plugins', eventName, `${plugin.id || '(anonymous)'}`, [plugin, ...data]);
|
|
111
126
|
}
|
|
127
|
+
|
|
128
|
+
// a workflow's creation events on the client follow its context: the
|
|
129
|
+
// workflows of a muted context (the item subworkflows) are muted as well
|
|
130
|
+
_handleClientWorkflowEvent(name, workflow) {
|
|
131
|
+
const context = workflow && workflow._context;
|
|
132
|
+
const silent = !!context && this._isMuted(_joinPath(_pluginComponentPath(context.meta.path)));
|
|
133
|
+
this._logw('client', name, workflow, {
|
|
134
|
+
silent
|
|
135
|
+
});
|
|
136
|
+
}
|
|
112
137
|
_handlePluginSpecificEvent(pluginId, path, name, data) {
|
|
113
|
-
this._logw([pluginId, path
|
|
138
|
+
this._logw(_pluginComponentPath([pluginId, ...path]), name, data);
|
|
114
139
|
}
|
|
115
140
|
_getPath(component) {
|
|
116
141
|
const path = [];
|
|
@@ -119,25 +144,48 @@ class DebugPlugin {
|
|
|
119
144
|
}
|
|
120
145
|
return path.reverse();
|
|
121
146
|
}
|
|
122
|
-
_logw(path, name, data) {
|
|
147
|
+
_logw(path, name, data, options) {
|
|
123
148
|
if (data === undefined) {
|
|
124
|
-
|
|
149
|
+
data = [];
|
|
125
150
|
} else if (Array.isArray(data)) {
|
|
126
|
-
|
|
151
|
+
data = data.map(_wrapObj);
|
|
127
152
|
} else {
|
|
128
|
-
|
|
153
|
+
data = [_wrapObj(data)];
|
|
129
154
|
}
|
|
155
|
+
this._logp(path, name, data, options);
|
|
130
156
|
}
|
|
131
157
|
_log(path, name, ...data) {
|
|
132
|
-
this.
|
|
158
|
+
this._logp(path, name, data);
|
|
159
|
+
}
|
|
160
|
+
_logp(path, name, data, {
|
|
161
|
+
silent = false
|
|
162
|
+
} = {}) {
|
|
163
|
+
path = _joinPath(path);
|
|
164
|
+
this._write([_path(path), _name(name), ...data], {
|
|
165
|
+
silent: silent || this._isMuted(path)
|
|
166
|
+
});
|
|
133
167
|
}
|
|
134
168
|
_logr(...data) {
|
|
169
|
+
this._write(data);
|
|
170
|
+
}
|
|
171
|
+
_write(data, {
|
|
172
|
+
silent = false
|
|
173
|
+
} = {}) {
|
|
135
174
|
const options = this._options.console || {};
|
|
136
175
|
if (this._options.preserveLog) {
|
|
137
176
|
this._logs._logs.push(data);
|
|
138
177
|
}
|
|
178
|
+
if (silent) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
139
181
|
console.log(_tag(options), _style(options), ...data);
|
|
140
182
|
}
|
|
183
|
+
_isMuted(path) {
|
|
184
|
+
const {
|
|
185
|
+
mute = DEFAULT_MUTE
|
|
186
|
+
} = this._options;
|
|
187
|
+
return mute.includes(path);
|
|
188
|
+
}
|
|
141
189
|
}
|
|
142
190
|
exports.default = DebugPlugin;
|
|
143
191
|
function _tag({
|
|
@@ -154,7 +202,17 @@ function _style({
|
|
|
154
202
|
|
|
155
203
|
// format path
|
|
156
204
|
function _path(path) {
|
|
157
|
-
return `<${
|
|
205
|
+
return `<${path}>`;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// the log path of a component under a plugin, off its meta path — which
|
|
209
|
+
// starts at the plugin ([pluginId, ...rest]): the plugins root reaches the
|
|
210
|
+
// plugins as subtrees, not as parents
|
|
211
|
+
function _pluginComponentPath(path) {
|
|
212
|
+
return [path[0], path.slice(1).join('.')];
|
|
213
|
+
}
|
|
214
|
+
function _joinPath(path) {
|
|
215
|
+
return typeof path === 'string' ? path : path.filter(v => v).join('/');
|
|
158
216
|
}
|
|
159
217
|
|
|
160
218
|
// format event name
|
package/dist/cjs/dry-run.js
CHANGED
|
@@ -5,6 +5,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _commons = require("@miso.ai/commons");
|
|
8
|
+
const {
|
|
9
|
+
GROUP,
|
|
10
|
+
NAME
|
|
11
|
+
} = _commons.API;
|
|
8
12
|
const ID = 'std:dry-run';
|
|
9
13
|
class DryRunPlugin {
|
|
10
14
|
constructor(options = {}) {
|
|
@@ -19,9 +23,11 @@ class DryRunPlugin {
|
|
|
19
23
|
// TODO: config({ active })
|
|
20
24
|
|
|
21
25
|
install(_, {
|
|
22
|
-
addUrlPass
|
|
26
|
+
addUrlPass,
|
|
27
|
+
addPayloadPass
|
|
23
28
|
}) {
|
|
24
29
|
addUrlPass(this._modifyUrl.bind(this));
|
|
30
|
+
addPayloadPass(this._modifyPayload.bind(this));
|
|
25
31
|
}
|
|
26
32
|
_modifyUrl({
|
|
27
33
|
apiGroup,
|
|
@@ -30,5 +36,21 @@ class DryRunPlugin {
|
|
|
30
36
|
}) {
|
|
31
37
|
return apiGroup === 'interactions' && apiName === 'upload' ? (0, _commons.addUrlParameter)(url, 'dry_run', '1') : url;
|
|
32
38
|
}
|
|
39
|
+
_modifyPayload({
|
|
40
|
+
apiGroup,
|
|
41
|
+
apiName,
|
|
42
|
+
payload
|
|
43
|
+
}) {
|
|
44
|
+
if (!payload) {
|
|
45
|
+
return payload; // the GET request
|
|
46
|
+
}
|
|
47
|
+
// questions (ask) and search (hybrid search) only, for now
|
|
48
|
+
if (apiGroup === GROUP.ASK && (apiName === NAME.QUESTIONS || apiName === NAME.SEARCH)) {
|
|
49
|
+
return Object.assign({}, payload, {
|
|
50
|
+
with_request_history: false
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return payload;
|
|
54
|
+
}
|
|
33
55
|
}
|
|
34
56
|
exports.default = DryRunPlugin;
|
package/dist/cjs/lorem.js
CHANGED
|
@@ -8,7 +8,8 @@ var _commons = require("@miso.ai/commons");
|
|
|
8
8
|
var _lorem = require("@miso.ai/lorem");
|
|
9
9
|
var _api = _interopRequireDefault(require("@miso.ai/doggoganger/src/api.js"));
|
|
10
10
|
var _fetch = _interopRequireDefault(require("@miso.ai/doggoganger/src/fetch.js"));
|
|
11
|
-
|
|
11
|
+
var _utils = require("@miso.ai/doggoganger/src/utils.js");
|
|
12
|
+
const _excluded = ["seed", "latency"];
|
|
12
13
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
14
|
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
14
15
|
const PLUGIN_ID = 'std:lorem';
|
|
@@ -20,14 +21,22 @@ class LoremPlugin {
|
|
|
20
21
|
this._lorem = (0, _lorem.lorem)();
|
|
21
22
|
this._api = (0, _api.default)();
|
|
22
23
|
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* `latency` adds a mock request latency to every api call, in the manner
|
|
27
|
+
* of the doggoganger server's latency middleware: a number of milliseconds
|
|
28
|
+
* (e.g. 500), or `{ min, max }` for a randomized roll.
|
|
29
|
+
*/
|
|
23
30
|
config(_ref = {}) {
|
|
24
31
|
let {
|
|
25
|
-
seed
|
|
32
|
+
seed,
|
|
33
|
+
latency
|
|
26
34
|
} = _ref,
|
|
27
35
|
options = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
28
36
|
this._lorem = (0, _lorem.lorem)({
|
|
29
37
|
seed
|
|
30
38
|
});
|
|
39
|
+
this._latency = latency;
|
|
31
40
|
this._api = (0, _api.default)(options);
|
|
32
41
|
}
|
|
33
42
|
get api() {
|
|
@@ -56,8 +65,14 @@ class LoremPlugin {
|
|
|
56
65
|
}));
|
|
57
66
|
};
|
|
58
67
|
}
|
|
59
|
-
_fetch(url, options) {
|
|
68
|
+
async _fetch(url, options) {
|
|
69
|
+
// the seed is captured before the delay, so the generated content stays
|
|
70
|
+
// tied to the request order, not the completion order
|
|
60
71
|
const seed = this._lorem.prng.seed();
|
|
72
|
+
const latency = this._latency;
|
|
73
|
+
if (latency) {
|
|
74
|
+
await (0, _utils.delay)(typeof latency === 'number' ? latency : (0, _utils.rollLatency)(latency.min || 0, latency.max || 0));
|
|
75
|
+
}
|
|
61
76
|
return (0, _fetch.default)(this._api, url, Object.assign({
|
|
62
77
|
seed
|
|
63
78
|
}, options));
|
package/package.json
CHANGED
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
"access": "public"
|
|
13
13
|
},
|
|
14
14
|
"scripts": {
|
|
15
|
-
"build:clean": "
|
|
16
|
-
"build:cjs": "BABEL_ENV=cjs
|
|
15
|
+
"build:clean": "rimraf dist",
|
|
16
|
+
"build:cjs": "BABEL_ENV=cjs babel src --root-mode upward --out-dir dist/cjs",
|
|
17
17
|
"build": "npm run build:clean && npm run build:cjs"
|
|
18
18
|
},
|
|
19
19
|
"repository": {
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
"url": "https://github.com/MisoAI/miso-client-js-sdk/issues"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@miso.ai/commons": "1.
|
|
34
|
-
"@miso.ai/doggoganger": "^0.10.0-beta.
|
|
35
|
-
"@miso.ai/lorem": "^0.10.0-beta.
|
|
33
|
+
"@miso.ai/commons": "1.14.0-beta.3",
|
|
34
|
+
"@miso.ai/doggoganger": "^0.10.0-beta.17",
|
|
35
|
+
"@miso.ai/lorem": "^0.10.0-beta.17"
|
|
36
36
|
},
|
|
37
|
-
"version": "1.
|
|
37
|
+
"version": "1.14.0-beta.3"
|
|
38
38
|
}
|
package/src/debug.js
CHANGED
|
@@ -2,6 +2,12 @@ import { Logs } from './logs.js';
|
|
|
2
2
|
|
|
3
3
|
const ID = 'std:debug';
|
|
4
4
|
|
|
5
|
+
// the item subworkflow contexts emit per item (one workflow per thread of
|
|
6
|
+
// the list, per message of the conversation), which floods the console.
|
|
7
|
+
// Muted paths stay out of the console only: they are still preserved for
|
|
8
|
+
// the log dump. Configurable via the `mute` option (`mute: []` shows all)
|
|
9
|
+
const DEFAULT_MUTE = Object.freeze(['workflow/thread-items', 'workflow/message-items']);
|
|
10
|
+
|
|
5
11
|
export default class DebugPlugin {
|
|
6
12
|
|
|
7
13
|
constructor(options = {}) {
|
|
@@ -55,6 +61,10 @@ export default class DebugPlugin {
|
|
|
55
61
|
this._handleApiEvent(name, { ...data, groupName: path[2] });
|
|
56
62
|
return;
|
|
57
63
|
}
|
|
64
|
+
if (path.length === 1 && (name === 'workflow' || name === 'postworkflow')) {
|
|
65
|
+
this._handleClientWorkflowEvent(name, data);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
58
68
|
break;
|
|
59
69
|
case 'plugins':
|
|
60
70
|
if (path.length === 1) {
|
|
@@ -77,7 +87,9 @@ export default class DebugPlugin {
|
|
|
77
87
|
|
|
78
88
|
bulk && args.push(`(bulk ${bulk.bulkId})`);
|
|
79
89
|
|
|
80
|
-
|
|
90
|
+
// the api helpers' fetch defaults to POST when no method is specified
|
|
91
|
+
const { method = 'POST' } = data.options || {};
|
|
92
|
+
args.push(`${method} ${pathname}`);
|
|
81
93
|
|
|
82
94
|
if (groupName === 'interactions') {
|
|
83
95
|
// TODO: handle multiple interactions
|
|
@@ -101,8 +113,16 @@ export default class DebugPlugin {
|
|
|
101
113
|
this._log('plugins', eventName, `${plugin.id || '(anonymous)'}`, [plugin, ...data]);
|
|
102
114
|
}
|
|
103
115
|
|
|
116
|
+
// a workflow's creation events on the client follow its context: the
|
|
117
|
+
// workflows of a muted context (the item subworkflows) are muted as well
|
|
118
|
+
_handleClientWorkflowEvent(name, workflow) {
|
|
119
|
+
const context = workflow && workflow._context;
|
|
120
|
+
const silent = !!context && this._isMuted(_joinPath(_pluginComponentPath(context.meta.path)));
|
|
121
|
+
this._logw('client', name, workflow, { silent });
|
|
122
|
+
}
|
|
123
|
+
|
|
104
124
|
_handlePluginSpecificEvent(pluginId, path, name, data) {
|
|
105
|
-
this._logw([pluginId, path
|
|
125
|
+
this._logw(_pluginComponentPath([pluginId, ...path]), name, data);
|
|
106
126
|
}
|
|
107
127
|
|
|
108
128
|
_getPath(component) {
|
|
@@ -113,28 +133,46 @@ export default class DebugPlugin {
|
|
|
113
133
|
return path.reverse();
|
|
114
134
|
}
|
|
115
135
|
|
|
116
|
-
_logw(path, name, data) {
|
|
136
|
+
_logw(path, name, data, options) {
|
|
117
137
|
if (data === undefined) {
|
|
118
|
-
|
|
138
|
+
data = [];
|
|
119
139
|
} else if (Array.isArray(data)) {
|
|
120
|
-
|
|
140
|
+
data = data.map(_wrapObj);
|
|
121
141
|
} else {
|
|
122
|
-
|
|
142
|
+
data = [_wrapObj(data)];
|
|
123
143
|
}
|
|
144
|
+
this._logp(path, name, data, options);
|
|
124
145
|
}
|
|
125
146
|
|
|
126
147
|
_log(path, name, ...data) {
|
|
127
|
-
this.
|
|
148
|
+
this._logp(path, name, data);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
_logp(path, name, data, { silent = false } = {}) {
|
|
152
|
+
path = _joinPath(path);
|
|
153
|
+
this._write([_path(path), _name(name), ...data], { silent: silent || this._isMuted(path) });
|
|
128
154
|
}
|
|
129
155
|
|
|
130
156
|
_logr(...data) {
|
|
157
|
+
this._write(data);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
_write(data, { silent = false } = {}) {
|
|
131
161
|
const options = this._options.console || {};
|
|
132
162
|
if (this._options.preserveLog) {
|
|
133
163
|
this._logs._logs.push(data);
|
|
134
164
|
}
|
|
165
|
+
if (silent) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
135
168
|
console.log(_tag(options), _style(options), ...data);
|
|
136
169
|
}
|
|
137
170
|
|
|
171
|
+
_isMuted(path) {
|
|
172
|
+
const { mute = DEFAULT_MUTE } = this._options;
|
|
173
|
+
return mute.includes(path);
|
|
174
|
+
}
|
|
175
|
+
|
|
138
176
|
}
|
|
139
177
|
|
|
140
178
|
function _tag({ text = 'Miso' } = {}) {
|
|
@@ -147,7 +185,18 @@ function _style({ color = '#fff', background = '#334cbb' } = {}) {
|
|
|
147
185
|
|
|
148
186
|
// format path
|
|
149
187
|
function _path(path) {
|
|
150
|
-
return `<${
|
|
188
|
+
return `<${path}>`;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// the log path of a component under a plugin, off its meta path — which
|
|
192
|
+
// starts at the plugin ([pluginId, ...rest]): the plugins root reaches the
|
|
193
|
+
// plugins as subtrees, not as parents
|
|
194
|
+
function _pluginComponentPath(path) {
|
|
195
|
+
return [path[0], path.slice(1).join('.')];
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function _joinPath(path) {
|
|
199
|
+
return typeof path === 'string' ? path : path.filter(v => v).join('/');
|
|
151
200
|
}
|
|
152
201
|
|
|
153
202
|
// format event name
|
package/src/dry-run.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { addUrlParameter } from '@miso.ai/commons';
|
|
1
|
+
import { API, addUrlParameter } from '@miso.ai/commons';
|
|
2
|
+
|
|
3
|
+
const { GROUP, NAME } = API;
|
|
2
4
|
|
|
3
5
|
const ID = 'std:dry-run';
|
|
4
6
|
|
|
@@ -16,12 +18,24 @@ export default class DryRunPlugin {
|
|
|
16
18
|
|
|
17
19
|
// TODO: config({ active })
|
|
18
20
|
|
|
19
|
-
install(_, { addUrlPass }) {
|
|
21
|
+
install(_, { addUrlPass, addPayloadPass }) {
|
|
20
22
|
addUrlPass(this._modifyUrl.bind(this));
|
|
23
|
+
addPayloadPass(this._modifyPayload.bind(this));
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
_modifyUrl({ apiGroup, apiName, url }) {
|
|
24
27
|
return apiGroup === 'interactions' && apiName === 'upload' ? addUrlParameter(url, 'dry_run', '1') : url;
|
|
25
28
|
}
|
|
26
29
|
|
|
30
|
+
_modifyPayload({ apiGroup, apiName, payload }) {
|
|
31
|
+
if (!payload) {
|
|
32
|
+
return payload; // the GET request
|
|
33
|
+
}
|
|
34
|
+
// questions (ask) and search (hybrid search) only, for now
|
|
35
|
+
if (apiGroup === GROUP.ASK && (apiName === NAME.QUESTIONS || apiName === NAME.SEARCH)) {
|
|
36
|
+
return { ...payload, with_request_history: false };
|
|
37
|
+
}
|
|
38
|
+
return payload;
|
|
39
|
+
}
|
|
40
|
+
|
|
27
41
|
}
|
package/src/lorem.js
CHANGED
|
@@ -2,6 +2,7 @@ import { isInBrowser } from '@miso.ai/commons';
|
|
|
2
2
|
import { lorem } from '@miso.ai/lorem';
|
|
3
3
|
import buildApi from '@miso.ai/doggoganger/src/api.js';
|
|
4
4
|
import fetch from '@miso.ai/doggoganger/src/fetch.js';
|
|
5
|
+
import { delay, rollLatency } from '@miso.ai/doggoganger/src/utils.js';
|
|
5
6
|
|
|
6
7
|
const PLUGIN_ID = 'std:lorem';
|
|
7
8
|
|
|
@@ -16,8 +17,14 @@ export default class LoremPlugin {
|
|
|
16
17
|
this._api = buildApi();
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
/**
|
|
21
|
+
* `latency` adds a mock request latency to every api call, in the manner
|
|
22
|
+
* of the doggoganger server's latency middleware: a number of milliseconds
|
|
23
|
+
* (e.g. 500), or `{ min, max }` for a randomized roll.
|
|
24
|
+
*/
|
|
25
|
+
config({ seed, latency, ...options } = {}) {
|
|
20
26
|
this._lorem = lorem({ seed });
|
|
27
|
+
this._latency = latency;
|
|
21
28
|
this._api = buildApi(options);
|
|
22
29
|
}
|
|
23
30
|
|
|
@@ -45,8 +52,14 @@ export default class LoremPlugin {
|
|
|
45
52
|
};
|
|
46
53
|
}
|
|
47
54
|
|
|
48
|
-
_fetch(url, options) {
|
|
55
|
+
async _fetch(url, options) {
|
|
56
|
+
// the seed is captured before the delay, so the generated content stays
|
|
57
|
+
// tied to the request order, not the completion order
|
|
49
58
|
const seed = this._lorem.prng.seed();
|
|
59
|
+
const latency = this._latency;
|
|
60
|
+
if (latency) {
|
|
61
|
+
await delay(typeof latency === 'number' ? latency : rollLatency(latency.min || 0, latency.max || 0));
|
|
62
|
+
}
|
|
50
63
|
return fetch(this._api, url, { seed, ...options });
|
|
51
64
|
}
|
|
52
65
|
|