@casual-simulation/aux-common 2.0.14-alpha.1392172559 → 2.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/aux-format-2/AuxStateHelpers.d.ts +11 -1
- package/aux-format-2/AuxStateHelpers.js +20 -5
- package/aux-format-2/AuxStateHelpers.js.map +1 -1
- package/aux-format-2/AuxWeaveHelpers.d.ts +0 -1
- package/aux-format-2/AuxWeaveHelpers.js +1 -15
- package/aux-format-2/AuxWeaveHelpers.js.map +1 -1
- package/aux-format-2/AuxWeaveReducer.js +6 -6
- package/aux-format-2/AuxWeaveReducer.js.map +1 -1
- package/bots/Bot.d.ts +80 -1
- package/bots/Bot.js +77 -2
- package/bots/Bot.js.map +1 -1
- package/bots/BotCalculations.d.ts +45 -1
- package/bots/BotCalculations.js +126 -22
- package/bots/BotCalculations.js.map +1 -1
- package/bots/BotEvents.d.ts +1 -65
- package/bots/BotEvents.js +0 -30
- package/bots/BotEvents.js.map +1 -1
- package/bots/test/BotCalculationContextTests.js +11 -4
- package/bots/test/BotCalculationContextTests.js.map +1 -1
- package/package.json +8 -6
- package/partitions/MemoryPartition.js +23 -6
- package/partitions/MemoryPartition.js.map +1 -1
- package/partitions/RemoteYjsPartition.js +2 -2
- package/partitions/RemoteYjsPartition.js.map +1 -1
- package/partitions/YjsPartition.js +2 -2
- package/partitions/YjsPartition.js.map +1 -1
- package/partitions/test/PartitionTests.js +93 -19
- package/partitions/test/PartitionTests.js.map +1 -1
- package/runtime/AuxGlobalContext.d.ts +2 -2
- package/runtime/AuxGlobalContext.js.map +1 -1
- package/runtime/AuxLibrary.d.ts +23 -5
- package/runtime/AuxLibrary.js +371 -46
- package/runtime/AuxLibrary.js.map +1 -1
- package/runtime/AuxLibraryDefinitions.def +173 -70
- package/runtime/AuxRuntime.d.ts +3 -0
- package/runtime/AuxRuntime.js +32 -14
- package/runtime/AuxRuntime.js.map +1 -1
- package/runtime/RuntimeBot.d.ts +6 -0
- package/runtime/RuntimeBot.js +107 -5
- package/runtime/RuntimeBot.js.map +1 -1
- package/runtime/Transpiler.js +3 -3
- package/runtime/Transpiler.js.map +1 -1
- package/runtime/Utils.d.ts +6 -0
- package/runtime/Utils.js +30 -0
- package/runtime/Utils.js.map +1 -1
- package/runtime/test/TestScriptBotFactory.js +6 -3
- package/runtime/test/TestScriptBotFactory.js.map +1 -1
package/runtime/AuxLibrary.js
CHANGED
|
@@ -8,11 +8,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { DEBUG_STRING, debugStringifyFunction, } from './AuxGlobalContext';
|
|
11
|
-
import { hasValue, trimTag, isBot, BOT_SPACE_TAG, toast as toastMessage, showJoinCode as calcShowJoinCode, requestFullscreen, exitFullscreen, html as htmlMessage, hideHtml as hideHtmlMessage, setClipboard as calcSetClipboard, tweenTo as calcTweenTo, showChat as calcShowChat, hideChat as calcHideChat, runScript, enableAR as calcEnableAR, disableAR as calcDisableAR, enableVR as calcEnableVR, disableVR as calcDisableVR, showUploadAuxFile as calcShowUploadAuxFile, openQRCodeScanner as calcOpenQRCodeScanner, showQRCode as calcShowQRCode, openBarcodeScanner as calcOpenBarcodeScanner, showBarcode as calcShowBarcode, importAUX as calcImportAUX, showInputForTag as calcShowInputForTag, showInput as calcShowInput, replaceDragBot as calcReplaceDragBot, goToDimension as calcGoToDimension, goToURL as calcGoToURL, openURL as calcOpenURL, checkout as calcCheckout, playSound as calcPlaySound, bufferSound as calcBufferSound, cancelSound as calcCancelSound, setupServer as calcSetupServer, shell as calcShell, backupToGithub as calcBackupToGithub, backupAsDownload as calcBackupAsDownload, finishCheckout as calcFinishCheckout, markHistory as calcMarkHistory, browseHistory as calcBrowseHistory, restoreHistoryMark as calcRestoreHistoryMark, loadFile as calcLoadFile, saveFile as calcSaveFile, reject as calcReject, localFormAnimation as calcLocalFormAnimation, webhook as calcWebhook, superShout as calcSuperShout, share as calcShare,
|
|
11
|
+
import { hasValue, trimTag, isBot, BOT_SPACE_TAG, toast as toastMessage, showJoinCode as calcShowJoinCode, requestFullscreen, exitFullscreen, html as htmlMessage, hideHtml as hideHtmlMessage, setClipboard as calcSetClipboard, tweenTo as calcTweenTo, showChat as calcShowChat, hideChat as calcHideChat, runScript, enableAR as calcEnableAR, disableAR as calcDisableAR, enableVR as calcEnableVR, disableVR as calcDisableVR, showUploadAuxFile as calcShowUploadAuxFile, openQRCodeScanner as calcOpenQRCodeScanner, showQRCode as calcShowQRCode, openBarcodeScanner as calcOpenBarcodeScanner, showBarcode as calcShowBarcode, importAUX as calcImportAUX, showInputForTag as calcShowInputForTag, showInput as calcShowInput, replaceDragBot as calcReplaceDragBot, goToDimension as calcGoToDimension, goToURL as calcGoToURL, openURL as calcOpenURL, checkout as calcCheckout, playSound as calcPlaySound, bufferSound as calcBufferSound, cancelSound as calcCancelSound, setupServer as calcSetupServer, shell as calcShell, backupToGithub as calcBackupToGithub, backupAsDownload as calcBackupAsDownload, finishCheckout as calcFinishCheckout, markHistory as calcMarkHistory, browseHistory as calcBrowseHistory, restoreHistoryMark as calcRestoreHistoryMark, loadFile as calcLoadFile, saveFile as calcSaveFile, reject as calcReject, localFormAnimation as calcLocalFormAnimation, webhook as calcWebhook, superShout as calcSuperShout, share as calcShare, registerPrefix as calcRegisterPrefix, createCertificate as calcCreateCertificate, signTag as calcSignTag, revokeCertificate as calcRevokeCertificate, localPositionTween as calcLocalPositionTween, localRotationTween as calcLocalRotationTween, showUploadFiles as calcShowUploadFiles, download, loadSimulation, unloadSimulation, getUploadState, addState, getPortalTag, KNOWN_PORTALS, openConsole, tagsOnBot, getOriginalObject, getBotSpace, trimEvent, CREATE_ACTION_NAME, CREATE_ANY_ACTION_NAME, DESTROY_ACTION_NAME, ORIGINAL_OBJECT, unlockSpace, getRemoteCount, getServers, getRemotes, action, getServerStatuses, setSpacePassword, exportGpioPin, unexportGpioPin, setGpioPin, getGpioPin, rpioInitPin, rpioExitPin, rpioOpenPin, rpioModePin, rpioReadPin, rpioReadSequencePin, rpioWritePin, rpioWriteSequencePin, rpioReadpadPin, rpioWritepadPin, rpioPudPin, rpioPollPin, rpioClosePin, rpioI2CBeginPin, rpioI2CSetSlaveAddressPin, rpioI2CSetBaudRatePin, rpioI2CSetClockDividerPin, rpioI2CReadPin, rpioI2CWritePin,
|
|
12
12
|
// rpioI2CReadRegisterRestartPin,
|
|
13
13
|
// rpioI2CWriteReadRestartPin,
|
|
14
|
-
rpioI2CEndPin, rpioPWMSetClockDividerPin, rpioPWMSetRangePin, rpioPWMSetDataPin, rpioSPIBeginPin, rpioSPIChipSelectPin, rpioSPISetCSPolarityPin, rpioSPISetClockDividerPin, rpioSPISetDataModePin, rpioSPITransferPin, rpioSPIWritePin, rpioSPIEndPin, serialConnectPin, serialOpenPin, serialStreamPin, serialUpdatePin, serialWritePin, serialReadPin, serialClosePin, serialFlushPin, serialDrainPin, serialPausePin, serialResumePin, calculateAnchorPoint, calculateAnchorPointOffset, getBotPosition as calcGetBotPosition, isRuntimeBot, SET_TAG_MASK_SYMBOL, CLEAR_TAG_MASKS_SYMBOL, getBotScale, EDIT_TAG_SYMBOL, EDIT_TAG_MASK_SYMBOL, circleWipe, addDropSnap as calcAddDropSnap, animateToPosition, beginAudioRecording as calcBeginAudioRecording, endAudioRecording as calcEndAudioRecording, beginRecording as calcBeginRecording, endRecording as calcEndRecording, speakText as calcSpeakText, getVoices as calcGetVoices, getGeolocation as calcGetGeolocation, cancelAnimation, disablePOV, enablePOV, enableCustomDragging as calcEnableCustomDragging, MINI_PORTAL, registerCustomApp, setAppOutput, unregisterCustomApp, requestAuthData as calcRequestAuthData, createBot, defineGlobalBot as calcDefineGlobalBot, TEMPORARY_BOT_PARTITION_ID, publishRecord as calcPublishRecord, DEFAULT_RECORD_SPACE, getRecords as calcGetRecords, requestPermanentAuthToken as calcRequestPermanentAuthToken, deleteRecord, } from '../bots';
|
|
15
|
-
import { sortBy, every } from 'lodash';
|
|
14
|
+
rpioI2CEndPin, rpioPWMSetClockDividerPin, rpioPWMSetRangePin, rpioPWMSetDataPin, rpioSPIBeginPin, rpioSPIChipSelectPin, rpioSPISetCSPolarityPin, rpioSPISetClockDividerPin, rpioSPISetDataModePin, rpioSPITransferPin, rpioSPIWritePin, rpioSPIEndPin, serialConnectPin, serialOpenPin, serialStreamPin, serialUpdatePin, serialWritePin, serialReadPin, serialClosePin, serialFlushPin, serialDrainPin, serialPausePin, serialResumePin, calculateAnchorPoint, calculateAnchorPointOffset, getBotPosition as calcGetBotPosition, isRuntimeBot, SET_TAG_MASK_SYMBOL, CLEAR_TAG_MASKS_SYMBOL, getBotScale, EDIT_TAG_SYMBOL, EDIT_TAG_MASK_SYMBOL, circleWipe, addDropSnap as calcAddDropSnap, animateToPosition, beginAudioRecording as calcBeginAudioRecording, endAudioRecording as calcEndAudioRecording, beginRecording as calcBeginRecording, endRecording as calcEndRecording, speakText as calcSpeakText, getVoices as calcGetVoices, getGeolocation as calcGetGeolocation, cancelAnimation, disablePOV, enablePOV, enableCustomDragging as calcEnableCustomDragging, MINI_PORTAL, registerCustomApp, setAppOutput, unregisterCustomApp, requestAuthData as calcRequestAuthData, createBot, defineGlobalBot as calcDefineGlobalBot, TEMPORARY_BOT_PARTITION_ID, publishRecord as calcPublishRecord, DEFAULT_RECORD_SPACE, getRecords as calcGetRecords, requestPermanentAuthToken as calcRequestPermanentAuthToken, deleteRecord, convertToString, GET_TAG_MASKS_SYMBOL, isBotLink, parseBotLink, createBotLink, } from '../bots';
|
|
15
|
+
import { sortBy, every, cloneDeep, union, isEqual, flatMap } from 'lodash';
|
|
16
16
|
import { remote as calcRemote, } from '@casual-simulation/causal-trees';
|
|
17
17
|
import { RanOutOfEnergyError } from './AuxResults';
|
|
18
18
|
import '../polyfill/Array.first.polyfill';
|
|
@@ -22,7 +22,7 @@ import { sha256 as hashSha256, sha512 as hashSha512, hmac } from 'hash.js';
|
|
|
22
22
|
import stableStringify from '@casual-simulation/fast-json-stable-stringify';
|
|
23
23
|
import { encrypt as realEncrypt, decrypt as realDecrypt, keypair as realKeypair, sign as realSign, verify as realVerify, asymmetricKeypair as realAsymmetricKeypair, asymmetricEncrypt as realAsymmetricEncrypt, asymmetricDecrypt as realAsymmetricDecrypt, isAsymmetricKeypair, isAsymmetricEncrypted, isEncrypted, } from '@casual-simulation/crypto';
|
|
24
24
|
import { tagValueHash } from '../aux-format-2/AuxOpTypes';
|
|
25
|
-
import {
|
|
25
|
+
import { apply, del, insert, isTagEdit, preserve } from '../aux-format-2';
|
|
26
26
|
import { Euler, Vector3, Plane, Ray, } from '@casual-simulation/three';
|
|
27
27
|
import mime from 'mime';
|
|
28
28
|
import TWEEN from '@tweenjs/tween.js';
|
|
@@ -31,12 +31,94 @@ import './BlobPolyfill';
|
|
|
31
31
|
import { Fragment, h } from 'preact';
|
|
32
32
|
import htm from 'htm';
|
|
33
33
|
import { fromByteArray, toByteArray } from 'base64-js';
|
|
34
|
+
import expect, { iterableEquality } from '@casual-simulation/expect';
|
|
34
35
|
const _html = htm.bind(h);
|
|
35
36
|
const html = ((...args) => {
|
|
36
37
|
return _html(...args);
|
|
37
38
|
});
|
|
38
39
|
html.h = h;
|
|
39
40
|
html.f = Fragment;
|
|
41
|
+
/**
|
|
42
|
+
* The status codes that should be used to retry web requests.
|
|
43
|
+
*/
|
|
44
|
+
const DEFUALT_RETRY_STATUS_CODES = [
|
|
45
|
+
408,
|
|
46
|
+
429,
|
|
47
|
+
500,
|
|
48
|
+
502,
|
|
49
|
+
503,
|
|
50
|
+
504,
|
|
51
|
+
0, // Network Failure / CORS
|
|
52
|
+
];
|
|
53
|
+
/**
|
|
54
|
+
* The time to wait until another web request retry unless specified by the webhook options.
|
|
55
|
+
* Defaults to 3 seconds.
|
|
56
|
+
*/
|
|
57
|
+
const DEFAULT_RETRY_AFTER_MS = 3 * 1000;
|
|
58
|
+
/**
|
|
59
|
+
* The maximum amount of time to wait before giving up on a set of requests.
|
|
60
|
+
* Defaults to 1 minute.
|
|
61
|
+
*/
|
|
62
|
+
const MAX_RETRY_AFTER_MS = 60 * 60 * 1000;
|
|
63
|
+
/**
|
|
64
|
+
* The maximum number of times that a web request should be retried for.
|
|
65
|
+
*/
|
|
66
|
+
const MAX_RETRY_COUNT = 10;
|
|
67
|
+
const botsEquality = function (first, second) {
|
|
68
|
+
if (isRuntimeBot(first) && isRuntimeBot(second)) {
|
|
69
|
+
expect(getBotSnapshot(first)).toEqual(getBotSnapshot(second));
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
return undefined;
|
|
73
|
+
};
|
|
74
|
+
expect.extend({
|
|
75
|
+
toEqual(received, expected) {
|
|
76
|
+
// Copied from https://github.com/facebook/jest/blob/7bb400c373a6f90ba956dd25fe24ee4d4788f41e/packages/expect/src/matchers.ts#L580
|
|
77
|
+
// Added the testBots matcher to make testing against bots easier.
|
|
78
|
+
const matcherName = 'toEqual';
|
|
79
|
+
const options = {
|
|
80
|
+
comment: 'deep equality',
|
|
81
|
+
isNot: this.isNot,
|
|
82
|
+
promise: this.promise,
|
|
83
|
+
};
|
|
84
|
+
const pass = this.equals(received, expected, [
|
|
85
|
+
botsEquality,
|
|
86
|
+
iterableEquality,
|
|
87
|
+
]);
|
|
88
|
+
const message = pass
|
|
89
|
+
? () => this.utils.matcherHint(matcherName, undefined, undefined, options) +
|
|
90
|
+
'\n\n' +
|
|
91
|
+
`Expected: not ${this.utils.printExpected(expected)}\n` +
|
|
92
|
+
(this.utils.stringify(expected) !==
|
|
93
|
+
this.utils.stringify(received)
|
|
94
|
+
? `Received: ${this.utils.printReceived(received)}`
|
|
95
|
+
: '')
|
|
96
|
+
: () => this.utils.matcherHint(matcherName, undefined, undefined, options) +
|
|
97
|
+
'\n\n' +
|
|
98
|
+
this.utils.printDiffOrStringify(expected, received, 'Expected', 'Received', this.expand !== false);
|
|
99
|
+
// Passing the actual and expected objects so that a custom reporter
|
|
100
|
+
// could access them, for example in order to display a custom visual diff,
|
|
101
|
+
// or create a different error message
|
|
102
|
+
return { actual: received, expected, message, name: matcherName, pass };
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
function getBotSnapshot(bot) {
|
|
106
|
+
var _a;
|
|
107
|
+
let b = {
|
|
108
|
+
id: bot.id,
|
|
109
|
+
space: bot.space,
|
|
110
|
+
tags: typeof bot.tags.toJSON === 'function'
|
|
111
|
+
? bot.tags.toJSON()
|
|
112
|
+
: bot.tags,
|
|
113
|
+
};
|
|
114
|
+
let masks = isRuntimeBot(bot)
|
|
115
|
+
? bot[GET_TAG_MASKS_SYMBOL]()
|
|
116
|
+
: cloneDeep((_a = bot.masks) !== null && _a !== void 0 ? _a : {});
|
|
117
|
+
if (Object.keys(masks).length > 0) {
|
|
118
|
+
b.masks = masks;
|
|
119
|
+
}
|
|
120
|
+
return b;
|
|
121
|
+
}
|
|
40
122
|
/**
|
|
41
123
|
* Creates a library that includes the default functions and APIs.
|
|
42
124
|
* @param context The global context that should be used.
|
|
@@ -57,6 +139,10 @@ export function createDefaultLibrary(context) {
|
|
|
57
139
|
getBotPosition,
|
|
58
140
|
getID,
|
|
59
141
|
getJSON,
|
|
142
|
+
getFormattedJSON,
|
|
143
|
+
getSnapshot,
|
|
144
|
+
diffSnapshots,
|
|
145
|
+
applyDiffToSnapshot,
|
|
60
146
|
getTag,
|
|
61
147
|
setTag,
|
|
62
148
|
setTagMask,
|
|
@@ -71,6 +157,9 @@ export function createDefaultLibrary(context) {
|
|
|
71
157
|
subtractMods,
|
|
72
158
|
destroy,
|
|
73
159
|
changeState,
|
|
160
|
+
getLink: createBotLinkApi,
|
|
161
|
+
getBotLinks,
|
|
162
|
+
updateBotLinks,
|
|
74
163
|
superShout,
|
|
75
164
|
priorityShout,
|
|
76
165
|
shout,
|
|
@@ -107,6 +196,7 @@ export function createDefaultLibrary(context) {
|
|
|
107
196
|
clearWatchPortal,
|
|
108
197
|
assert,
|
|
109
198
|
assertEqual,
|
|
199
|
+
expect,
|
|
110
200
|
html,
|
|
111
201
|
os: {
|
|
112
202
|
sleep,
|
|
@@ -190,8 +280,6 @@ export function createDefaultLibrary(context) {
|
|
|
190
280
|
getPointerDirection,
|
|
191
281
|
getInputState,
|
|
192
282
|
getInputList,
|
|
193
|
-
registerExecutable: openCustomPortal,
|
|
194
|
-
buildExecutable: buildBundle,
|
|
195
283
|
registerTagPrefix: registerPrefix,
|
|
196
284
|
registerApp: registerApp,
|
|
197
285
|
unregisterApp,
|
|
@@ -209,8 +297,6 @@ export function createDefaultLibrary(context) {
|
|
|
209
297
|
instStatuses: serverStatuses,
|
|
210
298
|
},
|
|
211
299
|
portal: {
|
|
212
|
-
open: openCustomPortal,
|
|
213
|
-
buildBundle,
|
|
214
300
|
registerPrefix,
|
|
215
301
|
},
|
|
216
302
|
server: {
|
|
@@ -476,11 +562,14 @@ export function createDefaultLibrary(context) {
|
|
|
476
562
|
* @param second The second value to test.
|
|
477
563
|
*/
|
|
478
564
|
function assertEqual(first, second) {
|
|
479
|
-
|
|
480
|
-
const
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
565
|
+
expect(first).toEqual(second);
|
|
566
|
+
// const json = getFormattedJSON(getAssertionValue(first));
|
|
567
|
+
// const json2 = getFormattedJSON(getAssertionValue(second));
|
|
568
|
+
// if (json !== json2) {
|
|
569
|
+
// throw new Error(
|
|
570
|
+
// `Assertion failed.\n\nExpected: ${json2}\nReceived: ${json}`
|
|
571
|
+
// );
|
|
572
|
+
// }
|
|
484
573
|
}
|
|
485
574
|
/**
|
|
486
575
|
* Gets a list of all the bots.
|
|
@@ -650,10 +739,37 @@ export function createDefaultLibrary(context) {
|
|
|
650
739
|
};
|
|
651
740
|
}
|
|
652
741
|
else if (hasValue(filter)) {
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
742
|
+
if (isBotLink(filter)) {
|
|
743
|
+
const ids = parseBotLink(filter);
|
|
744
|
+
if (ids.length === 0) {
|
|
745
|
+
return (bot) => {
|
|
746
|
+
let val = bot.tags[tag];
|
|
747
|
+
return val === filter;
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
else if (ids.length === 1) {
|
|
751
|
+
return (bot) => {
|
|
752
|
+
let val = bot.tags[tag];
|
|
753
|
+
return (ids[0] === val ||
|
|
754
|
+
(isBotLink(val) &&
|
|
755
|
+
parseBotLink(val).some((id) => id === ids[0])));
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
else {
|
|
759
|
+
return (bot) => {
|
|
760
|
+
let val = bot.tags[tag];
|
|
761
|
+
const valIds = parseBotLink(val);
|
|
762
|
+
return (!!valIds &&
|
|
763
|
+
ids.every((id1) => valIds.some((id2) => id1 === id2)));
|
|
764
|
+
};
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
else {
|
|
768
|
+
return (bot) => {
|
|
769
|
+
let val = bot.tags[tag];
|
|
770
|
+
return hasValue(val) && filter === val;
|
|
771
|
+
};
|
|
772
|
+
}
|
|
657
773
|
}
|
|
658
774
|
else if (filter === null) {
|
|
659
775
|
return (bot) => {
|
|
@@ -926,15 +1042,123 @@ export function createDefaultLibrary(context) {
|
|
|
926
1042
|
return stableStringify(data);
|
|
927
1043
|
}
|
|
928
1044
|
/**
|
|
929
|
-
* Gets JSON for the given data.
|
|
1045
|
+
* Gets formatted JSON for the given data.
|
|
930
1046
|
* @param data The data.
|
|
931
1047
|
*/
|
|
932
|
-
function
|
|
1048
|
+
function getFormattedJSON(data) {
|
|
933
1049
|
if (hasValue(data === null || data === void 0 ? void 0 : data[ORIGINAL_OBJECT])) {
|
|
934
1050
|
return stableStringify(data[ORIGINAL_OBJECT], { space: 2 });
|
|
935
1051
|
}
|
|
936
1052
|
return stableStringify(data, { space: 2 });
|
|
937
1053
|
}
|
|
1054
|
+
/**
|
|
1055
|
+
* Gets a snapshot of the data that the bots contain.
|
|
1056
|
+
* This is useful for getting all the tags and masks that are attached to the given bots.
|
|
1057
|
+
* @param bots The array of bots to get the snapshot for.
|
|
1058
|
+
*/
|
|
1059
|
+
function getSnapshot(bots) {
|
|
1060
|
+
var _a;
|
|
1061
|
+
if (!Array.isArray(bots)) {
|
|
1062
|
+
return getSnapshot([bots]);
|
|
1063
|
+
}
|
|
1064
|
+
let state = {};
|
|
1065
|
+
for (let bot of bots) {
|
|
1066
|
+
let b = (state[bot.id] = {
|
|
1067
|
+
id: bot.id,
|
|
1068
|
+
tags: Object.assign({}, (typeof bot.tags.toJSON === 'function'
|
|
1069
|
+
? bot.tags.toJSON()
|
|
1070
|
+
: bot.tags)),
|
|
1071
|
+
});
|
|
1072
|
+
if (bot.space) {
|
|
1073
|
+
b.space = bot.space;
|
|
1074
|
+
}
|
|
1075
|
+
let masks = isRuntimeBot(bot)
|
|
1076
|
+
? bot[GET_TAG_MASKS_SYMBOL]()
|
|
1077
|
+
: cloneDeep((_a = bot.masks) !== null && _a !== void 0 ? _a : {});
|
|
1078
|
+
if (Object.keys(masks).length > 0) {
|
|
1079
|
+
b.masks = masks;
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
return state;
|
|
1083
|
+
}
|
|
1084
|
+
/**
|
|
1085
|
+
* Calculates the difference between the two given snapshots.
|
|
1086
|
+
* @param first The first snapshot.
|
|
1087
|
+
* @param second The second snapshot.
|
|
1088
|
+
*/
|
|
1089
|
+
function diffSnapshots(first, second) {
|
|
1090
|
+
const allIds = union(Object.keys(first), Object.keys(second));
|
|
1091
|
+
let diff = {};
|
|
1092
|
+
for (let id of allIds) {
|
|
1093
|
+
const inFirst = id in first;
|
|
1094
|
+
const inSecond = id in second;
|
|
1095
|
+
if (inFirst && inSecond) {
|
|
1096
|
+
// possibly updated
|
|
1097
|
+
const firstBot = first[id];
|
|
1098
|
+
const secondBot = second[id];
|
|
1099
|
+
if (firstBot && secondBot) {
|
|
1100
|
+
let botDiff = {};
|
|
1101
|
+
let tagsDiff = diffTags(firstBot.tags, secondBot.tags);
|
|
1102
|
+
if (!!tagsDiff) {
|
|
1103
|
+
botDiff.tags = tagsDiff;
|
|
1104
|
+
}
|
|
1105
|
+
const firstBotMasks = firstBot.masks || {};
|
|
1106
|
+
const secondBotMasks = secondBot.masks || {};
|
|
1107
|
+
let masksDiff = {};
|
|
1108
|
+
let hasMasksDiff = false;
|
|
1109
|
+
const allMaskSpaces = union(Object.keys(firstBotMasks), Object.keys(secondBotMasks));
|
|
1110
|
+
for (let space of allMaskSpaces) {
|
|
1111
|
+
const firstMasks = firstBotMasks[space] || {};
|
|
1112
|
+
const secondMasks = secondBotMasks[space] || {};
|
|
1113
|
+
let tagsDiff = diffTags(firstMasks, secondMasks);
|
|
1114
|
+
if (!!tagsDiff) {
|
|
1115
|
+
hasMasksDiff = true;
|
|
1116
|
+
masksDiff[space] = tagsDiff;
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
if (hasMasksDiff) {
|
|
1120
|
+
botDiff.masks = masksDiff;
|
|
1121
|
+
}
|
|
1122
|
+
if (!!tagsDiff || hasMasksDiff) {
|
|
1123
|
+
diff[id] = botDiff;
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
else if (inFirst) {
|
|
1128
|
+
// deleted
|
|
1129
|
+
diff[id] = null;
|
|
1130
|
+
}
|
|
1131
|
+
else if (inSecond) {
|
|
1132
|
+
// added
|
|
1133
|
+
diff[id] = second[id];
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
return diff;
|
|
1137
|
+
function diffTags(firstTags, secondTags) {
|
|
1138
|
+
let tagsDiff = {};
|
|
1139
|
+
let hasTagsDiff = false;
|
|
1140
|
+
const allTags = union(Object.keys(firstTags), Object.keys(secondTags));
|
|
1141
|
+
for (let tag of allTags) {
|
|
1142
|
+
const firstValue = firstTags[tag];
|
|
1143
|
+
const secondValue = secondTags[tag];
|
|
1144
|
+
if (!isEqual(firstValue, secondValue)) {
|
|
1145
|
+
// updated, deleted, or added
|
|
1146
|
+
hasTagsDiff = true;
|
|
1147
|
+
tagsDiff[tag] = hasValue(secondValue) ? secondValue : null;
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
return hasTagsDiff ? tagsDiff : null;
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
/**
|
|
1154
|
+
* Applies the given delta to the given snapshot and returns the result.
|
|
1155
|
+
* This is essentially the opposite of diffSnapshots().
|
|
1156
|
+
* @param snapshot The snapshot that the diff should be applied to.
|
|
1157
|
+
* @param diff The delta that should be applied to the snapshot.
|
|
1158
|
+
*/
|
|
1159
|
+
function applyDiffToSnapshot(snapshot, diff) {
|
|
1160
|
+
return apply(snapshot, diff);
|
|
1161
|
+
}
|
|
938
1162
|
// Actions
|
|
939
1163
|
/**
|
|
940
1164
|
* Shows a toast message to the user.
|
|
@@ -1708,30 +1932,6 @@ export function createDefaultLibrary(context) {
|
|
|
1708
1932
|
const event = calcGetGeolocation(task.taskId);
|
|
1709
1933
|
return addAsyncAction(task, event);
|
|
1710
1934
|
}
|
|
1711
|
-
/**
|
|
1712
|
-
* Registers a custom portal with the given source code.
|
|
1713
|
-
* @param portalId The ID of the portal.
|
|
1714
|
-
* @param bot The bot that should be used to configure the portal.
|
|
1715
|
-
* @param tagOrSource The tag or source code that the portal should be created from.
|
|
1716
|
-
* @param options The options for the portal.
|
|
1717
|
-
*/
|
|
1718
|
-
function openCustomPortal(portalId, bot, tagOrSource = null, options = {}) {
|
|
1719
|
-
const task = context.createTask();
|
|
1720
|
-
const event = calcOpenCustomPortal(portalId, getID(bot), tagOrSource, {
|
|
1721
|
-
mode: (options === null || options === void 0 ? void 0 : options.mode) || 'tag',
|
|
1722
|
-
style: (options === null || options === void 0 ? void 0 : options.style) || {},
|
|
1723
|
-
}, task.taskId);
|
|
1724
|
-
return addAsyncAction(task, event);
|
|
1725
|
-
}
|
|
1726
|
-
/**
|
|
1727
|
-
* Builds a script bundle from the given tag.
|
|
1728
|
-
* @param tag The tag that the bundle should be created from.
|
|
1729
|
-
*/
|
|
1730
|
-
function buildBundle(tag) {
|
|
1731
|
-
const task = context.createTask();
|
|
1732
|
-
const event = calcBuildBundle(tag, task.taskId);
|
|
1733
|
-
return addAsyncAction(task, event);
|
|
1734
|
-
}
|
|
1735
1935
|
/**
|
|
1736
1936
|
* Specifies that the given prefix should be interpreted as code.
|
|
1737
1937
|
* @param prefix The prefix that code tags should start with.
|
|
@@ -1912,7 +2112,7 @@ export function createDefaultLibrary(context) {
|
|
|
1912
2112
|
totalCount: result.totalCount,
|
|
1913
2113
|
getMoreRecords: () => __awaiter(this, void 0, void 0, function* () {
|
|
1914
2114
|
if (result.hasMoreRecords && hasValue(result.cursor)) {
|
|
1915
|
-
return issueEvent({ cursor: result.cursor });
|
|
2115
|
+
return issueEvent(Object.assign(Object.assign({}, query), { cursor: result.cursor }));
|
|
1916
2116
|
}
|
|
1917
2117
|
else {
|
|
1918
2118
|
throw new Error('No more records to retrieve.');
|
|
@@ -2746,8 +2946,46 @@ export function createDefaultLibrary(context) {
|
|
|
2746
2946
|
* @param options The options that should be used to send the webhook.
|
|
2747
2947
|
*/
|
|
2748
2948
|
function webhook(options) {
|
|
2949
|
+
if (options.retryCount > 0) {
|
|
2950
|
+
return _retryWebhook(options);
|
|
2951
|
+
}
|
|
2952
|
+
else {
|
|
2953
|
+
return _webhook(options);
|
|
2954
|
+
}
|
|
2955
|
+
}
|
|
2956
|
+
function _retryWebhook(options) {
|
|
2957
|
+
var _a, _b, _c, _d;
|
|
2958
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2959
|
+
const retryCount = Math.min(options.retryCount, MAX_RETRY_COUNT);
|
|
2960
|
+
const timeToWait = Math.max(0, Math.min((_a = options.retryAfterMs) !== null && _a !== void 0 ? _a : DEFAULT_RETRY_AFTER_MS, MAX_RETRY_AFTER_MS));
|
|
2961
|
+
const statusCodes = (_b = options.retryStatusCodes) !== null && _b !== void 0 ? _b : DEFUALT_RETRY_STATUS_CODES;
|
|
2962
|
+
let retries = 0;
|
|
2963
|
+
while (true) {
|
|
2964
|
+
try {
|
|
2965
|
+
return yield _webhook(options);
|
|
2966
|
+
}
|
|
2967
|
+
catch (err) {
|
|
2968
|
+
if (retries >= retryCount) {
|
|
2969
|
+
throw err;
|
|
2970
|
+
}
|
|
2971
|
+
else if (!statusCodes.includes((_d = (_c = err.response) === null || _c === void 0 ? void 0 : _c.status) !== null && _d !== void 0 ? _d : 0)) {
|
|
2972
|
+
throw err;
|
|
2973
|
+
}
|
|
2974
|
+
yield sleep(timeToWait);
|
|
2975
|
+
retries += 1;
|
|
2976
|
+
}
|
|
2977
|
+
}
|
|
2978
|
+
});
|
|
2979
|
+
}
|
|
2980
|
+
function _webhook(options) {
|
|
2749
2981
|
const task = context.createTask();
|
|
2750
|
-
const event = calcWebhook(
|
|
2982
|
+
const event = calcWebhook({
|
|
2983
|
+
method: options.method,
|
|
2984
|
+
url: options.url,
|
|
2985
|
+
responseShout: options.responseShout,
|
|
2986
|
+
data: options.data,
|
|
2987
|
+
headers: options.headers,
|
|
2988
|
+
}, task.taskId);
|
|
2751
2989
|
return addAsyncAction(task, event);
|
|
2752
2990
|
}
|
|
2753
2991
|
/**
|
|
@@ -4200,7 +4438,7 @@ export function createDefaultLibrary(context) {
|
|
|
4200
4438
|
destroyChildren(id);
|
|
4201
4439
|
}
|
|
4202
4440
|
function destroyChildren(id) {
|
|
4203
|
-
const children = getBots('creator', id);
|
|
4441
|
+
const children = getBots(byTag('creator', createBotLink([id])));
|
|
4204
4442
|
for (let child of children) {
|
|
4205
4443
|
destroyBot(child);
|
|
4206
4444
|
}
|
|
@@ -4226,6 +4464,93 @@ export function createDefaultLibrary(context) {
|
|
|
4226
4464
|
}
|
|
4227
4465
|
whisper(bot, `${groupName}${stateName}OnEnter`, arg);
|
|
4228
4466
|
}
|
|
4467
|
+
/**
|
|
4468
|
+
* Creates a tag value that can be used to link to the given bots.
|
|
4469
|
+
* @param bots The bots that the link should point to.
|
|
4470
|
+
*/
|
|
4471
|
+
function createBotLinkApi(...bots) {
|
|
4472
|
+
let targets = flatMap(bots);
|
|
4473
|
+
let result = [];
|
|
4474
|
+
for (let t of targets) {
|
|
4475
|
+
if (isBot(t)) {
|
|
4476
|
+
result.push(t.id);
|
|
4477
|
+
}
|
|
4478
|
+
else {
|
|
4479
|
+
let links = parseBotLink(t);
|
|
4480
|
+
if (links) {
|
|
4481
|
+
result.push(...links);
|
|
4482
|
+
}
|
|
4483
|
+
else {
|
|
4484
|
+
result.push(t);
|
|
4485
|
+
}
|
|
4486
|
+
}
|
|
4487
|
+
}
|
|
4488
|
+
return createBotLink(result);
|
|
4489
|
+
}
|
|
4490
|
+
/**
|
|
4491
|
+
* Gets the list of bot links that are stored in this bot's tags.
|
|
4492
|
+
* @param bot The bot to get the links for.
|
|
4493
|
+
*/
|
|
4494
|
+
function getBotLinks(bot) {
|
|
4495
|
+
let links = [];
|
|
4496
|
+
for (let tag of Object.keys(bot.tags)) {
|
|
4497
|
+
const val = bot.tags[tag];
|
|
4498
|
+
const ids = parseBotLink(val);
|
|
4499
|
+
if (ids) {
|
|
4500
|
+
links.push({
|
|
4501
|
+
tag,
|
|
4502
|
+
botIDs: ids,
|
|
4503
|
+
});
|
|
4504
|
+
}
|
|
4505
|
+
}
|
|
4506
|
+
return links;
|
|
4507
|
+
}
|
|
4508
|
+
/**
|
|
4509
|
+
* Updates all the links in the given bot using the given ID map.
|
|
4510
|
+
* Useful if you know that the links in the given bot are outdated and you know which IDs map to the new IDs.
|
|
4511
|
+
* @param bot The bot to update.
|
|
4512
|
+
* @param idMap The map of old IDs to new IDs that should be used.
|
|
4513
|
+
*/
|
|
4514
|
+
function updateBotLinks(bot, idMap) {
|
|
4515
|
+
let map;
|
|
4516
|
+
if (idMap instanceof Map) {
|
|
4517
|
+
map = idMap;
|
|
4518
|
+
}
|
|
4519
|
+
else if (typeof idMap === 'object') {
|
|
4520
|
+
map = new Map();
|
|
4521
|
+
for (let key in idMap) {
|
|
4522
|
+
const newId = idMap[key];
|
|
4523
|
+
if (typeof newId === 'string') {
|
|
4524
|
+
map.set(key, newId);
|
|
4525
|
+
}
|
|
4526
|
+
else if (isBot(newId)) {
|
|
4527
|
+
map.set(key, newId.id);
|
|
4528
|
+
}
|
|
4529
|
+
}
|
|
4530
|
+
}
|
|
4531
|
+
else {
|
|
4532
|
+
return;
|
|
4533
|
+
}
|
|
4534
|
+
for (let tag of Object.keys(bot.tags)) {
|
|
4535
|
+
const val = bot.tags[tag];
|
|
4536
|
+
const ids = parseBotLink(val);
|
|
4537
|
+
if (ids) {
|
|
4538
|
+
const mapped = ids.map((id) => {
|
|
4539
|
+
if (map.has(id)) {
|
|
4540
|
+
const newId = map.get(id);
|
|
4541
|
+
if (typeof newId === 'string') {
|
|
4542
|
+
return newId;
|
|
4543
|
+
}
|
|
4544
|
+
else if (isBot(newId)) {
|
|
4545
|
+
return newId.id;
|
|
4546
|
+
}
|
|
4547
|
+
}
|
|
4548
|
+
return id;
|
|
4549
|
+
});
|
|
4550
|
+
bot.tags[tag] = createBotLink(mapped);
|
|
4551
|
+
}
|
|
4552
|
+
}
|
|
4553
|
+
}
|
|
4229
4554
|
/**
|
|
4230
4555
|
* Shouts the given event to every bot in every loaded simulation.
|
|
4231
4556
|
* @param eventName The name of the event to shout.
|