@casual-simulation/aux-common 3.2.6 → 3.2.7-alpha.6227012901

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 (212) hide show
  1. package/Errors.d.ts +29 -0
  2. package/Errors.js +2 -0
  3. package/Errors.js.map +1 -0
  4. package/{aux-format-2 → bots}/AuxStateHelpers.d.ts +2 -33
  5. package/{aux-format-2 → bots}/AuxStateHelpers.js +1 -116
  6. package/bots/AuxStateHelpers.js.map +1 -0
  7. package/bots/Bot.d.ts +1 -1
  8. package/bots/BotCalculations.d.ts +4 -1
  9. package/bots/BotCalculations.js +62 -0
  10. package/bots/BotCalculations.js.map +1 -1
  11. package/bots/BotEvents.d.ts +859 -3401
  12. package/bots/BotEvents.js +133 -1529
  13. package/bots/BotEvents.js.map +1 -1
  14. package/bots/StateUpdatedEvent.d.ts +1 -1
  15. package/bots/StateUpdatedEvent.js +1 -1
  16. package/bots/StateUpdatedEvent.js.map +1 -1
  17. package/bots/index.d.ts +1 -0
  18. package/bots/index.js +1 -0
  19. package/bots/index.js.map +1 -1
  20. package/common/Action.d.ts +17 -0
  21. package/common/Action.js +2 -0
  22. package/common/Action.js.map +1 -0
  23. package/common/ConnectionIndicator.d.ts +29 -0
  24. package/common/ConnectionIndicator.js +23 -0
  25. package/common/ConnectionIndicator.js.map +1 -0
  26. package/common/ConnectionInfo.d.ts +30 -0
  27. package/common/ConnectionInfo.js +14 -0
  28. package/common/ConnectionInfo.js.map +1 -0
  29. package/common/ConnectionToken.d.ts +37 -0
  30. package/common/ConnectionToken.js +93 -0
  31. package/common/ConnectionToken.js.map +1 -0
  32. package/common/CurrentVersion.d.ts +26 -0
  33. package/common/CurrentVersion.js +2 -0
  34. package/common/CurrentVersion.js.map +1 -0
  35. package/common/Iterators.d.ts +19 -0
  36. package/common/Iterators.js +39 -0
  37. package/common/Iterators.js.map +1 -0
  38. package/common/LoadingProgress.d.ts +26 -0
  39. package/common/LoadingProgress.js +2 -0
  40. package/common/LoadingProgress.js.map +1 -0
  41. package/common/RemoteActions.d.ts +558 -0
  42. package/common/RemoteActions.js +128 -0
  43. package/common/RemoteActions.js.map +1 -0
  44. package/common/StatusUpdate.d.ts +108 -0
  45. package/common/StatusUpdate.js +2 -0
  46. package/common/StatusUpdate.js.map +1 -0
  47. package/common/StatusUpdateUtils.d.ts +3 -0
  48. package/common/StatusUpdateUtils.js +11 -0
  49. package/common/StatusUpdateUtils.js.map +1 -0
  50. package/common/index.d.ts +11 -0
  51. package/common/index.js +11 -0
  52. package/common/index.js.map +1 -0
  53. package/index.d.ts +4 -1
  54. package/index.js +4 -1
  55. package/index.js.map +1 -1
  56. package/package.json +3 -4
  57. package/partitions/AuxPartition.d.ts +1 -11
  58. package/partitions/AuxPartition.js.map +1 -1
  59. package/partitions/AuxPartitionConfig.d.ts +39 -123
  60. package/partitions/MemoryPartition.d.ts +2 -2
  61. package/partitions/MemoryPartition.js +2 -2
  62. package/partitions/MemoryPartition.js.map +1 -1
  63. package/partitions/OtherPlayersPartition.d.ts +6 -7
  64. package/partitions/OtherPlayersPartition.js +40 -54
  65. package/partitions/OtherPlayersPartition.js.map +1 -1
  66. package/partitions/PartitionUtils.d.ts +28 -1
  67. package/partitions/PartitionUtils.js +174 -1
  68. package/partitions/PartitionUtils.js.map +1 -1
  69. package/partitions/ProxyBridgePartition.d.ts +1 -3
  70. package/partitions/ProxyBridgePartition.js +0 -14
  71. package/partitions/ProxyBridgePartition.js.map +1 -1
  72. package/partitions/RemoteYjsPartition.d.ts +7 -6
  73. package/partitions/RemoteYjsPartition.js +55 -75
  74. package/partitions/RemoteYjsPartition.js.map +1 -1
  75. package/partitions/YjsPartition.d.ts +1 -2
  76. package/partitions/YjsPartition.js +3 -6
  77. package/partitions/YjsPartition.js.map +1 -1
  78. package/partitions/index.d.ts +1 -7
  79. package/partitions/index.js +1 -7
  80. package/partitions/index.js.map +1 -1
  81. package/test/FuzzingHelpers.d.ts +1 -1
  82. package/test/FuzzingHelpers.js +1 -1
  83. package/test/FuzzingHelpers.js.map +1 -1
  84. package/test/TestHelpers.d.ts +8 -0
  85. package/test/TestHelpers.js +23 -0
  86. package/test/TestHelpers.js.map +1 -1
  87. package/utils.d.ts +10 -5
  88. package/utils.js +19 -7
  89. package/utils.js.map +1 -1
  90. package/websockets/AuthenticatedConnectionClient.d.ts +26 -0
  91. package/websockets/AuthenticatedConnectionClient.js +61 -0
  92. package/websockets/AuthenticatedConnectionClient.js.map +1 -0
  93. package/websockets/ConnectionClient.d.ts +59 -0
  94. package/websockets/ConnectionClient.js +2 -0
  95. package/websockets/ConnectionClient.js.map +1 -0
  96. package/websockets/InstRecordsClient.d.ts +118 -0
  97. package/websockets/InstRecordsClient.js +387 -0
  98. package/websockets/InstRecordsClient.js.map +1 -0
  99. package/websockets/InstRecordsClientTimeSyncConnection.d.ts +13 -0
  100. package/websockets/InstRecordsClientTimeSyncConnection.js +16 -0
  101. package/websockets/InstRecordsClientTimeSyncConnection.js.map +1 -0
  102. package/websockets/MemoryConnectionClient.d.ts +19 -0
  103. package/websockets/MemoryConnectionClient.js +41 -0
  104. package/websockets/MemoryConnectionClient.js.map +1 -0
  105. package/websockets/WebsocketEvents.d.ts +2670 -0
  106. package/websockets/WebsocketEvents.js +189 -0
  107. package/websockets/WebsocketEvents.js.map +1 -0
  108. package/websockets/index.d.ts +7 -0
  109. package/websockets/index.js +7 -0
  110. package/websockets/index.js.map +1 -0
  111. package/yjs/YjsHelpers.d.ts +1 -1
  112. package/LoadingProgress.d.ts +0 -54
  113. package/LoadingProgress.js +0 -105
  114. package/LoadingProgress.js.map +0 -1
  115. package/aux-format-2/AuxCausalTree2.d.ts +0 -98
  116. package/aux-format-2/AuxCausalTree2.js +0 -616
  117. package/aux-format-2/AuxCausalTree2.js.map +0 -1
  118. package/aux-format-2/AuxOpTypes.d.ts +0 -268
  119. package/aux-format-2/AuxOpTypes.js +0 -240
  120. package/aux-format-2/AuxOpTypes.js.map +0 -1
  121. package/aux-format-2/AuxStateHelpers.js.map +0 -1
  122. package/aux-format-2/AuxWeaveHelpers.d.ts +0 -132
  123. package/aux-format-2/AuxWeaveHelpers.js +0 -335
  124. package/aux-format-2/AuxWeaveHelpers.js.map +0 -1
  125. package/aux-format-2/AuxWeaveReducer.d.ts +0 -37
  126. package/aux-format-2/AuxWeaveReducer.js +0 -980
  127. package/aux-format-2/AuxWeaveReducer.js.map +0 -1
  128. package/aux-format-2/index.d.ts +0 -7
  129. package/aux-format-2/index.js +0 -7
  130. package/aux-format-2/index.js.map +0 -1
  131. package/partitions/AuxPartitionRealtimeEditModeProvider.d.ts +0 -9
  132. package/partitions/AuxPartitionRealtimeEditModeProvider.js +0 -21
  133. package/partitions/AuxPartitionRealtimeEditModeProvider.js.map +0 -1
  134. package/partitions/BotClient.d.ts +0 -24
  135. package/partitions/BotClient.js +0 -2
  136. package/partitions/BotClient.js.map +0 -1
  137. package/partitions/BotPartition.d.ts +0 -45
  138. package/partitions/BotPartition.js +0 -186
  139. package/partitions/BotPartition.js.map +0 -1
  140. package/partitions/CausalRepoPartition.d.ts +0 -45
  141. package/partitions/CausalRepoPartition.js +0 -157
  142. package/partitions/CausalRepoPartition.js.map +0 -1
  143. package/partitions/MemoryBotClient.d.ts +0 -11
  144. package/partitions/MemoryBotClient.js +0 -41
  145. package/partitions/MemoryBotClient.js.map +0 -1
  146. package/partitions/RemoteCausalRepoHistoryPartition.d.ts +0 -53
  147. package/partitions/RemoteCausalRepoHistoryPartition.js +0 -206
  148. package/partitions/RemoteCausalRepoHistoryPartition.js.map +0 -1
  149. package/partitions/RemoteCausalRepoPartition.d.ts +0 -72
  150. package/partitions/RemoteCausalRepoPartition.js +0 -468
  151. package/partitions/RemoteCausalRepoPartition.js.map +0 -1
  152. package/runtime/AuxCompiler.d.ts +0 -258
  153. package/runtime/AuxCompiler.js +0 -722
  154. package/runtime/AuxCompiler.js.map +0 -1
  155. package/runtime/AuxDevice.d.ts +0 -28
  156. package/runtime/AuxDevice.js +0 -2
  157. package/runtime/AuxDevice.js.map +0 -1
  158. package/runtime/AuxGlobalContext.d.ts +0 -571
  159. package/runtime/AuxGlobalContext.js +0 -606
  160. package/runtime/AuxGlobalContext.js.map +0 -1
  161. package/runtime/AuxLibrary.d.ts +0 -2702
  162. package/runtime/AuxLibrary.js +0 -11046
  163. package/runtime/AuxLibrary.js.map +0 -1
  164. package/runtime/AuxLibraryDefinitions.def +0 -13139
  165. package/runtime/AuxRealtimeEditModeProvider.d.ts +0 -35
  166. package/runtime/AuxRealtimeEditModeProvider.js +0 -34
  167. package/runtime/AuxRealtimeEditModeProvider.js.map +0 -1
  168. package/runtime/AuxResults.d.ts +0 -77
  169. package/runtime/AuxResults.js +0 -6
  170. package/runtime/AuxResults.js.map +0 -1
  171. package/runtime/AuxRuntime.d.ts +0 -253
  172. package/runtime/AuxRuntime.js +0 -2700
  173. package/runtime/AuxRuntime.js.map +0 -1
  174. package/runtime/AuxRuntimeDynamicImports.d.ts +0 -14
  175. package/runtime/AuxRuntimeDynamicImports.js +0 -24
  176. package/runtime/AuxRuntimeDynamicImports.js.map +0 -1
  177. package/runtime/AuxVersion.d.ts +0 -39
  178. package/runtime/AuxVersion.js +0 -2
  179. package/runtime/AuxVersion.js.map +0 -1
  180. package/runtime/CasualOSError.d.ts +0 -37
  181. package/runtime/CasualOSError.js +0 -25
  182. package/runtime/CasualOSError.js.map +0 -1
  183. package/runtime/CompiledBot.d.ts +0 -106
  184. package/runtime/CompiledBot.js +0 -44
  185. package/runtime/CompiledBot.js.map +0 -1
  186. package/runtime/PerformanceNowPolyfill.d.ts +0 -1
  187. package/runtime/PerformanceNowPolyfill.js +0 -8
  188. package/runtime/PerformanceNowPolyfill.js.map +0 -1
  189. package/runtime/RuntimeBot.d.ts +0 -176
  190. package/runtime/RuntimeBot.js +0 -732
  191. package/runtime/RuntimeBot.js.map +0 -1
  192. package/runtime/RuntimeStateVersion.d.ts +0 -23
  193. package/runtime/RuntimeStateVersion.js +0 -22
  194. package/runtime/RuntimeStateVersion.js.map +0 -1
  195. package/runtime/Transpiler.d.ts +0 -174
  196. package/runtime/Transpiler.js +0 -611
  197. package/runtime/Transpiler.js.map +0 -1
  198. package/runtime/Utils.d.ts +0 -74
  199. package/runtime/Utils.js +0 -488
  200. package/runtime/Utils.js.map +0 -1
  201. package/runtime/index.d.ts +0 -9
  202. package/runtime/index.js +0 -9
  203. package/runtime/index.js.map +0 -1
  204. package/runtime/test/RuntimeTestHelpers.d.ts +0 -11
  205. package/runtime/test/RuntimeTestHelpers.js +0 -26
  206. package/runtime/test/RuntimeTestHelpers.js.map +0 -1
  207. package/runtime/test/TestScriptBotFactory.d.ts +0 -16
  208. package/runtime/test/TestScriptBotFactory.js +0 -107
  209. package/runtime/test/TestScriptBotFactory.js.map +0 -1
  210. /package/{runtime/BlobPolyfill.d.ts → BlobPolyfill.d.ts} +0 -0
  211. /package/{runtime/BlobPolyfill.js → BlobPolyfill.js} +0 -0
  212. /package/{runtime/BlobPolyfill.js.map → BlobPolyfill.js.map} +0 -0
