@ldlework/categoric-decorators
v1.0.1
Published
Decorate things. Find them at runtime.
Downloads
5,248
Readme
Categoric Decorators
Decorate things. Find them at runtime.
This is a simple library that lets you create your own decorators. You can use these decorators to tag classes or class members such that you can find them all at runtime.
// decorators/enemy.ts
import { createCategoricDecorator } from "categoric-decorators"
export const [ enemy, locateEnemies ] = createClassCategoric()
// enemies/SnakeEnemy.ts
@enemy()
class SnakeEnemy extends Enemy {
// ...
}
// enemies/SpiderEnemy.ts
@enemy()
class SpiderEnemy extends Enemy {
// ...
}
Now at runtime you could use locateEnemies()
to get a collection containing SnakeEnemy
and SpiderEnemy
classes.
Installation
npm i categoric-decorators
Class Decorators
To create a class category, use createClassCategoric()
:
export const [ foo, locateFoos ] = createClassCategoric()
This creates a @foo()
decorator which can be used on any class.
Calling locateFoos()
will return an object mapping from class name => metadata.
The metadata looks like this:
type CategoricClassMeta<T> = {
data?: T
target: Constructable
}
Click here to find out more about metadata.
Member Decorators
To create a member category, use createMemberCategoric()
:
export const [ bar, locateBars ] = createMemberCategoric()
This creates a @bar()
decorator which can be used on class fields and methods.
Calling locateBars()
will return an object mapping from class name => metadata.
The metadata looks like this:
export type MemberMeta<T> = {
target: Constructable
name: string
data?: T
}
export type CategoricMemberMeta<T> = {
target: Constructable
members: Record<string, MemberMeta<T>>
}
Click here to find out more about metadata.
Metadata
You may have noticed the data?: T
fields on the metadata returned by this library.
This is actually metadata that you can supply to the decorators you create.
For example, if we define some enemy metadata:
export type EnemyMetadata {
name: string,
maxHealth: number
}
Then we can create our enemy decorator with type information:
const export [ enemy, locateEnemies ] = createClassCategoric<EnemyMetadata>()
Now we can provide this metadata to the @enemy()
decorator:
@enemy({
name: "snek",
maxHealth: 25,
})
class SnakeEnemy extends Enemy {
// ...
}
This information will appear as the data: EnemyMetadata
field on the metadata returned by your locator functions:
const enemyClasses = locateEnemies()
const { data } = enemyClasses['SnakeEnemy']
const { name, maxHealth } = data // "snek", 25