Skip to content

Commit

Permalink
Typed event emitters
Browse files Browse the repository at this point in the history
  • Loading branch information
Gerrit0 committed Jun 21, 2024
1 parent e35608f commit 6e6b3b6
Show file tree
Hide file tree
Showing 38 changed files with 408 additions and 1,924 deletions.
11 changes: 3 additions & 8 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
# Beta (full release: 2024-06-21)

### To Do

- Update website docs - consider if reworking website to just be a TypeDoc generated site is a good idea
`@license`, `@import`, `@hideGroups` `@hideCategories` sitemapBaseUrl, markedOptions -> markdownItOptions, markdownItLoader, navigation
sort - documents-first, documents-last, alphabetical-ignoring-documents
searchInDocuments, useHostedBaseUrlForAbsoluteLinks
# Unreleased

### Breaking Changes

Expand All @@ -28,6 +21,8 @@
This change was extended to apply not only to type aliases, but also other function-likes declared with variables and callable properties.
As a part of this change, comments on the implementation signature of overloaded functions will now be added to the function reflection, and will
not be inherited by signatures of that function, #2521.
- API: TypeDoc now uses a typed event emitter to provide improved type safety, this found a bug where `Converter.EVENT_CREATE_DECLARATION`
was emitted for `ProjectReflection` in some circumstances.
- API: `MapOptionDeclaration.mapError` has been removed.
- API: Deprecated `BindOption` decorator has been removed.
- API: `DeclarationReflection.indexSignature` has been renamed to `DeclarationReflection.indexSignatures`.
Expand Down
9 changes: 5 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export { Application } from "./lib/application";
export { Application, type ApplicationEvents } from "./lib/application";

export { EventDispatcher, Event } from "./lib/utils/events";
export { EventDispatcher } from "./lib/utils/events";
export { resetReflectionID } from "./lib/models/reflections/abstract";
/**
* All symbols documented under the Models namespace are also available in the root import.
Expand Down Expand Up @@ -29,6 +29,7 @@ export {
type MeaningKeyword,
type ExternalResolveResult,
type ExternalSymbolResolver,
type ConverterEvents,
} from "./lib/converter";

export {
Expand All @@ -47,6 +48,7 @@ export type {
RenderTemplate,
RendererHooks,
NavigationElement,
RendererEvents,
} from "./lib/output";

export {
Expand Down Expand Up @@ -94,11 +96,10 @@ export type {
JsDocCompatibility,
} from "./lib/utils";

export type { EventMap, EventCallback } from "./lib/utils/events";

export {
JSONOutput,
Serializer,
type SerializerEvents,
Deserializer,
type Deserializable,
type DeserializerComponent,
Expand Down
2 changes: 1 addition & 1 deletion src/lib/application-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ export const ApplicationEvents = {
BOOTSTRAP_END: "bootstrapEnd",
REVIVE: "reviveProject",
VALIDATE_PROJECT: "validateProject",
};
} as const;
13 changes: 10 additions & 3 deletions src/lib/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ const DEFAULT_READERS = [
new TSConfigReader(),
];

export interface ApplicationEvents {
bootstrapEnd: [Application];
reviveProject: [ProjectReflection];
validateProject: [ProjectReflection];
}

/**
* The default TypeDoc main application class.
*
Expand All @@ -95,7 +101,8 @@ const DEFAULT_READERS = [
@Component({ name: "application", internal: true })
export class Application extends ChildableComponent<
Application,
AbstractComponent<Application>
AbstractComponent<Application, {}>,
ApplicationEvents
> {
/**
* The converter used to create the declaration reflections.
Expand Down Expand Up @@ -187,8 +194,8 @@ export class Application extends ChildableComponent<
}
super(null!); // We own ourselves

this.converter = this.addComponent<Converter>("converter", Converter);
this.renderer = this.addComponent<Renderer>("renderer", Renderer);
this.converter = new Converter(this);
this.renderer = new Renderer(this);
this.logger.i18n = this.i18n;
}

Expand Down
5 changes: 4 additions & 1 deletion src/lib/converter/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@ import type { Converter } from "./converter";

export { Component };

export abstract class ConverterComponent extends AbstractComponent<Converter> {}
export abstract class ConverterComponent extends AbstractComponent<
Converter,
{}
> {}
13 changes: 0 additions & 13 deletions src/lib/converter/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,19 +262,6 @@ export class Context {
this.project.registerReflection(reflection, symbol, void 0);
}

/**
* Trigger a node reflection event.
*
* All events are dispatched on the current converter instance.
*
* @param name The name of the event that should be triggered.
* @param reflection The triggering reflection.
* @param node The triggering TypeScript node if available.
*/
trigger(name: string, reflection: Reflection, node?: ts.Node) {
this.converter.trigger(name, this, reflection, node);
}

