Files
slm-design/DRAFT/level-3/domains/presets.md

4.2 KiB
Raw Blame History

Presets и SSR

Пояснение повторяемой assembly Domain.

Связанные правила

Роль preset

Preset -- именованная повторяемая assembly одной business factory для конкретного execution context. Он выбирает concrete implementations ports, создаёт AuthApi и передаёт caller lifecycle operations, определённые module-владельцами resources.

authFactory
├── presets/application -> browser-compatible AuthApi
├── presets/request     -> request-scoped AuthApi
└── presets/server-action -> server action AuthApi

Среда определяется preset и adapters, а не mode внутри factory. Tests создают per-test assembly напрямую через factory и не требуют общего presets/testing.

Структура и public API

domains/auth/presets/application/
├── adapters/
├── create-application-auth.ts
├── create-application-auth.test.ts
└── index.ts

application -- пример имени. Preset называется по execution scope или устойчивому назначению: application, request, server-action. Он не называется по temporary consumer, если configuration не предназначена для повторного использования.

export const createApplicationAuth = (): AuthApi => {
  return authFactory({
    phone: createApplicationAuthPhoneAdapter(),
    session: createApplicationAuthSessionAdapter(),
  })
}

Preset не добавляет scenario, не меняет error mapping и не скрывает business rule. Он также не становится монополией на factory: явный composition graph owner может собрать одноразовый graph, если он принимает на себя все обязанности assembly.

Scope и lifecycle

Preset объявляет ожидаемый scope API instance. Application preset используется в application scope; request preset создаёт новый instance для каждого request. Graph owner удерживает instance только в этом scope и не хранит request data в application singleton.

Если assembly создаёт lifecycle resource, caller получает явный cleanup handle:

export type AuthRequestAssembly = {
  api: AuthApi
  dispose: () => void | Promise<void>
}

export const createAuthForRequest = (
  input: AuthRequestInput,
): AuthRequestAssembly => {
  const session = createRequestSessionAdapter(input)

  return {
    api: authFactory({
      phone: createRequestAuthPhoneAdapter(input),
      session,
    }),
    dispose: session.dispose,
  }
}

Factory и preset construction не запускают I/O или subscriptions. Если domain lifecycle должен начать resource, module-владелец выражает это отдельной API operation; graph owner вызывает её после начала scope и выполняет предоставленный cleanup при его завершении.

Server-only boundary

Server preset имеет отдельный entrypoint и marker выбранного framework/build system:

import 'server-only'

export { createAuthForRequest } from './create-auth-for-request'

Этот entrypoint не реэкспортируется через business, react или client-compatible preset. Server adapter может иметь собственный marker для защиты от ошибочного прямого import.

Framework module не вызывает preset и не создаёт factory. Он получает готовый AuthApi от graph owner, поэтому React lifecycle не смешивается с concrete assembly.