@casual-simulation/aux-common 3.1.17 → 3.1.20

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.
Files changed (41) hide show
  1. package/bots/Bot.d.ts +9 -1
  2. package/bots/Bot.js +4 -0
  3. package/bots/Bot.js.map +1 -1
  4. package/bots/BotCalculations.d.ts +0 -5
  5. package/bots/BotCalculations.js +2 -11
  6. package/bots/BotCalculations.js.map +1 -1
  7. package/bots/BotEvents.d.ts +127 -21
  8. package/bots/BotEvents.js +17 -1
  9. package/bots/BotEvents.js.map +1 -1
  10. package/bots/StoredAux.d.ts +52 -0
  11. package/bots/StoredAux.js +49 -0
  12. package/bots/StoredAux.js.map +1 -0
  13. package/bots/index.d.ts +1 -0
  14. package/bots/index.js +1 -0
  15. package/bots/index.js.map +1 -1
  16. package/bots/test/BotCalculationContextTests.js +1 -0
  17. package/bots/test/BotCalculationContextTests.js.map +1 -1
  18. package/package.json +4 -4
  19. package/partitions/PartitionUtils.d.ts +11 -0
  20. package/partitions/PartitionUtils.js +37 -0
  21. package/partitions/PartitionUtils.js.map +1 -0
  22. package/partitions/RemoteYjsPartition.js +7 -4
  23. package/partitions/RemoteYjsPartition.js.map +1 -1
  24. package/runtime/AuxCompiler.d.ts +4 -0
  25. package/runtime/AuxCompiler.js +13 -0
  26. package/runtime/AuxCompiler.js.map +1 -1
  27. package/runtime/AuxGlobalContext.js +2 -0
  28. package/runtime/AuxGlobalContext.js.map +1 -1
  29. package/runtime/AuxLibrary.d.ts +12 -2
  30. package/runtime/AuxLibrary.js +105 -15
  31. package/runtime/AuxLibrary.js.map +1 -1
  32. package/runtime/AuxLibraryDefinitions.def +172 -1
  33. package/runtime/AuxResults.d.ts +1 -0
  34. package/runtime/AuxRuntime.d.ts +7 -1
  35. package/runtime/AuxRuntime.js +387 -124
  36. package/runtime/AuxRuntime.js.map +1 -1
  37. package/runtime/RuntimeBot.d.ts +5 -1
  38. package/runtime/RuntimeBot.js +109 -7
  39. package/runtime/RuntimeBot.js.map +1 -1
  40. package/runtime/test/TestScriptBotFactory.js +1 -0
  41. package/runtime/test/TestScriptBotFactory.js.map +1 -1
@@ -14,13 +14,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
14
14
  step((generator = generator.apply(thisArg, _arguments || [])).next());
15
15
  });
16
16
  };
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';
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, REPLACE_BOT_SYMBOL, } from '../bots';
18
18
  import { Subject, Subscription } from 'rxjs';
19
19
  import { AuxCompiler, getInterpretableFunction, isInterpretableFunction, } from './AuxCompiler';
20
20
  import { addToContext, MemoryGlobalContext, removeFromContext, isInContext, } from './AuxGlobalContext';
21
21
  import { createDefaultLibrary, GET_RUNTIME, } from './AuxLibrary';
22
22
  import { createRuntimeBot, RealtimeEditMode, } from './RuntimeBot';
23
- import { RanOutOfEnergyError } from './AuxResults';
23
+ import { RanOutOfEnergyError, } from './AuxResults';
24
24
  import { convertToCopiableValue, DeepObjectError, isPromise, isRuntimePromise, markAsRuntimePromise, } from './Utils';
25
25
  import { DefaultRealtimeEditModeProvider, } from './AuxRealtimeEditModeProvider';
26
26
  import { sortBy, forOwn, merge, union } from 'lodash';
@@ -33,7 +33,7 @@ import { Rotation, Vector2, Vector3 } from '../math';
33
33
  import { isGenerator, UNCOPIABLE, } from '@casual-simulation/js-interpreter/InterpreterUtils';
34
34
  import { v4 as uuid } from 'uuid';
