@fjell/core
Version:
Core Item and Key Framework for Fjell
140 lines (139 loc) • 7.66 kB
TypeScript
import { ComKey, Item, ItemTypeArray, LocKeyArray, PriKey } from '@fjell/types';
import { BaseEvent } from './events';
import { Subscription, SubscriptionOptions } from './subscription';
/**
* Core EventEmitter interface that storage libraries implement.
* Each item type gets its own EventEmitter instance for full type safety.
* Libraries implement separate EventEmitters per item type (UserEventEmitter, MessageEventEmitter, etc.)
*/
export interface EventEmitter<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> {
/**
* Emit a generic event with full control over event properties.
* Libraries can use this for custom events or when they need full control.
*/
emit(event: BaseEvent<S, L1, L2, L3, L4, L5>): Promise<void>;
/**
* Emit a create event when an item is created.
* Convenience method that constructs a properly typed CreateEvent.
*/
emitCreate(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, scopes: string[], item: Item<S, L1, L2, L3, L4, L5>): Promise<void>;
/**
* Emit an update event when an item is modified.
* Convenience method that constructs a properly typed UpdateEvent.
*/
emitUpdate(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, scopes: string[], changes: string[], before?: Item<S, L1, L2, L3, L4, L5>, after?: Item<S, L1, L2, L3, L4, L5>): Promise<void>;
/**
* Emit a delete event when an item is deleted.
* Convenience method that constructs a properly typed DeleteEvent.
*/
emitDelete(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, scopes: string[], item?: Item<S, L1, L2, L3, L4, L5>): Promise<void>;
/**
* Emit an action event when a custom action is performed.
* Convenience method that constructs a properly typed ActionEvent.
*/
emitAction(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, scopes: string[], actionName: string, actionData?: Record<string, unknown>): Promise<void>;
/**
* Create a scoped emitter that automatically includes the specified scopes.
* Libraries can use this to avoid passing scopes to every emit call.
*/
withScopes(scopes: string[]): ScopedEventEmitter<S, L1, L2, L3, L4, L5>;
}
/**
* Scoped EventEmitter that automatically includes configured scopes.
* Convenience interface for libraries to avoid passing scopes repeatedly.
*/
export interface ScopedEventEmitter<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> {
/** The scopes that will be automatically included in all events */
readonly scopes: string[];
/**
* Emit a generic event with automatic scope inclusion.
* The event should omit scopes since they'll be added automatically.
*/
emit(event: Omit<BaseEvent<S, L1, L2, L3, L4, L5>, 'scopes'>): Promise<void>;
/**
* Emit a create event with automatic scope inclusion.
*/
emitCreate(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, item: Item<S, L1, L2, L3, L4, L5>): Promise<void>;
/**
* Emit an update event with automatic scope inclusion.
*/
emitUpdate(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, changes: string[], before?: Item<S, L1, L2, L3, L4, L5>, after?: Item<S, L1, L2, L3, L4, L5>): Promise<void>;
/**
* Emit a delete event with automatic scope inclusion.
*/
emitDelete(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, item?: Item<S, L1, L2, L3, L4, L5>): Promise<void>;
/**
* Emit an action event with automatic scope inclusion.
*/
emitAction(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, actionName: string, actionData?: Record<string, unknown>): Promise<void>;
}
/**
* EventSubscriber interface for subscribing to and receiving events.
* Each item type gets its own EventSubscriber instance for full type safety.
*/
export interface EventSubscriber<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> {
/**
* Subscribe to events using a full subscription object.
* Returns the subscription ID for later unsubscribing.
*/
subscribe(subscription: Omit<Subscription<S, L1, L2, L3, L4, L5>, 'id'>): Promise<string>;
/**
* Unsubscribe from events using the subscription ID.
*/
unsubscribe(subscriptionId: string): Promise<void>;
/**
* Register a callback to be called when events are received.
* Multiple callbacks can be registered and they'll all be called.
*/
onEvent(callback: (event: BaseEvent<S, L1, L2, L3, L4, L5>) => void): void;
/**
* Remove a previously registered event callback.
*/
removeEventListener(callback: (event: BaseEvent<S, L1, L2, L3, L4, L5>) => void): void;
/**
* Convenience method to subscribe to a specific item.
* Automatically creates an ItemSubscription with the provided options.
*/
subscribeToItem(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, options?: SubscriptionOptions<S, L1, L2, L3, L4, L5>): Promise<string>;
/**
* Convenience method to subscribe to a location.
* Automatically creates a LocationSubscription with the provided options.
*/
subscribeToLocation(kta: ItemTypeArray<S, L1, L2, L3, L4, L5>, location: LocKeyArray<L1, L2, L3, L4, L5>, options?: SubscriptionOptions<S, L1, L2, L3, L4, L5>): Promise<string>;
/**
* Get all currently active subscriptions.
* Useful for debugging and subscription management.
*/
getActiveSubscriptions(): Subscription<S, L1, L2, L3, L4, L5>[];
/**
* Check if an event matches any active subscriptions.
* Used internally by libraries to determine if an event should be processed.
*/
matchesSubscription(event: BaseEvent<S, L1, L2, L3, L4, L5>): boolean;
/**
* Check if an event matches a specific subscription.
* Used internally for subscription matching logic.
*/
matchesSpecificSubscription(event: BaseEvent<S, L1, L2, L3, L4, L5>, subscription: Subscription<S, L1, L2, L3, L4, L5>): boolean;
}
/**
* Combined EventSystem interface that includes both emitter and subscriber.
* Libraries can implement this interface to provide both event emission and subscription.
*/
export interface EventSystem<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> {
/** Event emitter for publishing events */
readonly emitter: EventEmitter<S, L1, L2, L3, L4, L5>;
/** Event subscriber for receiving events */
readonly subscriber: EventSubscriber<S, L1, L2, L3, L4, L5>;
}
/**
* Factory function type for creating EventSystems.
* Libraries implement this to create properly configured event systems.
*/
export type EventSystemFactory<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> = (scopes: string[]) => EventSystem<S, L1, L2, L3, L4, L5>;
export type UserEventEmitter = EventEmitter<'User'>;
export type UserEventSubscriber = EventSubscriber<'User'>;
export type UserEventSystem = EventSystem<'User'>;
export type MessageEventEmitter<L1 extends string, L2 extends string> = EventEmitter<'Message', L1, L2>;
export type MessageEventSubscriber<L1 extends string, L2 extends string> = EventSubscriber<'Message', L1, L2>;
export type MessageEventSystem<L1 extends string, L2 extends string> = EventSystem<'Message', L1, L2>;