@casual-simulation/aux-common 3.1.8 → 3.1.9-alpha.3340590989
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/math/Vector2.js +6 -1
- package/math/Vector2.js.map +1 -1
- package/math/Vector3.js +6 -1
- package/math/Vector3.js.map +1 -1
- package/package.json +4 -2
- package/runtime/AuxCompiler.d.ts +74 -1
- package/runtime/AuxCompiler.js +332 -25
- package/runtime/AuxCompiler.js.map +1 -1
- package/runtime/AuxGlobalContext.d.ts +14 -4
- package/runtime/AuxGlobalContext.js +9 -1
- package/runtime/AuxGlobalContext.js.map +1 -1
- package/runtime/AuxLibrary.d.ts +191 -10
- package/runtime/AuxLibrary.js +172 -37
- package/runtime/AuxLibrary.js.map +1 -1
- package/runtime/AuxLibraryDefinitions.def +469 -82
- package/runtime/AuxRuntime.d.ts +66 -7
- package/runtime/AuxRuntime.js +976 -118
- package/runtime/AuxRuntime.js.map +1 -1
- package/runtime/AuxRuntimeDynamicImports.d.ts +14 -0
- package/runtime/AuxRuntimeDynamicImports.js +24 -0
- package/runtime/AuxRuntimeDynamicImports.js.map +1 -0
- package/runtime/CompiledBot.d.ts +59 -1
- package/runtime/CompiledBot.js +2 -0
- package/runtime/CompiledBot.js.map +1 -1
- package/runtime/RuntimeBot.d.ts +17 -0
- package/runtime/RuntimeBot.js +85 -5
- package/runtime/RuntimeBot.js.map +1 -1
- package/runtime/Transpiler.d.ts +21 -0
- package/runtime/Transpiler.js +27 -0
- package/runtime/Transpiler.js.map +1 -1
- package/runtime/Utils.d.ts +11 -0
- package/runtime/Utils.js +30 -1
- package/runtime/Utils.js.map +1 -1
- package/runtime/test/RuntimeTestHelpers.d.ts +5 -0
- package/runtime/test/RuntimeTestHelpers.js +11 -0
- package/runtime/test/RuntimeTestHelpers.js.map +1 -1
- package/test/TestHelpers.js +2 -2
- package/test/TestHelpers.js.map +1 -1
package/runtime/AuxRuntime.js
CHANGED
|
@@ -5,14 +5,23 @@
|
|
|
5
5
|
// 3. Channel - These are manager objects which handle the persistence and runtime aspects of an AUX.
|
|
6
6
|
// 4. Partitions - These are services which manage the persistence and realtime sync of the AUX data model.
|
|
7
7
|
// 5. Runtimes - These are services which manage script execution and formula precalculation.
|
|
8
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
9
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
10
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
11
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
12
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
13
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
14
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
15
|
+
});
|
|
16
|
+
};
|
|
8
17
|
import { hasValue, tagsOnBot, isFormula, isScript, isNumber, BOT_SPACE_TAG, botUpdated, isBot, ORIGINAL_OBJECT, DEFAULT_ENERGY, getBotSpace, ON_ACTION_ACTION_NAME, breakIntoIndividualEvents, ON_BOT_ADDED_ACTION_NAME, ON_ANY_BOTS_ADDED_ACTION_NAME, ON_ANY_BOTS_REMOVED_ACTION_NAME, ON_BOT_CHANGED_ACTION_NAME, ON_ANY_BOTS_CHANGED_ACTION_NAME, updatedBot, TAG_MASK_SPACE_PRIORITIES, CLEAR_CHANGES_SYMBOL, DNA_TAG_PREFIX, isRuntimeBot, createBot, ON_ERROR, action, isBotInDimension, asyncResult, registerBuiltinPortal, defineGlobalBot, isBotLink, parseBotLink, isBotDate, parseBotDate, formatBotDate, isTaggedString, parseTaggedString, parseNumber, isTaggedNumber, isBotVector, parseBotVector, formatBotVector, isBotRotation, parseBotRotation, formatBotRotation, } from '../bots';
|
|
9
18
|
import { Subject, Subscription } from 'rxjs';
|
|
10
|
-
import { AuxCompiler } from './AuxCompiler';
|
|
19
|
+
import { AuxCompiler, getInterpretableFunction, isInterpretableFunction, } from './AuxCompiler';
|
|
11
20
|
import { addToContext, MemoryGlobalContext, removeFromContext, isInContext, } from './AuxGlobalContext';
|
|
12
21
|
import { createDefaultLibrary, } from './AuxLibrary';
|
|
13
22
|
import { createRuntimeBot, RealtimeEditMode, } from './RuntimeBot';
|
|
14
23
|
import { RanOutOfEnergyError } from './AuxResults';
|
|
15
|
-
import { convertToCopiableValue, DeepObjectError, } from './Utils';
|
|
24
|
+
import { convertToCopiableValue, DeepObjectError, isPromise, isRuntimePromise, markAsRuntimePromise, } from './Utils';
|
|
16
25
|
import { DefaultRealtimeEditModeProvider, } from './AuxRealtimeEditModeProvider';
|
|
17
26
|
import { sortBy, forOwn, merge, union } from 'lodash';
|
|
18
27
|
import { tagValueHash } from '../aux-format-2/AuxOpTypes';
|
|
@@ -21,6 +30,41 @@ import { updateRuntimeVersion, } from './RuntimeStateVersion';
|
|
|
21
30
|
import { replaceMacros } from './Transpiler';
|
|
22
31
|
import { DateTime } from 'luxon';
|
|
23
32
|
import { Rotation, Vector2, Vector3 } from '../math';
|
|
33
|
+
import { isGenerator, UNCOPIABLE, } from '@casual-simulation/js-interpreter/InterpreterUtils';
|
|
34
|
+
import { v4 as uuid } from 'uuid';
|
|
35
|
+
import { importInterpreter as _dynamicImportInterpreter } from './AuxRuntimeDynamicImports';
|
|
36
|
+
let Interpreter;
|
|
37
|
+
let DeclarativeEnvironmentRecord;
|
|
38
|
+
let DefinePropertyOrThrow;
|
|
39
|
+
let Descriptor;
|
|
40
|
+
let Value;
|
|
41
|
+
let hasModule = false;
|
|
42
|
+
let interpreterImportPromise;
|
|
43
|
+
export function registerInterpreterModule(module) {
|
|
44
|
+
hasModule = true;
|
|
45
|
+
Interpreter = module.Interpreter;
|
|
46
|
+
DeclarativeEnvironmentRecord = module.DeclarativeEnvironmentRecord;
|
|
47
|
+
DefinePropertyOrThrow = module.DefinePropertyOrThrow;
|
|
48
|
+
Descriptor = module.Descriptor;
|
|
49
|
+
Value = module.Value;
|
|
50
|
+
}
|
|
51
|
+
function importInterpreter() {
|
|
52
|
+
if (hasModule) {
|
|
53
|
+
return Promise.resolve();
|
|
54
|
+
}
|
|
55
|
+
if (interpreterImportPromise) {
|
|
56
|
+
return interpreterImportPromise;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
return (interpreterImportPromise = _importInterpreterCore());
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function _importInterpreterCore() {
|
|
63
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
64
|
+
const module = yield _dynamicImportInterpreter();
|
|
65
|
+
registerInterpreterModule(module);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
24
68
|
/**
|
|
25
69
|
* Defines an class that is able to manage the runtime state of an AUX.
|
|
26
70
|
*
|
|
@@ -33,11 +77,16 @@ export class AuxRuntime {
|
|
|
33
77
|
* @param libraryFactory
|
|
34
78
|
* @param forceSignedScripts Whether to force the runtime to only allow scripts that are signed.
|
|
35
79
|
* @param exemptSpaces The spaces that are exempt from requiring signed scripts.
|
|
80
|
+
* @param interpreter The interpreter that should be used for the runtime.
|
|
36
81
|
*/
|
|
37
|
-
constructor(version, device, libraryFactory = createDefaultLibrary, editModeProvider = new DefaultRealtimeEditModeProvider(), forceSignedScripts = false, exemptSpaces = ['local', 'tempLocal'], forceSyncScripts = false) {
|
|
82
|
+
constructor(version, device, libraryFactory = createDefaultLibrary, editModeProvider = new DefaultRealtimeEditModeProvider(), forceSignedScripts = false, exemptSpaces = ['local', 'tempLocal'], forceSyncScripts = false, interpreter = null) {
|
|
38
83
|
this._compiledState = {};
|
|
39
84
|
this._existingMasks = {};
|
|
40
85
|
this._compiler = new AuxCompiler();
|
|
86
|
+
this._stopState = null;
|
|
87
|
+
this._breakpoints = new Map();
|
|
88
|
+
this._currentStopCount = 0;
|
|
89
|
+
this._currentPromise = null;
|
|
41
90
|
this._actionBatch = [];
|
|
42
91
|
this._errorBatch = [];
|
|
43
92
|
this._currentVersion = {
|
|
@@ -47,6 +96,8 @@ export class AuxRuntime {
|
|
|
47
96
|
this._updatedBots = new Map();
|
|
48
97
|
this._newBots = new Map();
|
|
49
98
|
this._batchPending = false;
|
|
99
|
+
this._jobQueueCheckPending = false;
|
|
100
|
+
this._jobQueueCheckCount = 0;
|
|
50
101
|
this._processingErrors = false;
|
|
51
102
|
this._portalBots = new Map();
|
|
52
103
|
this._builtinPortalBots = [];
|
|
@@ -70,7 +121,8 @@ export class AuxRuntime {
|
|
|
70
121
|
this._forceSyncScripts = false;
|
|
71
122
|
this._currentDebugger = null;
|
|
72
123
|
this._libraryFactory = libraryFactory;
|
|
73
|
-
this.
|
|
124
|
+
this._interpreter = interpreter;
|
|
125
|
+
this._globalContext = new MemoryGlobalContext(version, device, this, this, this);
|
|
74
126
|
this._forceSyncScripts = forceSyncScripts;
|
|
75
127
|
this._globalContext.mockAsyncActions = forceSyncScripts;
|
|
76
128
|
this._library = merge(libraryFactory(this._globalContext), {
|
|
@@ -86,6 +138,7 @@ export class AuxRuntime {
|
|
|
86
138
|
this._exemptSpaces = exemptSpaces;
|
|
87
139
|
this._onActions = new Subject();
|
|
88
140
|
this._onErrors = new Subject();
|
|
141
|
+
this._onRuntimeStop = new Subject();
|
|
89
142
|
let sub = (this._sub = new Subscription(() => {
|
|
90
143
|
this._globalContext.cancelAllBotTimers();
|
|
91
144
|
}));
|
|
@@ -137,6 +190,24 @@ export class AuxRuntime {
|
|
|
137
190
|
},
|
|
138
191
|
});
|
|
139
192
|
this._globalContext.global = this._globalObject;
|
|
193
|
+
if (this._interpreter) {
|
|
194
|
+
// Use the interpreted versions of APIs
|
|
195
|
+
this._interpretedApi = Object.assign({}, this._library.api);
|
|
196
|
+
this._interpretedTagSpecificApi = Object.assign({}, this._library.tagSpecificApi);
|
|
197
|
+
for (let key in this._interpretedApi) {
|
|
198
|
+
const val = this._interpretedApi[key];
|
|
199
|
+
if (isInterpretableFunction(val)) {
|
|
200
|
+
this._interpretedApi[key] = getInterpretableFunction(val);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
for (let key in this._interpretedTagSpecificApi) {
|
|
204
|
+
const val = this._interpretedTagSpecificApi[key];
|
|
205
|
+
if (isInterpretableFunction(val)) {
|
|
206
|
+
this._interpretedTagSpecificApi[key] =
|
|
207
|
+
getInterpretableFunction(val);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
140
211
|
}
|
|
141
212
|
get forceSignedScripts() {
|
|
142
213
|
return this._forceSignedScripts;
|
|
@@ -150,6 +221,9 @@ export class AuxRuntime {
|
|
|
150
221
|
get globalObject() {
|
|
151
222
|
return this._globalObject;
|
|
152
223
|
}
|
|
224
|
+
get canTriggerBreakpoint() {
|
|
225
|
+
return !!this._interpreter && this._interpreter.debugging;
|
|
226
|
+
}
|
|
153
227
|
getShoutTimers() {
|
|
154
228
|
return {};
|
|
155
229
|
}
|
|
@@ -196,6 +270,12 @@ export class AuxRuntime {
|
|
|
196
270
|
get onErrors() {
|
|
197
271
|
return this._onErrors;
|
|
198
272
|
}
|
|
273
|
+
/**
|
|
274
|
+
* An observable that resolves whenever the runtime pauses in a script.
|
|
275
|
+
*/
|
|
276
|
+
get onRuntimeStop() {
|
|
277
|
+
return this._onRuntimeStop;
|
|
278
|
+
}
|
|
199
279
|
/**
|
|
200
280
|
* Processes the given bot actions and dispatches the resulting actions in the future.
|
|
201
281
|
* @param actions The actions to process.
|
|
@@ -209,85 +289,408 @@ export class AuxRuntime {
|
|
|
209
289
|
return this._currentDebugger;
|
|
210
290
|
}
|
|
211
291
|
_createDebugger(options) {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
292
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
293
|
+
const forceSyncScripts = typeof (options === null || options === void 0 ? void 0 : options.allowAsynchronousScripts) === 'boolean'
|
|
294
|
+
? !options.allowAsynchronousScripts
|
|
295
|
+
: false;
|
|
296
|
+
yield importInterpreter();
|
|
297
|
+
const interpreter = (options === null || options === void 0 ? void 0 : options.pausable) ? new Interpreter() : null;
|
|
298
|
+
const runtime = new AuxRuntime(this._globalContext.version, this._globalContext.device, this._libraryFactory, this._editModeProvider, this._forceSignedScripts, this._exemptSpaces, forceSyncScripts, interpreter);
|
|
299
|
+
runtime._autoBatch = false;
|
|
300
|
+
let idCount = 0;
|
|
301
|
+
if (!(options === null || options === void 0 ? void 0 : options.useRealUUIDs)) {
|
|
302
|
+
runtime._globalContext.uuid = () => {
|
|
303
|
+
idCount += 1;
|
|
304
|
+
return `uuid-${idCount}`;
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
let allActions = [];
|
|
308
|
+
let allErrors = [];
|
|
309
|
+
let create;
|
|
310
|
+
if (interpreter &&
|
|
311
|
+
isInterpretableFunction(runtime._library.tagSpecificApi.create)) {
|
|
312
|
+
const func = getInterpretableFunction(runtime._library.tagSpecificApi.create)({
|
|
313
|
+
bot: null,
|
|
314
|
+
config: null,
|
|
315
|
+
creator: null,
|
|
316
|
+
tag: null,
|
|
317
|
+
});
|
|
318
|
+
create = (...args) => {
|
|
319
|
+
const result = func(...args);
|
|
320
|
+
if (isGenerator(result)) {
|
|
321
|
+
return runtime._processGenerator(result);
|
|
322
|
+
}
|
|
323
|
+
return result;
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
create = runtime._library.tagSpecificApi.create({
|
|
328
|
+
bot: null,
|
|
329
|
+
config: null,
|
|
330
|
+
creator: null,
|
|
331
|
+
tag: null,
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
const isCommonAction = (action) => {
|
|
335
|
+
return !(action.type === 'add_bot' ||
|
|
336
|
+
action.type === 'remove_bot' ||
|
|
337
|
+
action.type === 'update_bot' ||
|
|
338
|
+
action.type === 'apply_state');
|
|
219
339
|
};
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
config
|
|
226
|
-
|
|
227
|
-
|
|
340
|
+
const getAllActions = () => {
|
|
341
|
+
const actions = runtime._processUnbatchedActions();
|
|
342
|
+
allActions.push(...actions);
|
|
343
|
+
return allActions;
|
|
344
|
+
};
|
|
345
|
+
// The config bot is always ID 0 in debuggers
|
|
346
|
+
const configBotId = (options === null || options === void 0 ? void 0 : options.useRealUUIDs)
|
|
347
|
+
? runtime.context.uuid()
|
|
348
|
+
: 'uuid-0';
|
|
349
|
+
const configBotTags = (options === null || options === void 0 ? void 0 : options.configBot)
|
|
350
|
+
? isBot(options === null || options === void 0 ? void 0 : options.configBot)
|
|
351
|
+
? options.configBot.tags
|
|
352
|
+
: options.configBot
|
|
353
|
+
: {};
|
|
354
|
+
runtime.context.createBot(createBot(configBotId, configBotTags, 'tempLocal'));
|
|
355
|
+
runtime.process(this._builtinPortalBots.map((b) => registerBuiltinPortal(b)));
|
|
356
|
+
runtime.userId = configBotId;
|
|
357
|
+
const api = Object.assign({}, runtime._library.api);
|
|
358
|
+
if (interpreter) {
|
|
359
|
+
for (let key in runtime._library.api) {
|
|
360
|
+
const val = runtime._library.api[key];
|
|
361
|
+
if (isInterpretableFunction(val)) {
|
|
362
|
+
const func = getInterpretableFunction(val);
|
|
363
|
+
api[key] = (...args) => {
|
|
364
|
+
const result = func(...args);
|
|
365
|
+
if (isGenerator(result)) {
|
|
366
|
+
return runtime._processGenerator(result);
|
|
367
|
+
}
|
|
368
|
+
return result;
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
if (interpreter && (options === null || options === void 0 ? void 0 : options.pausable)) {
|
|
374
|
+
interpreter.debugging = true;
|
|
375
|
+
}
|
|
376
|
+
const debug = Object.assign(Object.assign({ [UNCOPIABLE]: true }, api), { getAllActions, getCommonActions: () => {
|
|
377
|
+
return getAllActions().filter(isCommonAction);
|
|
378
|
+
}, getBotActions: () => {
|
|
379
|
+
return getAllActions().filter((a) => !isCommonAction(a));
|
|
380
|
+
}, getErrors: () => {
|
|
381
|
+
const errors = runtime._processUnbatchedErrors();
|
|
382
|
+
allErrors.push(...errors);
|
|
383
|
+
return allErrors;
|
|
384
|
+
}, setPauseTrigger(b, tag, options) {
|
|
385
|
+
var _a, _b, _c;
|
|
386
|
+
if (typeof b === 'object' && 'triggerId' in b) {
|
|
387
|
+
runtime.setBreakpoint({
|
|
388
|
+
id: b.triggerId,
|
|
389
|
+
botId: b.botId,
|
|
390
|
+
tag: b.tag,
|
|
391
|
+
lineNumber: b.lineNumber,
|
|
392
|
+
columnNumber: b.columnNumber,
|
|
393
|
+
states: (_a = b.states) !== null && _a !== void 0 ? _a : ['before'],
|
|
394
|
+
disabled: !((_b = b.enabled) !== null && _b !== void 0 ? _b : true),
|
|
395
|
+
});
|
|
396
|
+
return b;
|
|
397
|
+
}
|
|
398
|
+
else {
|
|
399
|
+
const id = isBot(b) ? b.id : b;
|
|
400
|
+
const trigger = Object.assign({ triggerId: uuid(), botId: id, tag: tag }, options);
|
|
401
|
+
runtime.setBreakpoint({
|
|
402
|
+
id: trigger.triggerId,
|
|
403
|
+
botId: id,
|
|
404
|
+
tag: tag,
|
|
405
|
+
lineNumber: trigger.lineNumber,
|
|
406
|
+
columnNumber: trigger.columnNumber,
|
|
407
|
+
states: (_c = trigger.states) !== null && _c !== void 0 ? _c : ['before'],
|
|
408
|
+
disabled: false,
|
|
409
|
+
});
|
|
410
|
+
return trigger;
|
|
411
|
+
}
|
|
412
|
+
},
|
|
413
|
+
removePauseTrigger(triggerOrId) {
|
|
414
|
+
let id = typeof triggerOrId === 'string'
|
|
415
|
+
? triggerOrId
|
|
416
|
+
: triggerOrId.triggerId;
|
|
417
|
+
runtime.removeBreakpoint(id);
|
|
418
|
+
},
|
|
419
|
+
disablePauseTrigger(triggerOrId) {
|
|
420
|
+
var _a;
|
|
421
|
+
if (typeof triggerOrId === 'string') {
|
|
422
|
+
let trigger = runtime._breakpoints.get(triggerOrId);
|
|
423
|
+
if (trigger) {
|
|
424
|
+
trigger.disabled = true;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
runtime.setBreakpoint({
|
|
429
|
+
id: triggerOrId.triggerId,
|
|
430
|
+
botId: triggerOrId.botId,
|
|
431
|
+
tag: triggerOrId.tag,
|
|
432
|
+
lineNumber: triggerOrId.lineNumber,
|
|
433
|
+
columnNumber: triggerOrId.columnNumber,
|
|
434
|
+
states: (_a = triggerOrId.states) !== null && _a !== void 0 ? _a : ['before'],
|
|
435
|
+
disabled: true,
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
},
|
|
439
|
+
enablePauseTrigger(triggerOrId) {
|
|
440
|
+
var _a;
|
|
441
|
+
if (typeof triggerOrId === 'string') {
|
|
442
|
+
let trigger = runtime._breakpoints.get(triggerOrId);
|
|
443
|
+
if (trigger) {
|
|
444
|
+
trigger.disabled = false;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
else {
|
|
448
|
+
runtime.setBreakpoint({
|
|
449
|
+
id: triggerOrId.triggerId,
|
|
450
|
+
botId: triggerOrId.botId,
|
|
451
|
+
tag: triggerOrId.tag,
|
|
452
|
+
lineNumber: triggerOrId.lineNumber,
|
|
453
|
+
columnNumber: triggerOrId.columnNumber,
|
|
454
|
+
states: (_a = triggerOrId.states) !== null && _a !== void 0 ? _a : ['before'],
|
|
455
|
+
disabled: false,
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
},
|
|
459
|
+
listPauseTriggers() {
|
|
460
|
+
let triggers = [];
|
|
461
|
+
for (let breakpoint of runtime._breakpoints.values()) {
|
|
462
|
+
triggers.push({
|
|
463
|
+
triggerId: breakpoint.id,
|
|
464
|
+
botId: breakpoint.botId,
|
|
465
|
+
tag: breakpoint.tag,
|
|
466
|
+
columnNumber: breakpoint.columnNumber,
|
|
467
|
+
lineNumber: breakpoint.lineNumber,
|
|
468
|
+
states: breakpoint.states.slice(),
|
|
469
|
+
enabled: !breakpoint.disabled,
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
return triggers;
|
|
473
|
+
},
|
|
474
|
+
listCommonPauseTriggers(botOrId, tag) {
|
|
475
|
+
const id = typeof botOrId === 'string' ? botOrId : botOrId.id;
|
|
476
|
+
const bot = runtime.currentState[id];
|
|
477
|
+
const func = bot.listeners[tag];
|
|
478
|
+
if (!func) {
|
|
479
|
+
return [];
|
|
480
|
+
}
|
|
481
|
+
return runtime._compiler.listPossibleBreakpoints(func, runtime._interpreter);
|
|
482
|
+
},
|
|
483
|
+
onPause(callback) {
|
|
484
|
+
runtime.onRuntimeStop.subscribe((stop) => {
|
|
485
|
+
const pause = {
|
|
486
|
+
pauseId: stop.stopId,
|
|
487
|
+
state: stop.state,
|
|
488
|
+
callStack: stop.stack.map((s) => {
|
|
489
|
+
const callSite = s.callSite;
|
|
490
|
+
const funcName = callSite.getFunctionName();
|
|
491
|
+
let funcLocation = {};
|
|
492
|
+
if (funcName) {
|
|
493
|
+
const f = runtime._functionMap.get(funcName);
|
|
494
|
+
if (f) {
|
|
495
|
+
funcLocation.name =
|
|
496
|
+
f.metadata.diagnosticFunctionName;
|
|
497
|
+
const location = runtime._compiler.calculateOriginalLineLocation(f, {
|
|
498
|
+
lineNumber: callSite.lineNumber,
|
|
499
|
+
column: callSite.columnNumber,
|
|
500
|
+
});
|
|
501
|
+
funcLocation.lineNumber =
|
|
502
|
+
location.lineNumber + 1;
|
|
503
|
+
funcLocation.columnNumber =
|
|
504
|
+
location.column + 1;
|
|
505
|
+
const tagName = f.metadata.context
|
|
506
|
+
.tag;
|
|
507
|
+
const bot = f.metadata.context.bot;
|
|
508
|
+
if (bot) {
|
|
509
|
+
funcLocation.botId = bot.id;
|
|
510
|
+
}
|
|
511
|
+
if (tagName) {
|
|
512
|
+
funcLocation.tag = tagName;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
else {
|
|
516
|
+
funcLocation.name = funcName;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
if (!hasValue(funcLocation.lineNumber) &&
|
|
520
|
+
!hasValue(funcLocation.columnNumber) &&
|
|
521
|
+
hasValue(callSite.lineNumber) &&
|
|
522
|
+
hasValue(callSite.columnNumber)) {
|
|
523
|
+
funcLocation.lineNumber = callSite.lineNumber;
|
|
524
|
+
funcLocation.columnNumber =
|
|
525
|
+
callSite.columnNumber;
|
|
526
|
+
}
|
|
527
|
+
if (!hasValue(funcLocation.lineNumber) &&
|
|
528
|
+
!hasValue(funcLocation.columnNumber) &&
|
|
529
|
+
!hasValue(funcLocation.name)) {
|
|
530
|
+
funcLocation = null;
|
|
531
|
+
}
|
|
532
|
+
const ret = {
|
|
533
|
+
location: funcLocation,
|
|
534
|
+
listVariables() {
|
|
535
|
+
let variables = [];
|
|
536
|
+
if (s.LexicalEnvironment instanceof
|
|
537
|
+
DeclarativeEnvironmentRecord) {
|
|
538
|
+
addBindingsFromEnvironment(s.LexicalEnvironment, 'block');
|
|
539
|
+
}
|
|
540
|
+
if (s.VariableEnvironment instanceof
|
|
541
|
+
DeclarativeEnvironmentRecord) {
|
|
542
|
+
addBindingsFromEnvironment(s.VariableEnvironment, 'frame');
|
|
543
|
+
let parent = s.VariableEnvironment.OuterEnv;
|
|
544
|
+
while (parent) {
|
|
545
|
+
if (parent instanceof
|
|
546
|
+
DeclarativeEnvironmentRecord) {
|
|
547
|
+
addBindingsFromEnvironment(parent, 'closure');
|
|
548
|
+
}
|
|
549
|
+
parent = parent.OuterEnv;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
return variables;
|
|
553
|
+
function addBindingsFromEnvironment(env, scope) {
|
|
554
|
+
for (let [nameValue, binding,] of env.bindings.entries()) {
|
|
555
|
+
const name = interpreter.copyFromValue(nameValue);
|
|
556
|
+
const initialized = !!binding.initialized;
|
|
557
|
+
const mutable = !!binding.mutable;
|
|
558
|
+
const value = initialized
|
|
559
|
+
? interpreter.reverseProxyObject(binding.value, false)
|
|
560
|
+
: undefined;
|
|
561
|
+
const variable = {
|
|
562
|
+
name,
|
|
563
|
+
value,
|
|
564
|
+
writable: mutable,
|
|
565
|
+
scope,
|
|
566
|
+
};
|
|
567
|
+
if (!initialized) {
|
|
568
|
+
variable.initialized = false;
|
|
569
|
+
}
|
|
570
|
+
variables.push(variable);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
},
|
|
574
|
+
setVariableValue(name, value) {
|
|
575
|
+
if (s.LexicalEnvironment instanceof
|
|
576
|
+
DeclarativeEnvironmentRecord) {
|
|
577
|
+
const nameValue = interpreter.copyToValue(name);
|
|
578
|
+
const proxiedValue = interpreter.proxyObject(value);
|
|
579
|
+
if (nameValue.Type !== 'normal') {
|
|
580
|
+
throw interpreter.copyFromValue(nameValue.Value);
|
|
581
|
+
}
|
|
582
|
+
if (proxiedValue.Type !== 'normal') {
|
|
583
|
+
throw interpreter.copyFromValue(proxiedValue.Value);
|
|
584
|
+
}
|
|
585
|
+
const result = s.LexicalEnvironment.SetMutableBinding(nameValue.Value, proxiedValue.Value, Value.true);
|
|
586
|
+
if (result.Type !== 'normal') {
|
|
587
|
+
throw interpreter.copyFromValue(result.Value);
|
|
588
|
+
}
|
|
589
|
+
return interpreter.copyFromValue(result.Value);
|
|
590
|
+
}
|
|
591
|
+
},
|
|
592
|
+
};
|
|
593
|
+
return ret;
|
|
594
|
+
}),
|
|
595
|
+
trigger: {
|
|
596
|
+
triggerId: stop.breakpoint.id,
|
|
597
|
+
botId: stop.breakpoint.botId,
|
|
598
|
+
tag: stop.breakpoint.tag,
|
|
599
|
+
lineNumber: stop.breakpoint.lineNumber,
|
|
600
|
+
columnNumber: stop.breakpoint.columnNumber,
|
|
601
|
+
states: stop.breakpoint.states,
|
|
602
|
+
},
|
|
603
|
+
};
|
|
604
|
+
callback(pause);
|
|
605
|
+
});
|
|
606
|
+
},
|
|
607
|
+
resume(pause) {
|
|
608
|
+
runtime.continueAfterStop(pause.pauseId);
|
|
609
|
+
},
|
|
610
|
+
create });
|
|
611
|
+
runtime._currentDebugger = debug;
|
|
612
|
+
this._scheduleJobQueueCheck();
|
|
613
|
+
return debug;
|
|
228
614
|
});
|
|
229
|
-
const isCommonAction = (action) => {
|
|
230
|
-
return !(action.type === 'add_bot' ||
|
|
231
|
-
action.type === 'remove_bot' ||
|
|
232
|
-
action.type === 'update_bot' ||
|
|
233
|
-
action.type === 'apply_state');
|
|
234
|
-
};
|
|
235
|
-
const getAllActions = () => {
|
|
236
|
-
const actions = runtime._processUnbatchedActions();
|
|
237
|
-
allActions.push(...actions);
|
|
238
|
-
return allActions;
|
|
239
|
-
};
|
|
240
|
-
// The config bot is always ID 0 in debuggers
|
|
241
|
-
const configBotId = (options === null || options === void 0 ? void 0 : options.useRealUUIDs)
|
|
242
|
-
? runtime.context.uuid()
|
|
243
|
-
: 'uuid-0';
|
|
244
|
-
const configBotTags = (options === null || options === void 0 ? void 0 : options.configBot)
|
|
245
|
-
? isBot(options === null || options === void 0 ? void 0 : options.configBot)
|
|
246
|
-
? options.configBot.tags
|
|
247
|
-
: options.configBot
|
|
248
|
-
: {};
|
|
249
|
-
runtime.context.createBot(createBot(configBotId, configBotTags, 'tempLocal'));
|
|
250
|
-
runtime.process(this._builtinPortalBots.map((b) => registerBuiltinPortal(b)));
|
|
251
|
-
runtime.userId = configBotId;
|
|
252
|
-
const debug = Object.assign(Object.assign({}, runtime._library.api), { getAllActions, getCommonActions: () => {
|
|
253
|
-
return getAllActions().filter(isCommonAction);
|
|
254
|
-
}, getBotActions: () => {
|
|
255
|
-
return getAllActions().filter((a) => !isCommonAction(a));
|
|
256
|
-
}, getErrors: () => {
|
|
257
|
-
const errors = runtime._processUnbatchedErrors();
|
|
258
|
-
allErrors.push(...errors);
|
|
259
|
-
return allErrors;
|
|
260
|
-
}, create });
|
|
261
|
-
runtime._currentDebugger = debug;
|
|
262
|
-
return debug;
|
|
263
615
|
}
|
|
264
616
|
_processCore(actions) {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
617
|
+
const _this = this;
|
|
618
|
+
function handleRejection(action, rejection) {
|
|
619
|
+
let promise = processListOfMaybePromises(null, rejection.newActions, (action) => {
|
|
620
|
+
return _this._processAction(action);
|
|
621
|
+
});
|
|
622
|
+
if (rejection.rejected) {
|
|
623
|
+
return;
|
|
269
624
|
}
|
|
270
|
-
if (
|
|
271
|
-
|
|
625
|
+
if (promise) {
|
|
626
|
+
return markAsRuntimePromise(promise.then((p) => _this._processAction(action)));
|
|
627
|
+
}
|
|
628
|
+
else {
|
|
629
|
+
return _this._processAction(action);
|
|
272
630
|
}
|
|
273
|
-
this._processAction(action);
|
|
274
631
|
}
|
|
632
|
+
return processListOfMaybePromises(null, actions, (action) => {
|
|
633
|
+
let rejection = this._rejectAction(action);
|
|
634
|
+
if (isRuntimePromise(rejection)) {
|
|
635
|
+
return markAsRuntimePromise(rejection.then((result) => handleRejection(action, result)));
|
|
636
|
+
}
|
|
637
|
+
else {
|
|
638
|
+
return handleRejection(action, rejection);
|
|
639
|
+
}
|
|
640
|
+
});
|
|
275
641
|
}
|
|
276
642
|
_processAction(action) {
|
|
277
643
|
if (action.type === 'action') {
|
|
278
644
|
const result = this._shout(action.eventName, action.botIds, action.argument, false);
|
|
279
|
-
|
|
645
|
+
if (isRuntimePromise(result)) {
|
|
646
|
+
return markAsRuntimePromise(result.then((result) => this._processCore(result.actions)));
|
|
647
|
+
}
|
|
648
|
+
else {
|
|
649
|
+
return this._processCore(result.actions);
|
|
650
|
+
}
|
|
280
651
|
}
|
|
281
652
|
else if (action.type === 'run_script') {
|
|
282
653
|
const result = this._execute(action.script, false, false);
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
654
|
+
if (isRuntimePromise(result)) {
|
|
655
|
+
return markAsRuntimePromise(result.then((result) => {
|
|
656
|
+
const p = this._processCore(result.actions);
|
|
657
|
+
if (isPromise(p)) {
|
|
658
|
+
return p.then(() => {
|
|
659
|
+
if (hasValue(action.taskId)) {
|
|
660
|
+
this._globalContext.resolveTask(action.taskId, result.result, false);
|
|
661
|
+
}
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
else {
|
|
665
|
+
if (hasValue(action.taskId)) {
|
|
666
|
+
if (this._globalContext.resolveTask(action.taskId, result.result, false)) {
|
|
667
|
+
this._scheduleJobQueueCheck();
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
}));
|
|
672
|
+
}
|
|
673
|
+
else {
|
|
674
|
+
const p = this._processCore(result.actions);
|
|
675
|
+
if (isRuntimePromise(p)) {
|
|
676
|
+
return markAsRuntimePromise(p.then(() => {
|
|
677
|
+
if (hasValue(action.taskId)) {
|
|
678
|
+
if (this._globalContext.resolveTask(action.taskId, result.result, false)) {
|
|
679
|
+
this._scheduleJobQueueCheck();
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
}));
|
|
683
|
+
}
|
|
684
|
+
if (hasValue(action.taskId)) {
|
|
685
|
+
if (this._globalContext.resolveTask(action.taskId, result.result, false)) {
|
|
686
|
+
this._scheduleJobQueueCheck();
|
|
687
|
+
}
|
|
688
|
+
}
|
|
286
689
|
}
|
|
287
690
|
}
|
|
288
691
|
else if (action.type === 'apply_state') {
|
|
289
692
|
const events = breakIntoIndividualEvents(this.currentState, action);
|
|
290
|
-
this._processCore(events);
|
|
693
|
+
return this._processCore(events);
|
|
291
694
|
}
|
|
292
695
|
else if (action.type === 'async_result') {
|
|
293
696
|
const value = action.mapBotsInResult === true
|
|
@@ -296,21 +699,33 @@ export class AuxRuntime {
|
|
|
296
699
|
if (!this._globalContext.resolveTask(action.taskId, value, false)) {
|
|
297
700
|
this._actionBatch.push(action);
|
|
298
701
|
}
|
|
702
|
+
else {
|
|
703
|
+
this._scheduleJobQueueCheck();
|
|
704
|
+
}
|
|
299
705
|
}
|
|
300
706
|
else if (action.type === 'async_error') {
|
|
301
707
|
if (!this._globalContext.rejectTask(action.taskId, action.error, false)) {
|
|
302
708
|
this._actionBatch.push(action);
|
|
303
709
|
}
|
|
710
|
+
else {
|
|
711
|
+
this._scheduleJobQueueCheck();
|
|
712
|
+
}
|
|
304
713
|
}
|
|
305
714
|
else if (action.type === 'device_result') {
|
|
306
715
|
if (!this._globalContext.resolveTask(action.taskId, action.result, true)) {
|
|
307
716
|
this._actionBatch.push(action);
|
|
308
717
|
}
|
|
718
|
+
else {
|
|
719
|
+
this._scheduleJobQueueCheck();
|
|
720
|
+
}
|
|
309
721
|
}
|
|
310
722
|
else if (action.type === 'device_error') {
|
|
311
723
|
if (!this._globalContext.rejectTask(action.taskId, action.error, true)) {
|
|
312
724
|
this._actionBatch.push(action);
|
|
313
725
|
}
|
|
726
|
+
else {
|
|
727
|
+
this._scheduleJobQueueCheck();
|
|
728
|
+
}
|
|
314
729
|
}
|
|
315
730
|
else if (action.type === 'register_custom_app') {
|
|
316
731
|
this._registerPortalBot(action.appId, action.botId);
|
|
@@ -330,7 +745,7 @@ export class AuxRuntime {
|
|
|
330
745
|
this._actionBatch.push(action);
|
|
331
746
|
}
|
|
332
747
|
if (hasValue(action.taskId)) {
|
|
333
|
-
this._processCore([asyncResult(action.taskId, null)]);
|
|
748
|
+
return this._processCore([asyncResult(action.taskId, null)]);
|
|
334
749
|
}
|
|
335
750
|
}
|
|
336
751
|
else {
|
|
@@ -342,35 +757,76 @@ export class AuxRuntime {
|
|
|
342
757
|
this._portalBots.set(portalId, botId);
|
|
343
758
|
if (!hadPortalBot) {
|
|
344
759
|
const variableName = `${portalId}Bot`;
|
|
760
|
+
const getValue = () => {
|
|
761
|
+
const botId = this._portalBots.get(portalId);
|
|
762
|
+
if (hasValue(botId)) {
|
|
763
|
+
return this.context.state[botId];
|
|
764
|
+
}
|
|
765
|
+
else {
|
|
766
|
+
return undefined;
|
|
767
|
+
}
|
|
768
|
+
};
|
|
345
769
|
Object.defineProperty(this._globalObject, variableName, {
|
|
346
|
-
get:
|
|
347
|
-
const botId = this._portalBots.get(portalId);
|
|
348
|
-
if (hasValue(botId)) {
|
|
349
|
-
return this.context.state[botId];
|
|
350
|
-
}
|
|
351
|
-
else {
|
|
352
|
-
return undefined;
|
|
353
|
-
}
|
|
354
|
-
},
|
|
770
|
+
get: getValue,
|
|
355
771
|
enumerable: false,
|
|
356
772
|
configurable: true,
|
|
357
773
|
});
|
|
774
|
+
if (this._interpreter) {
|
|
775
|
+
const proxiedGetResult = this._interpreter.proxyObject(getValue);
|
|
776
|
+
if (proxiedGetResult.Type !== 'normal') {
|
|
777
|
+
throw this._interpreter.copyFromValue(proxiedGetResult.Value);
|
|
778
|
+
}
|
|
779
|
+
DefinePropertyOrThrow(this._interpreter.realm.GlobalObject, new Value(variableName), new Descriptor({
|
|
780
|
+
Get: proxiedGetResult.Value,
|
|
781
|
+
Configurable: Value.true,
|
|
782
|
+
}));
|
|
783
|
+
}
|
|
358
784
|
}
|
|
359
785
|
}
|
|
360
786
|
_rejectAction(action) {
|
|
361
787
|
const result = this._shout(ON_ACTION_ACTION_NAME, null, {
|
|
362
788
|
action: action,
|
|
363
789
|
}, false);
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
790
|
+
if (isRuntimePromise(result)) {
|
|
791
|
+
return markAsRuntimePromise(result.then((result) => {
|
|
792
|
+
return handleResult(result);
|
|
793
|
+
}));
|
|
794
|
+
}
|
|
795
|
+
return handleResult(result);
|
|
796
|
+
function handleResult(result) {
|
|
797
|
+
let rejected = false;
|
|
798
|
+
for (let i = 0; i < result.actions.length; i++) {
|
|
799
|
+
const a = result.actions[i];
|
|
800
|
+
if (a.type === 'reject' && a.actions.indexOf(action) >= 0) {
|
|
801
|
+
rejected = true;
|
|
802
|
+
result.actions.splice(i, 1);
|
|
803
|
+
break;
|
|
804
|
+
}
|
|
371
805
|
}
|
|
806
|
+
return { rejected, newActions: result.actions };
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
/**
|
|
810
|
+
* Executes the given function based on the current execution state of the runtime.
|
|
811
|
+
* If the runtime is stopped, then the given function will be executed after the current promise finishes.
|
|
812
|
+
* If the runtime is executing normally, then the given function will be executed immediately.
|
|
813
|
+
* Returns the function result if the function executes immediately,
|
|
814
|
+
* or returns a runtime promise if the function executes after the current promise.
|
|
815
|
+
*
|
|
816
|
+
* This function essentially forces the given function to execute synchronously with respect to other functions wrapped with this function.
|
|
817
|
+
*
|
|
818
|
+
* @param func The function to execute.
|
|
819
|
+
*
|
|
820
|
+
*/
|
|
821
|
+
_wrapWithCurrentPromise(func) {
|
|
822
|
+
if (this._stopState && isRuntimePromise(this._currentPromise)) {
|
|
823
|
+
// We have hit a breakpoint,
|
|
824
|
+
// only trigger this shout after the current state has finished.
|
|
825
|
+
return (this._currentPromise = markAsRuntimePromise(this._currentPromise.then(() => {
|
|
826
|
+
return func();
|
|
827
|
+
})));
|
|
372
828
|
}
|
|
373
|
-
return
|
|
829
|
+
return (this._currentPromise = func());
|
|
374
830
|
}
|
|
375
831
|
/**
|
|
376
832
|
* Executes a shout with the given event name on the given bot IDs with the given argument.
|
|
@@ -380,25 +836,64 @@ export class AuxRuntime {
|
|
|
380
836
|
* @param arg The argument to include in the shout.
|
|
381
837
|
*/
|
|
382
838
|
shout(eventName, botIds, arg) {
|
|
383
|
-
return this.
|
|
839
|
+
return this._synchronousShout(eventName, botIds, arg, true, true);
|
|
840
|
+
}
|
|
841
|
+
/**
|
|
842
|
+
* Executes the given shout synchronously with respect to other scripts that may be running or paused.
|
|
843
|
+
* @param eventName The name of the event that should be executed.
|
|
844
|
+
* @param botIds The IDs of the bots that the shout should be sent to.
|
|
845
|
+
* @param arg The argument that should be sent with the shout.
|
|
846
|
+
* @param batch Whether to batch events.
|
|
847
|
+
* @param resetEnergy Whether to reset the runtime energy before executing the shout.
|
|
848
|
+
*/
|
|
849
|
+
_synchronousShout(eventName, botIds, arg, batch, resetEnergy = true) {
|
|
850
|
+
return this._wrapWithCurrentPromise(() => {
|
|
851
|
+
return this._shout(eventName, botIds, arg, batch, resetEnergy);
|
|
852
|
+
});
|
|
384
853
|
}
|
|
385
854
|
_shout(eventName, botIds, arg, batch, resetEnergy = true) {
|
|
386
855
|
try {
|
|
387
856
|
arg = this._mapBotsToRuntimeBots(arg);
|
|
857
|
+
if (this._interpreter) {
|
|
858
|
+
const result = this._interpreter.proxyObject(arg);
|
|
859
|
+
if (result.Type !== 'normal') {
|
|
860
|
+
throw new Error(`Unable to proxy shout argument!`);
|
|
861
|
+
}
|
|
862
|
+
arg = result.Value;
|
|
863
|
+
}
|
|
388
864
|
}
|
|
389
865
|
catch (err) {
|
|
390
866
|
arg = err;
|
|
391
867
|
}
|
|
392
|
-
const
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
868
|
+
const result = this._batchScriptResults(() => {
|
|
869
|
+
if (this.canTriggerBreakpoint) {
|
|
870
|
+
const results = (hasValue(botIds)
|
|
871
|
+
? getInterpretableFunction(this._library.api.whisper)(botIds, eventName, arg)
|
|
872
|
+
: getInterpretableFunction(this._library.api.shout)(eventName, arg));
|
|
873
|
+
return this._processGenerator(results);
|
|
874
|
+
}
|
|
875
|
+
else {
|
|
876
|
+
const results = hasValue(botIds)
|
|
877
|
+
? this._library.api.whisper(botIds, eventName, arg)
|
|
878
|
+
: this._library.api.shout(eventName, arg);
|
|
879
|
+
this._scheduleJobQueueCheck();
|
|
880
|
+
return results;
|
|
881
|
+
}
|
|
397
882
|
}, batch, resetEnergy);
|
|
883
|
+
if (isRuntimePromise(result)) {
|
|
884
|
+
return markAsRuntimePromise(result.then(({ actions, errors, result }) => {
|
|
885
|
+
return {
|
|
886
|
+
actions,
|
|
887
|
+
errors,
|
|
888
|
+
results: result,
|
|
889
|
+
listeners: [],
|
|
890
|
+
};
|
|
891
|
+
}));
|
|
892
|
+
}
|
|
398
893
|
return {
|
|
399
|
-
actions,
|
|
400
|
-
errors,
|
|
401
|
-
results: result,
|
|
894
|
+
actions: result.actions,
|
|
895
|
+
errors: result.errors,
|
|
896
|
+
results: result.result,
|
|
402
897
|
listeners: [],
|
|
403
898
|
};
|
|
404
899
|
}
|
|
@@ -407,7 +902,9 @@ export class AuxRuntime {
|
|
|
407
902
|
* @param script The script to run.
|
|
408
903
|
*/
|
|
409
904
|
execute(script) {
|
|
410
|
-
return this.
|
|
905
|
+
return this._wrapWithCurrentPromise(() => {
|
|
906
|
+
return this._execute(script, true, true);
|
|
907
|
+
});
|
|
411
908
|
}
|
|
412
909
|
_execute(script, batch, resetEnergy) {
|
|
413
910
|
let fn;
|
|
@@ -491,8 +988,8 @@ export class AuxRuntime {
|
|
|
491
988
|
_sendOnBotsAddedShouts(newBots, nextUpdate) {
|
|
492
989
|
if (newBots && nextUpdate.addedBots.length > 0) {
|
|
493
990
|
try {
|
|
494
|
-
this.
|
|
495
|
-
this.
|
|
991
|
+
this._synchronousShout(ON_BOT_ADDED_ACTION_NAME, nextUpdate.addedBots, undefined, true, false);
|
|
992
|
+
this._synchronousShout(ON_ANY_BOTS_ADDED_ACTION_NAME, null, {
|
|
496
993
|
bots: newBots.map(([bot, precalc]) => bot),
|
|
497
994
|
}, true, false);
|
|
498
995
|
}
|
|
@@ -509,15 +1006,47 @@ export class AuxRuntime {
|
|
|
509
1006
|
_sendOnBotsRemovedShouts(botIds) {
|
|
510
1007
|
if (botIds.length > 0) {
|
|
511
1008
|
try {
|
|
1009
|
+
let promise;
|
|
512
1010
|
for (let bot of botIds) {
|
|
513
1011
|
const watchers = this._globalContext.getWatchersForBot(bot);
|
|
514
|
-
|
|
515
|
-
watcher.handler();
|
|
1012
|
+
promise = processListOfMaybePromises(promise, watchers, (watcher) => {
|
|
1013
|
+
const generator = watcher.handler();
|
|
1014
|
+
if (isGenerator(generator)) {
|
|
1015
|
+
return this._processGenerator(generator);
|
|
1016
|
+
}
|
|
1017
|
+
});
|
|
1018
|
+
}
|
|
1019
|
+
if (promise) {
|
|
1020
|
+
return markAsRuntimePromise(promise
|
|
1021
|
+
.then(() => {
|
|
1022
|
+
return this._synchronousShout(ON_ANY_BOTS_REMOVED_ACTION_NAME, null, {
|
|
1023
|
+
botIDs: botIds,
|
|
1024
|
+
}, true, false);
|
|
1025
|
+
})
|
|
1026
|
+
.catch((err) => {
|
|
1027
|
+
if (!(err instanceof RanOutOfEnergyError)) {
|
|
1028
|
+
throw err;
|
|
1029
|
+
}
|
|
1030
|
+
else {
|
|
1031
|
+
console.warn(err);
|
|
1032
|
+
}
|
|
1033
|
+
}));
|
|
1034
|
+
}
|
|
1035
|
+
else {
|
|
1036
|
+
const maybePromise = this._synchronousShout(ON_ANY_BOTS_REMOVED_ACTION_NAME, null, {
|
|
1037
|
+
botIDs: botIds,
|
|
1038
|
+
}, true, false);
|
|
1039
|
+
if (isRuntimePromise(maybePromise)) {
|
|
1040
|
+
return markAsRuntimePromise(maybePromise.catch((err) => {
|
|
1041
|
+
if (!(err instanceof RanOutOfEnergyError)) {
|
|
1042
|
+
throw err;
|
|
1043
|
+
}
|
|
1044
|
+
else {
|
|
1045
|
+
console.warn(err);
|
|
1046
|
+
}
|
|
1047
|
+
}));
|
|
516
1048
|
}
|
|
517
1049
|
}
|
|
518
|
-
this._shout(ON_ANY_BOTS_REMOVED_ACTION_NAME, null, {
|
|
519
|
-
botIDs: botIds,
|
|
520
|
-
}, true, false);
|
|
521
1050
|
}
|
|
522
1051
|
catch (err) {
|
|
523
1052
|
if (!(err instanceof RanOutOfEnergyError)) {
|
|
@@ -532,19 +1061,52 @@ export class AuxRuntime {
|
|
|
532
1061
|
_sendOnBotsChangedShouts(updates) {
|
|
533
1062
|
if (updates && updates.length > 0) {
|
|
534
1063
|
try {
|
|
535
|
-
|
|
1064
|
+
let promise = processListOfMaybePromises(null, updates, (update) => {
|
|
536
1065
|
if (!update) {
|
|
537
|
-
|
|
1066
|
+
return;
|
|
538
1067
|
}
|
|
539
|
-
this.
|
|
1068
|
+
let promise = this._synchronousShout(ON_BOT_CHANGED_ACTION_NAME, [update.bot.id], {
|
|
540
1069
|
tags: update.tags,
|
|
541
1070
|
}, true, false);
|
|
542
1071
|
const watchers = this._globalContext.getWatchersForBot(update.bot.id);
|
|
543
|
-
|
|
544
|
-
watcher.handler();
|
|
1072
|
+
return processListOfMaybePromises(promise, watchers, (watcher) => {
|
|
1073
|
+
const generator = watcher.handler();
|
|
1074
|
+
if (isGenerator(generator)) {
|
|
1075
|
+
return this._processGenerator(generator);
|
|
1076
|
+
}
|
|
1077
|
+
return generator;
|
|
1078
|
+
});
|
|
1079
|
+
});
|
|
1080
|
+
if (isPromise(promise)) {
|
|
1081
|
+
return promise
|
|
1082
|
+
.then(() => {
|
|
1083
|
+
return this._synchronousShout(ON_ANY_BOTS_CHANGED_ACTION_NAME, null, updates, true, false);
|
|
1084
|
+
})
|
|
1085
|
+
.catch((err) => {
|
|
1086
|
+
if (!(err instanceof RanOutOfEnergyError)) {
|
|
1087
|
+
throw err;
|
|
1088
|
+
}
|
|
1089
|
+
else {
|
|
1090
|
+
console.warn(err);
|
|
1091
|
+
}
|
|
1092
|
+
});
|
|
1093
|
+
}
|
|
1094
|
+
else {
|
|
1095
|
+
const maybePromise = this._synchronousShout(ON_ANY_BOTS_CHANGED_ACTION_NAME, null, updates, true, false);
|
|
1096
|
+
if (isPromise(maybePromise)) {
|
|
1097
|
+
return maybePromise.catch((err) => {
|
|
1098
|
+
if (!(err instanceof RanOutOfEnergyError)) {
|
|
1099
|
+
throw err;
|
|
1100
|
+
}
|
|
1101
|
+
else {
|
|
1102
|
+
console.warn(err);
|
|
1103
|
+
}
|
|
1104
|
+
});
|
|
1105
|
+
}
|
|
1106
|
+
else {
|
|
1107
|
+
return maybePromise;
|
|
545
1108
|
}
|
|
546
1109
|
}
|
|
547
|
-
this._shout(ON_ANY_BOTS_CHANGED_ACTION_NAME, null, updates, true, false);
|
|
548
1110
|
}
|
|
549
1111
|
catch (err) {
|
|
550
1112
|
if (!(err instanceof RanOutOfEnergyError)) {
|
|
@@ -573,7 +1135,7 @@ export class AuxRuntime {
|
|
|
573
1135
|
if (!userBot) {
|
|
574
1136
|
return;
|
|
575
1137
|
}
|
|
576
|
-
|
|
1138
|
+
return processListOfMaybePromises(null, portals, (portal) => {
|
|
577
1139
|
const dimension = userBot.values[portal];
|
|
578
1140
|
let hasChange = false;
|
|
579
1141
|
if (hasValue(dimension)) {
|
|
@@ -617,11 +1179,14 @@ export class AuxRuntime {
|
|
|
617
1179
|
}
|
|
618
1180
|
if (hasChange) {
|
|
619
1181
|
const watchers = this._globalContext.getWatchersForPortal(portal);
|
|
620
|
-
|
|
621
|
-
watcher.handler();
|
|
622
|
-
|
|
1182
|
+
return processListOfMaybePromises(null, watchers, (watcher) => {
|
|
1183
|
+
const generator = watcher.handler();
|
|
1184
|
+
if (isGenerator(generator)) {
|
|
1185
|
+
return this._processGenerator(generator);
|
|
1186
|
+
}
|
|
1187
|
+
});
|
|
623
1188
|
}
|
|
624
|
-
}
|
|
1189
|
+
});
|
|
625
1190
|
}
|
|
626
1191
|
_addBotsToState(bots, nextUpdate) {
|
|
627
1192
|
let newBots = [];
|
|
@@ -679,6 +1244,10 @@ export class AuxRuntime {
|
|
|
679
1244
|
const bot = this._compiledState[id];
|
|
680
1245
|
if (bot) {
|
|
681
1246
|
removeFromContext(this._globalContext, [bot.script]);
|
|
1247
|
+
for (let breakpoint of bot.breakpoints) {
|
|
1248
|
+
this._interpreter.removeBreakpointById(breakpoint.id);
|
|
1249
|
+
this._breakpoints.delete(breakpoint.id);
|
|
1250
|
+
}
|
|
682
1251
|
}
|
|
683
1252
|
removedBots.push(bot);
|
|
684
1253
|
delete this._compiledState[id];
|
|
@@ -800,6 +1369,25 @@ export class AuxRuntime {
|
|
|
800
1369
|
const compiledValue = compiled.values[tag];
|
|
801
1370
|
partial.values[tag] = convertToCopiableValue(hasValue(compiledValue) ? compiledValue : null);
|
|
802
1371
|
}
|
|
1372
|
+
for (let breakpoint of compiled.breakpoints) {
|
|
1373
|
+
if (updatedTags.has(breakpoint.tag)) {
|
|
1374
|
+
// Update the breakpoint
|
|
1375
|
+
const func = compiled.listeners[breakpoint.tag];
|
|
1376
|
+
if (func) {
|
|
1377
|
+
this._compiler.setBreakpoint({
|
|
1378
|
+
id: breakpoint.id,
|
|
1379
|
+
func: func,
|
|
1380
|
+
interpreter: this._interpreter,
|
|
1381
|
+
lineNumber: breakpoint.lineNumber,
|
|
1382
|
+
columnNumber: breakpoint.columnNumber,
|
|
1383
|
+
states: breakpoint.states,
|
|
1384
|
+
});
|
|
1385
|
+
}
|
|
1386
|
+
else {
|
|
1387
|
+
this._interpreter.removeBreakpointById(breakpoint.id);
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
803
1391
|
if (u.signatures) {
|
|
804
1392
|
if (!compiled.signatures) {
|
|
805
1393
|
compiled.signatures = {};
|
|
@@ -829,6 +1417,12 @@ export class AuxRuntime {
|
|
|
829
1417
|
notifyChange() {
|
|
830
1418
|
if (!this._batchPending && this._autoBatch) {
|
|
831
1419
|
this._batchPending = true;
|
|
1420
|
+
if (this.canTriggerBreakpoint) {
|
|
1421
|
+
this._scheduleJob('notifyChange', () => {
|
|
1422
|
+
this._processBatch();
|
|
1423
|
+
});
|
|
1424
|
+
return;
|
|
1425
|
+
}
|
|
832
1426
|
queueMicrotask(() => {
|
|
833
1427
|
this._processBatch();
|
|
834
1428
|
});
|
|
@@ -901,12 +1495,22 @@ export class AuxRuntime {
|
|
|
901
1495
|
}
|
|
902
1496
|
}
|
|
903
1497
|
_batchScriptResults(callback, batch, resetEnergy) {
|
|
904
|
-
const
|
|
1498
|
+
const result = this._calculateScriptResults(callback, resetEnergy);
|
|
1499
|
+
if (isRuntimePromise(result)) {
|
|
1500
|
+
return markAsRuntimePromise(result.then((results) => {
|
|
1501
|
+
if (batch) {
|
|
1502
|
+
this._actionBatch.push(...results.actions);
|
|
1503
|
+
this.notifyChange();
|
|
1504
|
+
}
|
|
1505
|
+
this._errorBatch.push(...results.errors);
|
|
1506
|
+
return results;
|
|
1507
|
+
}));
|
|
1508
|
+
}
|
|
905
1509
|
if (batch) {
|
|
906
|
-
this._actionBatch.push(...
|
|
1510
|
+
this._actionBatch.push(...result.actions);
|
|
907
1511
|
}
|
|
908
|
-
this._errorBatch.push(...
|
|
909
|
-
return
|
|
1512
|
+
this._errorBatch.push(...result.errors);
|
|
1513
|
+
return result;
|
|
910
1514
|
}
|
|
911
1515
|
_calculateScriptResults(callback, resetEnergy) {
|
|
912
1516
|
this._globalContext.playerBot = this.userBot;
|
|
@@ -914,6 +1518,17 @@ export class AuxRuntime {
|
|
|
914
1518
|
this._globalContext.energy = DEFAULT_ENERGY;
|
|
915
1519
|
}
|
|
916
1520
|
const result = callback();
|
|
1521
|
+
if (isRuntimePromise(result)) {
|
|
1522
|
+
return markAsRuntimePromise(result.then((results) => {
|
|
1523
|
+
const actions = this._processUnbatchedActions();
|
|
1524
|
+
const errors = this._processUnbatchedErrors();
|
|
1525
|
+
return {
|
|
1526
|
+
result: results,
|
|
1527
|
+
actions: actions,
|
|
1528
|
+
errors: errors,
|
|
1529
|
+
};
|
|
1530
|
+
}));
|
|
1531
|
+
}
|
|
917
1532
|
const actions = this._processUnbatchedActions();
|
|
918
1533
|
const errors = this._processUnbatchedErrors();
|
|
919
1534
|
return {
|
|
@@ -994,6 +1609,7 @@ export class AuxRuntime {
|
|
|
994
1609
|
script: null,
|
|
995
1610
|
originalTagEditValues: {},
|
|
996
1611
|
originalTagMaskEditValues: {},
|
|
1612
|
+
breakpoints: [],
|
|
997
1613
|
};
|
|
998
1614
|
if (BOT_SPACE_TAG in bot) {
|
|
999
1615
|
compiledBot.space = bot.space;
|
|
@@ -1211,7 +1827,16 @@ export class AuxRuntime {
|
|
|
1211
1827
|
delete bot.originalTagEditValues[tag];
|
|
1212
1828
|
}
|
|
1213
1829
|
if (hasValue(tagValue)) {
|
|
1214
|
-
bot.
|
|
1830
|
+
if (this._newBots.has(bot.id) &&
|
|
1831
|
+
(tagValue instanceof DateTime ||
|
|
1832
|
+
tagValue instanceof Vector2 ||
|
|
1833
|
+
tagValue instanceof Vector3 ||
|
|
1834
|
+
tagValue instanceof Rotation)) {
|
|
1835
|
+
bot.tags[tag] = convertToCopiableValue(tagValue);
|
|
1836
|
+
}
|
|
1837
|
+
else {
|
|
1838
|
+
bot.tags[tag] = tagValue;
|
|
1839
|
+
}
|
|
1215
1840
|
}
|
|
1216
1841
|
else {
|
|
1217
1842
|
delete bot.tags[tag];
|
|
@@ -1315,12 +1940,22 @@ export class AuxRuntime {
|
|
|
1315
1940
|
diagnosticFunctionName = tag;
|
|
1316
1941
|
fileName = `${bot.id}.${diagnosticFunctionName}`;
|
|
1317
1942
|
}
|
|
1943
|
+
const constants = Object.assign(Object.assign({}, this._library.api), { tagName: tag, globalThis: this._globalObject });
|
|
1944
|
+
const specifics = Object.assign({}, this._library.tagSpecificApi);
|
|
1945
|
+
if (this._interpreter) {
|
|
1946
|
+
delete constants.globalThis;
|
|
1947
|
+
// if (this.canTriggerBreakpoint) {
|
|
1948
|
+
Object.assign(constants, this._interpretedApi);
|
|
1949
|
+
Object.assign(specifics, this._interpretedTagSpecificApi);
|
|
1950
|
+
// }
|
|
1951
|
+
}
|
|
1318
1952
|
const func = this._compiler.compile(script, {
|
|
1319
1953
|
// TODO: Support all the weird features
|
|
1320
1954
|
functionName: functionName,
|
|
1321
1955
|
diagnosticFunctionName: diagnosticFunctionName,
|
|
1322
1956
|
fileName: fileName,
|
|
1323
1957
|
forceSync: this._forceSyncScripts,
|
|
1958
|
+
interpreter: this._interpreter,
|
|
1324
1959
|
context: {
|
|
1325
1960
|
bot,
|
|
1326
1961
|
tag,
|
|
@@ -1335,8 +1970,8 @@ export class AuxRuntime {
|
|
|
1335
1970
|
const data = this._handleError(err, ctx.bot, ctx.tag);
|
|
1336
1971
|
throw data;
|
|
1337
1972
|
},
|
|
1338
|
-
constants:
|
|
1339
|
-
variables: Object.assign(Object.assign({},
|
|
1973
|
+
constants: constants,
|
|
1974
|
+
variables: Object.assign(Object.assign({}, specifics), { this: (ctx) => (ctx.bot ? ctx.bot.script : null), thisBot: (ctx) => (ctx.bot ? ctx.bot.script : null), bot: (ctx) => (ctx.bot ? ctx.bot.script : null), tags: (ctx) => (ctx.bot ? ctx.bot.script.tags : null), raw: (ctx) => (ctx.bot ? ctx.bot.script.raw : null), masks: (ctx) => (ctx.bot ? ctx.bot.script.masks : null), creatorBot: (ctx) => ctx.creator, configBot: () => this.context.playerBot, links: (ctx) => (ctx.bot ? ctx.bot.script.links : null) }),
|
|
1340
1975
|
arguments: [['that', 'data']],
|
|
1341
1976
|
});
|
|
1342
1977
|
if (hasValue(bot)) {
|
|
@@ -1477,5 +2112,228 @@ export class AuxRuntime {
|
|
|
1477
2112
|
}
|
|
1478
2113
|
return list;
|
|
1479
2114
|
}
|
|
2115
|
+
setBreakpoint(breakpoint) {
|
|
2116
|
+
const bot = this.currentState[breakpoint.botId];
|
|
2117
|
+
const breakpointIndex = bot.breakpoints.findIndex((b) => b.id === breakpoint.id);
|
|
2118
|
+
if (breakpointIndex >= 0) {
|
|
2119
|
+
bot.breakpoints[breakpointIndex] = breakpoint;
|
|
2120
|
+
}
|
|
2121
|
+
else {
|
|
2122
|
+
bot.breakpoints.push(breakpoint);
|
|
2123
|
+
}
|
|
2124
|
+
this._breakpoints.set(breakpoint.id, breakpoint);
|
|
2125
|
+
const func = bot.listeners[breakpoint.tag];
|
|
2126
|
+
if (func) {
|
|
2127
|
+
this._compiler.setBreakpoint({
|
|
2128
|
+
id: breakpoint.id,
|
|
2129
|
+
func: func,
|
|
2130
|
+
interpreter: this._interpreter,
|
|
2131
|
+
lineNumber: breakpoint.lineNumber,
|
|
2132
|
+
columnNumber: breakpoint.columnNumber,
|
|
2133
|
+
states: breakpoint.states,
|
|
2134
|
+
});
|
|
2135
|
+
}
|
|
2136
|
+
}
|
|
2137
|
+
removeBreakpoint(breakpointId) {
|
|
2138
|
+
const breakpoint = this._breakpoints.get(breakpointId);
|
|
2139
|
+
if (breakpoint) {
|
|
2140
|
+
this._breakpoints.delete(breakpointId);
|
|
2141
|
+
const bot = this.currentState[breakpoint.botId];
|
|
2142
|
+
const breakpointIndex = bot.breakpoints.findIndex((b) => b.id === breakpoint.id);
|
|
2143
|
+
if (breakpointIndex >= 0) {
|
|
2144
|
+
bot.breakpoints.splice(breakpointIndex, 1);
|
|
2145
|
+
}
|
|
2146
|
+
this._interpreter.removeBreakpointById(breakpoint.id);
|
|
2147
|
+
}
|
|
2148
|
+
}
|
|
2149
|
+
continueAfterStop(stopId, continuation) {
|
|
2150
|
+
const state = this._stopState;
|
|
2151
|
+
if (!state || state.stopId !== stopId) {
|
|
2152
|
+
return;
|
|
2153
|
+
}
|
|
2154
|
+
this._stopState = null;
|
|
2155
|
+
this._globalContext.actions.push(...state.actions);
|
|
2156
|
+
this._globalContext.errors.push(...state.errors);
|
|
2157
|
+
this._executeGenerator(state.resolve, state.reject, state.generator, continuation);
|
|
2158
|
+
// this._processGenerator(state.generator, continuation).then(state.resolve, state.reject);
|
|
2159
|
+
}
|
|
2160
|
+
_scheduleJob(queueName, job) {
|
|
2161
|
+
if (this._interpreter) {
|
|
2162
|
+
this._interpreter.realm.scope(() => {
|
|
2163
|
+
this._interpreter.agent.queueJob(queueName, () => {
|
|
2164
|
+
job();
|
|
2165
|
+
return Value.undefined;
|
|
2166
|
+
});
|
|
2167
|
+
});
|
|
2168
|
+
}
|
|
2169
|
+
}
|
|
2170
|
+
_scheduleJobQueueCheck() {
|
|
2171
|
+
if (this._interpreter) {
|
|
2172
|
+
// Increment the current job queue check count and save it.
|
|
2173
|
+
// This is used to short-circuit job queue checks if future checks are scheduled
|
|
2174
|
+
// before this one runs.
|
|
2175
|
+
this._jobQueueCheckCount++;
|
|
2176
|
+
const currentCheck = this._jobQueueCheckCount;
|
|
2177
|
+
this._jobQueueCheckPending = true;
|
|
2178
|
+
// Queue a microtask to fire before the current task finishes
|
|
2179
|
+
queueMicrotask(() => {
|
|
2180
|
+
// Short circuit if another check has been scheduled.
|
|
2181
|
+
if (this._jobQueueCheckCount !== currentCheck) {
|
|
2182
|
+
return;
|
|
2183
|
+
}
|
|
2184
|
+
// Queue another microtask to ensure that the job queue gets processed
|
|
2185
|
+
// after all current microtasks are executed.
|
|
2186
|
+
// This allows _scheduleJobQueueCheck() to be scheduled before other microtasks are queued.
|
|
2187
|
+
queueMicrotask(() => {
|
|
2188
|
+
// Short circuit if another check has been scheduled.
|
|
2189
|
+
if (this._jobQueueCheckCount !== currentCheck ||
|
|
2190
|
+
this._interpreter.agent.jobQueue.length <= 0) {
|
|
2191
|
+
return;
|
|
2192
|
+
}
|
|
2193
|
+
this._processJobQueueNow();
|
|
2194
|
+
if (this._interpreter.agent.jobQueue.length <= 0) {
|
|
2195
|
+
// Check to see if any more jobs have been added after the job queue has been processed
|
|
2196
|
+
// and trigger another job queue check if they have.
|
|
2197
|
+
this._scheduleJobQueueCheck();
|
|
2198
|
+
}
|
|
2199
|
+
});
|
|
2200
|
+
});
|
|
2201
|
+
}
|
|
2202
|
+
}
|
|
2203
|
+
// private _processJobQueueMicrotask() {
|
|
2204
|
+
// queueMicrotask(() => {
|
|
2205
|
+
// this._processJobQueueNow();
|
|
2206
|
+
// });
|
|
2207
|
+
// }
|
|
2208
|
+
_processJobQueueNow() {
|
|
2209
|
+
const queueGen = this._interpreter.runJobQueue();
|
|
2210
|
+
while (true) {
|
|
2211
|
+
const next = queueGen.next();
|
|
2212
|
+
if (next.done) {
|
|
2213
|
+
break;
|
|
2214
|
+
}
|
|
2215
|
+
else {
|
|
2216
|
+
// TODO: Process breakpoint
|
|
2217
|
+
}
|
|
2218
|
+
}
|
|
2219
|
+
this._jobQueueCheckPending = false;
|
|
2220
|
+
}
|
|
2221
|
+
processGenerator(generator) {
|
|
2222
|
+
this._processGenerator(generator);
|
|
2223
|
+
}
|
|
2224
|
+
_processGenerator(generator, continuation) {
|
|
2225
|
+
return markAsRuntimePromise(new Promise((resolve, reject) => {
|
|
2226
|
+
this._executeGenerator(resolve, reject, generator, continuation);
|
|
2227
|
+
}));
|
|
2228
|
+
}
|
|
2229
|
+
_executeGenerator(resolve, reject, generator, continuation) {
|
|
2230
|
+
try {
|
|
2231
|
+
let result;
|
|
2232
|
+
while (true) {
|
|
2233
|
+
const next = generator.next(continuation);
|
|
2234
|
+
if (next.done === true) {
|
|
2235
|
+
result = next.value;
|
|
2236
|
+
break;
|
|
2237
|
+
}
|
|
2238
|
+
else {
|
|
2239
|
+
this._currentStopCount += 1;
|
|
2240
|
+
const actions = this._processUnbatchedActions();
|
|
2241
|
+
const errors = this._processUnbatchedErrors();
|
|
2242
|
+
const state = {
|
|
2243
|
+
stopId: this._currentStopCount,
|
|
2244
|
+
generator,
|
|
2245
|
+
resolve,
|
|
2246
|
+
reject,
|
|
2247
|
+
actions,
|
|
2248
|
+
errors,
|
|
2249
|
+
};
|
|
2250
|
+
this._stopState = state;
|
|
2251
|
+
let breakpoint = this._breakpoints.get(next.value.breakpoint.id);
|
|
2252
|
+
this._onRuntimeStop.next(Object.assign(Object.assign({}, next.value), { breakpoint, stopId: this._currentStopCount }));
|
|
2253
|
+
return;
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
this._scheduleJobQueueCheck();
|
|
2257
|
+
resolve(result);
|
|
2258
|
+
}
|
|
2259
|
+
catch (err) {
|
|
2260
|
+
reject(err);
|
|
2261
|
+
}
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2264
|
+
/**
|
|
2265
|
+
* Recursively maps each of the given library's functions using the given map function and returns a new library that contains the converted functions.
|
|
2266
|
+
* The returned object will contain the same enumerable properties as the original library except that its functions have been mapped.
|
|
2267
|
+
* @param library The library to map.
|
|
2268
|
+
* @param map The function to use for mapping library functions.
|
|
2269
|
+
*/
|
|
2270
|
+
export function mapLibraryFunctions(library, map) {
|
|
2271
|
+
let newLibrary = Object.assign({}, library);
|
|
2272
|
+
newLibrary.api = mapFunctions(newLibrary.api, map);
|
|
2273
|
+
return newLibrary;
|
|
2274
|
+
}
|
|
2275
|
+
function mapFunctions(obj, map) {
|
|
2276
|
+
let newObj = Object.create(obj);
|
|
2277
|
+
assignFunctions(obj, newObj, map);
|
|
2278
|
+
return newObj;
|
|
2279
|
+
}
|
|
2280
|
+
function assignFunctions(obj, newObj, map) {
|
|
2281
|
+
let descriptors = Object.getOwnPropertyDescriptors(obj);
|
|
2282
|
+
for (let key in descriptors) {
|
|
2283
|
+
let descriptor = descriptors[key];
|
|
2284
|
+
if (descriptor.get || descriptor.set || !descriptor.enumerable) {
|
|
2285
|
+
continue;
|
|
2286
|
+
}
|
|
2287
|
+
const val = descriptor.value;
|
|
2288
|
+
if (typeof val === 'function') {
|
|
2289
|
+
let newFunc = (newObj[key] = map(val, key));
|
|
2290
|
+
if (newFunc) {
|
|
2291
|
+
assignFunctions(val, newFunc, map);
|
|
2292
|
+
}
|
|
2293
|
+
continue;
|
|
2294
|
+
}
|
|
2295
|
+
if (typeof val !== 'object' ||
|
|
2296
|
+
val === null ||
|
|
2297
|
+
Object.getPrototypeOf(val).constructor !== Object) {
|
|
2298
|
+
continue;
|
|
2299
|
+
}
|
|
2300
|
+
newObj[key] = mapFunctions(val, map);
|
|
2301
|
+
}
|
|
2302
|
+
}
|
|
2303
|
+
// function wrapGeneratorFunc<T>(
|
|
2304
|
+
// func: (...args: any[]) => T
|
|
2305
|
+
// ): (...args: any[]) => T {
|
|
2306
|
+
// return (...args: any[]) => {
|
|
2307
|
+
// let res = func(...args);
|
|
2308
|
+
// if (isGenerator(res)) {
|
|
2309
|
+
// return unwind(res);
|
|
2310
|
+
// }
|
|
2311
|
+
// return res;
|
|
2312
|
+
// };
|
|
2313
|
+
// }
|
|
2314
|
+
/**
|
|
2315
|
+
* Processes the given list of items in a sequential manner, calling the given function for each item.
|
|
2316
|
+
* @param list The list of items to process.
|
|
2317
|
+
* @param func The function that should be called for each item.
|
|
2318
|
+
*/
|
|
2319
|
+
function processListOfMaybePromises(promise, list, func) {
|
|
2320
|
+
for (let item of list) {
|
|
2321
|
+
if (!isRuntimePromise(promise)) {
|
|
2322
|
+
const p = func(item);
|
|
2323
|
+
if (isRuntimePromise(p)) {
|
|
2324
|
+
promise = p;
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2327
|
+
else {
|
|
2328
|
+
const copiedItem = item;
|
|
2329
|
+
promise = promise.then(() => {
|
|
2330
|
+
return func(copiedItem);
|
|
2331
|
+
});
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
2334
|
+
if (isPromise(promise)) {
|
|
2335
|
+
return markAsRuntimePromise(promise);
|
|
2336
|
+
}
|
|
2337
|
+
return promise;
|
|
1480
2338
|
}
|
|
1481
2339
|
//# sourceMappingURL=AuxRuntime.js.map
|