Add docs and further stress tests to the demo

This commit is contained in:
2026-07-21 17:56:58 +10:00
parent 9af84760fa
commit 92c61abcfe
15 changed files with 752 additions and 14 deletions
+12 -1
View File
@@ -1,6 +1,13 @@
<script setup lang="ts">
import { NativeLink } from '@native-vue-router/core'
import { NativeLink, useNativeRouter } from '@native-vue-router/core'
import AppHeader from '../components/AppHeader.vue'
import { runtimeLabGuard, setRuntimeLabBlocked } from '../lab-state'
const native = useNativeRouter()
function toggleLabGuard() {
setRuntimeLabBlocked(!runtimeLabGuard.blockEntry)
}
</script>
<template>
@@ -17,6 +24,10 @@ import AppHeader from '../components/AppHeader.vue'
</div>
</section>
<section class="settings-list">
<a href="/profile/runtime-lab" @click.prevent="native.sibling('/profile/runtime-lab')"><span>⌁</span><strong>Runtime stress lab</strong><i>›</i></a>
<button type="button" aria-label="Block Runtime Lab re-entry" :aria-pressed="runtimeLabGuard.blockEntry" @click="toggleLabGuard">
<span>⌽</span><strong>Block cached lab re-entry</strong><i>{{ runtimeLabGuard.blockEntry ? 'On' : 'Off' }}</i>
</button>
<NativeLink to="/settings"><span>⚙︎</span><strong>Navigation lab</strong><i>›</i></NativeLink>
<a href="https://github.com" target="_blank" rel="noreferrer"><span>⌘</span><strong>Project source</strong><i>↗</i></a>
<button type="button"><span>◐</span><strong>Appearance</strong><i>System</i></button>
+67
View File
@@ -0,0 +1,67 @@
<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref } from 'vue'
import AppHeader from '../components/AppHeader.vue'
import AsyncLabData from '../components/AsyncLabData.vue'
import { runtimeLabGuard } from '../lab-state'
const mountedSeconds = ref(0)
let mountedAt = 0
let timer: number | undefined
onMounted(() => {
mountedAt = Date.now()
timer = window.setInterval(() => {
mountedSeconds.value = Math.floor((Date.now() - mountedAt) / 1_000)
}, 200)
})
onBeforeUnmount(() => {
if (timer !== undefined) window.clearInterval(timer)
})
</script>
<template>
<main class="screen screen--tabs runtime-lab-screen">
<AppHeader title="Runtime stress lab" subtitle="A cached push-history sibling" back />
<section class="lab-intro lab-intro--timer">
<span>{{ mountedSeconds }}</span>
<div>
<strong>Seconds mounted</strong>
<p
data-testid="mounted-seconds"
:data-seconds="mountedSeconds"
>This timer continues while the route is cached and out of view.</p>
</div>
</section>
<section class="settings-group">
<h2>Suspense boundary</h2>
<Suspense :timeout="0">
<AsyncLabData />
<template #fallback>
<article class="lab-probe lab-probe--loading" data-testid="async-data-loading" aria-live="polite">
<span class="lab-spinner" aria-hidden="true" />
<div>
<strong>Waiting for async payload</strong>
<p>Data becomes available one second after the child mounts.</p>
</div>
</article>
</template>
</Suspense>
</section>
<section class="settings-group">
<h2>Guard and history state</h2>
<div>
<span><strong>Entry guard</strong><small>Asynchronous check #{{ runtimeLabGuard.checks }}</small></span>
<b data-testid="lab-guard-status" :class="{ offline: runtimeLabGuard.status === 'blocked' }">{{ runtimeLabGuard.status }}</b>
</div>
<div>
<span><strong>Sibling history</strong><small>This route pushes instead of replacing Profile</small></span>
<b>push</b>
</div>
<p>Use Back to return to Profile. The route remains mounted in the native view cache, so its timer and resolved async component keep their state.</p>
</section>
</main>
</template>