@casual-simulation/aux-runtime
Version:
Runtime for AUX projects
1,460 lines (1,459 loc) • 115 kB
TypeScript
import type { AuxGlobalContext } from './AuxGlobalContext';
import { DEBUG_STRING } from './AuxGlobalContext';
import type { BotTags, Bot, ShowChatOptions, BotAction, BotsState, CameraType, BarcodeFormat, PortalType, ShowInputOptions, LocalFormAnimationAction, ShareOptions, Easing, BotAnchorPoint, RuntimeBot, BotSpace, EaseType, RegisterPrefixOptions, OpenCircleWipeOptions, SuperShoutAction, ShowToastAction, ShowJoinCodeAction, RequestFullscreenAction, ExitFullscreenAction, ShowHtmlAction, HideHtmlAction, SetClipboardAction, FocusOnBotAction, ShowChatBarAction, EnableARAction, EnableVRAction, DownloadAction, ShowUploadAuxFileAction, OpenQRCodeScannerAction, ShowQRCodeAction, OpenBarcodeScannerAction, ShowBarcodeAction, LoadServerAction, UnloadServerAction, ReplaceDragBotAction, ShowInputForTagAction, GoToDimensionAction, GoToURLAction, OpenURLAction, OpenConsoleAction, RejectAction, FocusOnOptions, SnapTarget, AddDropSnapTargetsAction, RecordingOptions, Recording, SyntheticVoice, EnablePOVAction, EnableCustomDraggingAction, SetAppOutputAction, PartialBotsState, ParsedBotLink, ConvertGeolocationToWhat3WordsOptions, BeginAudioRecordingAction, MediaPermssionOptions, ImageClassifierOptions, ClassifyImagesOptions, ClassifyImagesResult, AddDropGridTargetsAction, InstUpdate, StartFormAnimationOptions, StopFormAnimationOptions, FormAnimationData, WakeLockConfiguration, EnableXROptions, ShowConfirmOptions, StoredAux, Geolocation, OpenPhotoCameraOptions, Photo, Point2D, RecordLoomOptions, LoomVideo, LoomVideoEmbedMetadata, InstallAuxFileMode, LoadServerConfigAction, InstConfig, UnloadServerConfigAction, Point3D, MapLayer, DynamicListener } from '@casual-simulation/aux-common/bots';
import type { AIChatOptions, AIGenerateSkyboxOptions, AIGenerateImageOptions, JoinRoomActionOptions, RoomOptions, RoomTrackOptions, SetRoomTrackOptions, RoomRemoteOptions, DataRecordOptions, RecordActionOptions, ListDataOptions, AISloydGenerateModelOptions, ListWebhooksOptions, ListNotificationsOptions, SendNotificationOptions, GrantEntitlementsRequest, GrantEntitlementsResult, InstallPackageResult } from './RecordsEvents';
import type { RemoteAction, AvailablePermissions, Entitlement, VersionNumber } from '@casual-simulation/aux-common';
import '@casual-simulation/aux-common/polyfill/Array.first.polyfill';
import '@casual-simulation/aux-common/polyfill/Array.last.polyfill';
import { isAsymmetricKeypair, isAsymmetricEncrypted, isEncrypted } from '@casual-simulation/crypto';
import './PerformanceNowPolyfill';
import '@casual-simulation/aux-common/BlobPolyfill';
import type { AuxDevice } from './AuxDevice';
import type { AuxVersion } from './AuxVersion';
import { Vector3, Vector2, Quaternion, Rotation } from '@casual-simulation/aux-common/math';
import type { AIChatMessage, GrantResourcePermissionResult, ListStudiosResult, ListSubscriptionsResult, NotificationRecord, PushNotificationPayload, RevokePermissionResult, SendNotificationResult, SubscribeToNotificationResult, UnsubscribeToNotificationResult, WebhookRecord, CreatePublicRecordKeyResult, GetDataResult, RecordDataResult, RecordFileFailure, EraseDataResult, EraseFileResult, ListDataResult, AddCountResult, GetCountResult, GrantMarkerPermissionResult, GrantRoleResult, RevokeRoleResult, PackageRecord, ListInstalledPackagesResult } from '@casual-simulation/aux-records';
import { DateTime } from 'luxon';
import * as hooks from 'preact/hooks';
import { render, createRef, createContext } from 'preact';
import * as compat from 'preact/compat';
import type { Breakpoint, InterpreterContinuation, InterpreterStop } from '@casual-simulation/js-interpreter';
import { UNCOPIABLE } from '@casual-simulation/js-interpreter/InterpreterUtils';
import { INTERPRETABLE_FUNCTION } from './AuxCompiler';
import type { AuxRuntime } from './AuxRuntime';
import type { AICreateOpenAIRealtimeSessionTokenResult, AIHumeGetAccessTokenResult, AISloydGenerateModelResponse } from '@casual-simulation/aux-records/AIController';
import type { TagMapper } from './RuntimeEvents';
import type { CrudEraseItemResult, CrudGetItemResult, CrudListItemsResult, CrudRecordItemResult } from '@casual-simulation/aux-records/crud/CrudRecordsController';
import type { HandleWebhookResult } from '@casual-simulation/aux-records/webhooks/WebhookRecordsController';
import type { SharedDocument } from '@casual-simulation/aux-common/documents/SharedDocument';
import type { CreateRealtimeSessionTokenRequest } from '@casual-simulation/aux-records/AIOpenAIRealtimeInterface';
import type { PackageRecordVersion, PackageRecordVersionKey, PackageRecordVersionKeySpecifier, RecordPackageVersionResult } from '@casual-simulation/aux-records/packages/version';
import type { EraseDocumentResult, SearchCollectionSchema, SearchDocument, SearchRecord, SearchRecordOutput, StoreDocumentResult } from '@casual-simulation/aux-records/search';
/**
* Defines an interface for a function that provides HTML VDOM capabilities to bots.
*/
export interface HtmlFunction {
(...args: any[]): any;
h: (name: string | Function, props: any, ...children: any[]) => any;
f: any;
}
/**
* Creates a new interpretable function based on the given function.
* @param interpretableFunc
*/
export declare function createInterpretableFunction<TArg extends Array<any>, R>(interpretableFunc: (...args: TArg) => Generator<any, R, any>): {
(...args: TArg): R;
[INTERPRETABLE_FUNCTION]: (...args: TArg) => Generator<any, R, any>;
};
/**
* Sets the INTERPRETABLE_FUNCTION property on the given object (semantically a function) to the given interpretable version and returns the object.
* @param interpretableFunc The version of the function that should be used as the interpretable version of the function.
* @param normalFunc The function that should be tagged.
*/
export declare function tagAsInterpretableFunction<T, N>(interpretableFunc: T, normalFunc: N): N & {
[INTERPRETABLE_FUNCTION]: T;
};
/**
* Defines an interface for a library of functions and values that can be used by formulas and listeners.
*/
export interface AuxLibrary {
/**
* The functions that are part of the general API.
*/
api: {
whisper(bot: (Bot | string)[] | Bot | string, eventName: string, arg?: any): any[];
shout(name: string, arg?: any): any[];
__energyCheck(): void;
[key: string]: any;
};
/**
* The functions that are part of the bot-specific API.
*/
tagSpecificApi: {
[key: string]: (options: TagSpecificApiOptions) => any;
};
typeDefinitions?: string;
}
/**
* Defines the possible values that can be used as a tag filter.
*
* @dochash types/core
* @docgroup 01-core
* @docname TagFilter
*/
export type TagFilter = ((value: any) => boolean) | string | number | boolean | null | undefined;
/**
* Defines a type that represents a mod.
* That is, a set of tags that can be applied to another bot.
*
* @dochash types/core
* @docgroup 01-core
* @docname Mod
*/
export type Mod = BotTags | Bot;
/**
* An interface that is used to say which user/device/session an event should be sent to.
*
* @dochash types/os/event
* @docname SessionSelector
*/
export interface SessionSelector {
userId?: string;
sessionId?: string;
connectionId?: string;
broadcast?: boolean;
}
/**
* Defines a set of options for a webhook.
*
* @dochash types/web
* @doctitle Web Types
* @docsidebar Web
* @docdescription These types are used for web requests.
* @docname WebhookOptions
*/
export interface WebhookOptions {
/**
* The HTTP Method that the request should use.
*/
method?: string;
/**
* The URL that the request should be made to.
*/
url?: string;
/**
* The headers to include in the request.
*
* @docsource Headers
*/
headers?: {
[key: string]: string;
};
/**
* The data to send with the request.
*/
data?: any;
/**
* The shout that should be made when the request finishes.
*/
responseShout?: string;
/**
* The number of retries that should be attempted for the webhook.
*/
retryCount?: number;
/**
* The HTTP response status codes that should allow the web request to be retried.
*/
retryStatusCodes?: number[];
/**
* The number of miliseconds to wait between retry requests.
*/
retryAfterMs?: number;
}
/**
* Defines an interface that represents a request for {@link ai.generateSkybox-request}.
*
* @dochash types/ai
* @docname AIGenerateSkyboxRequest
*/
export interface AIGenerateSkyboxRequest {
/**
* The prompt that describes what the generated skybox should look like.
*/
prompt: string;
/**
* The prompt that that describes what the generated skybox should avoid looking like.
*/
negativePrompt?: string;
/**
* The options that should be included in the request.
*/
options?: AIGenerateSkyboxOptions;
}
/**
* Defines an interface that represents the result from {@link ai.generateSkybox-request}.
*
* @dochash types/ai
* @docname AIGenerateSkyboxResult
*/
export interface AIGenerateSkyboxResult {
/**
* The URL that the generated skybox is located at.
*/
fileUrl: string;
/**
* The URL that the thumbnail for the generated skybox is located at.
*/
thumbnailUrl?: string;
}
/**
* Defines an interface that represents a result from {@link ai.generateImage-request}.
* @dochash types/ai
* @docname AIGenerateImageSuccess
*/
export interface AIGenerateImageAPISuccess {
success: true;
/**
* The list of images that were generated.
*/
images: AIGeneratedImageAPI[];
}
/**
* Defines an interface that represents an AI generated image.
*
* @dochash types/ai
* @docname AIGeneratedImage
*/
export interface AIGeneratedImageAPI {
/**
* The base64 encoded image.
*/
base64: string;
/**
* The URL that can be used to display the image.
*/
url: string;
/**
* The seed of the generated image.
*/
seed?: number;
/**
* The MIME Type of the image data.
*/
mimeType: string;
}
export interface RecordPackageVersionApiRequest {
/**
* The name of the record that the package version should be recorded to.
*/
recordName: string;
/**
* The address that the package version should be recorded to.
*/
address: string;
/**
* The version of the package that should be recorded.
*/
key: PackageRecordVersionKey;
/**
* The description that should be included in the package version.
*/
description: string;
/**
* The list of entitlements for the package version.
* If omitted, then the package version will be recorded without any entitlements.
*/
entitlements?: Entitlement[];
/**
* The bots that should be saved to the package.
*/
bots: Bot[];
/**
* The markers that should be applied to the package version.
*/
markers?: string[];
}
/**
* Defines an interface that represents a request for {@link recordSearchCollection}.
*
* @dochash types/records/search
* @docname RecordSearchCollectionRequest
*/
export interface RecordSearchCollectionApiRequest {
/**
* The name of the record that the package version should be recorded to.
*/
recordName: string;
/**
* The address that the package version should be recorded to.
*/
address: string;
/**
* The schema that should be used for the collection.
*/
schema: SearchCollectionSchema;
/**
* The markers that should be applied to the package version.
*/
markers?: string[];
}
/**
* Defines an interface that represents a request for {@link recordSearchDocument}.
*
* @dochash types/records/search
* @docname RecordSearchDocumentRequest
*/
export interface RecordSearchDocumentApiRequest {
recordName: string;
address: string;
document: SearchDocument;
}
/**
* Defines a set of options for {@link animateTag-byTag}.
*
* @dochash types/animation
* @doctitle Animation Types
* @docsidebar Animation
* @docdescription These types are used for animating tags.
* @docname AnimateTagOptions
*/
export interface AnimateTagFunctionOptions {
/**
* The value that should be animated from.
* If not specified then the current tag value will be used.
*/
fromValue?: any;
/**
* The value that should be animated to.
*/
toValue: any;
/**
* The duration of the animation in seconds.
*/
duration: number;
/**
* The time that the animation should start.
* Should be the number of miliseconds since January 1st 1970 UTC-0. (e.g. os.localTime or os.agreedUponTime).
*/
startTime?: number;
/**
* The type of easing to use.
* If not specified then "linear" "inout" will be used.
*
* Can also be a custom function that takes a single parameter and returns a number.
* The paramater will be a number between 0 and 1 indicating the progress through the tween.
*/
easing?: EaseType | Easing | ((progress: number) => number);
/**
* The space that the tag should be animated in.
* If not specified then "tempLocal" will be used.
* If false, then the bot will be edited instead of using tag masks.
*/
tagMaskSpace?: BotSpace | false;
}
/**
* Defines a bot filter function.
*
* Common bot filters are {@link byTag}
*
* @dochash types/core
* @docgroup 01-core
* @docname BotFilter
*/
export type BotFilter = ((bot: Bot) => boolean) | null;
/**
* Defines a bot filter function.
*/
export interface BotFilterFunction {
(bot: Bot): boolean;
sort?: (bot: Bot) => any;
[DEBUG_STRING]?: string;
}
/**
* Defines the options for {@link experiment.speakText}.
*
* @dochash types/experimental
* @docname SpeakTextOptions
*/
export interface SpeakTextApiOptions {
/**
* The rate that the text should be spoken at.
* This can be any positive number.
*/
rate?: number;
/**
* The pitch that the text should be spoken at.
* This can be any positive number.
*/
pitch?: number;
/**
* The voice that the text should be spoken with.
* This can be the voice object or the name of a voice.
* Note that not all browsers support the same voices.
*/
voice?: string | SyntheticVoice;
}
/**
* Defines a set of options for a tween.
*
* @dochash types/experimental
* @docname TweenOptions
*/
export interface TweenOptions {
/**
* The easing for the tween.
*/
easing?: Easing;
/**
* The duration of the tween in seconds.
*/
duration?: number;
}
/**
* Defines an interface that contains performance statistics about a inst.
*/
export interface PerformanceStats {
/**
* The number of bots in the inst.
*/
numberOfBots: number;
/**
* A list of listen tags and the amount of time spent executing them (in miliseconds).
* Useful to guage if a listen tag is causing the inst to slow down.
*/
shoutTimes: {
tag: string;
timeMs: number;
}[];
/**
* The total number of active setTimeout() and setInterval() timers that are active.
*/
numberOfActiveTimers: number;
loadTimes: {
[key: string]: number;
};
}
/**
* Options needed for the Bot-specific API.
*/
export interface TagSpecificApiOptions {
/**
* The Bot that the API is for.
*/
bot: Bot;
/**
* The tag that the API is for.
*/
tag: string;
/**
* The bot that is set as the creator of the current bot.
*/
creator: RuntimeBot;
/**
* The bot that is set as the config of the current bot.
*/
config?: RuntimeBot;
}
export declare const GET_RUNTIME: unique symbol;
/**
* Defines an interface for objects that represent a debugger and can retrieve their internal runtime.
*/
export interface DebuggerInterface {
/**
* Gets the runtime for the debugger.
*/
[GET_RUNTIME]: () => AuxRuntime;
}
export interface DebuggerBase {
/**
* Gets the list of portal bots in the debugger.
*/
getPortalBots(): Map<string, Bot>;
/**
* Gets the list of action objects that have been performed by bots in the current debugger.
* Action objects are used by CasualOS to represent changes to bots or external effects that should be performed.
* Examples of this are {@link create}, {@link os.toast} and {@link os.enableVR}.
*
* @example Get the list of bot changes and actions that have been performed in a debugger
* const debug = await os.createDebugger();
* debug.create({
* test: '@os.toast("Hello")'
* });
* debug.shout("test");
*
* const actions = debug.getAllActions();
*
* assertEqual(actions, [
* {
* type: 'add_bot',
* id: 'uuid-1',
* bot: {
* id: 'uuid-1',
* tags: {
* test: '@os.toast("Hello")'
* }
* }
* },
* {
* type: 'show_toast',
* message: 'Hello',
* duration: 2000
* }
* ]);
*/
getAllActions(): BotAction[];
/**
* Gets the list of common action objects that have been performed by bots in the current debugger. Action objects are used by CasualOS to represent changes to bots or external effects that should be performed.
* Common actions are actions that do not immediately change bots or bot tags or masks.
*
* Examples of common actions are {@link os.toast} and {@link os.enableVR}.
*
* @example Get the list of actions that have been performed in a debugger
* const debug = await os.createDebugger();
* debug.create({
* test: '@os.toast("Hello")'
* });
* debug.shout("test");
*
* const actions = debug.getCommonActions();
*
* assertEqual(actions, [
* {
* type: 'show_toast',
* message: 'Hello',
* duration: 2000
* }
* ]);
*/
getCommonActions(): BotAction[];
/**
* Gets the list of bot actions that have been performed by bots in the current debugger.
* Action objects are used by CasualOS to represent changes to bots or external effects that should be performed.
* Bot actions are actions that immediately change bots or bot tags or masks.
*
* Examples of bot actions are {@link create}, {@link destroy} or {@link setTagMask}.
*
* @example Get the list of bot changes that have been performed in a debugger
* const debug = await os.createDebugger();
* debug.create({
* test: '@os.toast("Hello")'
* });
* debug.shout("test");
*
* const actions = debug.getBotActions();
*
* assertEqual(actions, [
* {
* type: 'add_bot',
* id: 'uuid-1',
* bot: {
* id: 'uuid-1',
* tags: {
* test: '@os.toast("Hello")'
* }
* }
* },
* ]);
*/
getBotActions(): BotAction[];
/**
* Gets the list of errors that have occurred in the current debugger. Errors occur when an exceptional event happens in a script and prevents the rest of the script from executing.
*
* Debuggers capture these errors and let you inspect them afterwards.
*
* @example Get the list of errors that have happened in a debugger
* const debug = await os.createDebugger();
* debug.create({
* test: '@throw new Error("My Error")'
* });
* debug.shout("test");
*
* const errors = debug.getErrors();
*
* assertEqual(errors.length, 1);
* assertEqual(errors[0].error, new Error("My Error"));
* assertEqual(errors[0].tag, "test");
*/
getErrors(): any[];
/**
* Registers the given handler to be called before a bot action is executed in this debugger.
* @param handler The handler that should be called.
*/
onBeforeAction(handler: (action: BotAction) => void): void;
/**
* Registers the given handler to be called after a bot action is executed in this debugger.
* @param handler The handler that should be called.
*/
onAfterAction(handler: (action: BotAction) => void): void;
/**
* Registers the given handler function to be called before a user action is performed in the debugger.
*
* User actions are like normal actions, except they are generated by the CasualOS frontend.
* Generally, this only happens for built-in shouts and whispers.
* Additionally, these actions can only be automatically created for debuggers that are attached using {@link os.attachDebugger}.
*
* @param listener the function that should be called before a user action is performed.
*
* @example Listen for tag updates in a debugger
* const debug = await os.createDebugger({
* pausable: true
* });
*
* // Register a listener that gets called whenever a user action is about to be performed.
* debug.onBeforeUserAction(update => {
* console.log('user action', update);
* });
*
* // Because the debugger is pausable, the create() function returns a promise
* // because it calls @onCreate which could cause a pause trigger to be hit.
* const debuggerBot = await debug.create({
* home: true,
* });
*
* // Attach the debugger to the front end
* await os.attachDebugger(debug);
*
* @docname onBeforeUserAction
* @docid debug.onBeforeUserAction
*/
onBeforeUserAction(listener: (action: BotAction) => void): void;
/**
* Registers the given handler function to be called by the debugger whenever a script enqueues an action.
* This occurrs for common actions like {@link os.toast} and {@link os.showInput}.
*
* Every action that is enqueued ends up being performed.
*
* @param listener the function that should be called whenever an action is scheduled to be performed.
*
* @example Listen for actions to be enqueued in a debugger
* const debug = await os.createDebugger({
* pausable: true
* });
*
* // Register a listener that gets called whenever an action is scheduled to be performed.
* debug.onScriptActionEnqueued(action => {
* console.log('action enqueued', action);
* });
*
* // Because the debugger is pausable, the create() function returns a promise
* // because it calls @onCreate which could cause a pause trigger to be hit.
* const debuggerBot = await debug.create({
* test: '@let abc = 123; os.toast(abc);'
* });
*
* // Send a shout. Just like the create() function above, we recieve a promise that we can await.
* await debug.shout('test');
*/
onScriptActionEnqueued(listener: (action: BotAction) => void): void;
/**
* Registers the given handler function to be called after any tag is updated in the debugger.
*
* @param listener the function that should be called when a tag is updated.
*
* @example Listen for tag updates in a debugger
* const debug = await os.createDebugger({
* pausable: true
* });
*
* // Register a listener that gets called whenever a tag is updated.
* debug.onAfterScriptUpdatedTag(update => {
* console.log('tag updated', update);
* });
*
* // Because the debugger is pausable, the create() function returns a promise
* // because it calls @onCreate which could cause a pause trigger to be hit.
* const debuggerBot = await debug.create({
* test: '@tags.message = "hello, world";'
* });
*
* // Send a shout. Just like the create() function above, we recieve a promise that we can await.
* await debug.shout('test');
*/
onAfterScriptUpdatedTag(listener: (update: DebuggerTagUpdate) => void): void;
/**
* Registers the given handler function to be called after any tag mask is updated in the debugger.
*
* @param listener the function that should be called when a tag mask is updated.
*
* @example Listen for tag mask updates in a debugger
* const debug = await os.createDebugger({
* pausable: true
* });
*
* // Register a listener that gets called whenever a tag mask is updated.
* debug.onAfterScriptUpdatedTagMask(update => {
* console.log('tag mask updated', update);
* });
*
* // Because the debugger is pausable, the create() function returns a promise
* // because it calls @onCreate which could cause a pause trigger to be hit.
* const debuggerBot = await debug.create({
* test: '@masks.message = "hello, world";'
* });
*
* // Send a shout. Just like the create() function above, we recieve a promise that we can await.
* await debug.shout('test');
*/
onAfterScriptUpdatedTagMask(listener: (update: DebuggerTagMaskUpdate) => void): void;
/**
* Performs the given actions in order as if they were user actions.
*
* This function works similarly to {@link action.perform} except that actions performed with it will also call handlers registered with {@link debug.onBeforeUserAction}.
* @param actions the actions that should be performed.
*/
performUserAction(...actions: BotAction[]): Promise<(any[] | null)[]>;
/**
* The web actions that are available in this debugger.
*
* @docreferenceactions ^web\.
* @docsource WebActions
*/
web: {};
/**
* The OS actions that are available in this debugger.
*
* @docreferenceactions ^os\.
* @docsource OSActions
*/
os: {};
/**
* The action-related actions that are available in this debugger.
*
* @docreferenceactions ^action\.
* @docsource ActionActions
*/
action: {};
}
/**
* Defines the possible types that represent a debugger.
*
* @dochash types/debuggers
* @docname Debugger
*/
export type Debugger = NormalDebugger | PausableDebugger;
/**
* Defines an interface that represents a debugger.
*
* @dochash types/debuggers/debugger
* @doctitle Debugger
* @docsidebar Debugger
* @docdescription Defines an interface that represents a debugger.
* @docname Debugger
* @docreferenceactions ^\w+$
*/
export interface NormalDebugger extends DebuggerBase {
}
/**
* Defines an interface that represents a pausable debugger.
*
* @dochash types/debuggers/pausable-debugger
* @doctitle Pausable Debugger
* @docsidebar Pausable Debugger
* @docdescription Defines an interface that represents a pausable debugger.
* @docname PausableDebugger
* @docreferenceactions ^\w+$
*/
export interface PausableDebugger extends DebuggerBase {
/**
* Registers the given function to be called whenever the debugger is paused by hitting a pause trigger.
*
* @param handler the function that should be called when the debugger is paused.
*
* @example Listen for pauses on a debugger
* const debug = await os.createDebugger({
* pausable: true
* });
*
* debug.onPause(pause => {
* console.log('pause happened!', pause);
* });
*
* @docname onPause
* @docid debug.onPause
*/
onPause(handler: (pause: DebuggerPause) => void): void;
/**
* Registers or updates a pause trigger with a debugger. Returns the newly created trigger.
*
* Pause triggers can be used to tell the debugger where you want it to temporarily stop execution. You specify the bot, tag, line and column numbers, and the debugger will stop before it executes the code at that location.
* Additionally, the debugger will call all handlers that have been registered with {@link debug.onPause}.
*
* @param trigger The trigger that should be registered or updated.
*
* @docname setPauseTrigger
* @docid debug.setPauseTrigger-trigger
*/
_setPauseTrigger_trigger(trigger: PauseTrigger): PauseTrigger;
/**
* Registers or updates a pause trigger with this debugger.
* Pause triggers can be used to tell the debugger when you want it to stop execution.
* You specify the bot, tag, line and column numbers and the debugger will stop before/after it executes the code at that location.
* @param botOrIdOrTrigger the bot, or bot ID that should be registered.
* @param tag the name of the tag that the trigger should be set on.
* @param options The options that go with this pause trigger.
*
* @example Set a pause trigger on a script
* const debug = await os.createDebugger({
* pausable: true
* });
*
* const b = await debug.create({
* test: '@os.toast("Hello, World!")'
* });
*
* const trigger = debug.setPauseTrigger(b, 'test', {
* lineNumber: 1,
* columnNumber: 1
* });
*
* @example Update a pause trigger on a script
* const debug = await os.createDebugger({
* pausable: true
* });
*
* const b = await debug.create({
* test: '@os.toast("Hello, World!")'
* });
*
* let trigger = debug.setPauseTrigger(b, 'test', {
* lineNumber: 1,
* columnNumber: 1
* });
*
* trigger = debug.setPauseTrigger({
* ...trigger,
* states: ['before', 'after']
* });
* @docname setPauseTrigger
* @docid debug.setPauseTrigger-botOrId
*/
_setPauseTrigger_botOrId(botOrIdOrTrigger: Bot | string, tag?: string, options?: PauseTriggerOptions): PauseTrigger;
/**
* Removes the given pause trigger from the debugger.
* @param triggerOrId the trigger or trigger ID that should be removed from the debugger.
*
* @example Remove a pause trigger
* const debug = await os.createDebugger({
* pausable: true
* });
*
* const b = await debug.create({
* test: '@os.toast("Hello, World!")'
* });
*
* const trigger = debug.setPauseTrigger(b, 'test', {
* lineNumber: 1,
* columnNumber: 1
* });
*
* debug.removePauseTrigger(trigger);
*/
removePauseTrigger(triggerOrId: string | PauseTrigger): void;
/**
* Disables the given pause trigger.
* Disabled pause triggers will continue to be listed with {@link debug.listPauseTriggers}, but will not cause a pause to happen while they are disabled.
*
* @param triggerOrId The trigger or trigger ID that should be disabled.
*
* @example Disable a pause trigger
* const debug = await os.createDebugger({
* pausable: true
* });
*
* const b = await debug.create({
* test: '@os.toast("Hello, World!")'
* });
*
* const trigger = debug.setPauseTrigger(b, 'test', {
* lineNumber: 1,
* columnNumber: 1
* });
*
* debug.disablePauseTrigger(trigger);
*/
disablePauseTrigger(triggerOrId: string | PauseTrigger): void;
/**
* Enables the given pause trigger
* @param triggerOrId The trigger or trigger ID that should be enabled.
*
* @example Enable a pause trigger
* const debug = await os.createDebugger({
* pausable: true
* });
*
* const b = await debug.create({
* test: '@os.toast("Hello, World!")'
* });
*
* const trigger = debug.setPauseTrigger(b, 'test', {
* lineNumber: 1,
* columnNumber: 1,
* enabled: false
* });
*
* debug.enablePauseTrigger(trigger);
*/
enablePauseTrigger(triggerOrId: string | PauseTrigger): void;
/**
* Gets the list of pause triggers that have been registered with this debugger.
*
* @example List the triggers that are set on this debugger
* const debug = await os.createDebugger({
* pausable: true
* });
*
* const b = await debug.create({
* test: '@os.toast("Hello, World!")'
* });
*
* const trigger = debug.setPauseTrigger(b, 'test', {
* lineNumber: 1,
* columnNumber: 1,
* enabled: false
* });
*
* const triggers = debug.listPauseTriggers();
*
* @docname listPauseTriggers
* @docid debug.listPauseTriggers
*/
listPauseTriggers(): PauseTrigger[];
/**
* Gets a list of common trigger locations for the specified tag on the specified bot. Returns an array containing the list of possible pause trigger locations.
*
* @param botOrId the bot or bot ID that the locations should be listed for.
* @param tag the name of the tag that the locations should be listed for.
*
* @example List common trigger locations for a script
* const debug = await os.createDebugger({
* pausable: true
* });
*
* const b = await debug.create({
* test: '@os.toast("Hello, World!")'
* });
*
* const triggerLocations = debug.listCommonPauseTriggers(b, 'test');
*
* @example Register a trigger from a common location
* const debug = await os.createDebugger({
* pausable: true
* });
*
* const b = await debug.create({
* test: '@os.toast("Hello, World!")'
* });
*
* const triggerLocations = debug.listCommonPauseTriggers(b, 'test');
*
* const trigger = debug.setPauseTrigger(b, 'test', {
* lineNumber: triggerLocations[0].lineNumber,
* columnNumber: triggerLocations[0].columnNumber,
* states: triggerLocations[0].possibleStates
* });
*/
listCommonPauseTriggers(botOrId: Bot | string, tag: string): PossiblePauseTriggerLocation[];
/**
* Resumes the debugger execution from the given pause.
* @param pause the debugger pause that was passed to the handler of {@link debug.onPause}.
*
* @example Resume execution on a debugger
* const debug = await os.createDebugger({
* pausable: true
* });
*
* // Register a listener that gets called whenever a pause happens in this debugger.
* debug.onPause(pause => {
* // Get the current stack frame from the pause
* const currentFrame = pause.callStack[pause.callStack.length - 1];
*
* // Set the abc variable to 999
* currentFrame.setVariableValue('abc', 999);
*
* // Resume execution after the pause.
* debug.resume(pause);
* });
*
* // Because the debugger is pausable, the create() function returns a promise
* // because it calls @onCreate which could cause a pause trigger to be hit.
* const debuggerBot = await debug.create({
* test: '@let abc = 123; os.toast(abc);'
* });
*
* // Set a pause trigger in the "test" script of the bot we just created
* // at line 1 column 16
* const trigger = debug.setPauseTrigger(debuggerBot, 'test', {
* lineNumber: 1,
* columnNumber: 16
* });
*
* // Send a shout. Just like the create() function above, we recieve a promise that we can await.
* await debug.shout('test');
*
* // Get the resulting actions from the debugger
* // and perform the first one. This should be the os.toast(), but instead of printing 123,
* // it should print 999 because we changed the value of abc during the debugger pause.
* const actions = debug.getCommonActions();
* action.perform(actions[0]);
*/
resume(pause: DebuggerPause): void;
/**
* Gets the current call stack for the debugger. Call stacks are useful for determining program flow and how scripts interact with each other.
*
* @example Get the call stack from a debugger
* const debug = os.createDebugger({
* pausable: true
* });
*
* const callStack = debug.getCallStack();
*/
getCallStack(): DebuggerCallFrame[];
/**
* Creates a new bot and returns it.
* @param parent The bot that should be the parent of the new bot.
* @param mods The mods which specify the new bot's tag values. If given a mod with no tags, then an error will be thrown.
* @returns The bot(s) that were created.
*
* @example Create a red bot without a parent.
* let debugger = await os.createDebugger({
* pausable: true
* });
* let redBot = await debugger.create(null, { "color": "red" });
*
* @example Create a red bot and a blue bot with `this` as the parent.
* let debugger = await os.createDebugger({
* pausable: true
* });
* let [redBot, blueBot] = await debugger.create(this, [
* { "color": "red" },
* { "color": "blue" }
* ]);
*/
create(...mods: Mod[]): Promise<Bot | Bot[]>;
/**
* Destroys the given bot, bot ID, or list of bots.
* @param bot The bot, bot ID, or list of bots to destroy.
*/
destroy(bot: Bot | string | Bot[]): Promise<void>;
/**
* Shouts the given events in order until a bot returns a result.
* Returns the result that was produced or undefined if no result was produced.
* @param eventNames The names of the events to shout.
* @param arg The argument to shout.
*/
priorityShout(eventNames: string[], arg?: any): Promise<any>;
/**
* Asks every bot in the inst to run the given action.
* In effect, this is like shouting to a bunch of people in a room.
*
* @param name The event name.
* @param arg The optional argument to include in the shout.
* @returns Returns a list which contains the values returned from each script that was run for the shout.
*
* @example Tell every bot to reset themselves.
* let debugger = await os.createDebugger({
* pausable: true
* });
* await debugger.shout("reset()");
*
* @example Ask every bot for its name.
* let debugger = await os.createDebugger({
* pausable: true
* });
* const names = await debugger.shout("getName()");
*
* @example Tell every bot say "Hi" to you.
* let debugger = await os.createDebugger({
* pausable: true
* });
* await debugger.shout("sayHi()", "My Name");
*/
shout(name: string, arg?: any): Promise<any[]>;
/**
* Asks the given bots to run the given action.
* In effect, this is like whispering to a specific set of people in a room.
*
* @param bot The bot(s) to send the event to.
* @param eventName The name of the event to send.
* @param arg The optional argument to include.
* @returns Returns a list which contains the values returned from each script that was run for the shout.
*/
whisper(bot: (Bot | string)[] | Bot | string, eventName: string, arg?: any): Promise<any>;
/**
* Changes the state that the given bot is in.
* @param bot The bot to change.
* @param stateName The state that the bot should move to.
* @param groupName The group of states that the bot's state should change in. (Defaults to "state")
*/
changeState(bot: Bot, stateName: string, groupName?: string): Promise<void>;
}
export interface AuxFileOptions {
/**
* The version that should be used for the output file.
*
* Version 1 stores bots as pure JSON and is the original version of the file format.
* Version 2 stores bots as updates and is the new version of the file format.
*
* If not specifed, then version 2 will be used.
*/
version?: 1 | 2;
}
/**
* Defines an interface for a possible pause trigger location.
*
* @dochash types/debuggers/common
* @docname PossiblePauseTriggerLocation
*/
export interface PossiblePauseTriggerLocation {
/**
* The line number that the trigger would pause the debugger at.
*/
lineNumber: number;
/**
* The column number that the trigger would pause the debugger at.
*/
columnNumber: number;
/**
* The states that are reasonable for this pause trigger to stop at.
*/
possibleStates: PossiblePauseTriggerStates;
}
/**
* The possible states that a pause trigger can be set to.
*
* @dochash types/debuggers/common
* @docname PossiblePauseTriggerStates
*/
export type PossiblePauseTriggerStates = ['before' | 'after'] | ['before', 'after'];
/**
* Defines an interface for a debugger trace that represents when a tag was updated.
*
* @dochash types/debuggers/common
* @docname DebuggerTagUpdate
*/
export interface DebuggerTagUpdate {
/**
* The ID of the bot that was updated.
*/
botId: string;
/**
* The tag that was updated.
*/
tag: string;
/**
* The old value of the tag.
*/
oldValue: any;
/**
* The new value for the tag.
*/
newValue: any;
}
/**
* Defines an interface for a debugger trace that represents when a tag mask was updated.
*
* @dochash types/debuggers/common
* @docname DebuggerTagMaskUpdate
*/
export interface DebuggerTagMaskUpdate extends DebuggerTagUpdate {
/**
* The space of the tag mask.
*/
space: string;
}
/**
* Defines an interface that contains options for attaching a debugger.
*
* @dochash types/debuggers/common
* @doctitle Common
* @docsidebar Common
* @docdescription Defines common interfaces related to debuggers.
* @docname AttachDebuggerOptions
*/
export interface AttachDebuggerOptions {
/**
* Gets the tag name mapper that should be used.
* This is useful for ensuring that the debugger objects utilize different tag names for the front end.
*/
tagNameMapper?: TagMapper;
}
/**
* Defines an interface that contains options for a debugger.
*/
export interface CommonDebuggerOptions {
/**
* Whether to use "real" UUIDs instead of predictable ones.
*/
useRealUUIDs?: boolean;
/**
* Whether to allow scripts to be asynchronous.
* If false, then all scripts will be forced to be synchronous.
* Defaults to true.
*/
allowAsynchronousScripts?: boolean;
/**
* The data that the configBot should be created from.
* Can be a mod or another bot.
*/
configBot?: Bot | BotTags;
}
/**
* Defines an interface that contains options for a normal debugger.
* That is, a debugger that is not pausable.
*
* @dochash types/debuggers/common
* @docname NormalDebuggerOptions
*/
export interface NormalDebuggerOptions extends CommonDebuggerOptions {
pausable?: false;
}
/**
* Defines an interface that contains options for a pausable debugger.
* That is, a debugger that is pausable.
*
* @dochash types/debuggers/common
* @docname PausableDebuggerOptions
*/
export interface PausableDebuggerOptions extends CommonDebuggerOptions {
pausable: true;
}
/**
* Defines an interface that contains options for an aux debugger.
*
* @dochash types/debuggers/common
* @docname DebuggerOptions
*/
export interface AuxDebuggerOptions {
/**
* Whether the debugger should be pausable.
*/
pausable: boolean;
/**
* Whether to use "real" UUIDs instead of predictable ones.
*/
useRealUUIDs: boolean;
/**
* Whether to allow scripts to be asynchronous.
* If false, then all scripts will be forced to be synchronous.
* Defaults to true.
*/
allowAsynchronousScripts: boolean;
/**
* The data that the configBot should be created from.
* Can be a mod or another bot.
*/
configBot: Bot | BotTags;
}
/**
* Defines an interface that contains options for a pause trigger.
*
* @dochash types/debuggers/common
* @docname PauseTriggerOptions
*/
export interface PauseTriggerOptions {
/**
* The line number that the trigger starts at.
*/
lineNumber: number;
/**
* The column number that the trigger starts at.
*/
columnNumber: number;
/**
* The states that the trigger should use.
* Defaults to ["before"] if not specified.
*/
states?: Breakpoint['states'];
/**
* Whether the trigger is enabled.
* Defaults to true.
*/
enabled?: boolean;
}
/**
* Defines an interface that represents a pause trigger.
*
* @dochash types/debuggers/common
* @docname PauseTrigger
*/
export interface PauseTrigger extends PauseTriggerOptions {
/**
* The ID of the trigger.
*/
triggerId: string;
/**
* The ID of the bot that the trigger is set on.
*/
botId: string;
/**
* The tag that the trigger is set on.
*/
tag: string;
}
/**
* Defines an interface that contains information about the current debugger pause state.
* @dochash types/debuggers/common
* @docname DebuggerPause
*/
export interface DebuggerPause {
/**
* The ID of the pause.
*/
pauseId: string | number;
/**
* The pause trigger that started this pause.
*/
trigger: PauseTrigger;
/**
* The state of the pause.
* Indicates whether the pause is before or after the node was executed.
*/
state: 'before' | 'after';
/**
* The result of the node evaluation.
*/
result?: any;
/**
* The call stack that the debugger currently has.
*/
callStack: DebuggerCallFrame[];
}
/**
* Defines an interface that contains information about a single call stack frame.
*
* @dochash types/debuggers/common
* @docname DebuggerCallFrame
*/
export interface DebuggerCallFrame {
/**
* The location that was last evaluated in this frame.
*/
location: DebuggerFunctionLocation;
/**
* Gets the list of variables that are avaiable from this frame.
*/
listVariables(): DebuggerVariable[];
/**
* Sets the given variable name to the given value.
* @param variableName The name of the variable to set.
* @param value The value to set in the variable.
*/
setVariableValue(variableName: string, value: any): void;
}
/**
* Defines an interface that represents a location in a debugger.
*
* @dochash types/debuggers/common
* @docname DebuggerFunctionLocation
*/
export interface DebuggerFunctionLocation {
/**
* The name of the function.
*/
name?: string;
/**
* The ID of the bot that this function is defined in.
*/
botId?: string;
/**
* The name of the tag that this function is defined in.
*/
tag?: string;
/**
* The line number that this function is defined at.
*/
lineNumber?: number;
/**
* The column number that this function is defined at.
*/
columnNumber?: number;
}
/**
* Defines an interface that represents a debugger variable.
*
* @dochash types/debuggers/common
* @docname DebuggerVariable
*/
export interface DebuggerVariable {
/**
* The name of the variable.
*/
name: string;
/**
* The value contained by the variable.
*/
value: any;
/**
* The scope that the variable exists in.
*
* "block" indicates that the variable was defined in and exists only in the current block.
* "frame" indicates that the variable was defined in and exists in the current stack frame.
* "closure" indicates that the variable was inherited from a parent stack frame.
*/
scope: 'block' | 'frame' | 'closure';
/**
* Whether the variable value can be overwriten.
*/
writable: boolean;
/**
* Whether this variable has been initialized.
*/
initialized?: boolean;
}
/**
* Defines an interface for a random number generator.
*
* @dochash types/core
* @docname PseudoRandomNumberGenerator
*/
export interface PseudoRandomNumberGenerator {
/**
* The seed used for this random number generator.
* If null then an unpredictable seed was used.
*/
seed: number | string | null;
/**
* Generates a random number between 0 and 1.
*/
random(): number;
/**
* Generates a random decimal number between the given min and max values.
* @param min The minimum output number.
* @param max The maximum output number.
*/
random(min?: number, max?: number): number;
/**
* Generates a random integer between the given min and max values.
* @param min The minimum output number.
* @param max The maximum output number.
*/
randomInt(min: number, max: number): number;
}
export interface MaskableFunction {
mask(...args: any[]): MaskedFunction;
}
export interface MaskedFunction {
returns(value: any): void;
}
export interface WebhookInterface extends MaskableFunction {
(options: WebhookOptions): void;
post: ((url: string, data?: any, options?: WebhookOptions) => Promise<any>) & MaskableFunction;
}
/**
* Defines an interface that represents the result of a webhook.
*
* @dochash types/web
* @docname WebhookResult
*/
export interface WebhookResult {
/**
* The data that was returned from the webhook.
*/
data: any;
/**
* The HTTP Status Code that was returned from the webhook.
* See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status for more information.
*/
status: number;
/**
* The HTTP Headers that were included in the response.
* See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers for more information.
*
* @docsource Headers
*/
headers: {
[name: string]: string;
};
}
/**
* Defines the possible results of a "record file" request.
*
* @dochash types/records/files
* @docgroup 01-create
* @docorder 1
* @docname RecordFileResult
*/
export type RecordFileApiResult = RecordFileApiSuccess | RecordFileApiFailure;
/**
* Defines an interface that represents a successful "record file" request.
*
* @d