Topazdocs
애플리케이션 만들기

Data Lens

다중 모듈 로컬 우선 Topaz Web 애플리케이션을 만들고 테스트·패키징한 뒤 오프라인에서 실행합니다.

Data Lens는 Web Application Loop 전체를 하나의 유지보수 애플리케이션으로 보여 줍니다. 브라우저에서 JSON과 CSV를 파싱하고, 명목 타입으로 행과 요약을 관리하며, 잠긴 패키지 의존성으로 여러 언어의 레이블을 정규화합니다. 데이터는 서버로 보내지 않고 필터링·정렬·선택·오류·키보드 입력을 처리합니다. 현재 Topaz는 사용자 선택 파일 입력과 텍스트 내보내기를 포함한 이 흐름을 제공합니다.

애플리케이션 제품 선택

애플리케이션 상태, 이벤트, 갱신과 화면을 Topaz가 소유하면 web-app을 사용하세요. 컴파일러는 하나의 init/update/view 생명주기를 검사하고 범위가 제한된 안전한 DOM 호스트가 포함된 완전한 정적 제품을 만듭니다. 기존 JavaScript 호스트가 UI나 Worker 프로토콜을 소유하고 선택한 Topaz export만 호출해야 한다면 raw web 또는 web-worker를 사용하세요. Playground는 컴파일러 샌드박스이며 두 배포 모델 중 하나가 아닙니다.

Data Lens는 모델과 상호작용을 Topaz가 담당하므로 web-app을 사용합니다.

패키지 구조

설치된 스캐폴드에서 시작한 뒤 파싱, 변환, 모델, 뷰와 생명주기를 모듈로 나눕니다.

BASH
topaz init --target web-app --root data-lens
mkdir -p data-lens/src data-lens/tests registry/lens_labels/1.0.0/src

애플리케이션 매니페스트는 실제 빌드 대상, 관리형 스타일시트와 로컬 의존성 하나를 선언합니다.

TOML
[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       생명주기와 메시지
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> 구성

모델은 상태 전이를 명시적으로 만듭니다.

TOPAZ
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>,
}

엔트리는 생명주기 v2를 export합니다. 브라우저 정보와 로컬 데이터 완료는 WebAppEvent로 들어오며 애플리케이션 메시지는 명목 값을 유지합니다.

TOPAZ
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)
}

파싱은 JSON $[0].category: missing field처럼 안정적인 경로가 있는 Result를 반환합니다. update는 이 오류를 모델에 저장하고 view는 텍스트로 렌더링합니다. JavaScript에서 오류를 대신 처리하거나 innerHTML로 소스를 삽입하지 마세요.

OpenText는 사용자가 선택한 뒤 범위가 제한된 UTF-8 문서 이름, 미디어 타입, 바이트 수와 텍스트만 제공합니다. 경로나 재사용 가능한 파일 핸들은 제공하지 않습니다. DownloadTextDownloadStarted는 브라우저가 다운로드를 시작했다는 뜻이며, 사용자가 실제 저장을 끝냈다고 주장하지 않습니다.

세션 저장 범위는 의도적으로 모델보다 좁습니다. Save session은 검색어, 활성 행 필터와 정렬 방식만 saveState로 저장하고, 다시 열면 loadState가 이 설정만 복구합니다. 소스 텍스트, 파싱된 행, 요약, 파일 이름과 오류는 저장하지 않습니다. Forget session은 deleteState를 사용하며, 손상·거부·용량 초과·사용 불가 결과는 호스트가 숨기지 않고 타입이 지정된 애플리케이션 상태로 표시합니다.

잠금·검사·테스트

로컬 lens_labels registry 패키지를 작성한 뒤 한 번 vendoring합니다. 이후 모든 명령은 lockfile과 vendored 바이트를 사용합니다.

BASH
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

선택한 테스트 파일도 패키지 문맥에서 실행되므로 import, 의존성 식별자, 언어 모드와 모듈 루트가 애플리케이션과 같습니다.

개발 실행과 패키징

작성 중에는 루프백 개발 서버를 사용하고 마지막에 관리형 제품을 빌드합니다.

BASH
topaz dev --root data-lens --port 8000
topaz build --root data-lens --locked --release --out-dir data-lens-product

실제 CSV·JSON 파일 선택, 유니코드 레이블, 텍스트 필터, 활성 행 체크박스, 두 정렬 방식, 세션 저장·재로딩·삭제, submit과 Enter, 취소, 잘못된 UTF-8, 초기화, 누락 필드 오류 하나와 내려받은 CSV/JSON 내용을 확인하세요. 잘못된 편집이 생기면 개발 서버는 마지막 정상 제품을 계속 제공합니다. 유지보수 설치 경로는 256행 다국어 CSV와 128행 JSON, 유니코드 파일 이름, 8회 연속 파일·상태 작업, 의미 기반 요약, focus 복구와 정확한 내보내기 데이터까지 포함합니다.

최종 디렉터리에는 HTML, 안전한 애플리케이션 호스트, 검사된 raw Web facade, WASM, 선언한 스타일, 라이선스, 고지, topaz-web-capabilities.jsontopaz-artifact.json이 들어 있습니다. data-lens-product/만 새 정적 루트로 복사하고 패키지 소스와 빌드 저장소를 지운 뒤 네트워크를 끄고 이 디렉터리를 서빙하세요. 위 시나리오는 모두 계속 동작해야 합니다. 제품에는 Topaz 설치, registry, 소스 파일, npm 런타임, CDN, 원격 데이터 서비스가 필요하지 않습니다.

관련 문서