/** @internal */
setActiveProgram(program: ts.Program | undefined) {
this._program = program;
Expand Down
36 changes: 31 additions & 5 deletions src/lib/converter/converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@ import {
Comment,
type CommentDisplayPart,
type ContainerReflection,
type DeclarationReflection,
DocumentReflection,
type ParameterReflection,
ProjectReflection,
type Reflection,
ReflectionKind,
type ReflectionSymbolId,
type SignatureReflection,
type SomeType,
type TypeParameterReflection,
} from "../models/index";
import { Context } from "./context";
import { ConverterComponent } from "./components";
Expand Down Expand Up @@ -49,6 +53,31 @@ import {
import { basename, dirname, resolve } from "path";
import type { FileRegistry } from "../models/FileRegistry";

export interface ConverterEvents {
begin: [Context];
end: [Context];
createDeclaration: [Context, DeclarationReflection];
createSignature: [
Context,
SignatureReflection,
(
| ts.SignatureDeclaration
| ts.IndexSignatureDeclaration
| ts.JSDocSignature
)?,
ts.Signature?,
];
createParameter: [Context, ParameterReflection, ts.Node?];
createTypeParameter: [
Context,
TypeParameterReflection,
ts.TypeParameterDeclaration?,
];
resolveBegin: [Context];
resolveReflection: [Context, Reflection];
resolveEnd: [Context];
}

/**
* Compiles source files using TypeScript and converts compiler symbols to reflections.
*/
Expand All @@ -59,7 +88,8 @@ import type { FileRegistry } from "../models/FileRegistry";
})
export class Converter extends ChildableComponent<
Application,
ConverterComponent
ConverterComponent,
ConverterEvents
> {
/** @internal */
@Option("externalPattern")
Expand Down Expand Up @@ -440,10 +470,6 @@ export class Converter extends ChildableComponent<
? context.getComment(symbol, context.project.kind)
: context.getFileComment(node);
this.processDocumentTags(context.project, context.project);
context.trigger(
Converter.EVENT_CREATE_DECLARATION,
context.project,
);
moduleContext = context;
} else {
const reflection = context.createDeclarationReflection(
Expand Down
3 changes: 2 additions & 1 deletion src/lib/converter/factories/index-signature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ export function convertIndexSignatures(context: Context, symbol: ts.Symbol) {
context.scope.indexSignatures ||= [];
context.scope.indexSignatures.push(index);

context.trigger(
context.converter.trigger(
ConverterEvents.CREATE_SIGNATURE,
context,
index,
indexDeclaration,
);
Expand Down
28 changes: 23 additions & 5 deletions src/lib/converter/factories/signature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,11 @@ function convertParameters(
paramRefl.comment ||= context.getComment(param, paramRefl.kind);

context.registerReflection(paramRefl, param);
context.trigger(ConverterEvents.CREATE_PARAMETER, paramRefl);
context.converter.trigger(
ConverterEvents.CREATE_PARAMETER,
context,
paramRefl,
);

let type: ts.Type | ts.TypeNode | undefined;
if (declaration) {
Expand Down Expand Up @@ -289,7 +293,11 @@ export function convertParameterNodes(
paramRefl,
context.getSymbolAtLocation(param),
);
context.trigger(ConverterEvents.CREATE_PARAMETER, paramRefl);
context.converter.trigger(
ConverterEvents.CREATE_PARAMETER,
context,
paramRefl,
);

paramRefl.type = context.converter.convertType(
context.withScope(paramRefl),
Expand Down Expand Up @@ -377,7 +385,11 @@ function convertTypeParameters(
}

context.registerReflection(paramRefl, param.getSymbol());
context.trigger(ConverterEvents.CREATE_TYPE_PARAMETER, paramRefl);
context.converter.trigger(
ConverterEvents.CREATE_TYPE_PARAMETER,
context,
paramRefl,
);

return paramRefl;
});
Expand Down Expand Up @@ -418,7 +430,12 @@ export function createTypeParamReflection(
paramRefl.comment = context.getJsDocComment(param.parent);
}

context.trigger(ConverterEvents.CREATE_TYPE_PARAMETER, paramRefl, param);
context.converter.trigger(
ConverterEvents.CREATE_TYPE_PARAMETER,
context,
paramRefl,
param,
);
return paramRefl;
}

Expand Down Expand Up @@ -458,8 +475,9 @@ export function convertTemplateParameterNodes(
paramRefl.comment = context.getJsDocComment(param.parent);
}

context.trigger(
context.converter.trigger(
ConverterEvents.CREATE_TYPE_PARAMETER,
context,
paramRefl,
param,
);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/converter/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export { Context } from "./context";
export { Converter } from "./converter";
export { Converter, type ConverterEvents } from "./converter";
export type { CommentParserConfig } from "./comments/index";
export { convertDefaultValue, convertExpression } from "./convert-expression";
export type {
Expand Down
6 changes: 5 additions & 1 deletion src/lib/converter/jsdoc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,11 @@ function convertJsDocSignature(context: Context, node: ts.JSDocSignature) {
context.scope,
);
context.registerReflection(reflection, symbol);
context.trigger(ConverterEvents.CREATE_DECLARATION, reflection);
context.converter.trigger(
ConverterEvents.CREATE_DECLARATION,
context,
reflection,
);

const signature = new SignatureReflection(
"__type",
Expand Down
11 changes: 4 additions & 7 deletions src/lib/converter/plugins/CategoryPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,10 @@ export class CategoryPlugin extends ConverterComponent {
* Create a new CategoryPlugin instance.
*/
override initialize() {
this.listenTo(
this.owner,
{
[Converter.EVENT_BEGIN]: this.onBegin,
[Converter.EVENT_RESOLVE_END]: this.onEndResolve,
},
undefined,
this.owner.on(Converter.EVENT_BEGIN, this.onBegin.bind(this), -200);
this.owner.on(
Converter.EVENT_RESOLVE_END,
this.onEndResolve.bind(this),
-200,
);
}
Expand Down
28 changes: 19 additions & 9 deletions src/lib/converter/plugins/CommentPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,15 +155,25 @@ export class CommentPlugin extends ConverterComponent {
* Create a new CommentPlugin instance.
*/
override initialize() {
this.listenTo(this.owner, {
[Converter.EVENT_CREATE_DECLARATION]: this.onDeclaration,
[Converter.EVENT_CREATE_SIGNATURE]: this.onDeclaration,
[Converter.EVENT_CREATE_TYPE_PARAMETER]: this.onCreateTypeParameter,
[Converter.EVENT_RESOLVE_BEGIN]: this.onBeginResolve,
[Converter.EVENT_RESOLVE]: this.onResolve,
[Converter.EVENT_END]: () => {
this._excludeKinds = undefined;
},
this.owner.on(
Converter.EVENT_CREATE_DECLARATION,
this.onDeclaration.bind(this),
);
this.owner.on(
Converter.EVENT_CREATE_SIGNATURE,
this.onDeclaration.bind(this),
);
this.owner.on(
Converter.EVENT_CREATE_TYPE_PARAMETER,
this.onCreateTypeParameter.bind(this),
);
this.owner.on(
Converter.EVENT_RESOLVE_BEGIN,
this.onBeginResolve.bind(this),
);
this.owner.on(Converter.EVENT_RESOLVE, this.onResolve.bind(this));
this.owner.on(Converter.EVENT_END, () => {
this._excludeKinds = undefined;
});
}

Expand Down
33 changes: 16 additions & 17 deletions src/lib/converter/plugins/GroupPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,25 +63,24 @@ export class GroupPlugin extends ConverterComponent {
* Create a new GroupPlugin instance.
*/
override initialize() {
this.listenTo(
this.owner,
{
[Converter.EVENT_RESOLVE_BEGIN]: () => {
this.sortFunction = getSortFunction(
this.application.options,
this.owner.on(
Converter.EVENT_RESOLVE_BEGIN,
() => {
this.sortFunction = getSortFunction(this.application.options);
GroupPlugin.WEIGHTS = this.groupOrder;
if (GroupPlugin.WEIGHTS.length === 0) {
GroupPlugin.WEIGHTS = defaultGroupOrder.map((kind) =>
this.application.internationalization.kindPluralString(
kind,
),
);
GroupPlugin.WEIGHTS = this.groupOrder;
if (GroupPlugin.WEIGHTS.length === 0) {
GroupPlugin.WEIGHTS = defaultGroupOrder.map((kind) =>
this.application.internationalization.kindPluralString(
kind,
),
);
}
},
[Converter.EVENT_RESOLVE_END]: this.onEndResolve,
}
},
undefined,
-100,
);
this.owner.on(
Converter.EVENT_RESOLVE_END,
this.onEndResolve.bind(this),
-100,
);
}
Expand Down
Loading

0 comments on commit 6e6b3b6

Please sign in to comment.