You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
6.4 KiB
156 lines
6.4 KiB
<script lang="ts">
|
|
import CodeBlock from '../../_components/CodeBlock.svelte';
|
|
import ModuleHeader from '../../_components/ModuleHeader.svelte';
|
|
import PageNav from '../../_components/PageNav.svelte';
|
|
import Callout from '../../_components/Callout.svelte';
|
|
|
|
const quickStart = `import { createActiveApp } from '$active-app';
|
|
import { applyStandardOrca } from '$active-app/presets';
|
|
import {
|
|
defineActiveCache,
|
|
defineActiveConnections,
|
|
defineActivePerm,
|
|
defineActiveSession
|
|
} from '$active-app/services';
|
|
|
|
const App = createActiveApp({
|
|
services: {
|
|
cache: defineActiveCache({}),
|
|
perm: defineActivePerm({ endpoint: '/api/perm' }),
|
|
session: defineActiveSession({ onRefresh, onRevoke }),
|
|
connections: defineActiveConnections({})
|
|
}
|
|
});
|
|
|
|
applyStandardOrca(App);
|
|
|
|
App.session.adoptServer(nextSessionFromServer);
|
|
// session publishes session.identity.changed on App.bus;
|
|
// App.orca runs the presets registered by applyStandardOrca(App).`;
|
|
|
|
const customAction = `import {
|
|
ORCA_QUEUE_REPLACE_QUEUED,
|
|
ORCA_STAGE_POST,
|
|
orcaSuccess
|
|
} from '$orca';
|
|
|
|
App.orca.configureEvent('dating.match.created', {
|
|
queuePolicy: ORCA_QUEUE_REPLACE_QUEUED
|
|
});
|
|
|
|
App.orca.onEvent<{ userId: string }>('dating.match.created', {
|
|
id: 'dating.match.invalidate-feed',
|
|
stage: ORCA_STAGE_POST,
|
|
action: async (payload) => {
|
|
await App.cache.invalidate({
|
|
tags: [
|
|
{ type: 'dating:discover' },
|
|
{ type: 'dating:profile', id: payload.userId }
|
|
]
|
|
});
|
|
return orcaSuccess();
|
|
}
|
|
});`;
|
|
</script>
|
|
|
|
<svelte:head>
|
|
<title>Orca ($orca) - Active</title>
|
|
</svelte:head>
|
|
|
|
<article class="article">
|
|
<ModuleHeader
|
|
section="Infrastructure"
|
|
title="Orca"
|
|
alias="$orca"
|
|
summary="Orchestration engine for cross-module reactions, staged actions, queue policies, fan-in gates, validation and traceable runs."
|
|
factories={['createEngineOrca', 'createActiveOrca', 'App.orca']}
|
|
dependsOn={['$bus', '$timer', '$logger']}
|
|
layer="EngineOrca / ActiveOrca"
|
|
/>
|
|
|
|
<Callout variant="info" title="Core App service">
|
|
<p>
|
|
<code>Orca</code> is no longer optional documentation glue. <code>createActiveApp()</code>
|
|
builds <code>App.orca</code> as part of the fixed core alongside <code>Logger</code>,
|
|
<code>Bus</code>, <code>Timers</code> and <code>Prefs</code>. It stays inert until
|
|
actions or presets are registered.
|
|
</p>
|
|
</Callout>
|
|
|
|
<h2>Overview</h2>
|
|
<p>
|
|
Orca coordinates work that crosses module boundaries. Cache invalidation after identity
|
|
changes, permission refresh, connection reauth and feature-specific workflows should not
|
|
live inside those modules as hard-coded side effects. They are registered as Orca actions.
|
|
</p>
|
|
<p>
|
|
The engine listens through the shared Bus, schedules with Timers and reports through Logger.
|
|
A run is traceable: events produce staged actions, queue decisions, skipped gates, errors and
|
|
final run status.
|
|
</p>
|
|
|
|
<h2>Quick start</h2>
|
|
<CodeBlock code={quickStart} lang="ts" title="Standard App orchestration" />
|
|
|
|
<h2>Core concepts</h2>
|
|
<table>
|
|
<thead>
|
|
<tr><th>Concept</th><th>Purpose</th><th>Notes</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr><td><code>event</code></td><td>Trigger entering Orca.</td><td>Usually published through <code>App.bus</code>; derived events are emitted inside actions with <code>ctx.emit()</code>.</td></tr>
|
|
<tr><td><code>action</code></td><td>Unit of work for an event.</td><td>Has id, stage, guards, action function and error policy.</td></tr>
|
|
<tr><td><code>stage</code></td><td>Execution lane.</td><td>guard, pre, main, post, cleanup and finally keep ordering explicit.</td></tr>
|
|
<tr><td><code>queue</code></td><td>Concurrency policy.</td><td>Configured per event with <code>configureEvent()</code>: fifo, replace-queued, drop-latest and parallel.</td></tr>
|
|
<tr><td><code>fan-in</code></td><td>Wait for several tokens/events.</td><td>Useful for flows that need multiple prerequisites.</td></tr>
|
|
<tr><td><code>trace</code></td><td>Run identity and diagnostics.</td><td>Used by devtools, logs and tests.</td></tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<h2>Custom workflow</h2>
|
|
<CodeBlock code={customAction} lang="ts" title="Feature action" />
|
|
|
|
<h2>Standard presets</h2>
|
|
<p>
|
|
The presets under <code>$active-app/presets</code> are the canonical place for App-level
|
|
reactions. They wire identity/session events to cache clear, permission invalidation and
|
|
connection reauth/close without baking those reactions into the individual modules.
|
|
</p>
|
|
|
|
<table>
|
|
<thead>
|
|
<tr><th>Preset</th><th>Effect</th><th>Use when</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr><td><code>applyStandardOrca(App)</code></td><td>Registers the standard identity reactions.</td><td>Most client apps.</td></tr>
|
|
<tr><td><code>applyCacheClearOnIdentityChange(App)</code></td><td>Clears private cache after actor change.</td><td>Cache exists without full preset.</td></tr>
|
|
<tr><td><code>applyPermInvalidateOnIdentityChange(App)</code></td><td>Invalidates permission snapshots.</td><td>Permission decisions depend on actor state.</td></tr>
|
|
<tr><td><code>applyConnectionsReauthOnIdentityChange(App)</code></td><td>Reauthenticates connection registry.</td><td>Realtime channels depend on session identity.</td></tr>
|
|
<tr><td><code>applyConnectionsCloseOnRevoke(App)</code></td><td>Closes connections on revoke/logout.</td><td>Credentials must not survive session revocation.</td></tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<h2>Boundaries</h2>
|
|
<ul>
|
|
<li>Orca coordinates side effects; it does not own domain state.</li>
|
|
<li>Authorization decisions still belong to <code>$perm</code> / <code>$svrs/perm</code>.</li>
|
|
<li>Cache data still belongs to <code>$cache</code>.</li>
|
|
<li>Realtime transport still belongs to <code>$connection</code>.</li>
|
|
<li>Orca should make cross-module reactions visible, cancelable and testable.</li>
|
|
</ul>
|
|
|
|
<h2>Testing</h2>
|
|
<table>
|
|
<thead>
|
|
<tr><th>Target</th><th>Purpose</th><th>Notes</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr><td><code>src/arts/orca/test/engine-orca.test.ts</code></td><td>Core runtime.</td><td>Stages, queues, gates, fan-in, validation, reentry and error policies.</td></tr>
|
|
<tr><td><code>src/arts/orca/test/active-orca.svelte.test.ts</code></td><td>Reactive wrapper.</td><td>Active state and lifecycle.</td></tr>
|
|
<tr><td><code>src/arts/active-app/presets/*</code></td><td>App integration.</td><td>Identity reactions registered through Orca.</td></tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<PageNav />
|
|
</article>
|