pekfinger-red 0.4.18

A web-framework. Basically Svelte for Node-RED. With some sugar.

npm install pekfinger-red

Pekfinger-RED is a web-framework. Basically, it is Svelte for Node-RED. With some sugar.

Caution: The current version might not work as expected. A complete rewrite with new (and then hopefully stable) features is underway. Please be patient. Thank you!

It allows to create flow-based web applications by creating pages and corresponding actions. And the best is: all apps are Progressive Web Apps (PWAs) by default.

Screenshot of a sample-flow.

Actions trigger a flow and can result in either content being sent to the client, a redirect to another page, an action being triggered on the client or it might just end the request.

A page is based on a layout and has several components that are filled into the slots of the layout. You might thereby reuse layouts and components over multiple pages.

This framework is still under heavy development. Be aware that breaking changes are not only possible but will likely happen sooner or later and that you probably encounter bugs at the moment. Thus you should NOT use this in production. That said: Feel free to play. :)

Example

You wanna know what you can do with the App? Well... basically everything. A very simple App-template is delivered with the framework. But it's up to you to customize or replace the template files as you like. So here we go:

With that little code...

Sample App Code

... you get that App out of the box:

Sample App Code

Sample App Code

Node-types

App (web-app configuration node)

Every app needs a web-app configuration node that defines its basic configuration like e.g. the address it shall listen on, encryption parameters, theme color or it's basic layout. Web-pages and web-content then build upon that.

Screenshot of a sample web-app node.

Some configuration of the web-app (like manifest-information or icons) can be found within the pekfinger-red/config directory within your projects home directory. Please keep in mind that this directory is initialized when an App deployed for the first time.

Web page (web-page node)

Web-pages build the basic structure of your App. Based on a layout they serve the content of a page (which you can describe through a list of components). Each component might define properties that can automatically be filled with data provided through the result of a Jsonata selector run on msg (only msg.payload is visible!). By default msg.payload is passed as data to the page.

Actions further allow to define specific outputs that get triggered when called from the client.

Screenshot of a sample web-page node.

Important: The svelte-templates (default App layout and components) that come with Pekfinger-RED need smui to be installed. So don't forget to install them via npm.

The svelte templates can be edited directly from within the web-node and are stored in your project-folder under pekfinger-red/components respectively pekfinger-red/layouts.

When developing a web-page you have some exports you can use:

  • data: Contains the data that gets sent to the client by the server (on first rendering as well as on send-events; compare client-node).
  • client: Allows to interact with the client. E.g. client.data contains the above mentioned data object.
  • server: Allows to interact with the server. This mostly means to trigger actions on the server.

Client-server communication usually means two basic cases: Triggering actions on the server and defining actions that can be triggered from the server.

// Trigger an action on the server
let data = { // (= msg.payload on the node's corresponding action output)
  some: 'data for the server'
}
let options = { // (= msg.options on the node's action output)
  whatever: 'options you have for the server'
}
server.run('action-name', data, options)
// Define an action to be triggered from the server
client.define('action-name', (data, options) => {
  // data: contains whatever msg.payload contained on the server
  // options: contains whatever was defined as options within the client.node
})

Hints:

  • By default, options that were sent to the server from the client get sent back to client in case a client-action gets triggered. This allows you to identify the source of the action's response (by setting a unique key within the options).
  • Instead of showing a single instance of a component but rather a list of components, you need to return an object with a #each property of type Array having the list of properties that shall be rendered. Take care of the following: For components to be handdled correctly from Svelte, each component should have a id property. Be aware that server-actions triggered from within such a components should set an option with an identifier so that actions triggered by the server in response can be matched to this component's instance (see above). Otherwhise the client-action will be triggered on all instances of the component!
  • A component can update its parent's data through the data object or through client.data. Anyway, depending on the component's selector (the Jsonata-expression of the slot), it might not immediately be clear, which value needs to be altered. This can be solved as follows:
export let client, server, data // Default exports
export let myValue // The value that gets passed as property through the Jsonata-expression
export let selector // The selector used by Pekfinger-RED to determine the properties of this component (this gets passed if exported as property)
function update() {
    let props = client.select(selector)
    props.myValue = "new value"; // Will change the property as well as it's source value
    data = data // This is needed to inform Svelte that the data has changed
}
  • If you have small code snippets that are only needed once for a specific web-page, you can add that code directly (not saving it as a component). This might be the case for setting some specific header-information like meta-tags, manipulating the app's menu or alike. And it might help keeping the components directory clean.
  • You tell the client to open a page by calling client.open(url, data) whereby data is optional and allows to predefine the data that is shown on that page.
  • You can use Jsonata client-side by calling client.select(selectorString). It will be evaluated on the data property.
  • You have a client-side event-handling through the methods client.on(event, callback), client.once(event, callback) and client.notify(event, data). Predefined events are e.g. "server.connected", "server.disconnected", "server.reconnect" or "server.action". See src/communication/client for more events. But be aware that these might change. You may also define own events.
  • You can trigger a client action through the client as well by calling client.run(actionName, data, options).
  • You can run code deferred using client.deferred(callback, delay). This is an alternative to window.setTimeout based on requestAnimationFrame.

Web content (web-content node)

This node serves any content that is not a web-page. Usually this means that some static content like images gets served. You may put this static content into the pekfinger-red/static folder within your projects home-folder.

Screenshot of a sample web-content node.

Response (web-client node)

The client node is meant to return control back to the server. This can either mean that the client gets redirected to another page, that it gets (new) content (=data) or that a client action gets triggered (see above). An exception is that the request gets ended immediately (e.g. when a non-existent record was requested).

General hints

  • The svelte-templates (default App layout and components) that come with Pekfinger-RED need smui to be installed. So don't forget to install them via npm.
  • Caching means that the page and its data get cached on the client. So these pages might be viewed offline (though they need to be loaded by the client at least once before). If caching is disabled for a page, the client will request them from the server each time it gets requested by the user.

Current status

As mentioned before, Pekfinger-RED is still under heavy development. There is only one real life example where we test it at the moment. And yes: so far it seems to work (fingers crossed). Anyway, it is not really thoroughly tested and bugs are very likely.

Also: This page and the documentation of the nodes within Node-RED is all that you will find for documentation at the moment. There is a great tutorial on how to write Svelte templates and also the API documentation of Svelte is very good. Anyway, there are a lot of Pekfinger-RED specific things. And these are not well documented at the moment. Take a look at the sample templates. It might help. Apart from that: Good luck!

Any feedback that helps us making Pekfinger-RED is very welcome. As this is currently one of several Node-RED related side projects, we ask for your understanding that we might not be able to react to bug reports or other requests as quickly as you might wish. But promised: we try.

Planned features

See CHANGELOG.md for information on changes that already happened.

  • Hierarchical definition of components within the web-page
  • More checks (like whether the filename is valid or whether the address / port is already in use)
  • Make use of Node-RED's done-method
  • Saving rendered pages to disk to improve startup times
  • Adding a file-watcher to rerender a page in case a template file was altered from outside of Node-RED's editor
  • Having one configuration-directory for each App
  • A WYSIWYG-editor for the template-files would be great. But well... dreams...

Node Info

Version: 0.4.18
Updated 7 months, 1 week ago
License: MIT
Rating: 5.0 1

Downloads

25 in the last week

Nodes

  • web-page
  • web-content
  • web-client
  • web-app

Keywords

  • node-red
  • svelte
  • nodes
  • flow
  • web
  • serve
  • app
  • webclient
  • webserver

Maintainers