TouchDevelop/editor/messages.ts

145 строки
5.7 KiB
TypeScript

// This file contains no external references. It is meant to be used both by the
// TouchDevelop code (in [editor/external.ts], most likely) and by actual
// implementations of external editors.
module TDev {
export module External {
// The base class for messages. This is what gets sent via [postMessage].
// Discriminating on the actual value of the [type] field will tell you
// which one of the [Message_*] interfaces below you can cast into
// (TypeScript doesn't, quite regrettably, have sum types.)
export interface Message {
type: MessageType;
}
export enum MessageType {
Init,
Metadata, MetadataAck, // Not implemented, left here so that the enum doesn't change.
Save, SaveAck,
Compile, CompileAck,
Merge, Quit, // [Quit] has no attached data, so not defining a special interface
Upgrade, Run,
NewBaseVersion
};
export interface Message_Init extends Message {
type: MessageType; // == MessageType.Init
script: SavedScript;
merge?: PendingMerge;
fota: boolean; // Are we flashing over the air?
}
export interface Message_Save extends Message {
type: MessageType; // == MessageType.Save
script: SavedScript;
}
export interface Message_SaveAck extends Message {
type: MessageType; // == MessageType.SaveAck
where: SaveLocation;
status: Status;
error?: string; // non-null iff status == Error
newBaseSnapshot?: string; // non-null iff status == Ok && where == Cloud
cloudIsInSync?: boolean; // non-null iff status == Ok && where == Cloud
// true means the version we just wrote in
// the cloud is the latest version
// currently stored locally
}
export interface Message_Merge extends Message {
type: MessageType; // == MessageType.Merge
merge: PendingMerge;
}
// The [libs] field is a map from library name (e.g. "micro:bit") to the
// corresponding publication id. The receiver of the message takes care
// of fetching the latest version of the library, and gluing it to the
// provided AST. (This, naturally, only makes sense if the language is
// TouchDevelop).
export interface Message_Compile extends Message {
type: MessageType; // == MessageType.Compile
text: any; // string if language == CPlusPlus, TDev.AST.Json.JApp if language == TouchDevelop
language: Language;
libs: { [libName: string]: string };
name?: string; // Name of the script
}
export interface Message_CompileAck extends Message {
type: MessageType; // == MessageType.Message_CompileAck
status: Status;
error?: string; // non-null iff status == Error
}
// The [libs] fields is the same as in [Message_Compile].
export interface Message_Upgrade extends Message {
type: MessageType; // == MessageType.Message_Upgrade
name: string;
ast: any; // AST.Json.JApp
libs: { [libName: string]: string };
}
export interface Message_Run extends Message {
type: MessageType; // == MessageType.Message_Run
ast: any; // AST.Json.JApp
libs: { [libName: string]: string };
}
// This message is (currently) sent in the following situation. External
// editor requests a save for the first time; sync happens; we get back
// an "echo" from the server with the [baseSnapshot] that has been
// assigned to us. The external editor must change its internal base
// version from the empty string to this string. Failing to do that will
// result in the sync code refusing to take into account save messages
// that have an empty [baseSnapshot].
export interface Message_NewBaseVersion extends Message {
baseSnapshot: string;
}
// A saved script has some text (this is what ends up published when the
// user hits "publish"), an associated editor state (doesn't get
// published), and is saved on top of a cloud-assigned [baseSnapshot].
export interface SavedScript {
scriptText: string;
editorState: EditorState;
baseSnapshot: string;
metadata: Metadata; // Must be set to the correct value every time.
}
// All this says is that the editor state for an external editor may
// have as many fields as desired; however, the two fields below get a
// special treatment and serve to display tutorial progress in "the
// hub". What the hub displays (legacy code, apparently) is
// "[tutorialStep + 1] of [tutorialNumSteps + 1]".
export interface EditorState {
tutorialStep?: number;
tutorialNumSteps?: number;
}
export interface Metadata {
name: string;
comment: string;
}
// In case local and remote modifications have been posted on top of the same cloud
// version, the editor needs to merge, and can then save on top of the
// new cloud version.
export interface PendingMerge {
base: SavedScript;
theirs: SavedScript;
}
export enum Status {
Ok, Error
};
export enum SaveLocation {
Local, Cloud
};
export enum Language {
TouchDevelop, CPlusPlus
}
}
}