|
|
<script lang="ts">
|
|
|
import ModuleCard from './_components/ModuleCard.svelte';
|
|
|
import CodeBlock from './_components/CodeBlock.svelte';
|
|
|
import PageNav from './_components/PageNav.svelte';
|
|
|
|
|
|
const composition = `import { createActiveApp } from '$active-app';
|
|
|
import {
|
|
|
defineActiveLangs,
|
|
|
defineActiveDom,
|
|
|
defineActiveFormat
|
|
|
} from '$active-app/services';
|
|
|
import { createActivePrefsDomProjection } from '$prefs';
|
|
|
|
|
|
const App = createActiveApp({
|
|
|
logger: { level: LogLevel.INFO, transports: [consoleTransport()] },
|
|
|
prefs: {
|
|
|
capabilities,
|
|
|
environment,
|
|
|
intent: { language: 'es', locale: 'es-MX' }
|
|
|
},
|
|
|
services: {
|
|
|
dom: defineActiveDom(),
|
|
|
langs: defineActiveLangs({ schema, defaultLocale: 'es', fallbackChain: ['en'] }),
|
|
|
format: defineActiveFormat({})
|
|
|
}
|
|
|
});
|
|
|
|
|
|
const prefsProjection = createActivePrefsDomProjection({
|
|
|
prefs: App.prefs,
|
|
|
dom: App.dom
|
|
|
});
|
|
|
|
|
|
App.langs.t('common.ok');
|
|
|
App.format.currency.format(99.5);
|
|
|
App.prefs.locale.set('es-MX');
|
|
|
App.bus.publish('app.ready', {});`;
|
|
|
|
|
|
const sections = [
|
|
|
{
|
|
|
title: 'Composition',
|
|
|
items: [
|
|
|
{
|
|
|
title: 'Ecosystem',
|
|
|
alias: 'overview',
|
|
|
href: '/active/get-started/ecosystem',
|
|
|
description: 'Layer map, module domains, request flows and integration rules.',
|
|
|
factories: ['libs', 'svrs', 'arts', 'app']
|
|
|
},
|
|
|
{
|
|
|
title: 'AI Agents',
|
|
|
alias: 'rules',
|
|
|
href: '/active/get-started/ai-agents',
|
|
|
description: 'Instructions for coding assistants: layer rules, imports, logging, docs and audits.',
|
|
|
factories: ['read', 'verify', 'check']
|
|
|
},
|
|
|
{
|
|
|
title: 'App',
|
|
|
alias: '$active-app',
|
|
|
href: '/active/docs/aapp',
|
|
|
description: 'Builds the fixed core Logger, Bus, Timers, Orca and Prefs, then resolves typed services.',
|
|
|
factories: ['createActiveApp', 'services']
|
|
|
}
|
|
|
]
|
|
|
},
|
|
|
{
|
|
|
title: 'Server Layer',
|
|
|
items: [
|
|
|
{
|
|
|
title: 'Server Modules',
|
|
|
alias: '$svrs',
|
|
|
href: '/active/docs/svrs',
|
|
|
description: 'Server-authoritative auth, permissions and cache engines, with backend adapters.',
|
|
|
factories: ['createEngineAuth', 'createEnginePerms', 'createEngineCache']
|
|
|
}
|
|
|
]
|
|
|
},
|
|
|
{
|
|
|
title: 'Identity & Security',
|
|
|
items: [
|
|
|
{
|
|
|
title: 'Auth',
|
|
|
alias: '$auth',
|
|
|
href: '/active/docs/auth',
|
|
|
description: 'Password flows, CSRF, current session reflector and server auth primitives.',
|
|
|
factories: ['createActiveAuth', 'createEngineAuth']
|
|
|
},
|
|
|
{
|
|
|
title: 'Session',
|
|
|
alias: '$session',
|
|
|
href: '/active/docs/sess',
|
|
|
description: 'Session lifecycle: adopt, revoke, refresh, auto-refresh, SSR adoption.',
|
|
|
factories: ['createActiveSession', 'createEngineSession']
|
|
|
},
|
|
|
{
|
|
|
title: 'Perms',
|
|
|
alias: '$perm',
|
|
|
href: '/active/docs/perm',
|
|
|
description: 'Authorization runtime: policies, decisions, snapshot cache, <Can /> guard.',
|
|
|
factories: ['createActivePerms', 'createEnginePerms']
|
|
|
}
|
|
|
]
|
|
|
},
|
|
|
{
|
|
|
title: 'Data',
|
|
|
items: [
|
|
|
{
|
|
|
title: 'Cache',
|
|
|
alias: '$cache',
|
|
|
href: '/active/docs/cach',
|
|
|
description: 'Data cache: deterministic keys, scopes, stale/revalidate, tags.',
|
|
|
factories: ['createActiveCache', 'createEngineCache']
|
|
|
},
|
|
|
{
|
|
|
title: 'Storage',
|
|
|
alias: '$storage',
|
|
|
href: '/active/docs/stor',
|
|
|
description: 'Reactive sync key/value: adapters, version+migrate, TTL, validation.',
|
|
|
factories: ['createActiveStorage', 'createEngineStorage']
|
|
|
},
|
|
|
{
|
|
|
title: 'Http',
|
|
|
alias: '$http',
|
|
|
href: '/active/docs/http',
|
|
|
description: 'HTTP client: tagged HttpResult, schema validation, retry, timeouts.',
|
|
|
factories: ['createEngineHttp']
|
|
|
}
|
|
|
]
|
|
|
},
|
|
|
{
|
|
|
title: 'Preferences & Environment',
|
|
|
items: [
|
|
|
{
|
|
|
title: 'Prefs',
|
|
|
alias: '$prefs',
|
|
|
href: '/active/docs/prefs',
|
|
|
description: 'Cross-cutting user intent, environment defaults and effective runtime preferences.',
|
|
|
factories: ['createEnginePrefs', 'createActivePrefs']
|
|
|
}
|
|
|
]
|
|
|
},
|
|
|
{
|
|
|
title: 'I18n & Format',
|
|
|
items: [
|
|
|
{
|
|
|
title: 'Lang',
|
|
|
alias: '$langs',
|
|
|
href: '/active/docs/lang',
|
|
|
description: 'Type-safe translations, BCP 47 resolution, plurals, refs, JSON round-trip.',
|
|
|
factories: ['createActiveLangs', 'createEngineLangs']
|
|
|
},
|
|
|
{
|
|
|
title: 'Format',
|
|
|
alias: '$format',
|
|
|
href: '/active/docs/fmts',
|
|
|
description: 'Localized formatting: numbers, currency, units, dates.',
|
|
|
factories: ['createActiveFormat', 'createEngineFormat']
|
|
|
}
|
|
|
]
|
|
|
},
|
|
|
{
|
|
|
title: 'UI Layer',
|
|
|
items: [
|
|
|
{
|
|
|
title: 'Frontend (legacy)',
|
|
|
alias: '$frontend',
|
|
|
href: '/active/docs/fend',
|
|
|
description: 'Legacy presentation shell; new UIX apps use prefs projection and Eidos.',
|
|
|
factories: ['createActiveFrontend']
|
|
|
},
|
|
|
{
|
|
|
title: 'Dom',
|
|
|
alias: '$adom',
|
|
|
href: '/active/docs/adom',
|
|
|
description: 'Reactive DOM service: viewport, breakpoints, scroll lock, roving focus.',
|
|
|
factories: ['createActiveDom']
|
|
|
}
|
|
|
]
|
|
|
},
|
|
|
{
|
|
|
title: 'Validation',
|
|
|
items: [
|
|
|
{
|
|
|
title: 'Sium',
|
|
|
alias: '$sium',
|
|
|
href: '/active/docs/sium',
|
|
|
description: 'Validation contracts: schemas, issues, introspection, Standard Schema interop.',
|
|
|
factories: ['createEngineSium']
|
|
|
}
|
|
|
]
|
|
|
},
|
|
|
{
|
|
|
title: 'Infrastructure',
|
|
|
items: [
|
|
|
{
|
|
|
title: 'Bus',
|
|
|
alias: '$bus',
|
|
|
href: '/active/docs/buss',
|
|
|
description: 'Typed event bus used by App core and cross-module notifications.',
|
|
|
factories: ['createSvelteEngineBus']
|
|
|
},
|
|
|
{
|
|
|
title: 'Logger',
|
|
|
alias: '$logger',
|
|
|
href: '/active/docs/logr',
|
|
|
description: 'Structured logger: levels, transports, filters, vitals, dispose.',
|
|
|
factories: ['createEngineLogger']
|
|
|
},
|
|
|
{
|
|
|
title: 'Timers',
|
|
|
alias: '$timer',
|
|
|
href: '/active/docs/timr',
|
|
|
description: 'Deterministic timer scheduler: clock injection, intervals, snapshots.',
|
|
|
factories: ['createActiveTimers', 'createEngineTimers']
|
|
|
},
|
|
|
{
|
|
|
title: 'Orca',
|
|
|
alias: '$orca',
|
|
|
href: '/active/docs/orca',
|
|
|
description: 'Cross-module orchestration: staged actions, queue policies, fan-in gates and App presets.',
|
|
|
factories: ['createEngineOrca', 'App.orca']
|
|
|
},
|
|
|
{
|
|
|
title: 'Connections',
|
|
|
alias: '$connection',
|
|
|
href: '/active/docs/conn',
|
|
|
description: 'Realtime connection registry: transports, reconnect, heartbeat, channels.',
|
|
|
factories: ['createActiveConnections', 'createEngineConnections']
|
|
|
}
|
|
|
]
|
|
|
}
|
|
|
];
|
|
|
</script>
|
|
|
|
|
|
<svelte:head>
|
|
|
<title>Active — Documentation</title>
|
|
|
</svelte:head>
|
|
|
|
|
|
<article class="article">
|
|
|
<header class="hero">
|
|
|
<div class="hero-bg" aria-hidden="true"></div>
|
|
|
<div class="hero-inner">
|
|
|
<span class="eyebrow">
|
|
|
<span class="dot"></span>
|
|
|
Active framework — 1.0 candidate
|
|
|
</span>
|
|
|
<h1>The runtime that wires your <span class="hl">SvelteKit</span> app together.</h1>
|
|
|
<p class="lead">
|
|
|
A composable set of <strong>runtime artifacts</strong> — core App infrastructure,
|
|
|
i18n, preferences, logger, sessions, auth, permissions, cache, storage, HTTP, timers,
|
|
|
formatting, orchestration, realtime connections and DOM-aware preference projection.
|
|
|
</p>
|
|
|
<div class="cta">
|
|
|
<a class="btn primary" href="/active/get-started/installation">
|
|
|
Get Started
|
|
|
<svg viewBox="0 0 16 16" width="14" height="14" aria-hidden="true">
|
|
|
<path
|
|
|
d="M5 3l5 5-5 5"
|
|
|
fill="none"
|
|
|
stroke="currentColor"
|
|
|
stroke-width="2"
|
|
|
stroke-linecap="round"
|
|
|
stroke-linejoin="round"
|
|
|
/>
|
|
|
</svg>
|
|
|
</a>
|
|
|
<a class="btn ghost" href="/active/get-started/ecosystem">Read the ecosystem map</a>
|
|
|
</div>
|
|
|
<dl class="hero-stats">
|
|
|
<div>
|
|
|
<dt>Artifacts</dt>
|
|
|
<dd>18</dd>
|
|
|
</div>
|
|
|
<div>
|
|
|
<dt>Bundle</dt>
|
|
|
<dd>40–120 KB</dd>
|
|
|
</div>
|
|
|
<div>
|
|
|
<dt>Contract</dt>
|
|
|
<dd>1</dd>
|
|
|
</div>
|
|
|
<div>
|
|
|
<dt>Factories</dt>
|
|
|
<dd>2</dd>
|
|
|
</div>
|
|
|
</dl>
|
|
|
</div>
|
|
|
</header>
|
|
|
|
|
|
<section class="quick">
|
|
|
<h2>Quick look</h2>
|
|
|
<p>
|
|
|
Every app starts from <code>$active-app</code>. It always builds the core
|
|
|
<code>Logger</code>, <code>Bus</code>, <code>Timers</code> and <code>Orca</code>, then
|
|
|
declares feature modules as typed services on the same <code>App</code> object.
|
|
|
</p>
|
|
|
<CodeBlock code={composition} lang="ts" title="App composition" />
|
|
|
</section>
|
|
|
|
|
|
<section class="modules">
|
|
|
<h2>Modules</h2>
|
|
|
<p>
|
|
|
Every artifact ships with its own <code>README.md</code>, an interactive page under
|
|
|
<code>/test/<artifact></code>, and the same shape: an <code>Engine*</code> factory and,
|
|
|
when reactive state is needed, an <code>Active*</code> factory in a <code>.svelte.ts</code> file.
|
|
|
</p>
|
|
|
|
|
|
{#each sections as section (section.title)}
|
|
|
<h3>{section.title}</h3>
|
|
|
<div class="grid">
|
|
|
{#each section.items as item (item.href)}
|
|
|
<ModuleCard
|
|
|
title={item.title}
|
|
|
alias={item.alias}
|
|
|
href={item.href}
|
|
|
description={item.description}
|
|
|
factories={item.factories}
|
|
|
/>
|
|
|
{/each}
|
|
|
</div>
|
|
|
{/each}
|
|
|
</section>
|
|
|
|
|
|
<section class="contract">
|
|
|
<h2>The shared contract</h2>
|
|
|
<p>
|
|
|
Every reactive root implements <code>ActiveEngine<TSnapshot, TError></code>:
|
|
|
</p>
|
|
|
<CodeBlock
|
|
|
lang="ts"
|
|
|
code={`interface ActiveEngine<TSnapshot, TError> {
|
|
|
readonly loading: boolean;
|
|
|
readonly lastError: TError | null;
|
|
|
readonly disposed: boolean;
|
|
|
|
|
|
snapshot(): TSnapshot;
|
|
|
clearError(): void;
|
|
|
onChange(listener: (snapshot: TSnapshot) => void): () => void;
|
|
|
dispose(): void;
|
|
|
}`}
|
|
|
/>
|
|
|
<p>
|
|
|
This makes every artifact testable, composable and disposable in the same way — and lets
|
|
|
the <code>$active-app</code> composer wire them blindly.
|
|
|
</p>
|
|
|
</section>
|
|
|
|
|
|
<PageNav />
|
|
|
</article>
|
|
|
|
|
|
<style>
|
|
|
.hero {
|
|
|
position: relative;
|
|
|
isolation: isolate;
|
|
|
padding: 2.5rem 0 3rem;
|
|
|
margin: -2rem -1rem 3rem;
|
|
|
padding-left: 1rem;
|
|
|
padding-right: 1rem;
|
|
|
overflow: hidden;
|
|
|
border-bottom: 1px solid var(--c-border);
|
|
|
}
|
|
|
|
|
|
.hero-bg {
|
|
|
position: absolute;
|
|
|
inset: 0;
|
|
|
z-index: -1;
|
|
|
background:
|
|
|
radial-gradient(ellipse 60% 70% at 95% 0%,
|
|
|
color-mix(in oklab, var(--c-accent) 14%, transparent),
|
|
|
transparent 70%),
|
|
|
radial-gradient(ellipse 40% 60% at 0% 100%,
|
|
|
color-mix(in oklab, var(--c-accent) 6%, transparent),
|
|
|
transparent 70%);
|
|
|
}
|
|
|
|
|
|
.hero-bg::after {
|
|
|
content: '';
|
|
|
position: absolute;
|
|
|
inset: 0;
|
|
|
background-image:
|
|
|
linear-gradient(to right, var(--c-border) 1px, transparent 1px),
|
|
|
linear-gradient(to bottom, var(--c-border) 1px, transparent 1px);
|
|
|
background-size: 32px 32px;
|
|
|
mask-image: radial-gradient(ellipse 80% 50% at 50% 0%, black 0%, transparent 70%);
|
|
|
opacity: 0.45;
|
|
|
}
|
|
|
|
|
|
.hero-inner {
|
|
|
position: relative;
|
|
|
max-width: 100%;
|
|
|
}
|
|
|
|
|
|
.eyebrow {
|
|
|
display: inline-flex;
|
|
|
align-items: center;
|
|
|
gap: 0.4rem;
|
|
|
font-size: 0.72rem;
|
|
|
font-weight: 600;
|
|
|
letter-spacing: 0.06em;
|
|
|
text-transform: uppercase;
|
|
|
color: var(--c-accent-emphasized);
|
|
|
background: color-mix(in oklab, var(--c-bg) 88%, var(--c-accent));
|
|
|
padding: 0.3rem 0.7rem;
|
|
|
border-radius: 999px;
|
|
|
border: 1px solid var(--c-accent-subtle);
|
|
|
margin-bottom: 1.5rem;
|
|
|
box-shadow: 0 1px 2px rgb(0 0 0 / 0.03);
|
|
|
}
|
|
|
|
|
|
.eyebrow .dot {
|
|
|
width: 6px;
|
|
|
height: 6px;
|
|
|
border-radius: 50%;
|
|
|
background: var(--c-accent);
|
|
|
box-shadow: 0 0 0 3px color-mix(in oklab, var(--c-accent) 25%, transparent);
|
|
|
animation: pulse 2.4s var(--ease) infinite;
|
|
|
}
|
|
|
|
|
|
@keyframes pulse {
|
|
|
0%, 100% { opacity: 1; }
|
|
|
50% { opacity: 0.4; }
|
|
|
}
|
|
|
|
|
|
.hero h1 {
|
|
|
font-size: 3rem;
|
|
|
line-height: 1.05;
|
|
|
letter-spacing: -0.035em;
|
|
|
font-weight: 750;
|
|
|
margin: 0 0 1.25rem;
|
|
|
max-width: 18ch;
|
|
|
}
|
|
|
|
|
|
.hero h1 .hl {
|
|
|
background: linear-gradient(120deg, var(--c-accent), var(--c-accent-emphasized));
|
|
|
-webkit-background-clip: text;
|
|
|
background-clip: text;
|
|
|
color: transparent;
|
|
|
}
|
|
|
|
|
|
.hero .lead {
|
|
|
font-size: 1.125rem;
|
|
|
color: var(--c-fg-muted);
|
|
|
max-width: 62ch;
|
|
|
margin: 0 0 2rem;
|
|
|
line-height: 1.6;
|
|
|
}
|
|
|
|
|
|
.cta {
|
|
|
display: flex;
|
|
|
gap: 0.65rem;
|
|
|
flex-wrap: wrap;
|
|
|
margin-bottom: 2.5rem;
|
|
|
}
|
|
|
|
|
|
.btn {
|
|
|
display: inline-flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
gap: 0.4rem;
|
|
|
padding: 0.65rem 1.15rem;
|
|
|
border-radius: var(--r-md);
|
|
|
font-weight: 600;
|
|
|
font-size: 0.9rem;
|
|
|
border: 1px solid transparent;
|
|
|
transition:
|
|
|
background-color 150ms var(--ease),
|
|
|
border-color 150ms var(--ease),
|
|
|
color 150ms var(--ease),
|
|
|
box-shadow 150ms var(--ease),
|
|
|
transform 150ms var(--ease);
|
|
|
}
|
|
|
|
|
|
.btn.primary {
|
|
|
background: var(--c-accent);
|
|
|
color: var(--c-accent-fg);
|
|
|
box-shadow:
|
|
|
inset 0 1px 0 rgb(255 255 255 / 0.15),
|
|
|
0 1px 2px rgb(0 0 0 / 0.06);
|
|
|
}
|
|
|
|
|
|
.btn.primary:hover {
|
|
|
background: var(--c-accent-emphasized);
|
|
|
transform: translateY(-1px);
|
|
|
box-shadow:
|
|
|
inset 0 1px 0 rgb(255 255 255 / 0.18),
|
|
|
0 6px 16px -4px color-mix(in oklab, var(--c-accent) 60%, transparent);
|
|
|
text-decoration: none;
|
|
|
}
|
|
|
|
|
|
.btn.ghost {
|
|
|
background: var(--c-bg);
|
|
|
color: var(--c-fg);
|
|
|
border-color: var(--c-border-strong);
|
|
|
}
|
|
|
|
|
|
.btn.ghost:hover {
|
|
|
background: var(--c-bg-muted);
|
|
|
border-color: var(--c-fg-subtle);
|
|
|
text-decoration: none;
|
|
|
}
|
|
|
|
|
|
.hero-stats {
|
|
|
display: flex;
|
|
|
gap: 2.5rem;
|
|
|
margin: 0;
|
|
|
padding: 1rem 0 0;
|
|
|
border-top: 1px solid var(--c-border);
|
|
|
}
|
|
|
|
|
|
.hero-stats > div {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
gap: 0.15rem;
|
|
|
}
|
|
|
|
|
|
.hero-stats dt {
|
|
|
font-size: 0.7rem;
|
|
|
font-weight: 600;
|
|
|
text-transform: uppercase;
|
|
|
letter-spacing: 0.08em;
|
|
|
color: var(--c-fg-subtle);
|
|
|
margin: 0;
|
|
|
}
|
|
|
|
|
|
.hero-stats dd {
|
|
|
margin: 0;
|
|
|
font-family: var(--font-mono);
|
|
|
font-size: 1.25rem;
|
|
|
font-weight: 600;
|
|
|
color: var(--c-fg);
|
|
|
letter-spacing: -0.01em;
|
|
|
}
|
|
|
|
|
|
.modules .grid {
|
|
|
display: grid;
|
|
|
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
|
|
|
gap: 0.75rem;
|
|
|
margin: 0 0 2rem;
|
|
|
}
|
|
|
|
|
|
.modules h3 {
|
|
|
margin-top: 2.25rem;
|
|
|
margin-bottom: 0.85rem;
|
|
|
font-size: 0.78rem;
|
|
|
font-weight: 600;
|
|
|
text-transform: uppercase;
|
|
|
letter-spacing: 0.08em;
|
|
|
color: var(--c-fg-subtle);
|
|
|
}
|
|
|
|
|
|
.modules h3::before {
|
|
|
display: none;
|
|
|
}
|
|
|
|
|
|
@media (max-width: 720px) {
|
|
|
.hero h1 {
|
|
|
font-size: 2.15rem;
|
|
|
}
|
|
|
.hero .lead {
|
|
|
font-size: 1rem;
|
|
|
}
|
|
|
.hero-stats {
|
|
|
gap: 1.5rem;
|
|
|
flex-wrap: wrap;
|
|
|
}
|
|
|
}
|
|
|
</style>
|