1.2.2 • Published 6 years ago

@screencloud/app v1.2.2

Weekly downloads
-
License
ISC
Repository
-
Last release
6 years ago

Signage App Runtime

Install

This package is published using semantic-release and available on npm.

To install run

npm install @screencloud/app --save

Usage

The App-class is the most convinient way of getting your app to run. You can use it in several ways to best suit your style and handle all lifecycle events with ease.

Note that most of these events are optional, but the overall experience will be best if most events are respected.

Basic

To signalize to the player that your app has loaded successfully you need to instantiate an App and call its run-method.

import {App} from "@screencloud/app";

const app = new App();

app.connect();

connect() connects to the app-container of your screen and returns a promise. You can use this promise to kick off your internal app logic.

app.connect().then(() => {
   // your app logic goes here!
})

Responding to lifecycle-events

The App and its Container communicate via a defined set of Messages. For each incoming message from the container there is a matching methods in App.

The AppContainer may for instance send a FinishMessage to your app to announce that your app will be turned off in favor of the next app. This message comes with a payload specifying your apps remaining duration on screen.

app.onFinish((payload) => {
    // app will be turned off in payload.maximumDurationMS   
    // use this to gracefully fade out in time
});

Note that all lifecycle handlers are chainable, so you can set up your handlers like so:

const app = (new App())
    .onInitialize((payload => {
        // receive env variables and app data
    })
    .onPreload((payload) => {
        // preload data
    })
    .onStart(() => {
        // the app is live!
    })
    .onFinish(() => {
        // app will turn off, fade out gracefully
    })
    .connect();

Alternatively you can pass in a collection of handlers into the app's constructor

const app = new App({
    initialize: (payload) => {
        // receive env variables and app data
    },
    start: () => {
        // the app is live!
    },
    finish: (payload) => {
        // app will turn off, fade out gracefully
    },
});

app.connect();

Sending lifecycle events

Your app can send numerous events to the app-container of the screen. For each outgoing message from your app to the app-container there is an emitter method like emitPreloaded(). You can call these methods to inform the app-container about the app's current state or to respond to incoming messages as seen above.

If your app for instance specifies in its manifest.json that it supports preloading, then the app-container may send a PreloadMessage to your app, which you can handle by supplying a callback function to onPreload(). Once your app has finished preloading, it should inform the app-container by calling emitPreloaded().

const app = new App();

app.onPreload((payload) => {
    // preload some data from twitter or any other api
    twitter.loadSomeThings().then(() = {
        // inform app-container 
        app.emitPreloaded();
    });
})

Requesting resources

The app can utilize some of the app-container's APIs like requesting cached resources.

The available functions are prefixed with request such as requestResource() and always return a promise.

TODO: currently there are none of these

List of Lifecycle events

These are all available incoming events, outgoing events and resource requests an app can receive or utilize during its lifetime.

Incoming events

incoming eventhandlerdescription
initializeonInitializeprovides app, environment and related data to the app. Called shortly after a connection has been established. The app should respond with emitInitialized when ready.
preloadonPreloadinstructs the app to preload all required resources to run. The app should emitPreloaded when ready. The event may supply additional data as payload.
startonStartthe app is now visible on screen and should start to play animations as well as video and/or audio content
showonShowthe app container request to show a specific piece of content. This is used for long-running apps which may receive content updates during their lifetime.
finishonFinishthe app will terminate soon and should prepare to be shut down. A maximum duration is provided as payload. The app should respond with emitFiniching with an estimated duration and emitFinished when ready to be shut down.

Outgoing events

outgoing eventemitterdescription
initializedemitInitializedtells the app-container that the app is loaded and working. Should be sent after receiving an initialize-event.
preloadedemitPreloadedtells the app-container that the app has finished preloading and is ready to start immediately. Should be sent after receiving a preloaded-event.
startedemitStartedtell the app-container that the app is visible and running.
showingemitShowinginforms the app-container which piece of content is currently shown. This is useful for logs and statistics.
finishingemitFinishinginforms the app-container that the app will be ready to shut off soon. An estimated duration should be provided as payload.
finishedemitFinishedthe app is ready to shut down immediately.
logemitLogsends a log entry to be centrally stored. Using payload you can specify the severity from LogLevel.debug to LogLevel.error as well as a message.

Resource requests

TODO: none defined yet

Debugging and testing

There are special classes provided which should simplify testing and debugging of your app.

Using MockApp

In all testing scenarios you're safe to replace App with MockApp. Instead of establishing a connection to a higher level frame it will mock this connection, but otherwise behave in the exact same way. It does so by using MockBridge instead of the default PostMessageBridge.

MockApp exposes a method called fakeReceive(), which accepts a message as the first argument and treat it the same way it would an incoming message from the app-container.

import { IMessageHandlers, StartMessage, MessageTypes, MockApp } from "@screencloud/app";

// all incoming event handlers
const handlers: IMessageHandlers = {
   start: (payload) => {
      // your logic here
   },
};

// set up mock app
const app = new MockApp(handlers);

// connect the app
app.connect().then(() => {
    // and fake receive a start-message to kick of start-handler
    app.fakeReceive<StartMessage>({
        type: MessageTypes.start
    })
});
1.2.2

6 years ago

1.2.1

6 years ago

1.2.0

7 years ago

1.1.1

7 years ago

1.1.0

7 years ago

1.0.2

7 years ago

1.0.1

7 years ago

1.0.0

7 years ago