refactor: remove core-realtime from main (scaffoldable via gen core-package realtime)

This commit is contained in:
2026-05-09 13:45:52 +02:00
parent e28fe847fd
commit 57b2ff5191
55 changed files with 80 additions and 1777 deletions

View File

@@ -7,8 +7,6 @@ import config from "@repo/core-cms";
import {
bindNoopInstrumentation,
bindSentryInstrumentation,
withCapture,
withSpan,
type ITracer,
type ILogger,
} from "@repo/core-shared/instrumentation";
@@ -23,13 +21,6 @@ import {
PayloadJobQueue,
type IJobQueue,
} from "@repo/core-shared/jobs";
import {
InMemoryRealtimeBroadcaster,
RealtimeHandlerRegistry,
realtimePingInboundDescriptor,
type IRealtimeBroadcaster,
type IRealtimeHandlerRegistry,
} from "@repo/core-realtime";
import { bindProductionBlog } from "@repo/blog/di/bind-production";
import { bindProductionAuth } from "@repo/auth/di/bind-production";
import { bindProductionMarketingPages } from "@repo/marketing-pages/di/bind-production";
@@ -41,11 +32,6 @@ import { bindDevSeedMarketingPages } from "@repo/marketing-pages/di/bind-dev-see
import { bindDevSeedNavigation } from "@repo/navigation/di/bind-dev-seed";
import { bindDevSeedMedia } from "@repo/media/di/bind-dev-seed";
type BindAllDeps = {
realtime: IRealtimeBroadcaster;
realtimeRegistry: IRealtimeHandlerRegistry;
};
let bound = false;
// Shared container holds TRACER + LOGGER bindings; per-feature containers
@@ -112,22 +98,19 @@ function resolveEventsAndJobsDevSeed(): { bus: IEventBus; queue: IJobQueue } {
* Payload-backed one. Constructs `new XRepository(config, tracer, logger)` per
* feature as Phase E feature wiring lands (blog: task 18; remaining: tasks 1922).
*/
export async function bindAllProduction(deps: BindAllDeps): Promise<void> {
export async function bindAllProduction(): Promise<void> {
if (bound) return;
bound = true;
const { tracer, logger } = resolveInstrumentation(); // Rule 0
const { bus, queue } = await resolveEventsAndJobsProduction();
const resolvedConfig = await config;
const { realtime, realtimeRegistry } = deps;
const ctx: BindProductionContext<IEventBus, IRealtimeBroadcaster, IRealtimeHandlerRegistry> = {
const ctx: BindProductionContext<IEventBus> = {
config: resolvedConfig,
tracer,
logger,
bus,
queue,
realtime,
realtimeRegistry,
};
bindProductionAuth(ctx); // Phase E task 19
@@ -135,8 +118,6 @@ export async function bindAllProduction(deps: BindAllDeps): Promise<void> {
bindProductionMarketingPages(ctx); // Phase E task 20
bindProductionNavigation(ctx); // Phase E task 21
bindProductionMedia(ctx); // Phase E task 22
maybeRegisterRealtimePing(realtimeRegistry, realtime, tracer, logger);
bindRealtimeBridge(bus, realtime);
}
/**
@@ -144,20 +125,17 @@ export async function bindAllProduction(deps: BindAllDeps): Promise<void> {
* with realistic seed data so the running app shows non-empty UI without
* Payload booted. Mutually exclusive with `bindAllProduction()`.
*/
export async function bindAllDevSeed(deps: BindAllDeps): Promise<void> {
export async function bindAllDevSeed(): Promise<void> {
if (bound) return;
bound = true;
const { tracer, logger } = resolveInstrumentation(); // Rule 0
const { bus, queue } = resolveEventsAndJobsDevSeed();
const { realtime, realtimeRegistry } = deps;
const ctx: BindContext<IEventBus, IRealtimeBroadcaster, IRealtimeHandlerRegistry> = {
const ctx: BindContext<IEventBus> = {
tracer,
logger,
bus,
queue,
realtime,
realtimeRegistry,
};
await bindDevSeedAuth(ctx); // Phase E task 19
@@ -165,8 +143,6 @@ export async function bindAllDevSeed(deps: BindAllDeps): Promise<void> {
await bindDevSeedMarketingPages(ctx); // Phase E task 20
await bindDevSeedNavigation(ctx); // Phase E task 21
await bindDevSeedMedia(ctx); // Phase E task 22
maybeRegisterRealtimePing(realtimeRegistry, realtime, tracer, logger);
bindRealtimeBridge(bus, realtime);
}
/**
@@ -181,56 +157,20 @@ export async function bindAllDevSeed(deps: BindAllDeps): Promise<void> {
* Rule 2: NODE_ENV === "production" → real Payload via bindAllProduction
* Rule 3: otherwise → dev seed (developer-friendly default)
*
* `deps` is optional; omitting it (page-level fallback, already-bound guard)
* uses in-memory noop implementations. In the custom-server flow, `server.ts`
* always provides Socket.IO-backed deps before any page request runs.
* When @repo/core-realtime is scaffolded, extend this function to accept
* realtime deps (IRealtimeBroadcaster, IRealtimeHandlerRegistry) and pass
* them through to bindAllProduction / bindAllDevSeed.
*/
export async function bindAll(deps?: Partial<BindAllDeps>): Promise<void> {
const resolvedDeps: BindAllDeps = {
realtime: deps?.realtime ?? new InMemoryRealtimeBroadcaster(),
realtimeRegistry: deps?.realtimeRegistry ?? new RealtimeHandlerRegistry(),
};
export async function bindAll(): Promise<void> {
if (process.env.USE_DEV_SEED === "true") {
await bindAllDevSeed(resolvedDeps);
await bindAllDevSeed();
return;
}
if (process.env.NODE_ENV === "production") {
await bindAllProduction(resolvedDeps);
await bindAllProduction();
return;
}
await bindAllDevSeed(resolvedDeps);
}
// Wraps the built-in realtime-ping inbound handler in the same span+capture
// sandwich the realtime-handler generator emits (R41R44), so the
// proof-of-life channel models the convention rather than registering raw.
// Skipped entirely when REALTIME_PING_DISABLED === "true".
function maybeRegisterRealtimePing(
registry: IRealtimeHandlerRegistry,
realtime: IRealtimeBroadcaster,
tracer: ITracer,
logger: ILogger,
): void {
if (process.env.REALTIME_PING_DISABLED === "true") return;
const { descriptor, handler } = realtimePingInboundDescriptor(realtime);
const wrappedHandler = withSpan(
tracer,
{ name: "core-realtime.realtimePing", op: "realtime-handler" },
withCapture(
logger,
{ feature: "core-realtime", layer: "realtime-handler", name: "core-realtime.realtimePing" },
handler,
),
);
registry.register({ descriptor, handler: wrappedHandler });
}
function bindRealtimeBridge(_bus: IEventBus, _broadcaster: IRealtimeBroadcaster): void {
// v1 ships with an empty allowlist. The dashboard PR adds the first entries here.
// Example shape (commented out so v1 doesn't try to use it):
// bus.subscribe(userSignedUpEvent, "realtime-bridge", async (payload) =>
// broadcaster.broadcast(adminEventStreamChannel, { kind: "user.signed-up", payload }),
// );
await bindAllDevSeed();
}
/** Test-only resets — not exported via package. Used by bind-production.test.ts. */