STAGE: ViewStream
Defines HTML elements and content
Appends to DOM or nests ViewStream instances
Built in el$ Selector
Encapsulated and communicates with all Channels
Imports native methods from SpyneTraits
ViewStream
Dynamically generates the DOM by nesting ViewStream instances.
ViewStreamnew Instance
CONSTRUCTORnew ViewStream (
propsObject={}
)
Parameter |
Default |
Type(s) |
Description |
|---|---|---|---|
|
props |
{} |
Object |
Contains all properties for the instance. |
|
└─tagName |
"div" |
String |
The tag name of the HTML root element. |
|
└─[Attributes] |
— |
HTML Attributes |
HTML attributes (id, class, dataset, etc.) applied to the root element. Click here for a complete list of attributes. |
|
└─template |
undefined |
HTML Template |
The HTML markup for rendering dynamic content. See DomElementTemplate for syntax. |
|
String Literal |
Renders HTML content using String Literals |
||
|
└─data |
undefined |
Object | Array | String |
Data used for placeholder replacement in template. If a string is provided, it becomes text content. |
|
└─traits |
[] |
SpyneTrait Class |
An array of SpyneTrait classes. Each trait's methods are bound to the ViewStream instance, adding custom logic or behaviors. |
|
└─channels |
[] |
String | Array |
One or more channel names. Each entry is either "CHANNEL_NAME" or [CHANNEL_NAME, true], the boolean skips the replayed first payload (typically needed when the Channel's replay event triggers the rendering of the current ViewStream instance). See .addActionListeners for more info. |
|
└─el |
undefined |
HTML Element / DOM Element |
Usually defined by tagName, but can be added as an existing DOM element. |
{
}
constructor
Creates a new ViewStream instance responsible for rendering and managing a DOM element, using the provided configuration (props).
The constructor declaratively sets up:
- tagName + Attributes: Defines the root DOM element for the ViewStream. In most cases, a new element is created; providing an existing el is an optional edge case.
- template + data: Generate the view's HTML markup or text content dynamically.
- traits: Attach reusable logic methods to the ViewStream instance — cleanly separating functionality from structure.
- channels: Integrate behavior streams by listening to or broadcasting through named Channels.
The constructor shows how ViewStreams declaratively wire structure, content, and behavior — forming modular, scalable building blocks inside a SpyneJS application.
import { ViewStream } from 'spyne'; // Simple "Hello World" view const myView = new ViewStream({ data: 'Hello World' }); // Insert into DOM myView.appendToDom(document.body); STAGE: DomElement
DomElement is used to create ViewStreams HTML element and its content
Can be used to create HTML elements that do not require integration with Channels and SpyneTraits
DomElement
Creates a DOM element and populates it with HTML or text content, using the same underlying logic as a ViewStream.
DomElementNew Instance
CONSTRUCTORnew DomElement (
props: Object={}
)
Parameter |
Default |
Type(s) |
Description |
|---|---|---|---|
|
props |
{} |
Object |
Contains all of the properties used to define the element. |
|
└─tagName |
div |
String |
props.tagName |
|
└─[Attributes] |
undefined |
[ class , dataset ] etc. |
[ class , dataset ] etc. |
|
└─template |
undefined |
HTML | String | String Literal |
HTML | String | String Literal |
|
└─data |
undefined |
Object | Array | String |
Object | Array | String |
{
}
constructor
DomElement is used for basic HTML and text content generation using ViewStream's constructor interface.
Behavior
- Generates a top-level DOM element based on tagName and [Attributes].
- Renders HTML or text content via template and data.
- Excludes channel or trait functionality; use ViewStream if additional reactive features are needed.
// Define the data const data = "Hello World"; // Create the DomElement const html = new DomElement({data}); // Append to body document.body.appendChild(html.render()); STAGE: DomElementTemplate
This generates HTML from templates and data.
Fastest way to generate large amounts of DOM Content without any logic or code
Can be rendered as an HTML String or DocumentFragement
DomElementTemplate
A flexible system for generating HTML content using Templates and Data—primarily used for rendering HTML within ViewStreams and DomElements.
DomElementTemplateNew Instance
CONSTRUCTORnew DomElementTemplate (
templateHTML Template | String data Object | Array | String
)
Parameter |
Default |
Type(s) |
Description |
|---|---|---|---|
|
template |
undefined |
HTML | String | String Literal |
A mustache-style template containing {{variable}} placeholders. Placeholders are replaced by corresponding values from the data argument. |
|
data |
undefined |
Object | Array | String |
The values used to populate placeholders. Most commonly an object whose keys match the placeholder names. Arrays at the root work with the bare-array shorthand syntax. A primitive string passes through unchanged. |
{
}
constructor
DomElementTemplate is SpyneJS's template engine. It takes a template string with mustache-style placeholders and a data object, and produces either an HTML string or a DocumentFragment ready to mount into the DOM.
Templates support variable interpolation, dot-notation property access, array iteration, object sections as conditional wrappers, and one level of nested array iteration. Logic is intentionally not supported — no if/else, no computed expressions, no custom helpers. Decisions and data shaping happen in SpyneTrait methods, not in the template.
Security — Sanitized by Default
Template HTML and interpolated values are sanitized by default; no configuration is required. Bracket count is not significant — {{key}} and {{{key}}} behave identically, because protection doesn't depend on template syntax.
The security posture is decided once per application, in SpyneApp.init: mode selects the sanitization posture (app for production, richtext for CMS and authoring tools), and pairing it with strict: true — the recommended production posture — adds Trusted Types enforcement at the DOM-sink layer. See Security Configuration under SpyneApp for the full set of options.
What's Not Supported (and What to Use Instead)
Templates are data files, not code. A SpyneJS template is a declarative description of how data maps to DOM — it does not contain logic, decisions, or computation. SpyneJS enforces this by design: the engine has no syntax for it. The constructs below appear in other template engines but are deliberately omitted here, because every one of them belongs in a SpyneTrait or a ChannelPayloadFilter where logic lives. Each has an idiomatic replacement:
Inverted sections ({{^key}}) — shape the data so the section you want renders naturally, or emit a placeholder from a SpyneTrait.
If/else and conditional expressions — use object-section-as-conditional, or resolve the condition in a SpyneTrait and expose a resolved object.
Computed expressions and arithmetic — pre-compute in a SpyneTrait. The auto-injected {{loopNum}} handles 1-based indexing.
Custom helpers and filters — derived values are computed in SpyneTraits before reaching the template.
Partials and includes — composition happens at the ViewStream level. Nested ViewStream instances are SpyneJS's mechanism for reusable UI fragments, with lifecycle semantics built in.
Dynamic tag names (e.g. ) — use the flag-conditional pattern. Pre-compute a flag (e.g., ) and use object sections to emit the appropriate tag.
Deeper than one-level nesting — restructure into nested ViewStream instances.
// Define the template const template = "<p>{{text}}</p>"; // Define the data const data = {text: "Hello World"}; // Render using DomElementTemplate const html = new DomElementTemplate( template, data ).renderDocFrag(); // Append to body document.body.appendChild(html); STAGE: Channel
Unified system to transmit all types of events and data
Combines and parses data from other channels
Create advanced observables using rxjs library
Channel
Channels provide a unified interface to manage and synchronize application behavior, including user interactions, browser activities, and data fetching.
ChannelNew Instance
CONSTRUCTORnew Channel (
channelNameString=undefinedpropsObject={}
)
Parameter |
Default |
Type(s) |
Description |
|---|---|---|---|
|
channelName |
(required) |
String |
A unique identifier used by ViewStream and custom Channel instances for accessing the Channel via getChannel. |
|
props |
{} |
Object |
Holds all of the properties for the Channel instance. |
|
└─replay |
false |
Boolean |
Determines if the Channel "replays" the last payload for new subscribers. |
|
└─traits |
[] |
Array |
List of SpyneTrait instances; their methods become local methods of the Channel. |
{
}
constructor
The constructor initializes a new Channel instance and sets up a dedicated RxJS Subject, accessible via the instance's obs$ property.
replay Property:
This is an important behavioral feature, and determines if new subscribers receive the last, 'cached' ChannelPayload (also determines if obs$ is an RxJS Subject or a ReplaySubject).
What it Does:
- Emits: Persistent streams of observable data known as ChannelPayloads.
- Merges and Subscribes to: Multiple channel data streams for precise synchronization of UX and application behaviors.
- Registers: Actions specifically designed to connect ("wire") payloads to local methods.
- Extends: RxJS Subjects, providing access to the full RxJS library for creating custom observables and advanced stream management.
ChannelPayloads are emitted when:
- Filtered events from subscribed-to channels trigger actions.
- Typically used for edge cases and third-party libraries, local Channel methods can be called from a ViewStream's sendInfoToChannel method.
- The local obs$ instance is extended via the RxJS library.
ViewStream and Event Integration:
- Events: Captures events emitted by the three Event Channels.
- ViewStream Information: Receives observable data from ViewStream's sendInfoToChannel method.
SpyneTrait Integration:
- Adds Logic: By binding pure functions from SpyneTraits as local methods.
STAGE: ChannelPayload
This data interface for all channels
Provides consistent, immutable data
ChannelPayload
This provides a consistent interface to efficiently deliver behavior content.
ChannelPayloadNew Instance
CONSTRUCTORnew ChannelPayload (
channelNameString=undefinedactionString=undefinedpayloadObject=undefinedsrcElementObject=undefinedeventUIEvent=undefined
)
Parameter |
Default |
Type(s) |
Description |
|---|---|---|---|
|
channelName |
(required) |
String |
Name of the channel emitting the payload. |
|
action |
(required) |
String |
Action label used to filter and route logic. |
|
payload |
(required) |
Object |
Custom data (or user event dataset if broadcast from ViewStream). |
|
srcElement |
{} |
Object |
Reference to the DOM element that triggered the event (if applicable). |
|
event |
{} |
UIEvent |
Native event object from the browser (e.g., click, input). |
{
immutable Object Frozen Object.
}
constructor
ChannelPayload provides a consistent interface that transmits all Channel info.
Overview
- They are immutable: frozen in memory for consistent, reference-safe communication across ViewStream and Channel instances. Use
clone()to modify a copy. - Every payload carries the same four properties, whatever the source:
Why it Matters
- Immutability: Enables efficient, cross-component event handling by safely sharing references to data.
- Action Filtering: Action labels are matched to relevant methods.
- DOM Context: Includes the triggering DOM element (srcElement) and the event's values (event) for fine-grained control.
Good to know
- Dataset values are read when the event fires — update a
data-*attribute and the next payload carries the new value. - An element's
data-actionvalue lands atpayload.action, separate from the payload's action label. Filters checking{ action: X }see the payload's value first — when in doubt, use a payload method. - Avoid naming a property
payloadinside the payload data — Spyne warns, since it collides with the payload property itself. Rename at the source (result,data).
STAGE: ChannelPayloadFilter
Used by custom Channel and ViewStream instances to filter just the requreid Channel Payloads
ChannelPayloadFilter
Filters allow ViewStream and Channel instances to reactively connect to specific ChannelPayloads.
Channel Payload FilterNew Instance
CONSTRUCTORnew ChannelPayloadFilter (
selectorselector?: string | string[]filters?Object
)
Parameter |
Default |
Type(s) |
Description |
|---|---|---|---|
|
selector |
(optional) |
String | Array | HTMLElement |
A selector (or list of selectors) matched against the event target within a ViewStream's DOM — or an actual DOM element. |
|
filters |
{} |
Object |
An object of filtering criteria. Each value can be a string, number, or boolean (compared by equality), or a method that returns true or false. |
|
└─debugLabel |
undefined |
String |
A label for this filter. When set, every matching attempt logs to the console with each filter property's pass/fail — the first thing to reach for when a filter admits nothing or everything. |
{
}
constructor
ChannelPayloadFilter — Returns a Boolean function that is applied to ChannelPayload properties. The function resolves to true when all of its predicates passes.
This enables Channel and ViewStream instances to refine matching of ChannelPayloads beyond Action labels.
How it works
Add an exact string match or filter method for any property in the ChannelPayload target. All matches need to return true in order for the ChannelPayloadFIlter to pass.
Click on Examples to see the variety of filter options available.
STAGE: ChannelFetch
Creates a channel using content returned from the Fetch API
Can be used as CRUD connection to external APIs and services
ChannelFetch
Integrates the native Fetch API into SpyneJS’s Channel platform.
Standardizes API communication, enabling CRUD operations and external data integration within the Channel system.
ChannelFetchNew Instance
CONSTRUCTORnew ChannelFetch (
channelNameString=undefinedpropsObject={}
)
Parameter |
Default |
Type(s) |
Description |
|---|---|---|---|
|
channelName |
(required) |
String |
A unique name to identify and access the Channel via getChannel(). |
|
props |
(required) |
Object |
Holds all of the properties for the Channel instance. |
|
└─url |
(required) |
URL |
The URL for the Fetch request. |
|
└─map |
undefined |
Function |
Optional mapping function to customize the response before it's emitted. |
|
└─responseType |
json |
json | text | arrayBuffer | blob | formData |
Sets the expected response content type. |
|
└─[Fetch API Options] |
Default Fetch Request |
String | Objects |
All valid fetch options like method, headers, body, mode, etc. |
|
└─disableSanitize |
false |
Boolean |
Allows unsafe tags in a data source when set to true (for data considered secure) |
|
└─pause |
false |
Boolean |
Prevents the fetch from executing until explicitly triggered. |
|
└─debug |
false |
Boolean |
Logs request/response lifecycle to the console. |
{
}
constructor
ChannelFetch extends the Channel class by automatically triggering fetch requests and returning the response through a standardized ChannelPayload.
This channel can be extended, but it is typically interacted with by sending requests and returning responses via ChannelPayloads.
Every fetch outcome enters the channel system as a conformed ChannelPayload — a success under the response action, a failure under the error action. Both action labels are derived from the channel’s registered name and are registered alongside the channel’s other actions, so both participate in action validation and can be narrowed with addActionListeners and ChannelPayloadFilter.
Requests
Unless paused, the fetch request is sent when created.
Future requests or first requests for paused instances are sent via the "{CHANNEL_NAME}_REQUEST_EVENT" action (the generic "CHANNEL_FETCH_REQUEST_EVENT" label is also registered) sent via sendInfoToChannel.
Response
Responses are cached and returned with the "{CHANNEL_NAME}_RESPONSE_EVENT" action label.
The optional map function conforms the response data before it is emitted.
Error
Fetch failures are returned with the "{CHANNEL_NAME}_ERROR_EVENT" action label.
A failure is any of: a rejected fetch (network failure), a non-OK HTTP response (4xx/5xx), an unparseable response body, an unsupported responseType, or a map function that throws. The map function is not called for error payloads.
The error payload is a conformed, flat object with filterable properties:
- isChannelFetchError: Always true; discriminates framework fetch errors from response data.
- errorType: One of FETCH_HTTP_ERROR, FETCH_RESPONSE_PARSE_ERROR, FETCH_UNSUPPORTED_RESPONSE_TYPE, FETCH_UNKNOWN_ERROR.
- message: Human-readable description of the failure.
- status / statusText: HTTP status details, when a response was received.
- url / channelName / responseType: The request context.
- rawBodyPreview: The response body, truncated to 500 characters.
- originalErrorMessage: The message of the underlying error, when one exists.
Because ChannelFetch caches its last payload for late subscribers, an error payload becomes the cached payload until a subsequent request succeeds.
STAGE: ChannelFetchUtil
This utiliity is used by Channel Fetch to generate observables from the Fetch API
Can be added to ChannelFetch modules to create sophisticated APIs
ChannelFetchUtil
A utility class that powers ChannelFetch.
Provides a consistent, composable interface for configuring and executing Fetch API requests as observables.
ChannelFetchUtilNew Instance
CONSTRUCTORnew ChannelFetchUtil (
optionsObject=undefined subscriberFunction=undefined
)
Parameter |
Default |
Type(s) |
Description |
|---|---|---|---|
|
options |
(required) |
Object |
Fetch configuration settings. |
|
└─url |
(required) |
URL |
The request URL for the fetch call. |
|
└─map |
undefined |
Function |
A function to modify the response before it's returned. |
|
└─responseType |
json |
json | text | arrayBuffer | blob | formData |
Sets how the fetch response will be parsed. |
|
└─[Fetch API Options] |
Base Fetch Options |
Object |
All valid fetch options like method, headers, body, mode, etc. |
|
└─debug |
false |
Boolean |
Logs fetch request and response to the console. |
|
subscriber |
(required) |
Function |
Callback executed when the fetch completes. Receives either the parsed (and mapped) response or, on failure, the conformed error payload. |
{
}
constructor
ChannelFetchUtil is an internal utility used by ChannelFetch and custom implementations. It returns an observable that wraps a configured Fetch API call.
This makes it ideal for:
- Creating testable, standalone fetch logic.
- Reusing logic across channels or custom fetch setups.
- Integrating advanced stream behaviors (like retry, debounce, etc.).
Error conforming
The observable never errors out. Every failure — a rejected fetch, a non-OK HTTP response, an unparseable body, an unsupported responseType, or a throwing map function — is caught and conformed into a flat error payload (marked with isChannelFetchError: true and carrying errorType, message, status, statusText, url, rawBodyPreview) that is delivered to the subscriber through the same next path as a successful response.
The map function is only applied to successful responses. ChannelFetch uses this discriminator to route error payloads to its "{CHANNEL_NAME}_ERROR_EVENT" action.
STAGE: SpyneTrait
Organizes logic for codebase
Convenient system to test pure functions, that are automatically composed to instances
SpyneTrait
Encapsulates reusable logic as pure functions, easily bindable to ViewStream or Channel instances.
SpyneTraitNew Instance
CONSTRUCTORnew SpyneTrait (
parentContextViewStream | Channel instanceprefix$String=undefined
)
Parameter |
Default |
Type(s) |
Description |
|---|---|---|---|
|
parentContext |
(required) |
ViewStream | Channel |
The instance to which functions will be bound. |
|
prefix$ |
(required) |
String |
String prepended to all methods to maintain consistency. |
{
}
constructor
SpyneTraits improve maintainability by allowing logic to be organized, tested, and shared between ViewStream and Channel instances.
What SpyneTraits Provide:
- Pure Function Encapsulation: Write logic in isolated, testable functions with no side effects.
- Method Binding: Functions are auto-bound to parentContext (ViewStream or Channel) and namespaced using prefix$.
- Code Organization: Keeps application logic clean and modular by separating behavior from structure and event flow.
- RamdaJS Integration: Built-in access to functional utilities like compose, map, filter, etc., using the RamdaJS library.
STAGE: SpyneApp
Creates the Channel Pipeline on intialization
Takes in the configuration file for channels and other options
Registers Channels so that they can be access globally
SpyneApp
Initializes the SpyneJS application and applies configuration settings.
SpyneAppInitialize
init (
configObject={}
)
Parameter |
Default |
Type(s) |
Description |
|---|---|---|---|
|
config |
{} |
Object |
Object containing application setup parameters. |
|
└─debug |
false |
Boolean |
Enables developer-friendly logs that assist with app initialization and channel wiring. |
|
└─strict |
false |
Boolean |
Activates a Trusted Types policy to prevent unsafe HTML injection. |
|
└─pluginMethods |
[] |
Array |
Allows plugins to add methods to the application. |
{
}
init
The init() method boots up the SpyneJS application using the provided configuration.
It sets up:
- Event channels (UI, Route, Window).
- Application-level flags (debug, strict).
- Optional plugin methods for global access.
🔒 SpyneJS applications are initialized in memory. The application instance is not attached to the global window object and remains self-contained.
STAGE: SpyneAppProperties
Creates the Channel Pipeline on intialization
Takes in the configuration file for channels and other options
Registers Channels so that they can be access globally
SpyneAppProperties
This is a "Singleton" that can be used to store temporary properties, and to retrieve configuration and navlinks.
SpyneAppPropertiesMethods
setProp (
keyStringvalueAnyisTempBoolean=false
)
Parameter |
Default |
Type(s) |
Description |
|---|---|---|---|
|
key |
(required) |
String |
The key under which the property is stored. |
|
value |
undefined |
Any |
The value to be stored. |
|
isTemp |
false |
Boolean |
When true, the first retrieval removes the property from memory. |
{
}
setProp
Allows for the persistent or temporary storage of properties.
STAGE: SpynePlugin
Allows developers to create shareable code and components
SpynePlugin
In early beta, SpynePlugin allows for third-party plugins to be created
SpynePluginNew Instance
CONSTRUCTORnew SpynePlugin (
propsObject={}
)
Parameter |
Default |
Type(s) |
Description |
|---|---|---|---|
|
name |
(required) |
String |
The name of the plugin. |
|
props |
{} |
Object |
Holds all of the properties for the plugin instance. |
|
└─pluginName |
(required) |
String |
The unique identifier for the plugin. |
|
└─pluginMethods |
undefined |
Object |
Methods exposed by the plugin to be added to the application. |
{
}
constructor
SpynePlugin allows developers to create shareable ViewStream components, Channels, SpyneTraits and Themes and other functionality.