Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

Whack Red is an entire development suite for client-side WHATWG/W3C web and server-side NodeJS projects using the ShockScript language.

Whack Red implements a reactive UI model — called Whack DS — over the DOM with support for a more intricate and dynamically inserted CSS dialect during runtime.

The manifest format

This section describes the manifest format file whack_red.toml, placed at a project’s root directory.

A manifest may describe a package and a workspace simultaneously.

Example

[package]
name = "me.mattqual.eval"
version = "0.1.0"
runtime = "http://www.w3.org/1994/web"

[compiler-options]
main-class = "me.mattqual.eval.Main"

Package section

[package]
# The package ID.
#
# Patterns (may use subnamespaces):
#
# - `com.<company>.<project-name>`
# - `org.<organisation>.<project-name>`
# - `net.<organisation>.<project-name>`
# - `me.<author>.<project-name>`
# - `goog.<project-name>`
# - `<project-name>`
#
name = "com.company.project-name"

# SemVer-compatible version number.
#
version = "0.1.0"

# Target platform.
#
# Supported values:
#
# - "http://www.w3.org/1994/generic"
#   - Compatible with web and NodeJS.
# - "http://www.w3.org/1994/web" (web browser)
# - "http://www.nodejs.org/2009" (NodeJS)
#
runtime = "http://www.w3.org/1994/web"

# Author list.
#
authors = ["matt <me@matt.me>"]

# Homepage URL.
#
homepage = "https://project.com"

# Source repository URL.
#
repository = "https://github/example/project"

# License type.
#
# Examples:
#
# "MIT", "Apache-2.0", "MIT OR Apache-2.0"
#
license = "MIT OR Apache-2.0"

# Description.
#
description = "Package description."

# Keywords.
#
keywords = []

# Categories.
#
categories = []

# Files to exclude/include when publishing.
# (Similiar to .gitignore entries, possibly with an exclamation prefix.)
#
ignore = []

# Shared objects (.so or .dll) to contribute alongside
# the program. This may be used when creating
# native applications, by combining the Tauri technology
# with client-side Whack Red.
#
# Entries in this option can interpolate `{target}`
# for the arfifact directory.
#
# Entries not found here are ignored; for instance,
# you could have a .dll on Windows, but not on other platforms.
#
shared-objects = [
    "{target}/so/org.makers.plus/libcore.so",
]

# Plain metadata ignored by Whack Red
[package.metadata]
plain = 0

Workspace section

[workspace]
members = [
    "packages/foo",
    "packages/bar",
]

Dependencies sections

# Dependencies.
#
[dependencies]
me.mattqual.foo = "0.1"
me.mattqual.bar = { path = "../bar", version = "0.1" }
# git dependencies may have a `rev`, `tag` or `branch` keys.
#
# rev examples:
#
# - rev = "4c59b707" (a commit by its SHA1 hash)
# - rev = "refs/pull/493/head" (HEAD commit of PR 493)
#
# tag examples:
#
# - tag = "1.10.3"
#
# branch examples:
#
# - branch = "master"
#
# If it's a workspace, then Whack Red will look for the
# matching member, inheriting any dependencies.
#
me.mattqual.qux = { git = "https://github.com/matt/qux", version = "0.1" }

# Development dependencies. *Used by unit-testing.*
#
[dev-dependencies]
com.alpha.lets-go = "1"

# Build dependencies. *Used by build scripts.*
#
[build-dependencies]
com.omega.game = "1"

# NPM dependencies, for internal use
# in Whack Red projects.
#
[npm-dependencies]
"decimal.js" = "1"
"foo" = { path = "foo" }  # file: dependency

Compiler options section

[compiler-options]
# Directory at which to find ShockScript source files.
# (Defaults to "src".)
#
source-path = "src"

# For the web, a Whack DS component without props.
# For NodeJS, any class with default constructor.
#
main-class = "me.mattqual.eval.Main"

# following: "error", "warn" or "allow"
unreachable-code = "warn"
unused = "warn"

Constants section

The constants section is used for assigning configuration constants to plain expressions, booleans or numbers for use in ShockScript conditional compilation exclusively for the current package.

[constants]
__q__::x = true
__q__::x = "true"

Note that string literals must appear within nested quotes, as in:

[constants]
__q__::x = "'text'"

The precedence for configuration constant overrides is as follows:

  1. The constants specified in the constants section for the current package
  2. Shell-specified constants
  3. Compiler implicit constants

Shell section

Used for contributing command-line applications, installable through whackred shell install.

[[shell]]
name = "mycmd1"
main-class = "me.mattqual.eval.shell.MyCommand1"

[[shell]]
name = "mycmd2"
main-class = "me.mattqual.eval.shell.MyCommand2"

Unit-testing sections

[[test]]
# Test ID.
#
# This may be omitted if there is only one [[test]]
# section, defaulting to "test".
#
# This is required internally.
name = "test"

# Runtime. Accepts the same values as `application.runtime`.
#
# Defaults to "http://www.nodejs.org/2009".
#
runtime = "http://www.nodejs.org/2009"

# Directory at which to find ShockScript unit-testing source files.
#
# Defaults to "test" if there is only one [[test]] section.
#
source-path = "test/sx"

If there is no [[test]] section and there is a test directory, then a virtual [[test]] section is added with the default options.

Internally, test compilation results go under something like <package-dist-directory>/test/{name}.

Formatting section

[formatting]
# Number of spaces per indentation-level.
#
# Default: 4
tab-width = 4

# Use tabs for indentation?
#
# Default: false
use-tabs = false

# Insert semicolons after statements?
#
# Default: true
#
semicolon = true

# Use single quote strings were appropriate?
#
# Default: false
#
single-quote = false

Application section

The application section is reserved for visual-interactive application frameworks.

[application]
# Human name (`en` is the default locale).
human-name."en" = "Application 1"
human-name."pt" = "Aplicativo 1"
# Description
description."en" = "Description"
description."pt" = "Descrição"
# Frames per second.
framerate = 30
# Background color.
background = "#fff"
# App-installation resources directory.
#
# This is used by the `app:` scheme for resolving
# assets from the app's installation directory.
#
# Default: res.
#
resources = "res"

# For web projects, indicates the
# absolute path of the web project in its host.
#
wwwroot = "/"

[application.initial-window]
# Window size
width = 800
height = 600

Conditional compilation

Implicit constants

ShockScript implicitly defines certain configuration constants.

Whack Red defines the following in addition:

  • __whack__::web - Compiling for the web?
  • __whack__::node - Compiling for NodeJS?

EyeExp

The architecture for icons and logotypes is called EyeExp.

The whack.eyexp.* package contains an EyeExp singleton-like instance which is accessed like a Map for getting, setting and deleting icons or logotypes. Setting an entry causes Whack to re-render dependent EyeExp tags. An entry consists of an URL and a monochrome boolean.

Monochrome resources are displayed filled with the CSS (?inherited) color property. Non-monochrome resources may be displayed with a very discrete shadow whose color is the CSS (?inherited) color.

  • The <w:EyeExp/>’s shadow attribute only takes effect on non-monochrome resources.
  • The <w:EyeExp/> accepts size (square), width and height. The two latter are often most used for logotypes.

The convention is for EyeExp entries to have a name based on enum names, such as light_spark. There is an optional but recommended namespace prefix syntax: zero::light_spark, which prevents collision between libraries. Setting an entry will automatically manage namespaces efficiently to avoid internally repeating the prefix string in-memory.

The CSS eyexpPrefix property allows setting an inheritable namespace prefix to implicitly use within EyeExp names. It supports fallbacks as well.

Some examples:

import whack.eyexp.EyeExp;

// EyeExp : EyeExpSingleton

EyeExp["zero::flower"] = { url: Embed("flower.svg"), monochrome: true };

// E4X

final = (
    <div s:eyexpPrefix="'zero'">
        <w:EyeExp name="flower" size={37}/>
    </div>
)

The most common is for component libraries to provide an Application component that eliminates the general need for explicitly setting the implicit EyeExp prefix.

Enumeration

Obtain all entries of an EyeExp namespace using:

EyeExp.entries("zero")
    /*
    Returns something like
    [
        ["flower", { url, monochrome, ... }]
    ]
    */

Runtimes

Dependency compatibility

Dependencies of incompatible runtime are forbidden.

  • The runtime http://www.w3.org/1994/generic is compatible with:
    • http://www.w3.org/1994/web
    • http://www.nodejs.org/2009

A package of the generic runtime can still use all APIs, like mixing org.w3.web.* and org.node, although it’s necessary to use ShockScript conditional compilation with constants such as __whack__::web and __whack__::node where these APIs are used so that unnecessary and invalid bindings are not generated.

While developing a library, you may override such configuration constants in the constants section of the current project’s manifest for type-checking code sections using them.

Environment variables

Environment variables used by the Whack Red SDK

  • WHACKRED_HOME - Path to the Whack Red SDK.

Environment variables Whack Red sets for packages

These environment variables are available for use with Env::VAR_NAME expressions within Whack Red packages, their build scripts and unit-testing classes.

Env::WHACKRED_MANIFEST_DIR
  • TARGET - Path to the artifact target directory based on platform and build profile.
  • WHACKRED_MANIFEST_DIR - Path to the directory containing the manifest of your package.
  • WHACKRED_MANIFEST_PATH - Path to the manifest file of your package.
  • WHACKRED_PKG_NAME - Package name.
  • WHACKRED_PKG_VERSION - Package SemVer version number.
  • WHACKRED_PKG_VERSION_MAJOR - Package major version number.
  • WHACKRED_PKG_VERSION_MINOR - Package minor version number.
  • WHACKRED_PKG_VERSION_PATCH - Package patch version number.

Using static DotEnv variables

For setting static DotEnv variables for ShockScript to use, create an .env file in your package’s directory, with contents like:

FOO=bar

You can then refer to that in ShockScript with expressions like:

Env::FOO