35
35
  import { importInterpreter as _dynamicImportInterpreter } from './AuxRuntimeDynamicImports';
36
- import { UNMAPPABLE } from '../bots/BotEvents';
36
+ import { UNMAPPABLE, } from '../bots/BotEvents';
37
37
  let Interpreter;
38
38
  let DeclarativeEnvironmentRecord;
39
39
  let DefinePropertyOrThrow;
@@ -103,6 +103,16 @@ export class AuxRuntime {
103
103
  this._portalBots = new Map();
104
104
  this._builtinPortalBots = [];
105
105
  this._globalChanges = {};
106
+ this._beforeActionListeners = [];
107
+ this._scriptActionEnqueuedListeners = [];
108
+ this._scriptUpdatedTagListeners = [];
109
+ this._scriptUpdatedTagMaskListeners = [];
110
+ // private _beforeScriptEnterListeners: ((
111
+ // trace: DebuggerScriptEnterTrace
112
+ // ) => void)[] = [];
113
+ // private _afterScriptExitListeners: ((
114
+ // trace: DebuggerScriptExitTrace
115
+ // ) => void)[] = [];
106
116
  /**
107
117
  * The counter that is used to generate function names.
108
118
  */
@@ -282,9 +292,22 @@ export class AuxRuntime {
282
292
  * @param actions The actions to process.
283
293
  */
284
294
  process(actions) {
295
+ if (this._beforeActionListeners.length > 0) {
296
+ for (let func of this._beforeActionListeners) {
297
+ for (let action of actions) {
298
+ try {
299
+ func(action);
300
+ }
301
+ catch (err) {
302
+ console.error(err);
303
+ }
304
+ }
305
+ }
306
+ }
285
307
  this._processBatch();
286
- this._processCore(actions);
308
+ const result = this._processCore(actions);
287
309
  this._processBatch();
310
+ return result;
288
311
  }
289
312
  _getExecutingDebugger() {
290
313
  return this._currentDebugger;
@@ -297,7 +320,7 @@ export class AuxRuntime {
297
320
  yield importInterpreter();
298
321
  const interpreter = (options === null || options === void 0 ? void 0 : options.pausable) ? new Interpreter() : null;
299
322
  const runtime = new AuxRuntime(this._globalContext.version, this._globalContext.device, this._libraryFactory, this._editModeProvider, this._forceSignedScripts, this._exemptSpaces, forceSyncScripts, interpreter);
300
- runtime._autoBatch = false;
323
+ runtime._autoBatch = true;
301
324
  let idCount = 0;
302
325
  if (!(options === null || options === void 0 ? void 0 : options.useRealUUIDs)) {
303
326
  runtime._globalContext.uuid = () => {
@@ -382,7 +405,38 @@ export class AuxRuntime {
382
405
  const errors = runtime._processUnbatchedErrors();
383
406
  allErrors.push(...errors);
384
407
  return allErrors;
385
- }, setPauseTrigger(b, tag, options) {
408
+ }, onBeforeUserAction: (listener) => {
409
+ runtime._beforeActionListeners.push(listener);
410
+ }, onScriptActionEnqueued: (listener) => {
411
+ runtime._scriptActionEnqueuedListeners.push(listener);
412
+ }, onAfterScriptUpdatedTag: (listener) => {
413
+ runtime._scriptUpdatedTagListeners.push(listener);
414
+ }, onAfterScriptUpdatedTagMask: (listener) => {
415
+ runtime._scriptUpdatedTagMaskListeners.push(listener);
416
+ }, getCallStack() {
417
+ if (!interpreter) {
418
+ throw new Error('getCallStack() is only supported on pausable debuggers.');
419
+ }
420
+ return runtime._mapCallStack(interpreter.agent.executionContextStack);
421
+ },
422
+ performUserAction(...actions) {
423
+ return __awaiter(this, void 0, void 0, function* () {
424
+ const result = yield runtime.process(actions);
425
+ return result.map((r) => (r ? r.results : null));
426
+ });
427
+ },
428
+ // TODO: Determine whether to support this
429
+ // onBeforeScriptEnter: (
430
+ // listener: (trace: DebuggerScriptEnterTrace) => void
431
+ // ) => {
432
+ // runtime._beforeScriptEnterListeners.push(listener);
433
+ // },
434
+ // onAfterScriptExit: (
435
+ // listener: (trace: DebuggerScriptExitTrace) => void
436
+ // ) => {
437
+ // runtime._afterScriptExitListeners.push(listener);
438
+ // },
439
+ setPauseTrigger(b, tag, options) {
386
440
  var _a, _b, _c;
387
441
  if (typeof b === 'object' && 'triggerId' in b) {
388
442
  runtime.setBreakpoint({
@@ -486,113 +540,7 @@ export class AuxRuntime {
486
540
  const pause = {
487
541
  pauseId: stop.stopId,
488
542
  state: stop.state,
489
- callStack: stop.stack.map((s) => {
490
- const callSite = s.callSite;
491
- const funcName = callSite.getFunctionName();
492
- let funcLocation = {};
493
- if (funcName) {
494
- const f = runtime._functionMap.get(funcName);
495
- if (f) {
496
- funcLocation.name =
497
- f.metadata.diagnosticFunctionName;
498
- const location = runtime._compiler.calculateOriginalLineLocation(f, {
499
- lineNumber: callSite.lineNumber,
500
- column: callSite.columnNumber,
501
- });
502
- funcLocation.lineNumber =
503
- location.lineNumber + 1;
504
- funcLocation.columnNumber =
505
- location.column + 1;
506
- const tagName = f.metadata.context
507
- .tag;
508
- const bot = f.metadata.context.bot;
509
- if (bot) {
510
- funcLocation.botId = bot.id;
511
- }
512
- if (tagName) {
513
- funcLocation.tag = tagName;
514
- }
515
- }
516
- else {
517
- funcLocation.name = funcName;
518
- }
519
- }
520
- if (!hasValue(funcLocation.lineNumber) &&
521
- !hasValue(funcLocation.columnNumber) &&
522
- hasValue(callSite.lineNumber) &&
523
- hasValue(callSite.columnNumber)) {
524
- funcLocation.lineNumber = callSite.lineNumber;
525
- funcLocation.columnNumber =
526
- callSite.columnNumber;
527
- }
528
- if (!hasValue(funcLocation.lineNumber) &&
529
- !hasValue(funcLocation.columnNumber) &&
530
- !hasValue(funcLocation.name)) {
531
- funcLocation = null;
532
- }
533
- const ret = {
534
- location: funcLocation,
535
- listVariables() {
536
- let variables = [];
537
- if (s.LexicalEnvironment instanceof
538
- DeclarativeEnvironmentRecord) {
539
- addBindingsFromEnvironment(s.LexicalEnvironment, 'block');
540
- }
541
- if (s.VariableEnvironment instanceof
542
- DeclarativeEnvironmentRecord) {
543
- addBindingsFromEnvironment(s.VariableEnvironment, 'frame');
544
- let parent = s.VariableEnvironment.OuterEnv;
545
- while (parent) {
546
- if (parent instanceof
547
- DeclarativeEnvironmentRecord) {
548
- addBindingsFromEnvironment(parent, 'closure');
549
- }
550
- parent = parent.OuterEnv;
551
- }
552
- }
553
- return variables;
554
- function addBindingsFromEnvironment(env, scope) {
555
- for (let [nameValue, binding,] of env.bindings.entries()) {
556
- const name = interpreter.copyFromValue(nameValue);
557
- const initialized = !!binding.initialized;
558
- const mutable = !!binding.mutable;
559
- const value = initialized
560
- ? interpreter.reverseProxyObject(binding.value, false)
561
- : undefined;
562
- const variable = {
563
- name,
564
- value,
565
- writable: mutable,
566
- scope,
567
- };
568
- if (!initialized) {
569
- variable.initialized = false;
570
- }
571
- variables.push(variable);
572
- }
573
- }
574
- },
575
- setVariableValue(name, value) {
576
- if (s.LexicalEnvironment instanceof
577
- DeclarativeEnvironmentRecord) {
578
- const nameValue = interpreter.copyToValue(name);
579
- const proxiedValue = interpreter.proxyObject(value);
580
- if (nameValue.Type !== 'normal') {
581
- throw interpreter.copyFromValue(nameValue.Value);
582
- }
583
- if (proxiedValue.Type !== 'normal') {
584
- throw interpreter.copyFromValue(proxiedValue.Value);
585
- }
586
- const result = s.LexicalEnvironment.SetMutableBinding(nameValue.Value, proxiedValue.Value, Value.true);
587
- if (result.Type !== 'normal') {
588
- throw interpreter.copyFromValue(result.Value);
589
- }
590
- return interpreter.copyFromValue(result.Value);
591
- }
592
- },
593
- };
594
- return ret;
595
- }),
543
+ callStack: runtime._mapCallStack(stop.stack),
596
544
  trigger: {
597
545
  triggerId: stop.breakpoint.id,
598
546
  botId: stop.breakpoint.botId,
@@ -611,46 +559,193 @@ export class AuxRuntime {
611
559
  [GET_RUNTIME]() {
612
560
  return runtime;
613
561
  },
562
+ get configBot() {
563
+ return runtime.userBot;
564
+ },
565
+ getPortalBots() {
566
+ var _a;
567
+ let portalBots = new Map();
568
+ for (let [portal, id] of runtime._portalBots) {
569
+ portalBots.set(portal, (_a = runtime.currentState[id]) === null || _a === void 0 ? void 0 : _a.script);
570
+ }
571
+ return portalBots;
572
+ },
614
573
  create });
615
574
  runtime._currentDebugger = debug;
616
575
  this._scheduleJobQueueCheck();
617
576
  return debug;
618
577
  });
619
578
  }
579
+ _mapCallStack(stack) {
580
+ const interpreter = this._interpreter;
581
+ return stack.map((s) => {
582
+ const callSite = s.callSite;
583
+ const funcName = callSite.getFunctionName();
584
+ let funcLocation = {};
585
+ if (funcName) {
586
+ const f = this._functionMap.get(funcName);
587
+ if (f) {
588
+ funcLocation.name = f.metadata.diagnosticFunctionName;
589
+ const location = this._compiler.calculateOriginalLineLocation(f, {
590
+ lineNumber: callSite.lineNumber,
591
+ column: callSite.columnNumber,
592
+ });
593
+ funcLocation.lineNumber = location.lineNumber + 1;
594
+ funcLocation.columnNumber = location.column + 1;
595
+ const tagName = f.metadata.context.tag;
596
+ const bot = f.metadata.context.bot;
597
+ if (bot) {
598
+ funcLocation.botId = bot.id;
599
+ }
600
+ if (tagName) {
601
+ funcLocation.tag = tagName;
602
+ }
603
+ }
604
+ else {
605
+ funcLocation.name = funcName;
606
+ }
607
+ }
608
+ if (!hasValue(funcLocation.lineNumber) &&
609
+ !hasValue(funcLocation.columnNumber) &&
610
+ hasValue(callSite.lineNumber) &&
611
+ hasValue(callSite.columnNumber)) {
612
+ funcLocation.lineNumber = callSite.lineNumber;
613
+ funcLocation.columnNumber = callSite.columnNumber;
614
+ }
615
+ if (!hasValue(funcLocation.lineNumber) &&
616
+ !hasValue(funcLocation.columnNumber) &&
617
+ !hasValue(funcLocation.name)) {
618
+ funcLocation = null;
619
+ }
620
+ const ret = {
621
+ location: funcLocation,
622
+ listVariables() {
623
+ let variables = [];
624
+ if (s.LexicalEnvironment instanceof
625
+ DeclarativeEnvironmentRecord) {
626
+ addBindingsFromEnvironment(s.LexicalEnvironment, 'block');
627
+ }
628
+ if (s.VariableEnvironment instanceof
629
+ DeclarativeEnvironmentRecord) {
630
+ addBindingsFromEnvironment(s.VariableEnvironment, 'frame');
631
+ let parent = s.VariableEnvironment.OuterEnv;
632
+ while (parent) {
633
+ if (parent instanceof DeclarativeEnvironmentRecord) {
634
+ addBindingsFromEnvironment(parent, 'closure');
635
+ }
636
+ parent = parent.OuterEnv;
637
+ }
638
+ }
639
+ return variables;
640
+ function addBindingsFromEnvironment(env, scope) {
641
+ for (let [nameValue, binding,] of env.bindings.entries()) {
642
+ const name = interpreter.copyFromValue(nameValue);
643
+ const initialized = !!binding.initialized;
644
+ const mutable = !!binding.mutable;
645
+ const value = initialized
646
+ ? interpreter.reverseProxyObject(binding.value, false)
647
+ : undefined;
648
+ const variable = {
649
+ name,
650
+ value,
651
+ writable: mutable,
652
+ scope,
653
+ };
654
+ if (!initialized) {
655
+ variable.initialized = false;
656
+ }
657
+ variables.push(variable);
658
+ }
659
+ }
660
+ },
661
+ setVariableValue(name, value) {
662
+ if (s.LexicalEnvironment instanceof
663
+ DeclarativeEnvironmentRecord) {
664
+ const nameValue = interpreter.copyToValue(name);
665
+ const proxiedValue = interpreter.proxyObject(value);
666
+ if (nameValue.Type !== 'normal') {
667
+ throw interpreter.copyFromValue(nameValue.Value);
668
+ }
669
+ if (proxiedValue.Type !== 'normal') {
670
+ throw interpreter.copyFromValue(proxiedValue.Value);
671
+ }
672
+ const result = s.LexicalEnvironment.SetMutableBinding(nameValue.Value, proxiedValue.Value, Value.true);
673
+ if (result.Type !== 'normal') {
674
+ throw interpreter.copyFromValue(result.Value);
675
+ }
676
+ return interpreter.copyFromValue(result.Value);
677
+ }
678
+ },
679
+ };
680
+ return ret;
681
+ });
682
+ }
620
683
  _processCore(actions) {
621
684
  const _this = this;
685
+ const results = [];
686
+ function processAction(action, addToResults) {
687
+ let promise = _this._processAction(action);
688
+ if (addToResults) {
689
+ if (isRuntimePromise(promise)) {
690
+ return markAsRuntimePromise(promise.then((result) => {
691
+ results.push(result);
692
+ }));
693
+ }
694
+ else {
695
+ results.push(promise);
696
+ }
697
+ return;
698
+ }
699
+ return promise;
700
+ }
622
701
  function handleRejection(action, rejection) {
623
702
  let promise = processListOfMaybePromises(null, rejection.newActions, (action) => {
624
- return _this._processAction(action);
703
+ return processAction(action, false);
625
704
  });
626
705
  if (rejection.rejected) {
627
706
  return;
628
707
  }
629
708
  if (promise) {
630
- return markAsRuntimePromise(promise.then((p) => _this._processAction(action)));
709
+ return markAsRuntimePromise(promise.then((p) => processAction(action, true)));
631
710
  }
632
711
  else {
633
- return _this._processAction(action);
712
+ return processAction(action, true);
634
713
  }
635
714
  }
636
- return processListOfMaybePromises(null, actions, (action) => {
715
+ let promise = processListOfMaybePromises(null, actions, (action) => {
637
716
  let rejection = this._rejectAction(action);
717
+ let result;
638
718
  if (isRuntimePromise(rejection)) {
639
- return markAsRuntimePromise(rejection.then((result) => handleRejection(action, result)));
719
+ result = markAsRuntimePromise(rejection.then((result) => handleRejection(action, result)));
640
720
  }
641
721
  else {
642
- return handleRejection(action, rejection);
722
+ result = handleRejection(action, rejection);
643
723
  }
724
+ return result;
644
725
  });
726
+ if (isRuntimePromise(promise)) {
727
+ return markAsRuntimePromise(promise.then(() => results));
728
+ }
729
+ else {
730
+ return results;
731
+ }
645
732
  }
646
733
  _processAction(action) {
647
734
  if (action.type === 'action') {
648
735
  const result = this._shout(action.eventName, action.botIds, action.argument, false);
649
736
  if (isRuntimePromise(result)) {
650
- return markAsRuntimePromise(result.then((result) => this._processCore(result.actions)));
737
+ return markAsRuntimePromise(result
738
+ .then((result) => this._processCore(result.actions))
739
+ .then(() => result));
651
740
  }
652
741
  else {
653
- return this._processCore(result.actions);
742
+ let promise = this._processCore(result.actions);
743
+ if (isRuntimePromise(promise)) {
744
+ return markAsRuntimePromise(promise.then(() => result));
745
+ }
746
+ else {
747
+ return result;
748
+ }
654
749
  }
655
750
  }
656
751
  else if (action.type === 'run_script') {
@@ -663,6 +758,7 @@ export class AuxRuntime {
663
758
  if (hasValue(action.taskId)) {
664
759
  this._globalContext.resolveTask(action.taskId, result.result, false);
665
760
  }
761
+ return null;
666
762
  });
667
763
  }
668
764
  else {
@@ -672,6 +768,7 @@ export class AuxRuntime {
672
768
  }
673
769
  }
674
770
  }
771
+ return null;
675
772
  }));
676
773
  }
677
774
  else {
@@ -683,6 +780,7 @@ export class AuxRuntime {
683
780
  this._scheduleJobQueueCheck();
684
781
  }
685
782
  }
783
+ return null;
686
784
  }));
687
785
  }
688
786
  if (hasValue(action.taskId)) {
@@ -694,7 +792,13 @@ export class AuxRuntime {
694
792
  }
695
793
  else if (action.type === 'apply_state') {
696
794
  const events = breakIntoIndividualEvents(this.currentState, action);
697
- return this._processCore(events);
795
+ const promise = this._processCore(events);
796
+ if (isRuntimePromise(promise)) {
797
+ return markAsRuntimePromise(promise.then(() => null));
798
+ }
799
+ else {
800
+ return null;
801
+ }
698
802
  }
699
803
  else if (action.type === 'async_result') {
700
804
  const value = action.mapBotsInResult === true
@@ -753,12 +857,21 @@ export class AuxRuntime {
753
857
  this._actionBatch.push(action);
754
858
  }
755
859
  if (hasValue(action.taskId)) {
756
- return this._processCore([asyncResult(action.taskId, null)]);
860
+ const promise = this._processCore([
861
+ asyncResult(action.taskId, null),
862
+ ]);
863
+ if (isRuntimePromise(promise)) {
864
+ return markAsRuntimePromise(promise.then(() => null));
865
+ }
866
+ else {
867
+ return null;
868
+ }
757
869
  }
758
870
  }
759
871
  else {
760
872
  this._actionBatch.push(action);
761
873
  }
874
+ return null;
762
875
  }
763
876
  _registerPortalBot(portalId, botId) {
764
877
  const hadPortalBot = this._portalBots.has(portalId);
@@ -1197,6 +1310,7 @@ export class AuxRuntime {
1197
1310
  });
1198
1311
  }
1199
1312
  _addBotsToState(bots, nextUpdate) {
1313
+ var _a;
1200
1314
  let newBots = [];
1201
1315
  let newBotIDs = new Set();
1202
1316
  for (let bot of bots) {
@@ -1212,7 +1326,50 @@ export class AuxRuntime {
1212
1326
  }
1213
1327
  let newBot = this._createCompiledBot(bot, false);
1214
1328
  if (!!existing) {
1215
- newBot.script.vars = existing.script.vars;
1329
+ const changes = existing.script.changes;
1330
+ const maskChanges = existing.script.maskChanges;
1331
+ for (let key in changes) {
1332
+ newBot.tags[key] =
1333
+ newBot.values[key] =
1334
+ newBot.script.changes[key] =
1335
+ changes[key];
1336
+ }
1337
+ let maskTags = new Set();
1338
+ for (let space of TAG_MASK_SPACE_PRIORITIES) {
1339
+ const masks = maskChanges[space];
1340
+ let newMasks;
1341
+ let addNewMasks = false;
1342
+ let hasNewMasks = false;
1343
+ if (!((_a = newBot === null || newBot === void 0 ? void 0 : newBot.masks) === null || _a === void 0 ? void 0 : _a[space])) {
1344
+ addNewMasks = true;
1345
+ newMasks = {};
1346
+ }
1347
+ else {
1348
+ newMasks = newBot.masks[space];
1349
+ }
1350
+ if (masks) {
1351
+ if (!newBot.script.maskChanges[space]) {
1352
+ newBot.script.maskChanges[space] = {};
1353
+ }
1354
+ for (let key in masks) {
1355
+ hasNewMasks = true;
1356
+ maskTags.add(key);
1357
+ const value = (newMasks[key] =
1358
+ newBot.script.maskChanges[space][key] =
1359
+ masks[key]);
1360
+ if (!maskTags.has(key)) {
1361
+ newBot.values[key] = value;
1362
+ }
1363
+ }
1364
+ }
1365
+ if (addNewMasks && hasNewMasks) {
1366
+ if (!newBot.masks) {
1367
+ newBot.masks = {};
1368
+ }
1369
+ newBot.masks[space] = newMasks;
1370
+ }
1371
+ }
1372
+ existing.script[REPLACE_BOT_SYMBOL](newBot.script);
1216
1373
  }
1217
1374
  let precalculated = {
1218
1375
  id: bot.id,
@@ -1436,6 +1593,18 @@ export class AuxRuntime {
1436
1593
  });
1437
1594
  }
1438
1595
  }
1596
+ notifyActionEnqueued(action) {
1597
+ if (this._scriptActionEnqueuedListeners.length > 0) {
1598
+ for (let listener of this._scriptActionEnqueuedListeners) {
1599
+ try {
1600
+ listener(action);
1601
+ }
1602
+ catch (err) {
1603
+ console.error(err);
1604
+ }
1605
+ }
1606
+ }
1607
+ }
1439
1608
  createRuntimeBot(bot) {
1440
1609
  const space = getBotSpace(bot);
1441
1610
  const mode = this._editModeProvider.getEditMode(space);
@@ -1674,6 +1843,7 @@ export class AuxRuntime {
1674
1843
  if (isRuntimeBot(newValue)) {
1675
1844
  throw new Error(`It is not possible to save bots as tag values. (Setting '${tag}' on ${bot.id})`);
1676
1845
  }
1846
+ const oldValue = bot.values[tag];
1677
1847
  const space = getBotSpace(bot);
1678
1848
  const mode = this._editModeProvider.getEditMode(space);
1679
1849
  if (mode === RealtimeEditMode.Immediate) {
@@ -1690,6 +1860,21 @@ export class AuxRuntime {
1690
1860
  else if (newValue instanceof Rotation) {
1691
1861
  newValue = formatBotRotation(newValue);
1692
1862
  }
1863
+ if (this._scriptUpdatedTagListeners.length > 0) {
1864
+ for (let listener of this._scriptUpdatedTagListeners) {
1865
+ try {
1866
+ listener({
1867
+ botId: bot.id,
1868
+ tag,
1869
+ oldValue,
1870
+ newValue,
1871
+ });
1872
+ }
1873
+ catch (err) {
1874
+ console.error(err);
1875
+ }
1876
+ }
1877
+ }
1693
1878
  return {
1694
1879
  mode,
1695
1880
  changedValue: newValue,
@@ -1705,6 +1890,7 @@ export class AuxRuntime {
1705
1890
  if (isRuntimeBot(value)) {
1706
1891
  throw new Error(`It is not possible to save bots as tag values. (Setting '${tag}' on ${bot.id})`);
1707
1892
  }
1893
+ let oldValuesAndSpaces = [];
1708
1894
  let updated = false;
1709
1895
  for (let space of spaces) {
1710
1896
  const mode = this._editModeProvider.getEditMode(space);
@@ -1715,6 +1901,7 @@ export class AuxRuntime {
1715
1901
  if (!bot.masks[space]) {
1716
1902
  bot.masks[space] = {};
1717
1903
  }
1904
+ let oldValue = bot.masks[space][tag];
1718
1905
  if (isTagEdit(value)) {
1719
1906
  if (!bot.originalTagMaskEditValues[space]) {
1720
1907
  bot.originalTagMaskEditValues[space] = {};
@@ -1729,6 +1916,10 @@ export class AuxRuntime {
1729
1916
  bot.masks[space][tag] = value;
1730
1917
  }
1731
1918
  updated = true;
1919
+ oldValuesAndSpaces.push({
1920
+ space,
1921
+ oldValue,
1922
+ });
1732
1923
  }
1733
1924
  }
1734
1925
  if (updated) {
@@ -1745,6 +1936,24 @@ export class AuxRuntime {
1745
1936
  else if (value instanceof Rotation) {
1746
1937
  value = formatBotRotation(value);
1747
1938
  }
1939
+ if (updated && this._scriptUpdatedTagMaskListeners.length > 0) {
1940
+ for (let listener of this._scriptUpdatedTagMaskListeners) {
1941
+ for (let { oldValue, space } of oldValuesAndSpaces) {
1942
+ try {
1943
+ listener({
1944
+ botId: bot.id,
1945
+ tag,
1946
+ oldValue,
1947
+ newValue: value,
1948
+ space,
1949
+ });
1950
+ }
1951
+ catch (err) {
1952
+ console.error(err);
1953
+ }
1954
+ }
1955
+ }
1956
+ }
1748
1957
  return {
1749
1958
  mode: RealtimeEditMode.Immediate,
1750
1959
  changedValue: value,
@@ -1980,6 +2189,20 @@ export class AuxRuntime {
1980
2189
  ctx.creator = ctx.bot
1981
2190
  ? this._getRuntimeBot(ctx.bot.script.tags.creator)
1982
2191
  : null;
2192
+ // TODO: Determine whether to support this
2193
+ // if (this._beforeScriptEnterListeners.length > 0) {
2194
+ // for (let listener of this._beforeScriptEnterListeners) {
2195
+ // try {
2196
+ // listener({
2197
+ // botId: ctx.bot.id,
2198
+ // tag: ctx.tag,
2199
+ // enterType: 'call',
2200
+ // });
2201
+ // } catch (err) {
2202
+ // console.error(err);
2203
+ // }
2204
+ // }
2205
+ // }
1983
2206
  },
1984
2207
  onError: (err, ctx, meta) => {
1985
2208
  const data = this._handleError(err, ctx.bot, ctx.tag);
@@ -2226,6 +2449,46 @@ export class AuxRuntime {
2226
2449
  // });
2227
2450
  // }
2228
2451
  _processJobQueueNow() {
2452
+ // TODO: Determine whether to support this
2453
+ // let scriptJobs: { botId: string; tag: string }[] = [];
2454
+ // for (let job of this._interpreter.agent.jobQueue) {
2455
+ // if (
2456
+ // job.callerScriptOrModule &&
2457
+ // FUNCTION_METADATA in job.callerScriptOrModule
2458
+ // ) {
2459
+ // const meta: AuxScriptMetadata = (
2460
+ // job.callerScriptOrModule as any
2461
+ // )[FUNCTION_METADATA] as AuxScriptMetadata;
2462
+ // const context = meta.context as {
2463
+ // bot: CompiledBot;
2464
+ // tag: string;
2465
+ // };
2466
+ // const botId = context.bot.id;
2467
+ // const tag = context.tag;
2468
+ // scriptJobs.push({
2469
+ // botId,
2470
+ // tag,
2471
+ // });
2472
+ // }
2473
+ // }
2474
+ // if (
2475
+ // scriptJobs.length > 0 &&
2476
+ // this._beforeScriptEnterListeners.length > 0
2477
+ // ) {
2478
+ // for (let job of scriptJobs) {
2479
+ // for (let listener of this._beforeScriptEnterListeners) {
2480
+ // try {
2481
+ // listener({
2482
+ // enterType: 'task',
2483
+ // botId: job.botId,
2484
+ // tag: job.tag,
2485
+ // });
2486
+ // } catch (err) {
2487
+ // console.error(err);
2488
+ // }
2489
+ // }
2490
+ // }
2491
+ // }
2229
2492
  const queueGen = this._interpreter.runJobQueue();
2230
2493
  while (true) {
2231
2494
  const next = queueGen.next();