Data Lens is the full Web Application Loop in one maintained application. It
parses JSON and CSV in the browser, keeps rows and summaries in nominal types,
normalizes multilingual labels through a locked package dependency, and
renders filtering, sorting, selection, errors, and keyboard interaction without
sending the dataset to a server. Topaz 5.7.0 provides this workflow in language
mode topaz-5.7.
Choose the application product
Use web-app when Topaz owns application state, events, updates, and the view.
The compiler checks one init/update/view lifecycle and emits a complete
static product with a bounded safe DOM host. Use raw web or web-worker
instead when an existing JavaScript host owns the UI or worker protocol and
calls selected typed Topaz exports. The Playground is a compiler sandbox; it
is not either deployment model.
Data Lens uses web-app because its model and interactions belong in Topaz.
Package shape
Start with the installed scaffold, then split parsing, transformation, model, view, and lifecycle code into modules:
topaz init --target web-app --root data-lens
mkdir -p data-lens/src data-lens/tests registry/lens_labels/1.0.0/src
The application manifest declares the effective target, managed stylesheet, and one local dependency:
[package]
name = "data_lens"
version = "0.1.0"
language = "5.7"
entry = "src/main.tpz"
[build]
target = "web-app"
deterministic = true
[web]
title = "Topaz Data Lens"
styles = ["styles/app.css"]
assets = []
[dependencies]
std = "5.7"
lens_labels = "1.0.0"
Keep the application in five source modules:
src/main.tpz lifecycle and messages
src/model.tpz nominal rows, summary, model, and message enum
src/parsing.tpz JSON/CSV decoding and deterministic data-path errors
src/transform.tpz filtering, sorting, and aggregates
src/view.tpz typed Html<Msg> constructionThe model makes state transitions explicit:
export record DataRow {
name: string,
category: string,
value: int,
active: bool,
}
export record Summary {
totalRows: int,
activeRows: int,
totalValue: int,
}
export enum SortMode { ByName, ByValue }
export record Model {
source: string,
query: string,
activeOnly: bool,
sortMode: SortMode,
rows: Array<DataRow>,
summary: Summary,
status: string,
error: Option<string>,
}The entry exports exactly one compatible lifecycle. Browser details arrive as
the bounded BrowserEvent; application messages remain nominal values:
export function init() -> AppStep<Model, Msg> {
AppStep { model: initialModel(), commands: [] }
}
export function update(model: Model, message: Msg, event: BrowserEvent) -> AppStep<Model, Msg> {
match message {
case QueryChanged => step(applyQuery(model, event.value ?? ""), [])
case ActiveChanged => step(applyActive(model, event.checked ?? false), [])
case Apply | Submit => step(applyModel(model), [])
case SourceKey => {
if (event.key ?? "") == "Enter" {
return step(applyModel(model), [])
}
step(model, [])
}
case Clear => step(clearModel(), [focus("#source")])
}
}
export function view(model: Model) -> Html<Msg> {
render(model)
}Parsing returns Result with stable paths such as
JSON $[0].category: missing field. The update stores that error in the model;
the view renders it as text. Do not catch it in JavaScript or inject source
through innerHTML.
Lock, check, and test
Populate the local lens_labels registry package, then vendor it once. All
later commands use the lockfile and vendored bytes:
topaz vendor --root data-lens --from registry
rm -rf registry
topaz check --root data-lens --locked
topaz fmt --root data-lens --check
topaz test data-lens/tests/parsing.tpz --root data-lens --locked
topaz test data-lens/tests/transform.tpz --root data-lens --locked
topaz test data-lens/tests/application.tpz --root data-lens --locked
topaz doc --root data-lens --locked --out-dir data-lens-docs
Selected test files still run in package context, so imports, dependency identity, language mode, and the module root match the application.
Develop and package
Use the loopback development server while authoring, then build the managed product:
topaz dev --root data-lens --port 8000
topaz build --root data-lens --locked --release --out-dir data-lens-product
Exercise CSV and JSON samples, Unicode labels, text filtering, the active-only checkbox, both sort modes, submit and Enter, selection, clearing, and one missing-field error. A failed edit keeps the last good development product.
The final directory contains HTML, the safe application host, the checked raw
Web facade, WASM, declared styles, licenses, notices, and
topaz-artifact.json. Copy only data-lens-product/ to a fresh static root,
remove package source and build storage, disable network access, and serve that
directory. All scenarios above must continue to work: the product needs no
Topaz installation, registry, source file, npm runtime, CDN, or remote data
service.
Next steps
- Application Loop covers the native, Python, and Web workflows from installation.
- Packages & Distribution defines locking,
vendoring, and
[web]inputs. - Artifacts & Deployment defines managed files and source-free deployment.