Data Lens показывает весь Web Application Loop в одном поддерживаемом приложении. Оно разбирает JSON и CSV в браузере, хранит строки и сводки в номинальных типах, нормализует многоязычные метки через зафиксированную пакетную зависимость и обрабатывает фильтрацию, сортировку, выбор, ошибки и клавиатуру, не отправляя набор данных на сервер. Текущий Topaz предоставляет этот workflow, включая выбор локального файла и экспорт текста.
Выбор Web-продукта
Используйте web-app, когда Topaz владеет состоянием приложения, событиями,
обновлением и представлением. Компилятор проверяет единый lifecycle
init/update/view и создаёт полный статический продукт с ограниченным
безопасным DOM-host. Выбирайте raw web или web-worker, когда существующий
JavaScript-host владеет UI либо worker-протоколом и вызывает отдельные
типизированные exports Topaz. Playground — песочница компилятора, а не модель
развёртывания.
Data Lens использует web-app, потому что модель и взаимодействия принадлежат
Topaz.
Структура пакета
Начните с установленного scaffold, затем разделите parsing, transformation, model, view и lifecycle по модулям:
topaz init --target web-app --root data-lens
mkdir -p data-lens/src data-lens/tests registry/lens_labels/1.0.0/src
Manifest приложения задаёт эффективную цель сборки, управляемый stylesheet и одну локальную зависимость:
[package]
name = "data_lens"
version = "0.1.0"
language = "5.8"
entry = "src/main.tpz"
[build]
target = "web-app"
deterministic = true
[web]
title = "Topaz Data Lens"
styles = ["styles/app.css"]
assets = []
lifecycle = "v2"
[capabilities.web]
open_text = true
download_text = true
local_state = true
[dependencies]
std = "5.8"
lens_labels = "1.0.0"
Храните приложение в семи исходных модулях:
src/main.tpz lifecycle и сообщения
src/model.tpz номинальные строки, сводка, модель и enum сообщений
src/session.tpz ограниченные JSON-настройки для долговременного состояния
src/parsing.tpz декодирование JSON/CSV и детерминированные ошибки путей
src/transform.tpz фильтрация, сортировка и агрегаты
src/exporting.tpz детерминированный UTF-8 CSV/JSON
src/view.tpz типизированное построение Html<Msg>Модель делает переходы состояния явными:
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>,
}Entry экспортирует lifecycle v2. Данные браузера и завершения локальных
операций приходят как WebAppEvent, а сообщения приложения остаются
номинальными значениями:
export function init() -> WebAppStep<Model, Msg> {
WebAppStep { model: initialModel(), commands: [loadState("data-lens-session-load", "session", Msg.LocalCompleted)] }
}
export function update(model: Model, message: Msg, event: WebAppEvent) -> WebAppStep<Model, Msg> {
match message {
case OpenDocument => step(model, [openText("data-lens-open", ".csv,.json,text/csv,application/json", Msg.LocalCompleted)])
case SaveSession => saveSession(model)
case ForgetSession => step(model, [deleteState("data-lens-session-delete", "session", Msg.LocalCompleted)])
case LocalCompleted => {
match event {
case LocalData(local) => completeLocalData(model, local)
case LocalState(local) => completeLocalState(model, local)
case Browser(_) => step(model, [])
}
}
case DownloadResults => downloadResults(model)
case Apply | Submit => step(applyModel(model), [])
case Clear => step(clearModel(), [dom(focus("#source"))])
case _ => updateFromBrowser(model, message, event)
}
}
export function view(model: Model) -> Html<Msg> {
render(model)
}Parsing возвращает Result со стабильным путём, например
JSON $[0].category: missing field. Update сохраняет ошибку в модели, а view
выводит её как текст. Не переносите обработку в JavaScript и не вставляйте
исходные данные через innerHTML.
OpenText передаёт только ограниченные имя, media type, размер и UTF-8 текст
документа после явного выбора пользователем. Путь и повторно используемый
дескриптор не раскрываются. DownloadStarted от DownloadText сообщает о
запуске загрузки браузером, а не о физическом сохранении файла.
Сохраняемая сессия намеренно уже модели. Save session записывает через saveState только запрос, фильтр активных строк и режим сортировки; после перезагрузки loadState восстанавливает лишь эти настройки. Исходный текст, разобранные строки, сводка, имя файла и ошибки не сохраняются. Forget session использует deleteState, а повреждение, запрет, исчерпание квоты и недоступность хранилища отображаются как типизированное состояние приложения, а не скрываются host-слоем.
Lock, проверки и тесты
Создайте локальный registry-пакет lens_labels, затем один раз скопируйте его
в vendor. Все последующие команды используют lockfile и 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 test data-lens/tests/exporting.tpz --root data-lens --locked
topaz doc --root data-lens --locked --out-dir data-lens-docs
Выбранные тестовые файлы выполняются в контексте пакета, поэтому imports, идентичность зависимости, режим языка и корень модулей совпадают с приложением.
Разработка и упаковка
Во время разработки используйте loopback-сервер, затем соберите управляемый продукт:
topaz dev --root data-lens --port 8000
topaz build --root data-lens --locked --release --out-dir data-lens-product
Проверьте выбор реальных CSV/JSON-файлов, Unicode-метки, текстовый фильтр, checkbox активных строк, оба режима сортировки, сохранение, перезагрузку и удаление сессии, submit и Enter, отмену, неверный UTF-8, очистку, одну ошибку отсутствующего поля и содержимое загруженного CSV/JSON. После ошибочной правки сервер продолжает отдавать последний исправный продукт. Поддерживаемый установленный путь включает многоязычный CSV на 256 строк, JSON на 128 строк, Unicode-имена файлов, восемь последовательных файловых и state-операций, семантические сводки, восстановление focus и точные экспортированные данные.
Итоговый каталог содержит HTML, безопасный host приложения, проверенный raw
Web facade, WASM, объявленные стили, лицензии, notices,
topaz-web-capabilities.json и topaz-artifact.json. Скопируйте только
data-lens-product/ в новый
статический корень, удалите исходники пакета и build storage, отключите сеть и
раздавайте этот каталог. Все сценарии выше должны продолжить работу: продукту
не нужны установка Topaz, registry, исходные файлы, npm runtime, CDN или
удалённый сервис данных.
Связанная документация
- Цикл приложения охватывает native-, Python- и Web-workflow от установки.
- Пакеты и распространение определяют locking,
vendoring и входы
[web]. - Артефакты и развёртывание определяют управляемые файлы и границу развёртывания без исходников.