diff --git a/src/lib/structures/AliasPiece.ts b/src/lib/structures/AliasPiece.ts index 38e0ef85..245852be 100644 --- a/src/lib/structures/AliasPiece.ts +++ b/src/lib/structures/AliasPiece.ts @@ -1,5 +1,5 @@ import { Piece } from './Piece'; -import type { StoreRegistryEntries } from './StoreRegistry'; +import type { StoreRegistryKey } from './StoreRegistry'; export interface AliasPieceOptions extends Piece.Options { /** @@ -12,16 +12,16 @@ export interface AliasPieceOptions extends Piece.Options { /** * The piece to be stored in {@link AliasStore} instances. */ -export class AliasPiece< - Options extends AliasPieceOptions = AliasPieceOptions, - StoreName extends keyof StoreRegistryEntries = keyof StoreRegistryEntries -> extends Piece { +export class AliasPiece extends Piece< + Options, + StoreName +> { /** * The aliases for the piece. */ public aliases: readonly string[]; - public constructor(context: Piece.Context, options: AliasPieceOptions = {}) { + public constructor(context: AliasPiece.Context, options: AliasPieceOptions = {}) { super(context, options); this.aliases = options.aliases ?? []; } @@ -29,7 +29,7 @@ export class AliasPiece< /** * Defines the `JSON.stringify` behavior of this alias piece. */ - public override toJSON(): AliasPieceJSON { + public override toJSON(): AliasPiece.JSON { return { ...super.toJSON(), aliases: this.aliases.slice() @@ -48,7 +48,7 @@ export interface AliasPieceJSON extends Piece.JSON { export namespace AliasPiece { export const { Location } = Piece; export type Options = AliasPieceOptions; - export type Context = Piece.Context; + export type Context = Piece.Context; export type JSON = AliasPieceJSON; export type LocationJSON = Piece.LocationJSON; } diff --git a/src/lib/structures/AliasStore.ts b/src/lib/structures/AliasStore.ts index ef5f7079..825f23d3 100644 --- a/src/lib/structures/AliasStore.ts +++ b/src/lib/structures/AliasStore.ts @@ -1,12 +1,12 @@ import { Collection } from '@discordjs/collection'; import type { AliasPiece } from './AliasPiece'; import { Store } from './Store'; -import type { StoreRegistryEntries } from './StoreRegistry'; +import type { StoreRegistryKey } from './StoreRegistry'; /** * The store class which contains {@link AliasPiece}s. */ -export class AliasStore extends Store { +export class AliasStore extends Store { /** * The aliases referencing to pieces. */ diff --git a/src/lib/structures/Piece.ts b/src/lib/structures/Piece.ts index 037b8d76..75a5c8a2 100644 --- a/src/lib/structures/Piece.ts +++ b/src/lib/structures/Piece.ts @@ -2,13 +2,13 @@ import type { Awaitable } from '@sapphire/utilities'; import { container, type Container } from '../shared/Container'; import { PieceLocation, type PieceLocationJSON } from './PieceLocation'; import type { Store } from './Store'; -import type { StoreOf, StoreRegistryEntries } from './StoreRegistry'; +import type { StoreOf, StoreRegistryKey } from './StoreRegistry'; /** * The context for the piece, contains extra information from the store, * the piece's path, and the store that loaded it. */ -export interface PieceContext { +export interface PieceContext { /** * The root directory the piece was loaded from. */ @@ -27,7 +27,7 @@ export interface PieceContext { /** * The store that loaded the piece. */ - readonly store: Store; + readonly store: StoreOf; } /** @@ -50,7 +50,7 @@ export interface PieceOptions { /** * The piece to be stored in {@link Store} instances. */ -export class Piece { +export class Piece { /** * The store that contains the piece. */ @@ -76,7 +76,7 @@ export class Piece, options: PieceOptions = {}) { this.store = context.store; this.location = new PieceLocation(context.path, context.root); this.name = options.name ?? context.name; @@ -149,7 +149,7 @@ export interface PieceJSON { export namespace Piece { export const Location = PieceLocation; export type Options = PieceOptions; - export type Context = PieceContext; + export type Context = PieceContext; export type JSON = PieceJSON; export type LocationJSON = PieceLocationJSON; } diff --git a/src/lib/structures/Store.ts b/src/lib/structures/Store.ts index e683c330..d8b4e01b 100644 --- a/src/lib/structures/Store.ts +++ b/src/lib/structures/Store.ts @@ -9,16 +9,16 @@ import { container, type Container } from '../shared/Container'; import type { HydratedModuleData, ILoaderResultEntry, ILoaderStrategy, ModuleData } from '../strategies/ILoaderStrategy'; import { LoaderStrategy } from '../strategies/LoaderStrategy'; import type { Piece } from './Piece'; -import { StoreRegistry, type StoreRegistryEntries } from './StoreRegistry'; +import { StoreRegistry, StoreRegistryKey, type StoreRegistryEntries } from './StoreRegistry'; /** * The options for the store, this features both hooks (changes the behaviour) and handlers (similar to event listeners). */ -export interface StoreOptions { +export interface StoreOptions { /** * The name for this store. */ - readonly name: string; + readonly name: StoreName; /** * The paths to load pieces from, should be absolute. @@ -51,9 +51,9 @@ export interface StoreLogger { /** * The store class which contains {@link Piece}s. */ -export class Store extends Collection { +export class Store extends Collection { public readonly Constructor: AbstractConstructor; - public readonly name: keyof StoreRegistryEntries; + public readonly name: StoreName; public readonly paths: Set; public readonly strategy: ILoaderStrategy; @@ -71,10 +71,10 @@ export class Store, options: StoreOptions) { + public constructor(constructor: AbstractConstructor, options: StoreOptions) { super(); this.Constructor = constructor; - this.name = options.name as keyof StoreRegistryEntries; + this.name = options.name as StoreRegistryKey; this.paths = new Set(options.paths ?? []); this.strategy = options.strategy ?? Store.defaultStrategy; } @@ -396,7 +396,7 @@ export class Store { +export interface StoreManuallyRegisteredPiece { name: string; piece: StoreRegistryEntries[StoreName] extends Store ? Constructor : never; } diff --git a/src/lib/structures/StoreRegistry.ts b/src/lib/structures/StoreRegistry.ts index 3d91afcd..fb0118a8 100644 --- a/src/lib/structures/StoreRegistry.ts +++ b/src/lib/structures/StoreRegistry.ts @@ -8,9 +8,6 @@ import { ManuallyRegisteredPiecesSymbol, VirtualPath } from '../internal/constan import type { Piece } from './Piece'; import type { Store, StoreManuallyRegisteredPiece } from './Store'; -type Key = keyof StoreRegistryEntries; -type Value = StoreRegistryEntries[Key]; - /** * A strict-typed store registry. This is available in {@link container}. * @since 2.1.0 @@ -31,14 +28,11 @@ type Value = StoreRegistryEntries[Key]; * } * ``` */ -export class StoreRegistry extends Collection { +export class StoreRegistry extends Collection { /** * The queue of pieces to load. */ - readonly #pendingManuallyRegisteredPieces = new Collection< - keyof StoreRegistryEntries, - StoreManuallyRegisteredPiece[] - >(); + readonly #pendingManuallyRegisteredPieces = new Collection[]>(); /** * Loads all the registered stores. @@ -109,7 +103,7 @@ export class StoreRegistry extends Collection { * @param store The store to register. */ public register(store: Store): this { - this.set(store.name as Key, store as unknown as Value); + this.set(store.name as StoreRegistryKey, store as unknown as StoreRegistryValue); // If there was a queue for this store, add it to the store and delete the queue: const queue = this.#pendingManuallyRegisteredPieces.get(store.name); @@ -127,7 +121,7 @@ export class StoreRegistry extends Collection { * @param store The store to deregister. */ public deregister(store: Store): this { - this.delete(store.name as Key); + this.delete(store.name as StoreRegistryKey); return this; } @@ -168,7 +162,7 @@ export class StoreRegistry extends Collection { * }); * ``` */ - public async loadPiece(entry: StoreManagerManuallyRegisteredPiece) { + public async loadPiece(entry: StoreManagerManuallyRegisteredPiece) { const store = this.get(entry.store) as Store | undefined; if (store) { @@ -184,12 +178,24 @@ export class StoreRegistry extends Collection { } export interface StoreRegistry { - get(key: K): StoreRegistryEntries[K]; + get(key: K): StoreRegistryEntries[K]; get(key: string): undefined; - has(key: Key): true; + has(key: StoreRegistryKey): true; has(key: string): false; } +/** + * A type utility to get the keys of {@linkcode StoreRegistryEntries}. + * @since 3.10.0 + */ +export type StoreRegistryKey = keyof StoreRegistryEntries; + +/** + * A type utility to get the values of {@linkcode StoreRegistryEntries}. + * @since 3.10.0 + */ +export type StoreRegistryValue = StoreRegistryEntries[StoreRegistryKey]; + /** * The {@link StoreRegistry}'s registry, use module augmentation against this interface when adding new stores. * @since 2.1.0 @@ -201,21 +207,23 @@ export interface StoreRegistryEntries {} * @seealso {@linkcode StoreRegistry.loadPiece()} * @since 3.8.0 */ -export interface StoreManagerManuallyRegisteredPiece extends StoreManuallyRegisteredPiece { +export interface StoreManagerManuallyRegisteredPiece extends StoreManuallyRegisteredPiece { store: StoreName; } /** * Type utility to get the {@linkcode Store} given its name. + * @since 3.10.0 */ -export type StoreOf = keyof StoreRegistryEntries extends never +export type StoreOf = StoreRegistryKey extends never ? Store> : StoreRegistryEntries[StoreName]; /** * Type utility to get the {@linkcode Piece} given its {@linkcode Store}'s name. + * @since 3.10.0 */ -export type PieceOf = keyof StoreRegistryEntries extends never +export type PieceOf = StoreRegistryKey extends never ? Piece : StoreRegistryEntries[StoreName] extends Store ? PieceType