Concorde concept — Data flow. Recommended patterns for new Concorde apps (Lit + TypeScript). Under the hood, data lives in a DataProvider store (legacy Publisher API: Legacy: Sharing data). Doc ID: docs/_core-concept/dataFlow. Keywords: Concorde, supersoniks, docs/_core-concept/dataFlow, dataFlow, Data flow, concept, DataProvider, get, set, dp, DataProviderKey, sub(key), @subscribe, @state, @ancestorAttribute. URL: https://concorde.supersoniks.org/crawl/docs/_core-concept/dataFlow.html.
Data flow
Recommended patterns for new Concorde apps (Lit + TypeScript). Under the hood, data lives in a DataProvider store (legacy Publisher API: Legacy: Sharing data).
Quick map
| Need | Use |
|---|---|
| Read/write in code | get / set / dp + DataProviderKey (static paths only) |
| Reactive Lit template | sub(key) or @subscribe |
| Read component state from store | @subscribe + DataProviderKey<T, U> + @state |
| Inherit ancestor attributes | @ancestorAttribute |
| Write from component state | @publish |
| React to assignments | @handle |
| HTTP GET | @get + Endpoint, or sonic-list / sonic-queue with fetch |
| HTTP POST (body from store) | @post + Endpoint + body DataProviderKey |
| HTTP PUT / PATCH (body from store) | @put / @patch — same model as @post |
| Forms | formDataProvider + name on fields |
| Offline doc demos | serviceURL="/docs-mock-api" — Local API demos |
Skill: concorde-get-set-dp in the package ai/ folder.
DataProviderKey
import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
import { dp, get, set } from "@supersoniks/concorde/utils";
const cartKey = new DataProviderKey<{ items: string[] }>("cart");
set(cartKey, { items: [] });
dp(cartKey.items).set(["a", "b"]);
get(cartKey);
Dynamic paths (users.${userId}) → decorators or sub() — not get("users.${id}") in imperative code. Resolution rules: Dynamic path placeholders.
Decorators
| Decorator | Role |
|---|---|
@subscribe |
Read-only property from store — data configuration (type + key + scope) |
@publish |
Push property writes to store |
@handle |
Method called on assignment |
@ancestorAttribute |
Copy ancestor HTML attribute onto property |
@get |
HTTP GET into ApiResult<T> |
@post |
HTTP POST into ApiResult<T> (body from a publisher) |
@put / @patch |
HTTP PUT / PATCH into ApiResult<T> |
Walkthrough: My first component
HTTP and lists
- @get — single GET on a component
- @post — POST with body read from a
DataProviderKey - @put · @patch — PUT / PATCH (same options as
@post) - List —
fetch+key="data"+/docs-mock-api/api/users - Queue — lazy
offset=$offset&per_page=$limit+ optionaldataFilterProvider(form → query)
Starter kit
npx @supersoniks/create-concorde-ts-starter my-app
Interactive routes mirror these patterns (/concepts/*, /demo/*).
Legacy integration
| Topic | Page |
|---|---|
Subscriber / Fetcher mixins on app code |
Legacy: Subscriber mixin, Legacy: My first subscriber |
data-bind HTML (plain HTML hosts) |
HTML integration — doc demos use Lit in src/docs/example/ |
@onAssign |
@onAssign (prefer @handle) |
sonic-fetch alone |
Fetch |