Skip to content

Client Sync & Steps Islands

The UI is Astro pages hydrating React islands (src/islands). Islands read/write through the offline layer (Dexie cache + outbox) rather than calling the API directly, so the same optimistic, offline-first path backs every interaction.

The diagram below shows how the islands wire into the offline layer and the live/poll transports that refresh the cache.

flowchart LR
  Ctx["WorkspaceContext.tsx<br/>(shared state)"]
  Islands["islands<br/>(StepsRegion, TaskDetailPanel, ...)"]
  Status["SyncStatus.tsx"]
  Sync["sync.ts<br/>(offline mutation API)"]
  Core["sync-core.ts<br/>(reconcilers)"]
  Dexie[("Dexie cache<br/>+ outbox")]
  Live["live.ts<br/>(WS client)"]
  Poll["poll.ts<br/>(poll controller)"]
  Worker{{"Worker API"}}

  Ctx --> Islands
  Islands -->|mutate| Sync
  Sync -->|optimistic write + queue| Dexie
  Islands -->|liveQuery| Dexie
  Sync -->|replayOutbox| Worker
  Live --> Core
  Poll --> Core
  Core --> Dexie
  Live --> Status
  Poll --> Status
  • WorkspaceContext.tsx provides shared client state (current selection/scope, cached data) to islands.
  • Islands mutate via the offline mutation API (src/lib/offline/sync.ts) and observe reconciled data from the Dexie cache; the live/poll transports refresh that cache (see LiveConnection WS Client, Poll Controller, Sync-Core Reconcilers). SyncStatus.tsx surfaces transport state.
  • StepsRegion.tsx renders a Task’s Steps as a flat checklist (within TaskDetailPanel.tsx): add at bottom, toggle done, rename, reorder by drag (fractional rank, per-Task scope). It reflects the Step domain rules — no nesting, title + done only (Product Brief §5.2; see Steps in a Task).
  • Step edits are optimistic and queued like any other mutation; reconciliation uses reconcileSteps/reconcileAllSteps.

The sequence below traces a Step toggle from StepsRegion.tsx through the optimistic write to outbox replay and reconciliation.

sequenceDiagram
  participant User
  participant Steps as StepsRegion.tsx
  participant Sync as sync.ts
  participant Dexie as Dexie cache + outbox
  participant Worker as Worker API
  User->>Steps: toggle Step done
  Steps->>Sync: toggleStep(stepId, done)
  Sync->>Dexie: optimistic write + queue op
  Dexie-->>Steps: liveQuery emits (UI updates)
  Sync->>Worker: replayOutbox()
  Worker-->>Dexie: reconcileSteps / reconcileAllSteps

Related: Steps in a Task (server side), Offline Outbox & Optimistic Writes, Sync-Core Reconcilers.