chore: remove effects leftovers, dead SyncedState.set, add modules/resources skill refs
This commit is contained in:
@@ -18,7 +18,6 @@ import type { RudderContext } from '../core/context.js';
|
||||
import { request, type RequestContext } from '../transport/request.js';
|
||||
import { createDefaultTokenStore } from '../token/TokenStore.js';
|
||||
import { AuthService } from '../auth/AuthService.js';
|
||||
import { EffectsCenter, type Effects } from '../effects/EffectsCenter.js';
|
||||
import { SyncEngine } from '../state/SyncEngine.js';
|
||||
import { PlayerDomain } from '../domains/PlayerDomain.js';
|
||||
import { CatalogDomain } from '../domains/CatalogDomain.js';
|
||||
@@ -33,7 +32,6 @@ export class RudderClient {
|
||||
public readonly options: ResolvedRudderClientOptions;
|
||||
|
||||
public readonly auth: AuthService;
|
||||
public readonly effects: Effects;
|
||||
|
||||
public readonly player: PlayerDomain;
|
||||
public readonly catalog: CatalogDomain;
|
||||
@@ -42,7 +40,6 @@ export class RudderClient {
|
||||
public readonly modules: ModulesDomain;
|
||||
private readonly resourcesDomain: ResourcesDomain;
|
||||
|
||||
private readonly effectsCenter: EffectsCenter;
|
||||
private readonly syncEngine: SyncEngine;
|
||||
private readonly ctx: RudderContext;
|
||||
private readonly transportContext: RequestContext;
|
||||
@@ -74,12 +71,8 @@ export class RudderClient {
|
||||
},
|
||||
};
|
||||
|
||||
this.effectsCenter = new EffectsCenter(this.options.onEffectError);
|
||||
this.effects = this.effectsCenter;
|
||||
|
||||
this.ctx = {
|
||||
options: this.options,
|
||||
effects: this.effectsCenter,
|
||||
request: <TResponse>(method: string, path: string, body?: unknown) =>
|
||||
request<TResponse>(method, path, body, this.transportContext),
|
||||
};
|
||||
|
||||
@@ -25,12 +25,6 @@ export interface RudderClientOptions {
|
||||
|
||||
/** Revision sync poll interval in milliseconds (default: 30000, ±20% jitter). */
|
||||
syncIntervalMs?: number;
|
||||
|
||||
/**
|
||||
* Called when an effect handler (or effect preparation) throws.
|
||||
* Defaults to `console.error`.
|
||||
*/
|
||||
onEffectError?: (error: unknown) => void;
|
||||
}
|
||||
|
||||
/** Client options with all defaults resolved — what `client.options` exposes. */
|
||||
|
||||
+1
-3
@@ -1,9 +1,8 @@
|
||||
import type { ResolvedRudderClientOptions } from '../client/RudderClientOptions.js';
|
||||
import type { EffectsCenter } from '../effects/EffectsCenter.js';
|
||||
|
||||
/**
|
||||
* RudderContext — the low-level surface every feature service depends on:
|
||||
* the HTTP transport, client options, and the effects bus.
|
||||
* the HTTP transport and client options.
|
||||
*
|
||||
* Built once by {@link RudderClient} and injected into each service. Services
|
||||
* depend on this narrow interface instead of on the client itself, so the
|
||||
@@ -11,6 +10,5 @@ import type { EffectsCenter } from '../effects/EffectsCenter.js';
|
||||
*/
|
||||
export interface RudderContext {
|
||||
readonly options: ResolvedRudderClientOptions;
|
||||
readonly effects: EffectsCenter;
|
||||
request<TResponse>(method: string, path: string, body?: unknown): Promise<TResponse>;
|
||||
}
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
export type EffectUnsubscribe = () => void;
|
||||
|
||||
export interface NotificationEffect {
|
||||
readonly title: string;
|
||||
readonly message: string;
|
||||
done(): Promise<void>;
|
||||
}
|
||||
|
||||
export interface WaitEffect {
|
||||
readonly deadlineUtc: Date;
|
||||
}
|
||||
|
||||
export interface ScenarioCompletedEffect {
|
||||
readonly runId: string;
|
||||
readonly scenarioSlug: string;
|
||||
}
|
||||
|
||||
export interface ScenarioFailedEffect {
|
||||
readonly runId: string;
|
||||
readonly scenarioSlug: string;
|
||||
readonly nodeId: string;
|
||||
readonly error: Error;
|
||||
}
|
||||
|
||||
type EffectHandler<TEffect> = (effect: TEffect) => void | Promise<void>;
|
||||
|
||||
export interface Effects {
|
||||
onNotification(handler: EffectHandler<NotificationEffect>): EffectUnsubscribe;
|
||||
onWait(handler: EffectHandler<WaitEffect>): EffectUnsubscribe;
|
||||
onScenarioCompleted(handler: EffectHandler<ScenarioCompletedEffect>): EffectUnsubscribe;
|
||||
onScenarioFailed(handler: EffectHandler<ScenarioFailedEffect>): EffectUnsubscribe;
|
||||
}
|
||||
|
||||
export class EffectsCenter implements Effects {
|
||||
private readonly notificationHandlers = new Set<EffectHandler<NotificationEffect>>();
|
||||
private readonly waitHandlers = new Set<EffectHandler<WaitEffect>>();
|
||||
private readonly scenarioCompletedHandlers = new Set<EffectHandler<ScenarioCompletedEffect>>();
|
||||
private readonly scenarioFailedHandlers = new Set<EffectHandler<ScenarioFailedEffect>>();
|
||||
|
||||
constructor(
|
||||
private readonly onError: (error: unknown) => void = (error) =>
|
||||
console.error('[Rudder] Effect handler failed', error),
|
||||
) {}
|
||||
|
||||
onNotification(handler: EffectHandler<NotificationEffect>): EffectUnsubscribe {
|
||||
return this.addHandler(this.notificationHandlers, handler);
|
||||
}
|
||||
|
||||
onWait(handler: EffectHandler<WaitEffect>): EffectUnsubscribe {
|
||||
return this.addHandler(this.waitHandlers, handler);
|
||||
}
|
||||
|
||||
onScenarioCompleted(handler: EffectHandler<ScenarioCompletedEffect>): EffectUnsubscribe {
|
||||
return this.addHandler(this.scenarioCompletedHandlers, handler);
|
||||
}
|
||||
|
||||
onScenarioFailed(handler: EffectHandler<ScenarioFailedEffect>): EffectUnsubscribe {
|
||||
return this.addHandler(this.scenarioFailedHandlers, handler);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
emitNotification(effect: NotificationEffect): void {
|
||||
this.emit(this.notificationHandlers, effect);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
emitWait(effect: WaitEffect): void {
|
||||
this.emit(this.waitHandlers, effect);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
emitScenarioCompleted(effect: ScenarioCompletedEffect): void {
|
||||
this.emit(this.scenarioCompletedHandlers, effect);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
emitScenarioFailed(effect: ScenarioFailedEffect): void {
|
||||
this.emit(this.scenarioFailedHandlers, effect);
|
||||
}
|
||||
|
||||
private addHandler<TEffect>(
|
||||
handlers: Set<EffectHandler<TEffect>>,
|
||||
handler: EffectHandler<TEffect>,
|
||||
): EffectUnsubscribe {
|
||||
handlers.add(handler);
|
||||
return () => {
|
||||
handlers.delete(handler);
|
||||
};
|
||||
}
|
||||
|
||||
private emit<TEffect>(
|
||||
handlers: Set<EffectHandler<TEffect>>,
|
||||
effect: TEffect,
|
||||
): void {
|
||||
for (const handler of handlers) {
|
||||
try {
|
||||
Promise.resolve(handler(effect)).catch((error) => this.onError(error));
|
||||
} catch (error) {
|
||||
this.onError(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,16 +45,6 @@ export type { ResourcesDomain, ResourceHandle } from './domains/ResourcesDomain.
|
||||
export type { StorageDomain } from './domains/StorageDomain.js';
|
||||
export type { ProjectStorageDomain } from './domains/ProjectStorageDomain.js';
|
||||
|
||||
// Effects
|
||||
export type {
|
||||
Effects,
|
||||
EffectUnsubscribe,
|
||||
NotificationEffect,
|
||||
WaitEffect,
|
||||
ScenarioCompletedEffect,
|
||||
ScenarioFailedEffect,
|
||||
} from './effects/EffectsCenter.js';
|
||||
|
||||
// Generated wire types — the shapes returned by the observable state and
|
||||
// handles, so consumers can name them instead of re-declaring mirrors.
|
||||
export type { Player, PlayerProfile, PlayerProfileIdentity, Wallet } from './generated/player.js';
|
||||
|
||||
@@ -76,8 +76,8 @@ export class SyncedState<T> {
|
||||
if (this.listeners.size === 0 && this.snapshot.status === 'idle') return;
|
||||
this.invalidateScheduled = true;
|
||||
queueMicrotask(() => {
|
||||
// A reset() or set() between scheduling and flushing cancels the reload
|
||||
// (fresh data arrived, or the entity was dropped on logout).
|
||||
// A reset() between scheduling and flushing cancels the reload
|
||||
// (the entity was dropped on logout).
|
||||
if (!this.invalidateScheduled) return;
|
||||
this.invalidateScheduled = false;
|
||||
if (this.listeners.size === 0 && this.snapshot.status === 'idle') return;
|
||||
@@ -85,18 +85,6 @@ export class SyncedState<T> {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies externally-provided data (e.g. scenario config patches).
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
set(data: T): void {
|
||||
this.generation++;
|
||||
this.pending = undefined;
|
||||
this.invalidateScheduled = false;
|
||||
this.setSnapshot({ status: 'ready', data });
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops all state back to idle (logout).
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user