clone

a deno framework for local-first web apps that open instantly, work offline and sync when users choose

feat(example): make identity and cross-device sync legible in the starter

Dami committed f130b75
The starter UI hardcoded 'device-local key' and 'passkey backup blocked', which
now contradicts the device-passkey identity. Make it honest and observable so a
user can see what is syncing between devices:

- DeviceStatus reflects the actual identity mode (passkey account vs device-local),
  a Sync row (syncing to your account vs local-only), and account portability
  (travels with your passkey vs stays on this device); the recovery note tells
  the truth for each mode
- TaskList's write state reads 'synced to your account' / 'saved on this device'
  instead of the raw Jazz durability tier
- the index aside describes both identity modes and the cross-device story, and
  points at identity: device-passkey
commit
f130b757fe793ed4bdf80880a8eb191077b0144c
parent
3e17acdf9185bd0a4902440c8b7fdc0ec813172d
author
Dami <dami.etoile@gmail.com>
4 files changed, +31 -11
Mapps/reference/src/_lofi/DeviceStatus.tsx20+++++++++++++++-----
Mapps/reference/src/islands/TaskList.tsx10+++++++++-
Mapps/reference/src/pages/index.astro6++++--
Mpackage/testdata/starter.snapshot.json6+++---
M apps/reference/src/_lofi/DeviceStatus.tsx +15 -5
@@ -1,3 +1,5 @@
1+import { referenceApp } from "../app.ts";2+import { serverUrl } from "./config.ts";13 import { useDeviceCapabilities } from "./use-device-capabilities.ts";24 import { settleUiMutation } from "./ui-mutation.ts";35
@@ -5,6 +7,9 @@ export default function DeviceStatus() {
57 const { report, requestPersistence } = useDeviceCapabilities();68 if (!report) return <p class="device-status">Checking durable-storage capabilities…</p>;79 10+ const passkeyIdentity = referenceApp.identity === "device-passkey";11+ const synced = Boolean(serverUrl);12+813 return (914 <section class="device-status" aria-labelledby="device-status-title">1015 <header>
@@ -40,11 +45,15 @@ export default function DeviceStatus() {
4045 </div>4146 <div>4247 <dt>Identity</dt>43- <dd>device-local key</dd>48+ <dd>{passkeyIdentity ? "passkey account" : "device-local key"}</dd>49+ </div>50+ <div>51+ <dt>Sync</dt>52+ <dd>{synced ? "syncing to your account" : "local-only"}</dd>4453 </div>4554 <div>46- <dt>Passkey backup</dt>47- <dd>blocked by alpha security review</dd>55+ <dt>Account portability</dt>56+ <dd>{passkeyIdentity ? "travels with your passkey" : "stays on this device"}</dd>4857 </div>4958 </dl>5059 <button type="button" onClick={() => void settleUiMutation(requestPersistence())}>
@@ -55,8 +64,9 @@ export default function DeviceStatus() {
5564 not mean the Jazz driver is using memory.5665 </p>5766 <p>58- Clearing site data destroys the device-local identity unless a separate recovery mechanism59- has been verified. This reference does not claim passkey recovery.67+ {passkeyIdentity68+ ? "The passkey is the account: it lives wherever the key lives and reaches every device that key can. There is no recovery service — lose every copy of the key and the account is gone."69+ : 'Clearing site data destroys the device-local identity. This reference claims no recovery; set identity: "device-passkey" in src/app.ts for a portable, cross-device account.'}6070 </p>6171 </section>6272 );
M apps/reference/src/islands/TaskList.tsx +9 -1
M apps/reference/src/pages/index.astro +4 -2
M package/testdata/starter.snapshot.json +3 -3
@@ -13,7 +13,7 @@
1313 "src/_lofi/config.ts": "3ae7e31b3915e12eb595eeea158c0dbd026f4f0f8bf7b0f4809117bec9752f1a",1414 "src/_lofi/device-capabilities_test.ts": "be099ef5f0b3623dc2768b5b588f7e0eb313fea8cf31e4d86b3a52ed1f85cd5a",1515 "src/_lofi/device-capabilities.ts": "6911fbe8ce93cdd79531982fdafd505202141985baec874e4dd965b02e6115d3",16- "src/_lofi/DeviceStatus.tsx": "1ba2e2c2bee7ac15bc2830e879904deddf95bba1b55359f0376cf7cb1c9aafeb",16+ "src/_lofi/DeviceStatus.tsx": "50443e3411519029e679b9e8d94f11ffcac1fc06074ae05f25d31080f1fb4e8a",1717 "src/_lofi/diagnostics.ts": "abb2a5f8e4d6b8ab1a86d475db6c374aecf4580b534ba9d7d850e1dbb29bb7f8",1818 "src/_lofi/foreground-recovery_test.ts": "a5081aecaa70b71c63d721a0875f4d2b3898a49879eb8045c8e74baf0d867444",1919 "src/_lofi/foreground-recovery.ts": "a5ed7a65b9454770de62a4ba8cdac7b0d1a867ec3c703049d2c103791c4d0049",
@@ -35,9 +35,9 @@
3535 "src/_lofi/use-device-capabilities.ts": "f7c7b2321b400d8076a5347e0f1ff2924623535979d48a2d94a69f825b93841e",3636 "src/app.ts": "fa5068957b68a78d14a11d2bc48b130fc8e093bfa0865d1eabe361e3ef310ff5",3737 "src/env.d.ts": "b44daed05ec5cdfacfd8d8acf7866974b5f6b8db923ab53bd244419093c719da",38- "src/islands/TaskList.tsx": "2d6f4c7ed2475f1ce561e4b2c3a4e21210f4b55f0ec3eee6c4a6047f8622e189",38+ "src/islands/TaskList.tsx": "2030161deeaebfa2c33ae4df3691909f1f5ff72a49a906d8dc8154026808c467",3939 "src/islands/use-tasks.ts": "d2a9afa80590d4f38db7cfe0da37e6b7b17c00c1a73d82e06b800f97b5d609af",40- "src/pages/index.astro": "3746bbd23cca65f5561c23fd4690368ee3f1cebb38d16f8bc7552ddff1f3f7fa",40+ "src/pages/index.astro": "ac695d5729b3cc8e264b873d3403bc5a6c4eb36ffdf583584b9a60bec933f5b1",4141 "src/permissions.ts": "dcb00b7f0576d04ad527b8892b8096573b107c3130ed6d835243251c406a38b7",4242 "src/schema.ts": "f2c555b088ded8eea2653f5d955fc9aae69dfd588e891adf509e99052f1e9949",4343 "src/styles/global.css": "0e66a21e9b83cc115f01567ab8a87f949ce7fff8e42a3c3dc2efdd70cfffb706",