@@ -1,2700 +0,0 @@
1
- // CasualOS has several key components:
2
- //
3
- // 1. Simulations - These are wrapper objects that manage creating and interfacing with AUX virtual machines.
4
- // 2. VM - AUX Virtual Machines provide a security boundary to keep user scripts separate across multiple virtual machines.
5
- // 3. Channel - These are manager objects which handle the persistence and runtime aspects of an AUX.
6
- // 4. Partitions - These are services which manage the persistence and realtime sync of the AUX data model.
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
- };
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, parseTaggedNumber, REPLACE_BOT_SYMBOL, } from '../bots';
18
- import { Subject, Subscription } from 'rxjs';
19
- import { AuxCompiler, getInterpretableFunction, isInterpretableFunction, } from './AuxCompiler';
20
- import { addToContext, MemoryGlobalContext, removeFromContext, isInContext, } from './AuxGlobalContext';
21
- import { createDefaultLibrary, GET_RUNTIME, } from './AuxLibrary';
22
- import { createRuntimeBot, RealtimeEditMode, } from './RuntimeBot';
23
- import { RanOutOfEnergyError, } from './AuxResults';
24
- import { convertToCopiableValue, DeepObjectError, isPromise, isRuntimePromise, markAsRuntimePromise, } from './Utils';
25
- import { DefaultRealtimeEditModeProvider, } from './AuxRealtimeEditModeProvider';
26
- import { sortBy, forOwn, merge, union } from 'lodash';
27
- import { tagValueHash } from '../aux-format-2/AuxOpTypes';
28
- import { applyTagEdit, isTagEdit } from '../aux-format-2';
29
- import { updateRuntimeVersion, } from './RuntimeStateVersion';
30
- import { replaceMacros } from './Transpiler';
31
- import { DateTime } from 'luxon';
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
- import { UNMAPPABLE, } from '../bots/BotEvents';
37
- let Interpreter;
38
- let DeclarativeEnvironmentRecord;
39
- let DefinePropertyOrThrow;
40
- let Descriptor;
41
- let Value;
42
- let hasModule = false;
43
- let interpreterImportPromise;
44
- export function registerInterpreterModule(module) {
45
- hasModule = true;
46
- Interpreter = module.Interpreter;
47
- DeclarativeEnvironmentRecord = module.DeclarativeEnvironmentRecord;
48
- DefinePropertyOrThrow = module.DefinePropertyOrThrow;
49
- Descriptor = module.Descriptor;
50
- Value = module.Value;
51
- }
52
- function importInterpreter() {
53
- if (hasModule) {
54
- return Promise.resolve();
55
- }
56
- if (interpreterImportPromise) {
57
- return interpreterImportPromise;
58
- }
59
- else {
60
- return (interpreterImportPromise = _importInterpreterCore());
61
- }
62
- }
63
- function _importInterpreterCore() {
64
- return __awaiter(this, void 0, void 0, function* () {
65
- const module = yield _dynamicImportInterpreter();
66
- registerInterpreterModule(module);
67
- });
68
- }
69
- /**
70
- * Defines an class that is able to manage the runtime state of an AUX.
71
- *
72
- * Being a runtime means providing and managing the execution state that an AUX is in.
73
- * This means taking state updates events, shouts and whispers, and emitting additional events to affect the future state.
74
- */
75
- export class AuxRuntime {
76
- get forceSignedScripts() {
77
- return this._forceSignedScripts;
78
- }
79
- get context() {
80
- return this._globalContext;
81
- }
82
- get currentVersion() {
83
- return this._currentVersion;
84
- }
85
- get globalObject() {
86
- return this._globalObject;
87
- }
88
- get canTriggerBreakpoint() {
89
- return !!this._interpreter && this._interpreter.debugging;
90
- }
91
- /**
92
- * Creates a new AuxRuntime using the given library factory.
93
- * @param libraryFactory
94
- * @param forceSignedScripts Whether to force the runtime to only allow scripts that are signed.
95
- * @param exemptSpaces The spaces that are exempt from requiring signed scripts.
96
- * @param interpreter The interpreter that should be used for the runtime.
97
- */
98
- constructor(version, device, libraryFactory = createDefaultLibrary, editModeProvider = new DefaultRealtimeEditModeProvider(), forceSignedScripts = false, exemptSpaces = ['local', 'tempLocal'], forceSyncScripts = false, interpreter = null) {
99
- this._compiledState = {};
100
- this._existingMasks = {};
101
- this._compiler = new AuxCompiler();
102
- this._stopState = null;
103
- this._breakpoints = new Map();
104
- this._currentStopCount = 0;
105
- this._currentPromise = null;
106
- this._actionBatch = [];
107
- this._errorBatch = [];
108
- this._currentVersion = {
109
- localSites: {},
110
- vector: {},
111
- };
112
- this._updatedBots = new Map();
113
- this._newBots = new Map();
114
- this._batchPending = false;
115
- this._jobQueueCheckPending = false;
116
- this._jobQueueCheckCount = 0;
117
- this._processingErrors = false;
118
- this._portalBots = new Map();
119
- this._builtinPortalBots = [];
120
- this._globalChanges = {};
121
- this._beforeActionListeners = [];
122
- this._scriptActionEnqueuedListeners = [];
123
- this._scriptUpdatedTagListeners = [];
124
- this._scriptUpdatedTagMaskListeners = [];
125
- // private _beforeScriptEnterListeners: ((
126
- // trace: DebuggerScriptEnterTrace
127
- // ) => void)[] = [];
128
- // private _afterScriptExitListeners: ((
129
- // trace: DebuggerScriptExitTrace
130
- // ) => void)[] = [];
131
- /**
132
- * The counter that is used to generate function names.
133
- */
134
- this._functionNameCounter = 0;
135
- /**
136
- * A map of function names to their respective functions.
137
- */
138
- this._functionMap = new Map();
139
- /**
140
- * A map of bot IDs to a list of function names.
141
- */
142
- this._botFunctionMap = new Map();
143
- /**
144
- * Whether changes should be automatically batched.
145
- */
146
- this._autoBatch = true;
147
- this._forceSyncScripts = false;
148
- this._currentDebugger = null;
149
- /**
150
- * The number of times that the runtime can call onError for an error from the same script.
151
- */
152
- this.repeatedErrorLimit = 1000;
153
- this._libraryFactory = libraryFactory;
154
- this._interpreter = interpreter;
155
- this._globalContext = new MemoryGlobalContext(version, device, this, this, this);
156
- this._forceSyncScripts = forceSyncScripts;
157
- this._globalContext.mockAsyncActions = forceSyncScripts;
158
- this._library = merge(libraryFactory(this._globalContext), {
159
- api: {
160
- os: {
161
- createDebugger: this._createDebugger.bind(this),
162
- getExecutingDebugger: this._getExecutingDebugger.bind(this),
163
- },
164
- },
165
- });
166
- this._editModeProvider = editModeProvider;
167
- this._forceSignedScripts = forceSignedScripts;
168
- this._exemptSpaces = exemptSpaces;
169
- this._onActions = new Subject();
170
- this._onErrors = new Subject();
171
- this._onRuntimeStop = new Subject();
172
- let sub = (this._sub = new Subscription(() => {
173
- this._globalContext.cancelAllBotTimers();
174
- }));
175
- sub.add(this._globalContext.startAnimationLoop());
176
- if (globalThis.addEventListener) {
177
- const unhandledRejectionListener = (event) => {
178
- const data = this._handleError(event.reason, null, null);
179
- this._globalContext.enqueueError(data);
180
- event.preventDefault();
181
- };
182
- globalThis.addEventListener('unhandledrejection', unhandledRejectionListener);
183
- sub.add(() => {
184
- globalThis.removeEventListener('unhandledrejection', unhandledRejectionListener);
185
- });
186
- }
187
- this._globalObject = new Proxy(globalThis, {
188
- get: (target, key, receiver) => {
189
- if (key in this._globalChanges) {
190
- return Reflect.get(this._globalChanges, key);
191
- }
192
- else if (key in target) {
193
- return Reflect.get(target, key);
194
- }
195
- return Reflect.get(target, key, receiver);
196
- },
197
- set: (target, key, value, receiver) => {
198
- return Reflect.set(this._globalChanges, key, value);
199
- },
200
- deleteProperty: (target, key) => {
201
- return Reflect.deleteProperty(this._globalChanges, key);
202
- },
203
- defineProperty: (target, key, options) => {
204
- return Reflect.defineProperty(this._globalChanges, key, options);
205
- },
206
- ownKeys: (target) => {
207
- const addedKeys = Reflect.ownKeys(this._globalChanges);
208
- const otherKeys = Reflect.ownKeys(target);
209
- return union(addedKeys, otherKeys);
210
- },
211
- has: (target, key) => {
212
- return (Reflect.has(this._globalChanges, key) ||
213
- Reflect.has(target, key));
214
- },
215
- getOwnPropertyDescriptor: (target, key) => {
216
- if (key in this._globalChanges) {
217
- return Reflect.getOwnPropertyDescriptor(this._globalChanges, key);
218
- }
219
- return Reflect.getOwnPropertyDescriptor(target, key);
220
- },
221
- });
222
- this._globalContext.global = this._globalObject;
223
- if (this._interpreter) {
224
- // Use the interpreted versions of APIs
225
- this._interpretedApi = Object.assign({}, this._library.api);
226
- this._interpretedTagSpecificApi = Object.assign({}, this._library.tagSpecificApi);
227
- for (let key in this._interpretedApi) {
228
- const val = this._interpretedApi[key];
229
- if (isInterpretableFunction(val)) {
230
- this._interpretedApi[key] = getInterpretableFunction(val);
231
- }
232
- }
233
- for (let key in this._interpretedTagSpecificApi) {
234
- const val = this._interpretedTagSpecificApi[key];
235
- if (isInterpretableFunction(val)) {
236
- this._interpretedTagSpecificApi[key] =
237
- getInterpretableFunction(val);
238
- }
239
- }
240
- }
241
- }
242
- getShoutTimers() {
243
- return {};
244
- }
245
- get closed() {
246
- return this._sub.closed;
247
- }
248
- unsubscribe() {
249
- return this._sub.unsubscribe();
250
- }
251
- /**
252
- * Gets the current state that the runtime is operating on.
253
- */
254
- get currentState() {
255
- return this._compiledState;
256
- }
257
- get userId() {
258
- return this._userId;
259
- }
260
- set userId(id) {
261
- this._userId = id;
262
- this._globalContext.playerBot = this.userBot;
263
- }
264
- get userBot() {
265
- if (!this._userId) {
266
- return;
267
- }
268
- const bot = this._compiledState[this._userId];
269
- if (bot) {
270
- return bot.script;
271
- }
272
- else {
273
- return null;
274
- }
275
- }
276
- /**
277
- * An observable that resolves whenever the runtime issues an action.
278
- */
279
- get onActions() {
280
- return this._onActions;
281
- }
282
- /**
283
- * An observable that resolves whenever the runtime issues an error.
284
- */
285
- get onErrors() {
286
- return this._onErrors;
287
- }
288
- /**
289
- * An observable that resolves whenever the runtime pauses in a script.
290
- */
291
- get onRuntimeStop() {
292
- return this._onRuntimeStop;
293
- }
294
- /**
295
- * Processes the given bot actions and dispatches the resulting actions in the future.
296
- * @param actions The actions to process.
297
- */
298
- process(actions) {
299
- if (this._beforeActionListeners.length > 0) {
300
- for (let func of this._beforeActionListeners) {
301
- for (let action of actions) {
302
- try {
303
- func(action);
304
- }
305
- catch (err) {
306
- console.error(err);
307
- }
308
- }
309
- }
310
- }
311
- this._processBatch();
312
- const result = this._processCore(actions);
313
- this._processBatch();
314
- return result;
315
- }
316
- _getExecutingDebugger() {
317
- return this._currentDebugger;
318
- }
319
- _createDebugger(options) {
320
- return __awaiter(this, void 0, void 0, function* () {
321
- const forceSyncScripts = typeof (options === null || options === void 0 ? void 0 : options.allowAsynchronousScripts) === 'boolean'
322
- ? !options.allowAsynchronousScripts
323
- : false;
324
- yield importInterpreter();
325
- const interpreter = (options === null || options === void 0 ? void 0 : options.pausable) ? new Interpreter() : null;
326
- const runtime = new AuxRuntime(this._globalContext.version, this._globalContext.device, this._libraryFactory, this._editModeProvider, this._forceSignedScripts, this._exemptSpaces, forceSyncScripts, interpreter);
327
- runtime._autoBatch = true;
328
- let idCount = 0;
329
- if (!(options === null || options === void 0 ? void 0 : options.useRealUUIDs)) {
330
- runtime._globalContext.uuid = () => {
331
- idCount += 1;
332
- return `uuid-${idCount}`;
333
- };
334
- }
335
- let allActions = [];
336
- let allErrors = [];
337
- let create;
338
- if (interpreter &&
339
- isInterpretableFunction(runtime._library.tagSpecificApi.create)) {
340
- const func = getInterpretableFunction(runtime._library.tagSpecificApi.create)({
341
- bot: null,
342
- config: null,
343
- creator: null,
344
- tag: null,
345
- });
346
- create = (...args) => {
347
- const result = func(...args);
348
- if (isGenerator(result)) {
349
- return runtime._processGenerator(result);
350
- }
351
- return result;
352
- };
353
- }
354
- else {
355
- create = runtime._library.tagSpecificApi.create({
356
- bot: null,
357
- config: null,
358
- creator: null,
359
- tag: null,
360
- });
361
- }
362
- const isCommonAction = (action) => {
363
- return !(action.type === 'add_bot' ||
364
- action.type === 'remove_bot' ||
365
- action.type === 'update_bot' ||
366
- action.type === 'apply_state');
367
- };
368
- const getAllActions = () => {
369
- const actions = runtime._processUnbatchedActions();
370
- allActions.push(...actions);
371
- return allActions;
372
- };
373
- // The config bot is always ID 0 in debuggers
374
- const configBotId = (options === null || options === void 0 ? void 0 : options.useRealUUIDs)
375
- ? runtime.context.uuid()
376
- : 'uuid-0';
377
- const configBotTags = (options === null || options === void 0 ? void 0 : options.configBot)
378
- ? isBot(options === null || options === void 0 ? void 0 : options.configBot)
379
- ? options.configBot.tags
380
- : options.configBot
381
- : {};
382
- runtime.context.createBot(createBot(configBotId, configBotTags, 'tempLocal'));
383
- runtime.process(this._builtinPortalBots.map((b) => registerBuiltinPortal(b)));
384
- runtime.userId = configBotId;
385
- const api = Object.assign({}, runtime._library.api);
386
- if (interpreter) {
387
- for (let key in runtime._library.api) {
388
- const val = runtime._library.api[key];
389
- if (isInterpretableFunction(val)) {
390
- const func = getInterpretableFunction(val);
391
- api[key] = (...args) => {
392
- const result = func(...args);
393
- if (isGenerator(result)) {
394
- return runtime._processGenerator(result);
395
- }
396
- return result;
397
- };
398
- }
399
- }
400
- }
401
- if (interpreter && (options === null || options === void 0 ? void 0 : options.pausable)) {
402
- interpreter.debugging = true;
403
- }
404
- const debug = Object.assign(Object.assign({ [UNCOPIABLE]: true }, api), { getAllActions, getCommonActions: () => {
405
- return getAllActions().filter(isCommonAction);
406
- }, getBotActions: () => {
407
- return getAllActions().filter((a) => !isCommonAction(a));
408
- }, getErrors: () => {
409
- const errors = runtime._processUnbatchedErrors();
410
- allErrors.push(...errors);
411
- return allErrors;
412
- }, onBeforeUserAction: (listener) => {
413
- runtime._beforeActionListeners.push(listener);
414
- }, onScriptActionEnqueued: (listener) => {
415
- runtime._scriptActionEnqueuedListeners.push(listener);
416
- }, onAfterScriptUpdatedTag: (listener) => {
417
- runtime._scriptUpdatedTagListeners.push(listener);
418
- }, onAfterScriptUpdatedTagMask: (listener) => {
419
- runtime._scriptUpdatedTagMaskListeners.push(listener);
420
- }, getCallStack() {
421
- if (!interpreter) {
422
- throw new Error('getCallStack() is only supported on pausable debuggers.');
423
- }
424
- return runtime._mapCallStack(interpreter.agent.executionContextStack);
425
- },
426
- performUserAction(...actions) {
427
- return __awaiter(this, void 0, void 0, function* () {
428
- const result = yield runtime.process(actions);
429
- return result.map((r) => (r ? r.results : null));
430
- });
431
- },
432
- // TODO: Determine whether to support this
433
- // onBeforeScriptEnter: (
434
- // listener: (trace: DebuggerScriptEnterTrace) => void
435
- // ) => {
436
- // runtime._beforeScriptEnterListeners.push(listener);
437
- // },
438
- // onAfterScriptExit: (
439
- // listener: (trace: DebuggerScriptExitTrace) => void
440
- // ) => {
441
- // runtime._afterScriptExitListeners.push(listener);
442
- // },
443
- setPauseTrigger(b, tag, options) {
444
- var _a, _b, _c;
445
- if (typeof b === 'object' && 'triggerId' in b) {
446
- runtime.setBreakpoint({
447
- id: b.triggerId,
448
- botId: b.botId,
449
- tag: b.tag,
450
- lineNumber: b.lineNumber,
451
- columnNumber: b.columnNumber,
452
- states: (_a = b.states) !== null && _a !== void 0 ? _a : ['before'],
453
- disabled: !((_b = b.enabled) !== null && _b !== void 0 ? _b : true),
454
- });
455
- return b;
456
- }
457
- else {
458
- const id = isBot(b) ? b.id : b;
459
- const trigger = Object.assign({ triggerId: uuid(), botId: id, tag: tag }, options);
460
- runtime.setBreakpoint({
461
- id: trigger.triggerId,
462
- botId: id,
463
- tag: tag,
464
- lineNumber: trigger.lineNumber,
465
- columnNumber: trigger.columnNumber,
466
- states: (_c = trigger.states) !== null && _c !== void 0 ? _c : ['before'],
467
- disabled: false,
468
- });
469
- return trigger;
470
- }
471
- },
472
- removePauseTrigger(triggerOrId) {
473
- let id = typeof triggerOrId === 'string'
474
- ? triggerOrId
475
- : triggerOrId.triggerId;
476
- runtime.removeBreakpoint(id);
477
- },
478
- disablePauseTrigger(triggerOrId) {
479
- var _a;
480
- if (typeof triggerOrId === 'string') {
481
- let trigger = runtime._breakpoints.get(triggerOrId);
482
- if (trigger) {
483
- trigger.disabled = true;
484
- }
485
- }
486
- else {
487
- runtime.setBreakpoint({
488
- id: triggerOrId.triggerId,
489
- botId: triggerOrId.botId,
490
- tag: triggerOrId.tag,
491
- lineNumber: triggerOrId.lineNumber,
492
- columnNumber: triggerOrId.columnNumber,
493
- states: (_a = triggerOrId.states) !== null && _a !== void 0 ? _a : ['before'],
494
- disabled: true,
495
- });
496
- }
497
- },
498
- enablePauseTrigger(triggerOrId) {
499
- var _a;
500
- if (typeof triggerOrId === 'string') {
501
- let trigger = runtime._breakpoints.get(triggerOrId);
502
- if (trigger) {
503
- trigger.disabled = false;
504
- }
505
- }
506
- else {
507
- runtime.setBreakpoint({
508
- id: triggerOrId.triggerId,
509
- botId: triggerOrId.botId,
510
- tag: triggerOrId.tag,
511
- lineNumber: triggerOrId.lineNumber,
512
- columnNumber: triggerOrId.columnNumber,
513
- states: (_a = triggerOrId.states) !== null && _a !== void 0 ? _a : ['before'],
514
- disabled: false,
515
- });
516
- }
517
- },
518
- listPauseTriggers() {
519
- let triggers = [];
520
- for (let breakpoint of runtime._breakpoints.values()) {
521
- triggers.push({
522
- triggerId: breakpoint.id,
523
- botId: breakpoint.botId,
524
- tag: breakpoint.tag,
525
- columnNumber: breakpoint.columnNumber,
526
- lineNumber: breakpoint.lineNumber,
527
- states: breakpoint.states.slice(),
528
- enabled: !breakpoint.disabled,
529
- });
530
- }
531
- return triggers;
532
- },
533
- listCommonPauseTriggers(botOrId, tag) {
534
- const id = typeof botOrId === 'string' ? botOrId : botOrId.id;
535
- const bot = runtime.currentState[id];
536
- const func = bot.listeners[tag];
537
- if (!func) {
538
- return [];
539
- }
540
- return runtime._compiler.listPossibleBreakpoints(func, runtime._interpreter);
541
- },
542
- onPause(callback) {
543
- runtime.onRuntimeStop.subscribe((stop) => {
544
- const pause = {
545
- pauseId: stop.stopId,
546
- state: stop.state,
547
- callStack: runtime._mapCallStack(stop.stack),
548
- trigger: {
549
- triggerId: stop.breakpoint.id,
550
- botId: stop.breakpoint.botId,
551
- tag: stop.breakpoint.tag,
552
- lineNumber: stop.breakpoint.lineNumber,
553
- columnNumber: stop.breakpoint.columnNumber,
554
- states: stop.breakpoint.states,
555
- },
556
- };
557
- callback(pause);
558
- });
559
- },
560
- resume(pause) {
561
- runtime.continueAfterStop(pause.pauseId);
562
- },
563
- [GET_RUNTIME]() {
564
- return runtime;
565
- },
566
- get configBot() {
567
- return runtime.userBot;
568
- },
569
- getPortalBots() {
570
- var _a;
571
- let portalBots = new Map();
572
- for (let [portal, id] of runtime._portalBots) {
573
- portalBots.set(portal, (_a = runtime.currentState[id]) === null || _a === void 0 ? void 0 : _a.script);
574
- }
575
- return portalBots;
576
- },
577
- create });
578
- runtime._currentDebugger = debug;
579
- this._scheduleJobQueueCheck();
580
- return debug;
581
- });
582
- }
583
- _mapCallStack(stack) {
584
- const interpreter = this._interpreter;
585
- return stack.map((s) => {
586
- const callSite = s.callSite;
587
- const funcName = callSite.getFunctionName();
588
- let funcLocation = {};
589
- if (funcName) {
590
- const f = this._functionMap.get(funcName);
591
- if (f) {
592
- funcLocation.name = f.metadata.diagnosticFunctionName;
593
- const location = this._compiler.calculateOriginalLineLocation(f, {
594
- lineNumber: callSite.lineNumber,
595
- column: callSite.columnNumber,
596
- });
597
- funcLocation.lineNumber = location.lineNumber + 1;
598
- funcLocation.columnNumber = location.column + 1;
599
- const tagName = f.metadata.context.tag;
600
- const bot = f.metadata.context.bot;
601
- if (bot) {
602
- funcLocation.botId = bot.id;
603
- }
604
- if (tagName) {
605
- funcLocation.tag = tagName;
606
- }
607
- }
608
- else {
609
- funcLocation.name = funcName;
610
- }
611
- }
612
- if (!hasValue(funcLocation.lineNumber) &&
613
- !hasValue(funcLocation.columnNumber) &&
614
- hasValue(callSite.lineNumber) &&
615
- hasValue(callSite.columnNumber)) {
616
- funcLocation.lineNumber = callSite.lineNumber;
617
- funcLocation.columnNumber = callSite.columnNumber;
618
- }
619
- if (!hasValue(funcLocation.lineNumber) &&
620
- !hasValue(funcLocation.columnNumber) &&
621
- !hasValue(funcLocation.name)) {
622
- funcLocation = null;
623
- }
624
- const ret = {
625
- location: funcLocation,
626
- listVariables() {
627
- let variables = [];
628
- if (s.LexicalEnvironment instanceof
629
- DeclarativeEnvironmentRecord) {
630
- addBindingsFromEnvironment(s.LexicalEnvironment, 'block');
631
- }
632
- if (s.VariableEnvironment instanceof
633
- DeclarativeEnvironmentRecord) {
634
- addBindingsFromEnvironment(s.VariableEnvironment, 'frame');
635
- let parent = s.VariableEnvironment.OuterEnv;
636
- while (parent) {
637
- if (parent instanceof DeclarativeEnvironmentRecord) {
638
- addBindingsFromEnvironment(parent, 'closure');
639
- }
640
- parent = parent.OuterEnv;
641
- }
642
- }
643
- return variables;
644
- function addBindingsFromEnvironment(env, scope) {
645
- for (let [nameValue, binding,] of env.bindings.entries()) {
646
- const name = interpreter.copyFromValue(nameValue);
647
- const initialized = !!binding.initialized;
648
- const mutable = !!binding.mutable;
649
- const value = initialized
650
- ? interpreter.reverseProxyObject(binding.value, false)
651
- : undefined;
652
- const variable = {
653
- name,
654
- value,
655
- writable: mutable,
656
- scope,
657
- };
658
- if (!initialized) {
659
- variable.initialized = false;
660
- }
661
- variables.push(variable);
662
- }
663
- }
664
- },
665
- setVariableValue(name, value) {
666
- if (s.LexicalEnvironment instanceof
667
- DeclarativeEnvironmentRecord) {
668
- const nameValue = interpreter.copyToValue(name);
669
- const proxiedValue = interpreter.proxyObject(value);
670
- if (nameValue.Type !== 'normal') {
671
- throw interpreter.copyFromValue(nameValue.Value);
672
- }
673
- if (proxiedValue.Type !== 'normal') {
674
- throw interpreter.copyFromValue(proxiedValue.Value);
675
- }
676
- const result = s.LexicalEnvironment.SetMutableBinding(nameValue.Value, proxiedValue.Value, Value.true);
677
- if (result.Type !== 'normal') {
678
- throw interpreter.copyFromValue(result.Value);
679
- }
680
- return interpreter.copyFromValue(result.Value);
681
- }
682
- },
683
- };
684
- return ret;
685
- });
686
- }
687
- _processCore(actions) {
688
- const _this = this;
689
- const results = [];
690
- function processAction(action, addToResults) {
691
- let promise = _this._processAction(action);
692
- if (addToResults) {
693
- if (isRuntimePromise(promise)) {
694
- return markAsRuntimePromise(promise.then((result) => {
695
- results.push(result);
696
- }));
697
- }
698
- else {
699
- results.push(promise);
700
- }
701
- return;
702
- }
703
- return promise;
704
- }
705
- function handleRejection(action, rejection) {
706
- let promise = processListOfMaybePromises(null, rejection.newActions, (action) => {
707
- return processAction(action, false);
708
- });
709
- if (rejection.rejected) {
710
- return;
711
- }
712
- if (promise) {
713
- return markAsRuntimePromise(promise.then((p) => processAction(action, true)));
714
- }
715
- else {
716
- return processAction(action, true);
717
- }
718
- }
719
- let promise = processListOfMaybePromises(null, actions, (action) => {
720
- let rejection = this._rejectAction(action);
721
- let result;
722
- if (isRuntimePromise(rejection)) {
723
- result = markAsRuntimePromise(rejection.then((result) => handleRejection(action, result)));
724
- }
725
- else {
726
- result = handleRejection(action, rejection);
727
- }
728
- return result;
729
- });
730
- if (isRuntimePromise(promise)) {
731
- return markAsRuntimePromise(promise.then(() => results));
732
- }
733
- else {
734
- return results;
735
- }
736
- }
737
- _processAction(action) {
738
- if (action.type === 'action') {
739
- const result = this._shout(action.eventName, action.botIds, action.argument, false);
740
- if (isRuntimePromise(result)) {
741
- return markAsRuntimePromise(result
742
- .then((result) => this._processCore(result.actions))
743
- .then(() => result));
744
- }
745
- else {
746
- let promise = this._processCore(result.actions);
747
- if (isRuntimePromise(promise)) {
748
- return markAsRuntimePromise(promise.then(() => result));
749
- }
750
- else {
751
- return result;
752
- }
753
- }
754
- }
755
- else if (action.type === 'run_script') {
756
- const result = this._execute(action.script, false, false);
757
- if (isRuntimePromise(result)) {
758
- return markAsRuntimePromise(result.then((result) => {
759
- const p = this._processCore(result.actions);
760
- if (isPromise(p)) {
761
- return p.then(() => {
762
- if (hasValue(action.taskId)) {
763
- this._globalContext.resolveTask(action.taskId, result.result, false);
764
- }
765
- return null;
766
- });
767
- }
768
- else {
769
- if (hasValue(action.taskId)) {
770
- if (this._globalContext.resolveTask(action.taskId, result.result, false)) {
771
- this._scheduleJobQueueCheck();
772
- }
773
- }
774
- }
775
- return null;
776
- }));
777
- }
778
- else {
779
- const p = this._processCore(result.actions);
780
- if (isRuntimePromise(p)) {
781
- return markAsRuntimePromise(p.then(() => {
782
- if (hasValue(action.taskId)) {
783
- if (this._globalContext.resolveTask(action.taskId, result.result, false)) {
784
- this._scheduleJobQueueCheck();
785
- }
786
- }
787
- return null;
788
- }));
789
- }
790
- if (hasValue(action.taskId)) {
791
- if (this._globalContext.resolveTask(action.taskId, result.result, false)) {
792
- this._scheduleJobQueueCheck();
793
- }
794
- }
795
- }
796
- }
797
- else if (action.type === 'apply_state') {
798
- const events = breakIntoIndividualEvents(this.currentState, action);
799
- const promise = this._processCore(events);
800
- if (isRuntimePromise(promise)) {
801
- return markAsRuntimePromise(promise.then(() => null));
802
- }
803
- else {
804
- return null;
805
- }
806
- }
807
- else if (action.type === 'async_result') {
808
- const value = action.mapBotsInResult === true
809
- ? this._mapBotsToRuntimeBots(action.result)
810
- : action.result;
811
- if (!this._globalContext.resolveTask(action.taskId, value, false)) {
812
- this._actionBatch.push(action);
813
- }
814
- else {
815
- this._scheduleJobQueueCheck();
816
- }
817
- }
818
- else if (action.type === 'async_error') {
819
- if (!this._globalContext.rejectTask(action.taskId, action.error, false)) {
820
- this._actionBatch.push(action);
821
- }
822
- else {
823
- this._scheduleJobQueueCheck();
824
- }
825
- }
826
- else if (action.type === 'device_result') {
827
- if (!this._globalContext.resolveTask(action.taskId, action.result, true)) {
828
- this._actionBatch.push(action);
829
- }
830
- else {
831
- this._scheduleJobQueueCheck();
832
- }
833
- }
834
- else if (action.type === 'device_error') {
835
- if (!this._globalContext.rejectTask(action.taskId, action.error, true)) {
836
- this._actionBatch.push(action);
837
- }
838
- else {
839
- this._scheduleJobQueueCheck();
840
- }
841
- }
842
- else if (action.type === 'register_custom_app') {
843
- this._registerPortalBot(action.appId, action.botId);
844
- this._actionBatch.push(action);
845
- }
846
- else if (action.type === 'register_builtin_portal') {
847
- if (!this._portalBots.has(action.portalId)) {
848
- const newBot = this.context.createBot(createBot(this.context.uuid(), undefined, 'tempLocal'));
849
- this._builtinPortalBots.push(action.portalId);
850
- this._registerPortalBot(action.portalId, newBot.id);
851
- this._actionBatch.push(defineGlobalBot(action.portalId, newBot.id));
852
- }
853
- else {
854
- const botId = this._portalBots.get(action.portalId);
855
- this._actionBatch.push(defineGlobalBot(action.portalId, botId));
856
- }
857
- }
858
- else if (action.type === 'define_global_bot') {
859
- if (this._portalBots.get(action.name) !== action.botId) {
860
- this._registerPortalBot(action.name, action.botId);
861
- this._actionBatch.push(action);
862
- }
863
- if (hasValue(action.taskId)) {
864
- const promise = this._processCore([
865
- asyncResult(action.taskId, null),
866
- ]);
867
- if (isRuntimePromise(promise)) {
868
- return markAsRuntimePromise(promise.then(() => null));
869
- }
870
- else {
871
- return null;
872
- }
873
- }
874
- }
875
- else {
876
- this._actionBatch.push(action);
877
- }
878
- return null;
879
- }
880
- _registerPortalBot(portalId, botId) {
881
- const hadPortalBot = this._portalBots.has(portalId);
882
- this._portalBots.set(portalId, botId);
883
- if (!hadPortalBot) {
884
- const variableName = `${portalId}Bot`;
885
- const getValue = () => {
886
- const botId = this._portalBots.get(portalId);
887
- if (hasValue(botId)) {
888
- return this.context.state[botId];
889
- }
890
- else {
891
- return undefined;
892
- }
893
- };
894
- Object.defineProperty(this._globalObject, variableName, {
895
- get: getValue,
896
- enumerable: false,
897
- configurable: true,
898
- });
899
- if (this._interpreter) {
900
- const proxiedGetResult = this._interpreter.proxyObject(getValue);
901
- if (proxiedGetResult.Type !== 'normal') {
902
- throw this._interpreter.copyFromValue(proxiedGetResult.Value);
903
- }
904
- DefinePropertyOrThrow(this._interpreter.realm.GlobalObject, new Value(variableName), new Descriptor({
905
- Get: proxiedGetResult.Value,
906
- Configurable: Value.true,
907
- }));
908
- }
909
- }
910
- }
911
- _rejectAction(action) {
912
- const result = this._shout(ON_ACTION_ACTION_NAME, null, {
913
- action: action,
914
- }, false);
915
- if (isRuntimePromise(result)) {
916
- return markAsRuntimePromise(result.then((result) => {
917
- return handleResult(result);
918
- }));
919
- }
920
- return handleResult(result);
921
- function handleResult(result) {
922
- let rejected = false;
923
- for (let i = 0; i < result.actions.length; i++) {
924
- const a = result.actions[i];
925
- if (a.type === 'reject' && a.actions.indexOf(action) >= 0) {
926
- rejected = true;
927
- result.actions.splice(i, 1);
928
- break;
929
- }
930
- }
931
- return { rejected, newActions: result.actions };
932
- }
933
- }
934
- /**
935
- * Executes the given function based on the current execution state of the runtime.
936
- * If the runtime is stopped, then the given function will be executed after the current promise finishes.
937
- * If the runtime is executing normally, then the given function will be executed immediately.
938
- * Returns the function result if the function executes immediately,
939
- * or returns a runtime promise if the function executes after the current promise.
940
- *
941
- * This function essentially forces the given function to execute synchronously with respect to other functions wrapped with this function.
942
- *
943
- * @param func The function to execute.
944
- *
945
- */
946
- _wrapWithCurrentPromise(func) {
947
- if (this._stopState && isRuntimePromise(this._currentPromise)) {
948
- // We have hit a breakpoint,
949
- // only trigger this shout after the current state has finished.
950
- return (this._currentPromise = markAsRuntimePromise(this._currentPromise.then(() => {
951
- return func();
952
- })));
953
- }
954
- return (this._currentPromise = func());
955
- }
956
- /**
957
- * Executes a shout with the given event name on the given bot IDs with the given argument.
958
- * Also dispatches any actions and errors that occur.
959
- * @param eventName The name of the event.
960
- * @param botIds The Bot IDs that the shout is being sent to.
961
- * @param arg The argument to include in the shout.
962
- */
963
- shout(eventName, botIds, arg) {
964
- return this._synchronousShout(eventName, botIds, arg, true, true);
965
- }
966
- /**
967
- * Executes the given shout synchronously with respect to other scripts that may be running or paused.
968
- * @param eventName The name of the event that should be executed.
969
- * @param botIds The IDs of the bots that the shout should be sent to.
970
- * @param arg The argument that should be sent with the shout.
971
- * @param batch Whether to batch events.
972
- * @param resetEnergy Whether to reset the runtime energy before executing the shout.
973
- */
974
- _synchronousShout(eventName, botIds, arg, batch, resetEnergy = true) {
975
- return this._wrapWithCurrentPromise(() => {
976
- return this._shout(eventName, botIds, arg, batch, resetEnergy);
977
- });
978
- }
979
- _shout(eventName, botIds, arg, batch, resetEnergy = true) {
980
- try {
981
- arg = this._mapBotsToRuntimeBots(arg);
982
- if (this._interpreter) {
983
- const result = this._interpreter.proxyObject(arg);
984
- if (result.Type !== 'normal') {
985
- throw new Error(`Unable to proxy shout argument!`);
986
- }
987
- arg = result.Value;
988
- }
989
- }
990
- catch (err) {
991
- arg = err;
992
- }
993
- const result = this._batchScriptResults(() => {
994
- if (this.canTriggerBreakpoint) {
995
- const results = (hasValue(botIds)
996
- ? getInterpretableFunction(this._library.api.whisper)(botIds, eventName, arg)
997
- : getInterpretableFunction(this._library.api.shout)(eventName, arg));
998
- return this._processGenerator(results);
999
- }
1000
- else {
1001
- const results = hasValue(botIds)
1002
- ? this._library.api.whisper(botIds, eventName, arg)
1003
- : this._library.api.shout(eventName, arg);
1004
- this._scheduleJobQueueCheck();
1005
- return results;
1006
- }
1007
- }, batch, resetEnergy);
1008
- if (isRuntimePromise(result)) {
1009
- return markAsRuntimePromise(result.then(({ actions, errors, result }) => {
1010
- return {
1011
- actions,
1012
- errors,
1013
- results: result,
1014
- listeners: [],
1015
- };
1016
- }));
1017
- }
1018
- return {
1019
- actions: result.actions,
1020
- errors: result.errors,
1021
- results: result.result,
1022
- listeners: [],
1023
- };
1024
- }
1025
- /**
1026
- * Executes the given script.
1027
- * @param script The script to run.
1028
- */
1029
- execute(script) {
1030
- return this._wrapWithCurrentPromise(() => {
1031
- return this._execute(script, true, true);
1032
- });
1033
- }
1034
- _execute(script, batch, resetEnergy) {
1035
- let fn;
1036
- try {
1037
- fn = this._compile(null, null, script, {});
1038
- }
1039
- catch (ex) {
1040
- let errors = [
1041
- {
1042
- error: ex,
1043
- bot: null,
1044
- tag: null,
1045
- script: script,
1046
- },
1047
- ];
1048
- this._onErrors.next(errors);
1049
- return {
1050
- result: undefined,
1051
- actions: [],
1052
- errors,
1053
- };
1054
- }
1055
- return this._batchScriptResults(() => {
1056
- try {
1057
- return fn();
1058
- }
1059
- catch (ex) {
1060
- this._globalContext.enqueueError(ex);
1061
- }
1062
- }, batch, resetEnergy);
1063
- }
1064
- /**
1065
- * Signals to the runtime that the bots state has been updated.
1066
- * @param update The bot state update.
1067
- */
1068
- stateUpdated(update) {
1069
- let nextUpdate = {
1070
- state: {},
1071
- addedBots: [],
1072
- updatedBots: [],
1073
- removedBots: [],
1074
- version: update.version,
1075
- };
1076
- let newBotIds = null;
1077
- let newBots = null;
1078
- let updates = null;
1079
- if (update.addedBots.length > 0) {
1080
- const { newBots: addedNewBots, newBotIDs: addedBotIds } = this._addBotsToState(update.addedBots.map((id) => update.state[id]), nextUpdate);
1081
- newBots = addedNewBots;
1082
- newBotIds = addedBotIds;
1083
- }
1084
- let removedBots = null;
1085
- if (update.removedBots.length > 0) {
1086
- removedBots = this._removeBotsFromState(update.removedBots, nextUpdate);
1087
- }
1088
- if (update.updatedBots.length > 0) {
1089
- updates = update.updatedBots.map((id) => {
1090
- const partial = update.state[id];
1091
- const current = this.currentState[id];
1092
- if (!current) {
1093
- return null;
1094
- }
1095
- return updatedBot(partial, current);
1096
- });
1097
- this._updateBotsWithState(update, updates, nextUpdate, newBotIds || new Set());
1098
- }
1099
- this._sendOnBotsAddedShouts(newBots, nextUpdate);
1100
- this._sendOnBotsRemovedShouts(update.removedBots);
1101
- this._sendOnBotsChangedShouts(updates);
1102
- this._triggerPortalChangedHandlers(newBots, removedBots, updates);
1103
- return nextUpdate;
1104
- }
1105
- /**
1106
- * Signals to the runtime that the state version has been updated.
1107
- * @param newVersion The version update.
1108
- */
1109
- versionUpdated(newVersion) {
1110
- this._currentVersion = updateRuntimeVersion(newVersion, this._currentVersion);
1111
- return this._currentVersion;
1112
- }
1113
- _sendOnBotsAddedShouts(newBots, nextUpdate) {
1114
- if (newBots && nextUpdate.addedBots.length > 0) {
1115
- try {
1116
- this._synchronousShout(ON_BOT_ADDED_ACTION_NAME, nextUpdate.addedBots, undefined, true, false);
1117
- this._synchronousShout(ON_ANY_BOTS_ADDED_ACTION_NAME, null, {
1118
- bots: newBots.map(([bot, precalc]) => bot),
1119
- }, true, false);
1120
- }
1121
- catch (err) {
1122
- if (!(err instanceof RanOutOfEnergyError)) {
1123
- throw err;
1124
- }
1125
- else {
1126
- console.warn(err);
1127
- }
1128
- }
1129
- }
1130
- }
1131
- _sendOnBotsRemovedShouts(botIds) {
1132
- if (botIds.length > 0) {
1133
- try {
1134
- let promise;
1135
- for (let bot of botIds) {
1136
- const watchers = this._globalContext.getWatchersForBot(bot);
1137
- promise = processListOfMaybePromises(promise, watchers, (watcher) => {
1138
- const generator = watcher.handler();
1139
- if (isGenerator(generator)) {
1140
- return this._processGenerator(generator);
1141
- }
1142
- });
1143
- }
1144
- if (promise) {
1145
- return markAsRuntimePromise(promise
1146
- .then(() => {
1147
- return this._synchronousShout(ON_ANY_BOTS_REMOVED_ACTION_NAME, null, {
1148
- botIDs: botIds,
1149
- }, true, false);
1150
- })
1151
- .catch((err) => {
1152
- if (!(err instanceof RanOutOfEnergyError)) {
1153
- throw err;
1154
- }
1155
- else {
1156
- console.warn(err);
1157
- }
1158
- }));
1159
- }
1160
- else {
1161
- const maybePromise = this._synchronousShout(ON_ANY_BOTS_REMOVED_ACTION_NAME, null, {
1162
- botIDs: botIds,
1163
- }, true, false);
1164
- if (isRuntimePromise(maybePromise)) {
1165
- return markAsRuntimePromise(maybePromise.catch((err) => {
1166
- if (!(err instanceof RanOutOfEnergyError)) {
1167
- throw err;
1168
- }
1169
- else {
1170
- console.warn(err);
1171
- }
1172
- }));
1173
- }
1174
- }
1175
- }
1176
- catch (err) {
1177
- if (!(err instanceof RanOutOfEnergyError)) {
1178
- throw err;
1179
- }
1180
- else {
1181
- console.warn(err);
1182
- }
1183
- }
1184
- }
1185
- }
1186
- _sendOnBotsChangedShouts(updates) {
1187
- if (updates && updates.length > 0) {
1188
- try {
1189
- let promise = processListOfMaybePromises(null, updates, (update) => {
1190
- if (!update) {
1191
- return;
1192
- }
1193
- let promise = this._synchronousShout(ON_BOT_CHANGED_ACTION_NAME, [update.bot.id], {
1194
- tags: update.tags,
1195
- }, true, false);
1196
- const watchers = this._globalContext.getWatchersForBot(update.bot.id);
1197
- return processListOfMaybePromises(promise, watchers, (watcher) => {
1198
- const generator = watcher.handler();
1199
- if (isGenerator(generator)) {
1200
- return this._processGenerator(generator);
1201
- }
1202
- return generator;
1203
- });
1204
- });
1205
- if (isPromise(promise)) {
1206
- return promise
1207
- .then(() => {
1208
- return this._synchronousShout(ON_ANY_BOTS_CHANGED_ACTION_NAME, null, updates, true, false);
1209
- })
1210
- .catch((err) => {
1211
- if (!(err instanceof RanOutOfEnergyError)) {
1212
- throw err;
1213
- }
1214
- else {
1215
- console.warn(err);
1216
- }
1217
- });
1218
- }
1219
- else {
1220
- const maybePromise = this._synchronousShout(ON_ANY_BOTS_CHANGED_ACTION_NAME, null, updates, true, false);
1221
- if (isPromise(maybePromise)) {
1222
- return maybePromise.catch((err) => {
1223
- if (!(err instanceof RanOutOfEnergyError)) {
1224
- throw err;
1225
- }
1226
- else {
1227
- console.warn(err);
1228
- }
1229
- });
1230
- }
1231
- else {
1232
- return maybePromise;
1233
- }
1234
- }
1235
- }
1236
- catch (err) {
1237
- if (!(err instanceof RanOutOfEnergyError)) {
1238
- throw err;
1239
- }
1240
- else {
1241
- console.warn(err);
1242
- }
1243
- }
1244
- }
1245
- }
1246
- _triggerPortalChangedHandlers(newBots, removedBots, updates) {
1247
- const portals = this._globalContext.getWatchedPortals();
1248
- if (!hasValue(this.userId)) {
1249
- return;
1250
- }
1251
- if (portals.size <= 0) {
1252
- return;
1253
- }
1254
- if ((!newBots || newBots.length <= 0) &&
1255
- (!removedBots || removedBots.length <= 0) &&
1256
- (!updates || updates.length <= 0)) {
1257
- return;
1258
- }
1259
- const userBot = this.currentState[this.userId];
1260
- if (!userBot) {
1261
- return;
1262
- }
1263
- return processListOfMaybePromises(null, portals, (portal) => {
1264
- const dimension = userBot.values[portal];
1265
- let hasChange = false;
1266
- if (hasValue(dimension)) {
1267
- if (newBots && newBots.length > 0) {
1268
- for (let [_, newBot] of newBots) {
1269
- if (isBotInDimension(null, newBot, dimension)) {
1270
- hasChange = true;
1271
- break;
1272
- }
1273
- }
1274
- }
1275
- if (!hasChange && removedBots && removedBots.length > 0) {
1276
- for (let bot of removedBots) {
1277
- if (bot) {
1278
- if (isBotInDimension(null, bot, dimension)) {
1279
- hasChange = true;
1280
- break;
1281
- }
1282
- }
1283
- }
1284
- }
1285
- }
1286
- if (!hasChange && updates && updates.length > 0) {
1287
- for (let update of updates) {
1288
- if (hasValue(dimension)) {
1289
- if (update.tags.includes(dimension)) {
1290
- hasChange = true;
1291
- break;
1292
- }
1293
- }
1294
- if (update.bot.id === this.userId &&
1295
- update.tags.includes(portal)) {
1296
- hasChange = true;
1297
- break;
1298
- }
1299
- if (this._portalBots.get(portal) === update.bot.id) {
1300
- hasChange = true;
1301
- break;
1302
- }
1303
- }
1304
- }
1305
- if (hasChange) {
1306
- const watchers = this._globalContext.getWatchersForPortal(portal);
1307
- return processListOfMaybePromises(null, watchers, (watcher) => {
1308
- const generator = watcher.handler();
1309
- if (isGenerator(generator)) {
1310
- return this._processGenerator(generator);
1311
- }
1312
- });
1313
- }
1314
- });
1315
- }
1316
- _addBotsToState(bots, nextUpdate) {
1317
- var _a;
1318
- let newBots = [];
1319
- let newBotIDs = new Set();
1320
- for (let bot of bots) {
1321
- const existing = this._compiledState[bot.id];
1322
- if (!!existing) {
1323
- removeFromContext(this._globalContext, [existing.script], false);
1324
- delete this._compiledState[bot.id];
1325
- const index = newBots.findIndex(([b]) => b === existing);
1326
- if (index >= 0) {
1327
- newBots.splice(index, 1);
1328
- nextUpdate.addedBots.splice(index, 1);
1329
- }
1330
- }
1331
- let newBot = this._createCompiledBot(bot, false);
1332
- if (!!existing) {
1333
- const changes = existing.script.changes;
1334
- const maskChanges = existing.script.maskChanges;
1335
- for (let key in changes) {
1336
- newBot.tags[key] =
1337
- newBot.values[key] =
1338
- newBot.script.changes[key] =
1339
- changes[key];
1340
- }
1341
- let maskTags = new Set();
1342
- for (let space of TAG_MASK_SPACE_PRIORITIES) {
1343
- const masks = maskChanges[space];
1344
- let newMasks;
1345
- let addNewMasks = false;
1346
- let hasNewMasks = false;
1347
- if (!((_a = newBot === null || newBot === void 0 ? void 0 : newBot.masks) === null || _a === void 0 ? void 0 : _a[space])) {
1348
- addNewMasks = true;
1349
- newMasks = {};
1350
- }
1351
- else {
1352
- newMasks = newBot.masks[space];
1353
- }
1354
- if (masks) {
1355
- if (!newBot.script.maskChanges[space]) {
1356
- newBot.script.maskChanges[space] = {};
1357
- }
1358
- for (let key in masks) {
1359
- hasNewMasks = true;
1360
- maskTags.add(key);
1361
- const value = (newMasks[key] =
1362
- newBot.script.maskChanges[space][key] =
1363
- masks[key]);
1364
- if (!maskTags.has(key)) {
1365
- newBot.values[key] = value;
1366
- }
1367
- }
1368
- }
1369
- if (addNewMasks && hasNewMasks) {
1370
- if (!newBot.masks) {
1371
- newBot.masks = {};
1372
- }
1373
- newBot.masks[space] = newMasks;
1374
- }
1375
- }
1376
- existing.script[REPLACE_BOT_SYMBOL](newBot.script);
1377
- }
1378
- let precalculated = {
1379
- id: bot.id,
1380
- precalculated: true,
1381
- tags: bot.tags,
1382
- values: {},
1383
- };
1384
- if (hasValue(bot.space)) {
1385
- newBot.space = bot.space;
1386
- precalculated.space = bot.space;
1387
- }
1388
- if (hasValue(bot.signatures)) {
1389
- precalculated.signatures = bot.signatures;
1390
- }
1391
- if (hasValue(newBot.masks)) {
1392
- precalculated.masks = newBot.masks;
1393
- }
1394
- newBots.push([newBot, precalculated]);
1395
- newBotIDs.add(newBot.id);
1396
- nextUpdate.state[bot.id] = precalculated;
1397
- nextUpdate.addedBots.push(bot.id);
1398
- }
1399
- for (let [bot, precalculated] of newBots) {
1400
- let tags = Object.keys(bot.values);
1401
- for (let tag of tags) {
1402
- precalculated.values[tag] = convertToCopiableValue(bot.values[tag]);
1403
- }
1404
- }
1405
- return {
1406
- newBotIDs,
1407
- newBots,
1408
- };
1409
- }
1410
- _removeBotsFromState(botIds, nextUpdate) {
1411
- let removedBots = [];
1412
- for (let id of botIds) {
1413
- const bot = this._compiledState[id];
1414
- if (bot) {
1415
- removeFromContext(this._globalContext, [bot.script]);
1416
- for (let breakpoint of bot.breakpoints) {
1417
- this._interpreter.removeBreakpointById(breakpoint.id);
1418
- this._breakpoints.delete(breakpoint.id);
1419
- }
1420
- }
1421
- removedBots.push(bot);
1422
- delete this._compiledState[id];
1423
- const list = this._getFunctionNamesForBot(id, false);
1424
- if (list) {
1425
- for (let name of list) {
1426
- this._functionMap.delete(name);
1427
- }
1428
- this._botFunctionMap.delete(id);
1429
- }
1430
- nextUpdate.state[id] = null;
1431
- nextUpdate.removedBots.push(id);
1432
- }
1433
- return removedBots;
1434
- }
1435
- _updateBotsWithState(update, updates, nextUpdate, newBotIds) {
1436
- var _a, _b;
1437
- for (let id of update.updatedBots) {
1438
- if (!id) {
1439
- continue;
1440
- }
1441
- const u = update.state[id];
1442
- // 1. get compiled bot
1443
- let compiled = this._compiledState[id];
1444
- if (!compiled) {
1445
- // buffer tag masks
1446
- if (u.masks) {
1447
- const existing = this._existingMasks[id] || {};
1448
- this._existingMasks[id] = merge(existing, u.masks);
1449
- }
1450
- continue;
1451
- }
1452
- let partial = {
1453
- tags: {},
1454
- values: {},
1455
- };
1456
- let updatedTags = new Set();
1457
- if (u.tags) {
1458
- for (let tag in u.tags) {
1459
- const tagValue = u.tags[tag];
1460
- if (hasValue(tagValue) || tagValue === null) {
1461
- if (isTagEdit(tagValue)) {
1462
- const originalValue = tag in compiled.originalTagEditValues
1463
- ? compiled.originalTagEditValues[tag]
1464
- : compiled.tags[tag];
1465
- compiled.tags[tag] = applyTagEdit(originalValue, tagValue);
1466
- }
1467
- else {
1468
- compiled.tags[tag] = tagValue;
1469
- }
1470
- delete compiled.originalTagEditValues[tag];
1471
- partial.tags[tag] = tagValue;
1472
- updatedTags.add(tag);
1473
- }
1474
- }
1475
- }
1476
- if (u.masks) {
1477
- for (let space in u.masks) {
1478
- const tags = u.masks[space];
1479
- for (let tag in tags) {
1480
- const tagValue = u.masks[space][tag];
1481
- if (hasValue(tagValue) || tagValue === null) {
1482
- if (!compiled.masks) {
1483
- compiled.masks = {};
1484
- }
1485
- if (!compiled.masks[space]) {
1486
- compiled.masks[space] = {};
1487
- }
1488
- if (!partial.masks) {
1489
- partial.masks = {};
1490
- }
1491
- if (!partial.masks[space]) {
1492
- partial.masks[space] = {};
1493
- }
1494
- if (tagValue === null) {
1495
- delete compiled.masks[space][tag];
1496
- }
1497
- else if (isTagEdit(tagValue)) {
1498
- const originalValue = compiled.originalTagMaskEditValues[space] &&
1499
- tag in
1500
- compiled.originalTagMaskEditValues[space]
1501
- ? compiled.originalTagMaskEditValues[space][tag]
1502
- : compiled.masks[space][tag];
1503
- compiled.masks[space][tag] = applyTagEdit(originalValue, tagValue);
1504
- }
1505
- else {
1506
- compiled.masks[space][tag] = tagValue;
1507
- }
1508
- (_a = compiled.originalTagMaskEditValues[space]) === null || _a === void 0 ? true : delete _a[tag];
1509
- updatedTags.add(tag);
1510
- partial.masks[space][tag] = tagValue;
1511
- }
1512
- }
1513
- }
1514
- }
1515
- for (let tag of updatedTags) {
1516
- let hasTag = false;
1517
- if (compiled.masks) {
1518
- for (let space of TAG_MASK_SPACE_PRIORITIES) {
1519
- const tagValue = (_b = compiled.masks[space]) === null || _b === void 0 ? void 0 : _b[tag];
1520
- if (hasValue(tagValue)) {
1521
- this._compileTagValue(compiled, tag, tagValue);
1522
- hasTag = true;
1523
- break;
1524
- }
1525
- }
1526
- }
1527
- if (!hasTag) {
1528
- const tagValue = compiled.tags[tag];
1529
- if (hasValue(tagValue) || tagValue === null) {
1530
- this._compileTagValue(compiled, tag, tagValue);
1531
- hasTag = true;
1532
- }
1533
- }
1534
- if (!hasTag) {
1535
- // no tag or tag mask has a value
1536
- this._compileTagValue(compiled, tag, null);
1537
- }
1538
- const compiledValue = compiled.values[tag];
1539
- partial.values[tag] = convertToCopiableValue(hasValue(compiledValue) ? compiledValue : null);
1540
- }
1541
- for (let breakpoint of compiled.breakpoints) {
1542
- if (updatedTags.has(breakpoint.tag)) {
1543
- // Update the breakpoint
1544
- const func = compiled.listeners[breakpoint.tag];
1545
- if (func) {
1546
- this._compiler.setBreakpoint({
1547
- id: breakpoint.id,
1548
- func: func,
1549
- interpreter: this._interpreter,
1550
- lineNumber: breakpoint.lineNumber,
1551
- columnNumber: breakpoint.columnNumber,
1552
- states: breakpoint.states,
1553
- });
1554
- }
1555
- else {
1556
- this._interpreter.removeBreakpointById(breakpoint.id);
1557
- }
1558
- }
1559
- }
1560
- if (u.signatures) {
1561
- if (!compiled.signatures) {
1562
- compiled.signatures = {};
1563
- }
1564
- partial.signatures = {};
1565
- for (let sig in u.signatures) {
1566
- const val = !!u.signatures
1567
- ? u.signatures[sig] || null
1568
- : null;
1569
- const current = compiled.signatures[sig];
1570
- compiled.signatures[sig] = val;
1571
- partial.signatures[sig] = val;
1572
- if (!val && current) {
1573
- this._compileTag(compiled, current, compiled.tags[current]);
1574
- }
1575
- else if (val && !current) {
1576
- this._compileTag(compiled, val, compiled.tags[val]);
1577
- }
1578
- }
1579
- }
1580
- nextUpdate.state[id] = partial;
1581
- if (!newBotIds.has(id)) {
1582
- nextUpdate.updatedBots.push(id);
1583
- }
1584
- }
1585
- }
1586
- notifyChange() {
1587
- if (!this._batchPending && this._autoBatch) {
1588
- this._batchPending = true;
1589
- if (this.canTriggerBreakpoint) {
1590
- this._scheduleJob('notifyChange', () => {
1591
- this._processBatch();
1592
- });
1593
- return;
1594
- }
1595
- queueMicrotask(() => {
1596
- this._processBatch();
1597
- });
1598
- }
1599
- }
1600
- notifyActionEnqueued(action) {
1601
- if (this._scriptActionEnqueuedListeners.length > 0) {
1602
- for (let listener of this._scriptActionEnqueuedListeners) {
1603
- try {
1604
- listener(action);
1605
- }
1606
- catch (err) {
1607
- console.error(err);
1608
- }
1609
- }
1610
- }
1611
- }
1612
- createRuntimeBot(bot) {
1613
- const space = getBotSpace(bot);
1614
- const mode = this._editModeProvider.getEditMode(space);
1615
- if (mode === RealtimeEditMode.Immediate) {
1616
- const compiled = this._createCompiledBot(bot, true);
1617
- this._newBots.set(bot.id, bot);
1618
- return compiled.script;
1619
- }
1620
- return null;
1621
- }
1622
- destroyScriptBot(bot) {
1623
- const space = getBotSpace(bot);
1624
- const mode = this._editModeProvider.getEditMode(space);
1625
- if (mode === RealtimeEditMode.Immediate) {
1626
- delete this._compiledState[bot.id];
1627
- }
1628
- return mode;
1629
- }
1630
- _processBatch() {
1631
- this._batchPending = false;
1632
- // Send the batch once all the micro tasks are completed
1633
- // Grab any unbatched actions and errors.
1634
- // This can happen if an action is queued during a callback
1635
- // or promise.
1636
- const unbatchedActions = this._processUnbatchedActions();
1637
- const unbatchedErrors = this._processUnbatchedErrors();
1638
- const actions = this._actionBatch;
1639
- const errors = this._errorBatch;
1640
- this._processCore(unbatchedActions);
1641
- errors.push(...unbatchedErrors);
1642
- this._actionBatch = [];
1643
- this._errorBatch = [];
1644
- if (actions.length <= 0 && errors.length <= 0) {
1645
- return;
1646
- }
1647
- // Schedule a new micro task to
1648
- // run at a later time with the actions.
1649
- // This ensures that we don't block other flush operations
1650
- // due to handlers running synchronously.
1651
- queueMicrotask(() => {
1652
- this._onActions.next(actions);
1653
- this._onErrors.next(errors);
1654
- });
1655
- this._processErrors(errors);
1656
- }
1657
- _processErrors(errors) {
1658
- if (this._processingErrors) {
1659
- return;
1660
- }
1661
- try {
1662
- this._processingErrors = true;
1663
- if (errors.length > 0) {
1664
- const actions = [];
1665
- for (let e of errors) {
1666
- if (e.tag === ON_ERROR) {
1667
- continue;
1668
- }
1669
- if (e.bot && e.tag) {
1670
- const b = this._compiledState[e.bot.id];
1671
- if (b) {
1672
- let currentCount = b.errorCounts[e.tag] || 0;
1673
- if (currentCount === this.repeatedErrorLimit) {
1674
- console.warn(`[AuxRuntime] Repeated error limit reached for tag on bot: ${e.bot.id}.${e.tag}`);
1675
- console.warn(`[AuxRuntime] If this happens, then there is likely a bug in your inst that causes @onError and @${e.tag} to call each other infinitely.`);
1676
- }
1677
- currentCount = b.errorCounts[e.tag] =
1678
- currentCount + 1;
1679
- if (currentCount > this.repeatedErrorLimit) {
1680
- continue;
1681
- }
1682
- }
1683
- }
1684
- actions.push(action(ON_ERROR, undefined, undefined, {
1685
- bot: e.bot,
1686
- tag: e.tag,
1687
- error: e.error,
1688
- }));
1689
- }
1690
- this.process(actions);
1691
- }
1692
- }
1693
- finally {
1694
- this._processingErrors = false;
1695
- }
1696
- }
1697
- _batchScriptResults(callback, batch, resetEnergy) {
1698
- const result = this._calculateScriptResults(callback, resetEnergy);
1699
- if (isRuntimePromise(result)) {
1700
- return markAsRuntimePromise(result.then((results) => {
1701
- if (batch) {
1702
- this._actionBatch.push(...results.actions);
1703
- this.notifyChange();
1704
- }
1705
- this._errorBatch.push(...results.errors);
1706
- return results;
1707
- }));
1708
- }
1709
- if (batch) {
1710
- this._actionBatch.push(...result.actions);
1711
- }
1712
- this._errorBatch.push(...result.errors);
1713
- return result;
1714
- }
1715
- _calculateScriptResults(callback, resetEnergy) {
1716
- this._globalContext.playerBot = this.userBot;
1717
- if (resetEnergy) {
1718
- this._globalContext.energy = DEFAULT_ENERGY;
1719
- }
1720
- const result = callback();
1721
- if (isRuntimePromise(result)) {
1722
- return markAsRuntimePromise(result.then((results) => {
1723
- const actions = this._processUnbatchedActions();
1724
- const errors = this._processUnbatchedErrors();
1725
- return {
1726
- result: results,
1727
- actions: actions,
1728
- errors: errors,
1729
- };
1730
- }));
1731
- }
1732
- const actions = this._processUnbatchedActions();
1733
- const errors = this._processUnbatchedErrors();
1734
- return {
1735
- result: result,
1736
- actions: actions,
1737
- errors: errors,
1738
- };
1739
- }
1740
- _processUnbatchedErrors() {
1741
- // TODO: Improve to correctly handle when a non ScriptError object is added
1742
- // but contains symbol properties that reference the throwing bot and tag.
1743
- // The AuxRuntime should look for these error objects and create ScriptErrors for them.
1744
- return this._globalContext.dequeueErrors();
1745
- }
1746
- _processUnbatchedActions() {
1747
- const actions = this._globalContext.dequeueActions();
1748
- const updatedBots = [...this._updatedBots.values()];
1749
- for (let action of actions) {
1750
- if (action.type === 'add_bot') {
1751
- if (this._newBots.has(action.id)) {
1752
- action.bot.tags = Object.assign({}, action.bot.tags);
1753
- }
1754
- }
1755
- }
1756
- let updates = [];
1757
- for (let bot of updatedBots) {
1758
- const hasTagChange = Object.keys(bot.changes).length > 0;
1759
- const hasMaskChange = Object.keys(bot.maskChanges).length > 0;
1760
- const hasChange = hasTagChange || hasMaskChange;
1761
- if (hasChange) {
1762
- const isNewBot = this._newBots.has(bot.id);
1763
- if (isNewBot) {
1764
- // tag mask changes need to be handled here
1765
- // because new bots don't share the same reference to the
1766
- // bot in the add bot event (unlike normal bots)
1767
- if (hasMaskChange) {
1768
- const newBot = this._newBots.get(bot.id);
1769
- newBot.masks = {};
1770
- for (let space in bot.maskChanges) {
1771
- newBot.masks[space] = Object.assign({}, bot.maskChanges[space]);
1772
- }
1773
- }
1774
- }
1775
- else {
1776
- if (isInContext(this._globalContext, bot)) {
1777
- let update = {};
1778
- if (hasTagChange) {
1779
- update.tags = Object.assign({}, bot.changes);
1780
- }
1781
- if (hasMaskChange) {
1782
- update.masks = {};
1783
- for (let space in bot.maskChanges) {
1784
- update.masks[space] = Object.assign({}, bot.maskChanges[space]);
1785
- }
1786
- }
1787
- updates.push(botUpdated(bot.id, update));
1788
- }
1789
- }
1790
- }
1791
- }
1792
- for (let bot of updatedBots) {
1793
- bot[CLEAR_CHANGES_SYMBOL]();
1794
- }
1795
- const sortedUpdates = sortBy(updates, (u) => u.id);
1796
- this._updatedBots.clear();
1797
- this._newBots.clear();
1798
- actions.push(...sortedUpdates);
1799
- return actions;
1800
- }
1801
- _compileTags(tags, compiled, bot) {
1802
- let updates = [];
1803
- for (let tag of tags) {
1804
- updates.push(this._compileTagOrMask(compiled, bot, tag));
1805
- }
1806
- return updates;
1807
- }
1808
- _createCompiledBot(bot, fromFactory) {
1809
- var _a, _b;
1810
- let compiledBot = {
1811
- id: bot.id,
1812
- precalculated: true,
1813
- tags: fromFactory ? bot.tags : Object.assign({}, bot.tags),
1814
- listeners: {},
1815
- values: {},
1816
- script: null,
1817
- originalTagEditValues: {},
1818
- originalTagMaskEditValues: {},
1819
- breakpoints: [],
1820
- errorCounts: {},
1821
- };
1822
- if (BOT_SPACE_TAG in bot) {
1823
- compiledBot.space = bot.space;
1824
- }
1825
- if (hasValue(bot.signatures)) {
1826
- compiledBot.signatures = bot.signatures;
1827
- }
1828
- // Copy existing tag masks to the new bot
1829
- if (!fromFactory && this._existingMasks[bot.id]) {
1830
- const existing = this._existingMasks[bot.id];
1831
- delete this._existingMasks[bot.id];
1832
- for (let space in existing) {
1833
- if (!bot.masks) {
1834
- bot.masks = {};
1835
- }
1836
- for (let tag in existing[space]) {
1837
- if (hasValue((_b = (_a = bot.masks) === null || _a === void 0 ? void 0 : _a[space]) === null || _b === void 0 ? void 0 : _b[tag])) {
1838
- continue;
1839
- }
1840
- if (!bot.masks[space]) {
1841
- bot.masks[space] = {};
1842
- }
1843
- bot.masks[space][tag] = existing[space][tag];
1844
- }
1845
- }
1846
- }
1847
- // Copy the new bot tag masks to the compiled bot
1848
- if (hasValue(bot.masks)) {
1849
- compiledBot.masks = {};
1850
- for (let space in bot.masks) {
1851
- compiledBot.masks[space] = Object.assign({}, bot.masks[space]);
1852
- }
1853
- }
1854
- compiledBot.script = this._createRuntimeBot(compiledBot);
1855
- const tags = tagsOnBot(compiledBot);
1856
- this._compileTags(tags, compiledBot, bot);
1857
- if (!fromFactory) {
1858
- addToContext(this._globalContext, compiledBot.script);
1859
- }
1860
- this._compiledState[bot.id] = compiledBot;
1861
- return compiledBot;
1862
- }
1863
- _createRuntimeBot(bot) {
1864
- return createRuntimeBot(bot, this);
1865
- }
1866
- updateTag(bot, tag, newValue) {
1867
- if (isRuntimeBot(newValue)) {
1868
- throw new Error(`It is not possible to save bots as tag values. (Setting '${tag}' on ${bot.id})`);
1869
- }
1870
- const oldValue = bot.values[tag];
1871
- const space = getBotSpace(bot);
1872
- const mode = this._editModeProvider.getEditMode(space);
1873
- if (mode === RealtimeEditMode.Immediate) {
1874
- this._compileTag(bot, tag, newValue);
1875
- }
1876
- this._updatedBots.set(bot.id, bot.script);
1877
- this.notifyChange();
1878
- if (newValue instanceof DateTime) {
1879
- newValue = formatBotDate(newValue);
1880
- }
1881
- else if (newValue instanceof Vector2 || newValue instanceof Vector3) {
1882
- newValue = formatBotVector(newValue);
1883
- }
1884
- else if (newValue instanceof Rotation) {
1885
- newValue = formatBotRotation(newValue);
1886
- }
1887
- if (this._scriptUpdatedTagListeners.length > 0) {
1888
- for (let listener of this._scriptUpdatedTagListeners) {
1889
- try {
1890
- listener({
1891
- botId: bot.id,
1892
- tag,
1893
- oldValue,
1894
- newValue,
1895
- });
1896
- }
1897
- catch (err) {
1898
- console.error(err);
1899
- }
1900
- }
1901
- }
1902
- return {
1903
- mode,
1904
- changedValue: newValue,
1905
- };
1906
- }
1907
- getValue(bot, tag) {
1908
- return bot.values[tag];
1909
- }
1910
- getRawValue(bot, tag) {
1911
- return bot.tags[tag];
1912
- }
1913
- updateTagMask(bot, tag, spaces, value) {
1914
- if (isRuntimeBot(value)) {
1915
- throw new Error(`It is not possible to save bots as tag values. (Setting '${tag}' on ${bot.id})`);
1916
- }
1917
- let oldValuesAndSpaces = [];
1918
- let updated = false;
1919
- for (let space of spaces) {
1920
- const mode = this._editModeProvider.getEditMode(space);
1921
- if (mode === RealtimeEditMode.Immediate) {
1922
- if (!bot.masks) {
1923
- bot.masks = {};
1924
- }
1925
- if (!bot.masks[space]) {
1926
- bot.masks[space] = {};
1927
- }
1928
- let oldValue = bot.masks[space][tag];
1929
- if (isTagEdit(value)) {
1930
- if (!bot.originalTagMaskEditValues[space]) {
1931
- bot.originalTagMaskEditValues[space] = {};
1932
- }
1933
- if (!(tag in bot.originalTagMaskEditValues[space])) {
1934
- bot.originalTagMaskEditValues[space][tag] =
1935
- bot.masks[space][tag];
1936
- }
1937
- bot.masks[space][tag] = applyTagEdit(bot.masks[space][tag], value);
1938
- }
1939
- else {
1940
- bot.masks[space][tag] = value;
1941
- }
1942
- updated = true;
1943
- oldValuesAndSpaces.push({
1944
- space,
1945
- oldValue,
1946
- });
1947
- }
1948
- }
1949
- if (updated) {
1950
- this._compileTagOrMask(bot, bot, tag);
1951
- this._updatedBots.set(bot.id, bot.script);
1952
- this.notifyChange();
1953
- }
1954
- if (value instanceof DateTime) {
1955
- value = formatBotDate(value);
1956
- }
1957
- else if (value instanceof Vector2 || value instanceof Vector3) {
1958
- value = formatBotVector(value);
1959
- }
1960
- else if (value instanceof Rotation) {
1961
- value = formatBotRotation(value);
1962
- }
1963
- if (updated && this._scriptUpdatedTagMaskListeners.length > 0) {
1964
- for (let listener of this._scriptUpdatedTagMaskListeners) {
1965
- for (let { oldValue, space } of oldValuesAndSpaces) {
1966
- try {
1967
- listener({
1968
- botId: bot.id,
1969
- tag,
1970
- oldValue,
1971
- newValue: value,
1972
- space,
1973
- });
1974
- }
1975
- catch (err) {
1976
- console.error(err);
1977
- }
1978
- }
1979
- }
1980
- }
1981
- return {
1982
- mode: RealtimeEditMode.Immediate,
1983
- changedValue: value,
1984
- };
1985
- }
1986
- getTagMask(bot, tag) {
1987
- var _a, _b;
1988
- for (let space of TAG_MASK_SPACE_PRIORITIES) {
1989
- const tagValue = (_b = (_a = bot.masks) === null || _a === void 0 ? void 0 : _a[space]) === null || _b === void 0 ? void 0 : _b[tag];
1990
- if (hasValue(tagValue)) {
1991
- return this._compileTagMaskValue(bot, tag, space, tagValue);
1992
- }
1993
- }
1994
- return undefined;
1995
- }
1996
- getListener(bot, tag) {
1997
- const listener = bot.listeners[tag];
1998
- if (listener) {
1999
- return listener;
2000
- }
2001
- this.getValue(bot, tag);
2002
- return bot.listeners[tag] || null;
2003
- }
2004
- getTagLink(bot, tag) {
2005
- const tagValue = bot.values[tag];
2006
- if (isBotLink(tagValue)) {
2007
- const links = parseBotLink(tagValue);
2008
- const bots = links.map((link) => this.context.state[link] || null);
2009
- if (bots.length === 1) {
2010
- return bots[0];
2011
- }
2012
- return bots;
2013
- }
2014
- return undefined;
2015
- }
2016
- getSignature(bot, signature) {
2017
- return !!bot.signatures ? bot.signatures[signature] : undefined;
2018
- }
2019
- _compileTagOrMask(bot, existingBot, tag) {
2020
- var _a, _b, _c;
2021
- let hadMask = false;
2022
- if (existingBot.masks) {
2023
- for (let space of TAG_MASK_SPACE_PRIORITIES) {
2024
- const tagValue = (_a = existingBot.masks[space]) === null || _a === void 0 ? void 0 : _a[tag];
2025
- if (hasValue(tagValue)) {
2026
- if (!bot.masks) {
2027
- bot.masks = {};
2028
- }
2029
- if (!bot.masks[space]) {
2030
- bot.masks[space] = {};
2031
- }
2032
- bot.masks[space][tag] = tagValue;
2033
- this._compileTagValue(bot, tag, tagValue);
2034
- return [space, tag];
2035
- }
2036
- else if (hasValue((_c = (_b = bot.masks) === null || _b === void 0 ? void 0 : _b[space]) === null || _c === void 0 ? void 0 : _c[tag])) {
2037
- // Indicate that there used to be a value for the tag mask
2038
- // but it has been removed.
2039
- hadMask = true;
2040
- break;
2041
- }
2042
- }
2043
- }
2044
- const tagValue = existingBot.tags[tag];
2045
- if (hasValue(tagValue) || tagValue === null) {
2046
- bot.tags[tag] = tagValue;
2047
- this._compileTagValue(bot, tag, tagValue);
2048
- if (hadMask) {
2049
- return [undefined, tag];
2050
- }
2051
- else {
2052
- return [null, tag];
2053
- }
2054
- }
2055
- // Undefined means that a tag mask was removed.
2056
- return [undefined, tag];
2057
- }
2058
- _compileTag(bot, tag, tagValue) {
2059
- var _a;
2060
- if (bot.masks) {
2061
- for (let space of TAG_MASK_SPACE_PRIORITIES) {
2062
- if (hasValue((_a = bot.masks[space]) === null || _a === void 0 ? void 0 : _a[tag])) {
2063
- return;
2064
- }
2065
- }
2066
- }
2067
- if (isTagEdit(tagValue)) {
2068
- if (!(tag in bot.originalTagEditValues)) {
2069
- bot.originalTagEditValues[tag] = bot.tags[tag];
2070
- }
2071
- tagValue = bot.tags[tag] = applyTagEdit(bot.tags[tag], tagValue);
2072
- }
2073
- else {
2074
- if (tag in bot.originalTagEditValues) {
2075
- delete bot.originalTagEditValues[tag];
2076
- }
2077
- if (hasValue(tagValue)) {
2078
- if (this._newBots.has(bot.id) &&
2079
- (tagValue instanceof DateTime ||
2080
- tagValue instanceof Vector2 ||
2081
- tagValue instanceof Vector3 ||
2082
- tagValue instanceof Rotation)) {
2083
- bot.tags[tag] = convertToCopiableValue(tagValue);
2084
- }
2085
- else {
2086
- bot.tags[tag] = tagValue;
2087
- }
2088
- }
2089
- else {
2090
- delete bot.tags[tag];
2091
- }
2092
- }
2093
- this._compileTagValue(bot, tag, tagValue);
2094
- }
2095
- _compileTagValue(bot, tag, tagValue) {
2096
- let { value, listener } = this._compileValue(bot, tag, tagValue);
2097
- if (listener) {
2098
- bot.listeners[tag] = listener;
2099
- this._globalContext.recordListenerPresense(bot.id, tag, true);
2100
- }
2101
- else if (!!bot.listeners[tag]) {
2102
- delete bot.listeners[tag];
2103
- this._globalContext.recordListenerPresense(bot.id, tag, false);
2104
- }
2105
- if (typeof value !== 'function') {
2106
- if (hasValue(value)) {
2107
- bot.values[tag] = value;
2108
- }
2109
- else {
2110
- delete bot.values[tag];
2111
- }
2112
- }
2113
- return value;
2114
- }
2115
- _compileValue(bot, tag, value) {
2116
- let listener;
2117
- if (isFormula(value)) {
2118
- const parsed = value.substring(DNA_TAG_PREFIX.length);
2119
- const transformed = replaceMacros(parsed);
2120
- try {
2121
- value = JSON.parse(transformed);
2122
- }
2123
- catch (ex) {
2124
- value = ex;
2125
- }
2126
- }
2127
- else if (isScript(value)) {
2128
- try {
2129
- listener = this._compile(bot, tag, value, {});
2130
- }
2131
- catch (ex) {
2132
- value = ex;
2133
- }
2134
- }
2135
- else if (isTaggedString(value)) {
2136
- value = parseTaggedString(value);
2137
- }
2138
- else if (isNumber(value)) {
2139
- value = parseNumber(value);
2140
- }
2141
- else if (isTaggedNumber(value)) {
2142
- // Tagged numbers that are not valid numbers
2143
- // should always be NaN.
2144
- value = NaN;
2145
- }
2146
- else if (value === 'true') {
2147
- value = true;
2148
- }
2149
- else if (value === 'false') {
2150
- value = false;
2151
- }
2152
- else if (isBotDate(value)) {
2153
- const result = parseBotDate(value);
2154
- if (result) {
2155
- value = result;
2156
- }
2157
- }
2158
- else if (isBotVector(value)) {
2159
- const result = parseBotVector(value);
2160
- if (result) {
2161
- value = result;
2162
- }
2163
- }
2164
- else if (isBotRotation(value)) {
2165
- const result = parseBotRotation(value);
2166
- if (result) {
2167
- value = result;
2168
- }
2169
- }
2170
- return { value, listener };
2171
- }
2172
- _compileTagMaskValue(bot, tag, space, value) {
2173
- let changedValue = false;
2174
- let newValue = value;
2175
- if (isFormula(value)) {
2176
- const parsed = value.substring(DNA_TAG_PREFIX.length);
2177
- const transformed = replaceMacros(parsed);
2178
- try {
2179
- newValue = JSON.parse(transformed);
2180
- changedValue = true;
2181
- }
2182
- catch (ex) {
2183
- newValue = ex;
2184
- }
2185
- }
2186
- if (isTaggedString(value)) {
2187
- newValue = parseTaggedString(value);
2188
- changedValue = true;
2189
- }
2190
- else if (isTaggedNumber(value)) {
2191
- const parsed = parseTaggedNumber(value);
2192
- if (isNumber(parsed)) {
2193
- newValue = parseNumber(parsed);
2194
- changedValue = true;
2195
- }
2196
- }
2197
- else if (isBotDate(value)) {
2198
- const result = parseBotDate(value);
2199
- if (result) {
2200
- newValue = result;
2201
- changedValue = true;
2202
- }
2203
- }
2204
- else if (isBotVector(value)) {
2205
- const result = parseBotVector(value);
2206
- if (result) {
2207
- newValue = result;
2208
- changedValue = true;
2209
- }
2210
- }
2211
- else if (isBotRotation(value)) {
2212
- const result = parseBotRotation(value);
2213
- if (result) {
2214
- newValue = result;
2215
- changedValue = true;
2216
- }
2217
- }
2218
- if (changedValue) {
2219
- bot.masks[space][tag] = newValue;
2220
- return newValue;
2221
- }
2222
- else {
2223
- return value;
2224
- }
2225
- }
2226
- _compile(bot, tag, script, options) {
2227
- if (this._forceSignedScripts) {
2228
- if (this._exemptSpaces.indexOf(bot.space) < 0) {
2229
- const hash = tagValueHash(bot.id, tag, script);
2230
- if (!bot.signatures || bot.signatures[hash] !== tag) {
2231
- throw new Error('Unable to compile script. It is not signed with a valid certificate.');
2232
- }
2233
- }
2234
- }
2235
- script = replaceMacros(script);
2236
- let functionName;
2237
- let diagnosticFunctionName;
2238
- let fileName;
2239
- if (hasValue(bot)) {
2240
- this._functionNameCounter += 1;
2241
- functionName = '_' + this._functionNameCounter;
2242
- diagnosticFunctionName = tag;
2243
- fileName = `${bot.id}.${diagnosticFunctionName}`;
2244
- }
2245
- const constants = Object.assign(Object.assign({}, this._library.api), { tagName: tag, globalThis: this._globalObject });
2246
- const specifics = Object.assign({}, this._library.tagSpecificApi);
2247
- if (this._interpreter) {
2248
- delete constants.globalThis;
2249
- // if (this.canTriggerBreakpoint) {
2250
- Object.assign(constants, this._interpretedApi);
2251
- Object.assign(specifics, this._interpretedTagSpecificApi);
2252
- // }
2253
- }
2254
- const func = this._compiler.compile(script, {
2255
- // TODO: Support all the weird features
2256
- functionName: functionName,
2257
- diagnosticFunctionName: diagnosticFunctionName,
2258
- fileName: fileName,
2259
- forceSync: this._forceSyncScripts,
2260
- interpreter: this._interpreter,
2261
- context: {
2262
- bot,
2263
- tag,
2264
- creator: null,
2265
- },
2266
- before: (ctx) => {
2267
- ctx.creator = ctx.bot
2268
- ? this._getRuntimeBot(ctx.bot.script.tags.creator)
2269
- : null;
2270
- // TODO: Determine whether to support this
2271
- // if (this._beforeScriptEnterListeners.length > 0) {
2272
- // for (let listener of this._beforeScriptEnterListeners) {
2273
- // try {
2274
- // listener({
2275
- // botId: ctx.bot.id,
2276
- // tag: ctx.tag,
2277
- // enterType: 'call',
2278
- // });
2279
- // } catch (err) {
2280
- // console.error(err);
2281
- // }
2282
- // }
2283
- // }
2284
- },
2285
- onError: (err, ctx, meta) => {
2286
- const data = this._handleError(err, ctx.bot, ctx.tag);
2287
- throw data;
2288
- },
2289
- constants: constants,
2290
- 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) }),
2291
- arguments: [['that', 'data']],
2292
- });
2293
- if (hasValue(bot)) {
2294
- this._functionMap.set(functionName, func);
2295
- const botFunctionNames = this._getFunctionNamesForBot(bot.id);
2296
- botFunctionNames.add(functionName);
2297
- }
2298
- return func;
2299
- }
2300
- _handleError(err, bot, tag) {
2301
- if (err instanceof RanOutOfEnergyError) {
2302
- throw err;
2303
- }
2304
- let data = {
2305
- error: err,
2306
- bot: bot,
2307
- tag: tag,
2308
- };
2309
- if (err instanceof Error) {
2310
- try {
2311
- const newStack = this._compiler.calculateOriginalStackTrace(this._functionMap, err);
2312
- if (newStack) {
2313
- err.oldStack = err.stack;
2314
- err.stack = newStack;
2315
- }
2316
- }
2317
- catch (stackError) {
2318
- console.error('[AuxRuntime] Unable to transform error stack trace', stackError);
2319
- }
2320
- }
2321
- return data;
2322
- }
2323
- _getRuntimeBot(id) {
2324
- if (hasValue(id) && typeof id === 'string') {
2325
- const creator = this._compiledState[id];
2326
- if (creator) {
2327
- return creator.script;
2328
- }
2329
- }
2330
- return null;
2331
- }
2332
- /**
2333
- * Maps the given value to a new value where bots are replaced with script bots.
2334
- * This makes it easy to modify other bot values in listeners. If the value is not convertable,
2335
- * then it is returned unaffected. Only objects and arrays are convertable.
2336
- *
2337
- * Works by making a copy of the value where every bot value is replaced with a reference
2338
- * to a script bot instance for the bot. The copy has a reference to the original value in the ORIGINAL_OBJECT symbol property.
2339
- * We use this property in action.reject() to resolve the original action value so that doing a action.reject() in a onAnyAction works properly.
2340
- *
2341
- * @param context The sandbox context.
2342
- * @param value The value that should be converted.
2343
- */
2344
- _mapBotsToRuntimeBots(value) {
2345
- return this._mapBotsToRuntimeBotsCore(value, 0, new Map());
2346
- }
2347
- _mapBotsToRuntimeBotsCore(value, depth, map) {
2348
- if (depth > 1000) {
2349
- throw new DeepObjectError();
2350
- }
2351
- if (isBot(value)) {
2352
- return this._globalContext.state[value.id] || value;
2353
- }
2354
- else if (Array.isArray(value) && value.some(isBot)) {
2355
- let arr = value.map((b) => isBot(b) ? this._globalContext.state[b.id] || b : b);
2356
- arr[ORIGINAL_OBJECT] = value;
2357
- return arr;
2358
- }
2359
- else if (typeof value === 'string') {
2360
- if (isTaggedString(value)) {
2361
- return parseTaggedString(value);
2362
- }
2363
- else if (isTaggedNumber(value)) {
2364
- return parseNumber(value);
2365
- }
2366
- else if (isBotVector(value)) {
2367
- return parseBotVector(value);
2368
- }
2369
- else if (isBotDate(value)) {
2370
- return parseBotDate(value);
2371
- }
2372
- else if (isBotRotation(value)) {
2373
- return parseBotRotation(value);
2374
- }
2375
- else if (isBotLink(value)) {
2376
- const ids = parseBotLink(value);
2377
- if (ids && ids.length > 1) {
2378
- return ids.map((id) => this._globalContext.state[id]);
2379
- }
2380
- else if (ids && ids.length > 0) {
2381
- return this._globalContext.state[ids[0]];
2382
- }
2383
- else {
2384
- return null;
2385
- }
2386
- }
2387
- }
2388
- else {
2389
- if (map.has(value)) {
2390
- return map.get(value);
2391
- }
2392
- if (typeof value === 'object' &&
2393
- value !== null &&
2394
- value[UNMAPPABLE] === true) {
2395
- return value;
2396
- }
2397
- if (hasValue(value) &&
2398
- !Array.isArray(value) &&
2399
- !(value instanceof ArrayBuffer) &&
2400
- typeof value === 'object' &&
2401
- Object.getPrototypeOf(value) === Object.prototype) {
2402
- let result = {
2403
- [ORIGINAL_OBJECT]: value,
2404
- };
2405
- map.set(value, result);
2406
- forOwn(value, (value, key, object) => {
2407
- result[key] = this._mapBotsToRuntimeBotsCore(value, depth + 1, map);
2408
- });
2409
- return result;
2410
- // return transform(
2411
- // value,
2412
- // (result, value, key) =>
2413
- // this._transformBotsToRuntimeBots(result, value, key),
2414
- // { [ORIGINAL_OBJECT]: value }
2415
- // );
2416
- }
2417
- else if (hasValue(value) &&
2418
- Array.isArray(value) &&
2419
- !(value instanceof ArrayBuffer)) {
2420
- const result = [];
2421
- map.set(value, result);
2422
- result.push(...value.map((v) => this._mapBotsToRuntimeBotsCore(v, depth + 1, map)));
2423
- return result;
2424
- }
2425
- }
2426
- return value;
2427
- }
2428
- _getFunctionNamesForBot(botId, createIfDoesNotExist = true) {
2429
- let list = this._botFunctionMap.get(botId);
2430
- if (!list && createIfDoesNotExist) {
2431
- list = new Set();
2432
- this._botFunctionMap.set(botId, list);
2433
- }
2434
- return list;
2435
- }
2436
- setBreakpoint(breakpoint) {
2437
- const bot = this.currentState[breakpoint.botId];
2438
- const breakpointIndex = bot.breakpoints.findIndex((b) => b.id === breakpoint.id);
2439
- if (breakpointIndex >= 0) {
2440
- bot.breakpoints[breakpointIndex] = breakpoint;
2441
- }
2442
- else {
2443
- bot.breakpoints.push(breakpoint);
2444
- }
2445
- this._breakpoints.set(breakpoint.id, breakpoint);
2446
- const func = bot.listeners[breakpoint.tag];
2447
- if (func) {
2448
- this._compiler.setBreakpoint({
2449
- id: breakpoint.id,
2450
- func: func,
2451
- interpreter: this._interpreter,
2452
- lineNumber: breakpoint.lineNumber,
2453
- columnNumber: breakpoint.columnNumber,
2454
- states: breakpoint.states,
2455
- });
2456
- }
2457
- }
2458
- removeBreakpoint(breakpointId) {
2459
- const breakpoint = this._breakpoints.get(breakpointId);
2460
- if (breakpoint) {
2461
- this._breakpoints.delete(breakpointId);
2462
- const bot = this.currentState[breakpoint.botId];
2463
- const breakpointIndex = bot.breakpoints.findIndex((b) => b.id === breakpoint.id);
2464
- if (breakpointIndex >= 0) {
2465
- bot.breakpoints.splice(breakpointIndex, 1);
2466
- }
2467
- this._interpreter.removeBreakpointById(breakpoint.id);
2468
- }
2469
- }
2470
- continueAfterStop(stopId, continuation) {
2471
- const state = this._stopState;
2472
- if (!state || state.stopId !== stopId) {
2473
- return;
2474
- }
2475
- this._stopState = null;
2476
- this._globalContext.actions.push(...state.actions);
2477
- this._globalContext.errors.push(...state.errors);
2478
- this._executeGenerator(state.resolve, state.reject, state.generator, continuation);
2479
- // this._processGenerator(state.generator, continuation).then(state.resolve, state.reject);
2480
- }
2481
- _scheduleJob(queueName, job) {
2482
- if (this._interpreter) {
2483
- this._interpreter.realm.scope(() => {
2484
- this._interpreter.agent.queueJob(queueName, () => {
2485
- job();
2486
- return Value.undefined;
2487
- });
2488
- });
2489
- }
2490
- }
2491
- _scheduleJobQueueCheck() {
2492
- if (this._interpreter) {
2493
- // Increment the current job queue check count and save it.
2494
- // This is used to short-circuit job queue checks if future checks are scheduled
2495
- // before this one runs.
2496
- this._jobQueueCheckCount++;
2497
- const currentCheck = this._jobQueueCheckCount;
2498
- this._jobQueueCheckPending = true;
2499
- // Queue a microtask to fire before the current task finishes
2500
- queueMicrotask(() => {
2501
- // Short circuit if another check has been scheduled.
2502
- if (this._jobQueueCheckCount !== currentCheck) {
2503
- return;
2504
- }
2505
- // Queue another microtask to ensure that the job queue gets processed
2506
- // after all current microtasks are executed.
2507
- // This allows _scheduleJobQueueCheck() to be scheduled before other microtasks are queued.
2508
- queueMicrotask(() => {
2509
- // Short circuit if another check has been scheduled.
2510
- if (this._jobQueueCheckCount !== currentCheck ||
2511
- this._interpreter.agent.jobQueue.length <= 0) {
2512
- return;
2513
- }
2514
- this._processJobQueueNow();
2515
- if (this._interpreter.agent.jobQueue.length <= 0) {
2516
- // Check to see if any more jobs have been added after the job queue has been processed
2517
- // and trigger another job queue check if they have.
2518
- this._scheduleJobQueueCheck();
2519
- }
2520
- });
2521
- });
2522
- }
2523
- }
2524
- // private _processJobQueueMicrotask() {
2525
- // queueMicrotask(() => {
2526
- // this._processJobQueueNow();
2527
- // });
2528
- // }
2529
- _processJobQueueNow() {
2530
- // TODO: Determine whether to support this
2531
- // let scriptJobs: { botId: string; tag: string }[] = [];
2532
- // for (let job of this._interpreter.agent.jobQueue) {
2533
- // if (
2534
- // job.callerScriptOrModule &&
2535
- // FUNCTION_METADATA in job.callerScriptOrModule
2536
- // ) {
2537
- // const meta: AuxScriptMetadata = (
2538
- // job.callerScriptOrModule as any
2539
- // )[FUNCTION_METADATA] as AuxScriptMetadata;
2540
- // const context = meta.context as {
2541
- // bot: CompiledBot;
2542
- // tag: string;
2543
- // };
2544
- // const botId = context.bot.id;
2545
- // const tag = context.tag;
2546
- // scriptJobs.push({
2547
- // botId,
2548
- // tag,
2549
- // });
2550
- // }
2551
- // }
2552
- // if (
2553
- // scriptJobs.length > 0 &&
2554
- // this._beforeScriptEnterListeners.length > 0
2555
- // ) {
2556
- // for (let job of scriptJobs) {
2557
- // for (let listener of this._beforeScriptEnterListeners) {
2558
- // try {
2559
- // listener({
2560
- // enterType: 'task',
2561
- // botId: job.botId,
2562
- // tag: job.tag,
2563
- // });
2564
- // } catch (err) {
2565
- // console.error(err);
2566
- // }
2567
- // }
2568
- // }
2569
- // }
2570
- const queueGen = this._interpreter.runJobQueue();
2571
- while (true) {
2572
- const next = queueGen.next();
2573
- if (next.done) {
2574
- break;
2575
- }
2576
- else {
2577
- // TODO: Process breakpoint
2578
- }
2579
- }
2580
- this._jobQueueCheckPending = false;
2581
- }
2582
- processGenerator(generator) {
2583
- this._processGenerator(generator);
2584
- }
2585
- _processGenerator(generator, continuation) {
2586
- return markAsRuntimePromise(new Promise((resolve, reject) => {
2587
- this._executeGenerator(resolve, reject, generator, continuation);
2588
- }));
2589
- }
2590
- _executeGenerator(resolve, reject, generator, continuation) {
2591
- try {
2592
- let result;
2593
- while (true) {
2594
- const next = generator.next(continuation);
2595
- if (next.done === true) {
2596
- result = next.value;
2597
- break;
2598
- }
2599
- else {
2600
- this._currentStopCount += 1;
2601
- const actions = this._processUnbatchedActions();
2602
- const errors = this._processUnbatchedErrors();
2603
- const state = {
2604
- stopId: this._currentStopCount,
2605
- generator,
2606
- resolve,
2607
- reject,
2608
- actions,
2609
- errors,
2610
- };
2611
- this._stopState = state;
2612
- let breakpoint = this._breakpoints.get(next.value.breakpoint.id);
2613
- this._onRuntimeStop.next(Object.assign(Object.assign({}, next.value), { breakpoint, stopId: this._currentStopCount }));
2614
- return;
2615
- }
2616
- }
2617
- this._scheduleJobQueueCheck();
2618
- resolve(result);
2619
- }
2620
- catch (err) {
2621
- reject(err);
2622
- }
2623
- }
2624
- }
2625
- /**
2626
- * Recursively maps each of the given library's functions using the given map function and returns a new library that contains the converted functions.
2627
- * The returned object will contain the same enumerable properties as the original library except that its functions have been mapped.
2628
- * @param library The library to map.
2629
- * @param map The function to use for mapping library functions.
2630
- */
2631
- export function mapLibraryFunctions(library, map) {
2632
- let newLibrary = Object.assign({}, library);
2633
- newLibrary.api = mapFunctions(newLibrary.api, map);
2634
- return newLibrary;
2635
- }
2636
- function mapFunctions(obj, map) {
2637
- let newObj = Object.create(obj);
2638
- assignFunctions(obj, newObj, map);
2639
- return newObj;
2640
- }
2641
- function assignFunctions(obj, newObj, map) {
2642
- let descriptors = Object.getOwnPropertyDescriptors(obj);
2643
- for (let key in descriptors) {
2644
- let descriptor = descriptors[key];
2645
- if (descriptor.get || descriptor.set || !descriptor.enumerable) {
2646
- continue;
2647
- }
2648
- const val = descriptor.value;
2649
- if (typeof val === 'function') {
2650
- let newFunc = (newObj[key] = map(val, key));
2651
- if (newFunc) {
2652
- assignFunctions(val, newFunc, map);
2653
- }
2654
- continue;
2655
- }
2656
- if (typeof val !== 'object' ||
2657
- val === null ||
2658
- Object.getPrototypeOf(val).constructor !== Object) {
2659
- continue;
2660
- }
2661
- newObj[key] = mapFunctions(val, map);
2662
- }
2663
- }
2664
- // function wrapGeneratorFunc<T>(
2665
- // func: (...args: any[]) => T
2666
- // ): (...args: any[]) => T {
2667
- // return (...args: any[]) => {
2668
- // let res = func(...args);
2669
- // if (isGenerator(res)) {
2670
- // return unwind(res);
2671
- // }
2672
- // return res;
2673
- // };
2674
- // }
2675
- /**
2676
- * Processes the given list of items in a sequential manner, calling the given function for each item.
2677
- * @param list The list of items to process.
2678
- * @param func The function that should be called for each item.
2679
- */
2680
- function processListOfMaybePromises(promise, list, func) {
2681
- for (let item of list) {
2682
- if (!isRuntimePromise(promise)) {
2683
- const p = func(item);
2684
- if (isRuntimePromise(p)) {
2685
- promise = p;
2686
- }
2687
- }
2688
- else {
2689
- const copiedItem = item;
2690
- promise = promise.then(() => {
2691
- return func(copiedItem);
2692
- });
2693
- }
2694
- }
2695
- if (isPromise(promise)) {
2696
- return markAsRuntimePromise(promise);
2697
- }
2698
- return promise;
2699
- }
2700
- //# sourceMappingURL=AuxRuntime.js.map