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.
115 lines
3.8 KiB
115 lines
3.8 KiB
import { Context } from 'runed';
|
|
import { getActiveUix, type ActiveUix } from '$active-uix';
|
|
import type { ActiveLangs } from '$langs';
|
|
import type { ActiveDom } from '$adom';
|
|
import type { ActiveNumbers } from '$format/numbers/types';
|
|
import type { ActiveCurrency } from '$format/currency/types';
|
|
import type { ActiveDates } from '$format/dates/types';
|
|
import type { ActiveUnits } from '$format/units/types';
|
|
import type { EngineLogger } from '$logger';
|
|
import type { EngineSemantic } from '$uix/sema';
|
|
import { createActiveUixPrefsView, type ActiveUixPrefsView } from '$active-uix/prefs';
|
|
import type { Morfo } from '$uix/morfo';
|
|
import { createSomaRuntime, type SomaRuntime, type SomaRuntimeSources } from '../runtime.svelte';
|
|
import { SomaNoContextError } from '../errors';
|
|
|
|
// ── Soma class ──────────────────────────────────────────────────────────────
|
|
|
|
const _ctx = new Context<Soma>('Soma');
|
|
|
|
export interface SomaOptions {
|
|
/** Override portal target for this scope */
|
|
portalTo?: string | HTMLElement;
|
|
}
|
|
|
|
/**
|
|
* Soma — component runtime scope.
|
|
*
|
|
* Reads `ActiveUix` from Svelte context (`getActiveUix()`) and exposes
|
|
* services to soma components through a stable adapter surface. Soma
|
|
* components import local internals through relative paths, NEVER from
|
|
* `$active-app` directly — the UIX layer is decoupled from the App
|
|
* composition layer by design.
|
|
*
|
|
* The adapter exposes the services soma actually consumes: langs, DOM,
|
|
* events, format slices and prefs view.
|
|
*
|
|
* Nestable: child <Soma portalTo="#modals"> overrides parent.
|
|
*/
|
|
export class Soma {
|
|
readonly uix: ActiveUix;
|
|
readonly portalTo: string | HTMLElement | undefined;
|
|
readonly #prefs: ActiveUixPrefsView;
|
|
|
|
private constructor(uix: ActiveUix, opts: SomaOptions = {}) {
|
|
this.uix = uix;
|
|
const parent = _ctx.getOr(null as unknown as Soma) as Soma | null;
|
|
this.portalTo = opts.portalTo ?? parent?.portalTo ?? uix.portal;
|
|
this.#prefs = createActiveUixPrefsView(uix.prefs);
|
|
}
|
|
|
|
// ── Service accessors (delegate to ActiveUix) ──────────────────────
|
|
|
|
get langs(): ActiveLangs {
|
|
return this.uix.langs;
|
|
}
|
|
get dom(): ActiveDom {
|
|
return this.uix.dom;
|
|
}
|
|
get events(): EngineSemantic | undefined {
|
|
return this.uix.events;
|
|
}
|
|
get nums(): ActiveNumbers | undefined {
|
|
return this.uix.format?.numbers;
|
|
}
|
|
get money(): ActiveCurrency | undefined {
|
|
return this.uix.format?.currency;
|
|
}
|
|
get dates(): ActiveDates | undefined {
|
|
return this.uix.format?.dates;
|
|
}
|
|
get units(): ActiveUnits | undefined {
|
|
return this.uix.format?.units;
|
|
}
|
|
get prefs(): ActiveUixPrefsView {
|
|
return this.#prefs;
|
|
}
|
|
get logger(): EngineLogger {
|
|
return this.uix.logger;
|
|
}
|
|
|
|
runtime<M extends Morfo>(
|
|
morfo: M,
|
|
sources: Omit<SomaRuntimeSources, 'dom' | 'eventEngine'>
|
|
): SomaRuntime {
|
|
return createSomaRuntime(morfo, {
|
|
dom: this.dom,
|
|
eventEngine: this.events,
|
|
translate: (key) => this.langs.ts(key),
|
|
// Wire the shared aria-live region to morfo events that declare
|
|
// `a11ySemantic.requiresLiveRegion`. The SomaRuntime calls this
|
|
// only when the caller passes a `message` via TriggerOptions.
|
|
announce: (message, priority) => this.uix.announce(message, priority),
|
|
...sources
|
|
});
|
|
}
|
|
|
|
// ── Static methods ──────────────────────────────────────────────────
|
|
|
|
static create(opts: SomaOptions = {}): Soma {
|
|
const uix = getActiveUix();
|
|
const instance = new Soma(uix, opts);
|
|
return _ctx.set(instance);
|
|
}
|
|
|
|
static get(): Soma | undefined {
|
|
return _ctx.getOr(undefined) as Soma | undefined;
|
|
}
|
|
|
|
static require(): Soma {
|
|
const soma = _ctx.getOr(null as unknown as Soma);
|
|
if (!soma) throw new SomaNoContextError();
|
|
return soma;
|
|
}
|
|
}
|