Example: Observing Data Structures Creating Our New Composite Type Logging Changes To Console The Full Code References

Example: Observing Data Structures

JSOS uses immutable data structures by default. However, for all its composites like Struct-based types, Vector, and Dict, it also has the corresponding mutable versions: MStruct, MVector, and MDict.

Not only are these typed alternatives to JavaScript's Object, Array, and Map, they come with a crucial additional benefit:

Changes to their data can be observed using callbacks.

In this short example, we will create a new mutable composite type and log any changes to an instance of the new type to the console.

Creating Our New Composite Type

Let's say we're developing an app for reading and writing song metadata. We will need a composite type that holds all the info for a song.

First, let's grab the necessary imports. For structs, everything we need is part of JSOS Core:

import { MStruct, observe, JSString, JSNumber } from "@fed1/jsos";

Now we can declare the structure of our new composite type with MStruct.<name>():

const { Song } = MStruct({
    name: JSString,
    artist: JSString,
    album: JSString,
    year: JSNumber,
    length: JSNumber // seconds
});

No we can create a new Song instance:

const blackwaterPark = Song.new({
    name: "Blackwater Park",
    artist: "Opeth",
    album: "Blackwater Park",
    year: 1999,
    length: 12 * 60 + 11
});

Logging Changes To Console

Next, let's log any changes done to our new song to the console. We can accomplish this with the observe() function. We already imported it in the first step of this example.

observe(blackwaterPark, (key, value) => {
    console.log(
        `Song '${ blackwaterPark.name }' changed: ${ key } = ${ value }`
    );
});

The observe() function takes the object to be observed as its first argument. The second argument has to be a callback funtion. It will be called whenever something in the blackwaterPark song changes.

The callback has two optional arguments: The key of the changed property and the new value of that property.

The return value of observe() is a function that removes the callback from the list of callbacks that are registered for changes.

Oh, what's that? I think we made a mistake when we created our song: we got the year wrong! Blackwater Park was actually released in 2001!

Let's change our song:

blackwaterPark.year = 2001;

If you now look at the console output of your script, you will see the following:

Song 'Blackwater Park' changed: year = 2001

And that's it for this example!

The Full Code

import { MStruct, observe, JSString, JSNumber } from "@fed1/jsos";

const { Song } = MStruct({
    name: JSString,
    artist: JSString,
    album: JSString,
    year: JSNumber,
    length: JSNumber // seconds
});

const blackwaterPark = Song.new({
    name: "Blackwater Park",
    artist: "Opeth",
    album: "Blackwater Park",
    year: 1999,
    length: 12 * 60 + 11
});

observe(blackwaterPark, (key, value) => {
    console.log(
        `Song '${ blackwaterPark.name }' changed: ${ key } = ${ value }`
    );
});

blackwaterPark.year = 2001;

References