Lurch web app user interface

Class

Message

This class simplifies communication between the main thread and worker threads by encapsulating their communication protocol into a single class that can be used on both ends of the channel.

To send a message to a worker, create an instance of this class and then call message.send( worker ). To send a message from a worker, create an instance and call message.send() (which therefore just goes "out"). In the message event handler on either end, you can construct a new Message instance from the event itself, and its data will be extracted appropriately. For example, the validation worker has code something like this:

addEventListener( 'message', event => {
    const message = new Message( event )
    if ( message.is( 'putdown' ) ) { // check type
        const putdown = message.get( 'putdown' ) // read message content
        // validate document sent in putdown format
    } else {
        // send error message because we expected putdown
    }
} )

Having one class that's imported into both the main thread and the worker means not dividing the communication protocol code over multiple files, and thus improving consistency and reducing chances of logic errors.

There are also some static members that make certain message-sending operations more concise and readable; see below.

Constructor

new Message(content)

Construct a new message instance with the given content. The content may be any of the following:

  • An Event instance, as shown in the example at the top of this class documentation. In that case, the data attribute of the event will be stored as the content attribute of the new Message instance, because event.data is where user-specific information is stored for message events.
  • A string, which will be interpreted as the text of the message, and thus the newly created instance will have as its content field an object with just a text field, this string.
  • An object, which will be used directly as the newly created instance's content field.

Any other kind of content throws an error.

Parameters

  • content Object | string

    the content of the message, as described above

Source

Classes

Message

Methods

get(key) → {*}

Because a message's content field is an object, it can be used like a dictionary of key-value pairs. This function looks up the given key in the content member. It is just a more readable/convenient version of message.content["key"].

There is no corresponding setter function because messages are intended to be lightweight, short-lived objects. You provide their content when instantiating them, then you send them somewhere or react to them, and then let them be garbage collected.

Parameters

  • key string

    the key whose value should be looked up

Returns

  • *

    the corresponding value (or undefined if the key is absent)

Source

getAllFeedback() → {Array.<Object>}

A message may contain two types of feedback that need to be displayed to the user: either explicit feedback generated by the deductive engine or an error message indicating that something went wrong internally, which will explain to the user why they didn't get any other feedback. This function returns all the feedback messages in this object, if any, including treating an error as a single feedback message.

Each entry in the resulting array is created by passing primitive feedback that the LDE generated through the function makeFeedbackPresentable(). See the documentation for that function to see what the format will be.

Returns

  • Array.<Object>

    array of data for validation feedback, as defined above

Source

is(type) → {boolean}

The content of a message, given at construction time, may include a type field, which should be a string, if present. It can indicate whether the message is a piece of feedback, an error, or some other type of message. Any string is permitted; there is no official list. A message is not required to have a type field.

This function tests whether this instance has the given type. It simply compares the parameter passed to the type field in the instance's content field (which is undefined if absent).

Parameters

  • type string

    the type to test this instance against

Returns

  • boolean

    whether this instance is of that type

Source

send(targetnullable)

Send this message to a worker or to the main thread. If you provide a target, we will attempt to send the message there, so if you are using a Message in the main thread and want to send it to a worker, call message.send( worker ). If you do not provide a target, we will attempt to send the message to the main thread. So workers can just call message.send().

Note that there are also static members of this class for sending common types of messages that let you write slightly more compact and readable code than constructing and sending a message in one line of code.

Parameters

  • target Worker <nullable>

    the worker to which to send the message, if any

Source

static

document(editor, encoding) → {Message}

Convert the document inside the given editor into a serialized form and encapsulate it into a single Message instance, for transmitting to the validation worker. Such a message, when received by the worker, is viewed as a command to begin validating the document, and sending feedback messages for all of its parts that are amenable to validation.

The primary client of this function is the run() function in the validation module. You probably do not need to call this function if you are using that one.

Parameters

  • editor tinymce.editor

    the editor containing the document to be converted

  • encoding string json

    the name of the encoding to use (currently supporting only "putdown" and "json" options)

Returns

  • Message
    • the message that can be sent to the validation worker to transmit the entire document, in serialized form

Source

static

done()

This function is intended for use in workers, to communicate back to the main thread. It constructs a message instance, gives it the type "done", and sends that message back to the main thread.

This can be done in one line of code without this convenience function, but using this method makes the code more concise and readable.

Source

static

error(text, morenullable)

This function is intended for use in workers, to communicate back to the main thread. It constructs a message instance, gives it the type "error", sets its text field to the parameter given, and sends that message back to the main thread. If the second parameter is provided, all of its fields are also included in the message's content.

This can be done in one line of code without this convenience function, but using this method makes the code more concise and readable.

Parameters

  • text string

    the contents of the error message

  • more Object <nullable>

    any other key-value pairs to be included in the message's content (optional)

Source

static

feedback(data)

This function is intended for use in workers, to communicate back to the main thread. It constructs a message instance, gives it the type "feedback", also includes all of the fields in the parameter provided, and sends that message back to the main thread.

This can be done in one line of code without this convenience function, but using this method makes the code more concise and readable.

Parameters

  • data Object

    any type of data to include in the feedback message

Source

static

makeFeedbackPresentable(data)

Feedback data from the Lurch Deductive Engine does not always come in human-readable form. This is partly because we want to keep the data small, and partly because we're still developing the LDE and thus its messages are not well-organized yet. This function converts any feedback object in JSON form from the LDE into something presentable, for use in the UI, as feedback to a human user.

The result is guaranteed to have these three fields, and possibly more:

  • type - a human-readable string categorizing the feedback into one of these possible types:
    • 'inference', meaning the logical inferences from earlier expressions and environments to this expression
    • 'scoping', meaning the scopes of variables, including declarations and the lack thereof
    • 'instantiation', or what the LDE calls "basic instantiation hints" (BIHs)
    • 'error', meaning an internal error took place in the LDE or the communication with the LDE
  • result - a human-readable string that is one of three possible values: 'valid', 'invalid', or 'indeterminate', meaning, respectively, correct work, incorrect work, and work that may or may not be correct, but the LDE doesn't have enough information; these correspond to the types of icons shown in the UI, respectively, green, red, and yellow
  • reason - a human-readable string that is short enough to show in a pop-up message when hovering over the validation icon in the UI. In fact, this string is not only human-readable, but written in a simple and informal style that we aim to be natural and simple for students to read.
  • code - a brief, English summary of the feedback, from which most of the rest of the data could be deduced. Examples include:
    • 'undeclared variable' (or more than one undeclared variables)
    • 'redeclared variable' (or more than one redeclared variables)
    • 'valid inference'
    • 'indeterminate inference'
    • 'invalid inference'
    • 'valid instantiation'
    • 'invalid instantiation' (for now, there are no indeterminate instantiations)
    • 'error' (for now, all errors are lumped into one category)

Parameters

  • data Object

    the feedback data from the deductive engine, in JSON form

Source

static

progress(complete)

This function is intended for use in workers, to communicate back to the main thread. It constructs a message instance, gives it the type "progress", and says what percentage of the total progress of validation has been accomplished, as an integer in the set ${0,1,...,99,100}$.

This can be done in one line of code without this convenience function, but using this method makes the code more concise and readable.

Parameters

  • complete integer

    the progress value, from 0 to 100 inclusive

Source