File detail
typescript.rq
reqlan rq/codestyle/typescript.rq
| Idea | Status | Tags | Summary | Katz |
|---|---|---|---|---|
| scope | TypeScript package standards for `packages/extension` ( npm `reqlan-extension` ), especially UI state. Complements [development_core.rust_mindset] and [extension_architecture.state_machine_mindset]. Webview inventory: [webview_doc.webview]. Package role: [core_architecture.extension_package]. | 0.040 | ||
| ui_state_management | done | Extension UI state is explicit, typed, and layered — not a single global store shared across host and webview. Choose the layer by lifetime and owner: - Host session / durable prefs live in the extension process ( `ExtensionContext`, plain modules ). - Webview view-models live in Svelte 5 runes ( `$state` / `$derived` / `$effect` ). - Cross-boundary traffic uses typed `postMessage` contracts only. Prefer small state machines ( named phases, request ids, clear transitions ) over ad-hoc flags. Related: [webview_app_state], [persistence_tiers], [zustand_boundary], [host_webview_ownership]. | 0.080 | |
| webview_app_state | done | Complex webviews ( activity bar, Ideas Summary ) own a single `AppState` class in `state/app.svelte.ts`. Fields that drive UI are Svelte 5 `$state` properties on that class; side effects and host I / O are methods. Export one module singleton ( `export const app = new AppState()` ) and inject it via [svelte_app_context]. Do not use `svelte/store` writable / readable stores for new UI, and do not put zustand inside webview code ( [zustand_boundary] ). Simple panels ( export form, onboarding, index diagnostics ) may keep `$state` on the root `App.svelte` instead of a separate AppState module when the surface is a single form / flow. Related: ["../extension/workspace-summary/ideas_summary/webview.rq".table_column_filters] `$derived` binding rule; ["../extension/workspace-summary/ideas_summary/graphical_graph.rq".graph_ui_persistence]. | 0.070 | |
| svelte_app_context | done | Webview components read AppState through Svelte context helpers ( `setAppContext` / `getApp` with a `Symbol` key ) in `state/context.ts` — not by importing the singleton from deep child leaves when a context is available. Root `App.svelte` sets context once after constructing / using `app`. | 0.049 | |
| derived_host_bindings | done | Components that display host-driven AppState fields must bind through Svelte 5 `$derived` / `$derived.by` ( not legacy `$:` ) so updates from the message listener re-render reliably. Keep ephemeral widget-only UI ( open menus, local filter drafts, selection ) as component-local `$state`. Do not mirror host payloads into a second parallel store inside the component. | 0.040 | |
| host_webview_ownership | done | The extension host owns durable data, index / analysis queries, and VS Code APIs. The webview owns presentation state and posts intents ( search, navigate, persist UI prefs, export ). Host session objects ( e. g. activity-bar context session ) mutate on the host and push snapshots to the webview; the webview must not invent a second source of truth for the same domain fields. Typed message modules define the contract; keep request ids / error scopes on async host calls. | 0.050 | |
| persistence_tiers | done | Three persistence tiers — pick the shallowest that matches lifetime: 1. `acquireVsCodeApi().getState` / `setState` — ephemeral webview session ( pane expand / heights, active tab ). 2. `ExtensionContext.workspaceState` — durable UI prefs shared across reloads ( graph / table UI keys under `reqlan.ideasSummary.*`, optionally per-base ). Normalize + default on read ( `normalizeGraphUiState` / table defaults ); never trust raw JSON shape. 3. `ExtensionContext.globalState` — install / user-level flags ( e. g. onboarding ), not pane view-models. Debounce persist posts ( ~ 200 – 250 ms ) when UI controls churn. Related: [webview_app_state]. | 0.050 | |
| postmessage_clone_safety | done | Before `postMessage` from a Svelte webview, JSON-clone payloads ( `JSON.parse(JSON.stringify(...))` ) so `$state` proxies remain structured-clone safe. Shared helpers live in each webview's `lib/vscode.ts`. | 0.040 | |
| zustand_boundary | done | [extension_architecture.state_machine_mindset] still applies: design UI and host flows as state machines. Zustand is no longer used anywhere: the index lifecycle FSM ( `opening` / `syncing` / `ready` / `error` ), counts, file issues, and the document-update ring now live in Rust `WorkspaceIndexRuntime` and are read over napi via `statusSnapshot()` ( ["../core_analysis/rust_port.rq".native_bridge] ); durable diagnostics persist in `index-diagnostics.sqlite`. TypeScript keeps no parallel copy of that state. Do not reintroduce zustand ( or Redux-like globals ) in `packages/extension/webviews/**` or the analytical package. Extension-host TypeScript may keep plain mutable session modules when the surface is small and message-pushed; owned lifecycle / state machines belong in the Rust runtime. | 0.069 | |
| imperative_view_controllers | done | Heavy imperative widgets ( Cytoscape graph ) keep lifecycle state on a controller class ( `GraphCyController` ), not inside AppState `$state` fields. AppState holds query / slice / loading / error and persisted UI prefs; the component holds the controller instance. See ["../extension/presentation/graph.rq".webview_threading] and ["../extension/workspace-summary/ideas_summary/graphical_graph.rq".graph_loading]. | 0.040 |
Related clusters
community
folder
status
status
tag
file
Local graph
Initialising graph…