Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

197 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

fstage [ALPHA v0.6.1]

A modular ES module toolkit for building JavaScript apps — no build step required.

Fstage is a platform layer: it provides a loader, import map resolution, and a set of composable modules you use to assemble your own framework. Works with any rendering library (LitElement, plain DOM, etc.).

Alpha — breaking changes may occur.

Design philosophy

  • No build step — native ES modules and import maps only
  • Platform stability — conservative ES2020 baseline, explicit control flow, minimal dependencies (see CONTRIBUTING.md)
  • Composable — use only the modules you need; wire them together via the registry
  • No component lock-in — the component model is defined by a versioned open standard that any runtime can implement

Requirements

  • ES module support (<script type="module">)
  • Import map support (Safari 16.4+, Chrome 96+)

Quick start

  1. Add the fstage loader to your HTML and set a config path:
<script>
  window.FSCONFIG = { configPath: 'js/config.mjs' };
</script>
<script type="module" src="https://cdn.jsdelivr.net/gh/codi0/fstage@latest/src/js/fstage.min.mjs"></script>
  1. Create js/config.mjs — this is where you declare your import map, load phases, and wire up services. See the tasks example config for a complete reference, or the starter example config for an annotated walkthrough.

fstage dispatches fstage.ready on window when the app is loaded, and fstage.failed on error.

How it works

Apps load in sequential phases declared under loadAssets in your config:

export default {
  importMap: {
    'lit': 'https://cdn.jsdelivr.net/npm/lit-element@4/+esm',
  },
  loadAssets: {
    preload: [ '@fstage/env', '@fstage/registry', '@fstage/stack' ],
    libs:    [ 'lit', '@fstage/component', '@fstage/store', '@fstage/sync',
               '@fstage/history', '@fstage/router', '@fstage/animator',
               '@fstage/gestures', '@fstage/transitions',
               '@fstage/interactions', '@fstage/form' ],
    app:     [ 'js/components/app.mjs', 'css/style.css' ],
  },
  router: {
    urlScheme: 'hash',
    routes: [ { path: '/', meta: { component: 'my-home', title: 'Home' } } ],
  },
  storage: { name: 'myapp', schemas: { items: { keyPath: 'id' } } },
  afterLoadPreload(e) { e.modules.get('stack.wirePreload', [ e ]); },
  afterLoadLibs(e)    { e.modules.get('stack.wireStack',   [ e ]); },
  afterLoadApp(e)     { e.modules.get('stack.startStack',  [ e ]); },
};

Each phase completes before the next starts. afterLoad, afterLoadPreload, afterLoadLibs, and afterLoadApp hooks fire at the end of each phase. The registry is the central service locator — modules register instances there and components inject what they need.

@fstage/stack provides wirePreload, wireStack, and startStack helpers that handle all standard service wiring from config keys alone. Hooks receive an e object with modules and configs namespaces:

e.configs.root()                         // full root config object
e.configs.root().debug                   // nested config value
e.modules.get('stack.wireStack', [ e ])  // calls wireStack(e)
e.modules.get('store.createStore', [])   // calls createStore(), returns instance

See the getting started guide for a full walkthrough.

Examples

Example Description
examples/starter Minimal annotated shell — single route, counter demo, start here
examples/tasks Complete To-Do PWA — sync, offline, animations, gestures, Capacitor
cd examples/starter && npx serve .

See examples/README.md for details.

Modules

Module Description
stack Default service wiring — wirePreload, wireStack, startStack helpers that replace ~80 lines of afterLoadLibs/afterLoadApp boilerplate with a single call
store Reactive store — get/set/watch, computed, effects, and a full data-lifecycle system (fetch, cache, TTL, optimistic updates, pagination)
sync Offline-first sync — local-first reads/writes, remote handler abstraction, write queue with exponential backoff retry. Also re-exports storage and http — import from here unless you need those modules standalone
storage Two-tier IndexedDB — simple key/value blob store or schema-based rows with SQL-like querying. Re-exported by sync
http Thin fetch wrapper with timeout, form/JSON body helpers, and response parsing. Re-exported by sync
router Client-side router — deterministic matching, param extraction, navigation handler, scroll state
history Browser history abstraction — hash, query string, or path URL schemes
component Web component runtime implementing the Universal Component Definition Standard — declarative state, bindings, watches, computed, animations, interactions
plugin Plugin lifecycle runtime — source registration, activation/deactivation, cleanup scope, handler/contribution ownership
registry Service registry / DI container — the glue between modules
env Platform detection, capability facts, and a layered policy system with CSS variable output
animator WAAPI animation engine — named presets, toggle controllers, flip, stagger, collapse
transitions View transition engine and screen host for page-level animations
interactions Delegated event handling with debounce/throttle and gesture/transition extensions
gestures Touch/pointer gesture detection — swipe, edge pan, long press, tap
ui Reusable, accessible UI primitives — fs-action-sheet (imperative iOS-style sheet), fs-bottom-sheet (swipe-dismissable modal), fs-dialog (centered modal), fs-disclosure (animated show/hide), fs-listbox (keyboard-navigable select with typeahead). All unstyled, CSS-custom-property driven
form Store-backed form validation and submit lifecycle for component definitions
ssr Server-side rendering via Declarative Shadow DOM — createSsrRuntime + renderToString. Supports state defaults, reactive getters, all $src shorthands, host attribute stamping, and per-call error handling. Requires @lit-labs/ssr as a peer dep
devtools Debug panel — store event log, sync queue inspector, storage browser
push Unified push facade with native (Capacitor) + web adapters
websocket Small WebSocket helper with reconnect, send queue, custom events, and channel pub/sub
utils Shared primitives: deep copy, equality, diff, hash, debounce, schedule, nested key access, DOM helpers

Documentation

Contributing

See CONTRIBUTING.md for the coding standard, syntax baseline, and source style guide.

License

MIT

About

Build your own javascript framework. Create PWAs and more.

Topics

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages