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.
svelte-kit-vice/src/uix/active-uix/services.ts

101 lines
4.0 KiB

/**
* Service-factory contract that `active-uix` proposes to `active-app`.
*
* `defineUixServices(options)` returns the slice of an `AppServiceSchema`
* that the UIX layer needs when the application chooses attach mode:
*
* - `createActiveUix(options)` (standalone) — composes UIX services
* directly and does not use this helper.
*
* - External app composition — the application calls
* `createActiveApp({ services: { ...defineUixServices(...), cache,
* session, http, ... } })` itself, then `attachActiveUix(app)` to
* wire UIX-level setup on top.
*
* In both cases, components never know which path was taken — they
* read `ActiveUix` from context and that's it.
*/
import {
defineActiveClipboard,
defineActiveDom,
defineActiveFormat,
defineActiveLangs,
defineEngineMotion,
defineEngineScene,
defineEngineSound
} from '$active-app/service-factories';
import { defineEngineSemantic } from '$uix/sema';
import type { AppServiceSchema } from '$active-app';
import type { ActiveUixOptions } from './types';
/**
* Service slice that `active-uix` requires/proposes. Apps that
* `attachActiveUix(app)` MUST include at least these services in
* their `createActiveApp({ services })` declaration. `prefs` is
* ActiveApp core, not a service. `dom` is required in attach mode:
* when an external app is passed, ActiveUix consumes the app's services
* and fails early if one is missing instead of creating replacements.
*/
export const UIX_REQUIRED_SERVICES = ['langs', 'dom'] as const;
export type UixRequiredService = (typeof UIX_REQUIRED_SERVICES)[number];
/**
* Build the `services: { … }` slice the UIX layer needs. The result
* spreads cleanly into a `createActiveApp({ services: { ...this,
* ...customServices } })` call.
*
* ActiveUix does not project preferences to the DOM. Visual attrs are owned
* by Eidos; cross-modal prefs projection belongs to `$prefs` when an app
* explicitly wires it.
*/
export function defineUixServices(
options: Pick<ActiveUixOptions, 'langs' | 'clipboard' | 'format' | 'dom' | 'events'>
): AppServiceSchema {
const services: Record<string, unknown> = {
langs: defineActiveLangs(options.langs)
};
if (options.clipboard !== false) {
const clipboardOpts =
typeof options.clipboard === 'object' && options.clipboard !== null ? options.clipboard : {};
services.clipboard = defineActiveClipboard(clipboardOpts);
}
if (options.format !== false) {
const formatOpts =
typeof options.format === 'object' && options.format !== null ? options.format : {};
services.format = defineActiveFormat(formatOpts);
}
if (options.dom !== false) {
const domOpts = typeof options.dom === 'object' && options.dom !== null ? options.dom : {};
services.dom = defineActiveDom(domOpts);
// Motion needs the dom port for its JS drivers; register it alongside dom so
// `app.motion` is real in attach mode — the active-uix fallback then becomes the
// true edge case (an app declaring its own engine), not the rule. CSS presets
// settle regardless of dom.
services.motion = defineEngineMotion();
// Scene (D4 promotion, executed at Aura's arrival): same shape as motion —
// the ambient-scene engine rides the dom port; one shared engine keeps the
// concurrent-scene budget global across every canonical consumer.
services.scene = defineEngineScene();
// Sound: same shape again, and here the shared engine is not a preference
// but the contract (`contracts.ts` → `singleContextPerDocument`). Declared
// BEFORE events on purpose: `defineEngineSemantic` takes it as a service
// dependency and forwards it as `soundEngine`, so the app's sound channel
// and everything hanging off `uix.sound.context` (a player, a waveform)
// meet at ONE `AudioContext` instead of racing the browser's cap.
services.sound = defineEngineSound();
}
if (options.events !== false && options.dom !== false) {
const eventsOpts =
typeof options.events === 'object' && options.events !== null ? options.events : {};
services.events = defineEngineSemantic(eventsOpts);
}
return services as AppServiceSchema;
}

Powered by TurnKey Linux.