Skip to content

Commit

Permalink
Merge pull request LemLib#8 from meisZWFLZ/master
Browse files Browse the repository at this point in the history
Merge meisZWFLZ/LemLink
  • Loading branch information
meisZWFLZ authored Dec 5, 2023
2 parents efea6cc + a4cf523 commit bafc61f
Show file tree
Hide file tree
Showing 9 changed files with 810 additions and 73 deletions.
Empty file modified .husky/commit-msg
100644 → 100755
Empty file.
2 changes: 1 addition & 1 deletion .husky/pre-commit
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm run clean
npm run check-format
1 change: 1 addition & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
653 changes: 591 additions & 62 deletions package-lock.json

Large diffs are not rendered by default.

11 changes: 4 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@lemlib/lemlink",
"version": "0.0.0-development",
"description": "An alternative project manager and uploader for vex v5 projects",
"main": "out/main.js",
"main": "out/index.js",
"scripts": {
"build": "tsc",
"check-lint": "eslint \"src/**.ts\" --cache --cache-location node_modules/.cache/eslint/.eslintcache",
Expand Down Expand Up @@ -37,14 +37,11 @@
"husky": "^8.0.0",
"jest": "^29.7.0",
"prettier": "^3.1.0",
"typescript": "^5.0.2",
"semantic-release": "^22.0.8"
"semantic-release": "^22.0.8",
"typescript": "^5.0.2"
},
"bin": {
"lem-link": "out/main.js"
},
"dependencies": {
"semantic-release": "^22.0.8"
"lem-link": "out/index.js"
},
"release": {
"branches": [
Expand Down
9 changes: 9 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export {
/** The version of this LemLink instance */ version as VERSION,
} from "../package.json";
export {
ExternalLogger as Logger,
LOG_LEVEL,
type LogMessage,
BaseSink,
} from "./logger";
202 changes: 202 additions & 0 deletions src/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
/** specifies severity of a log message */
export enum LOG_LEVEL {
/** verbose description */
VERBOSE,
/** debug description */
DEBUG,
/** info description */
INFO,
/** warning description */
WARNING,
/** error description */
ERROR,
/** fatal description */
FATAL,
}
/**
* Represents the a message for the {@linkcode ExternalLogger}
* @template Source where did this message come from?
*/
export interface LogMessage<Source extends string> {
/** where did this message come from? */
source: Source;
/** the severity of the message */
level: LOG_LEVEL;
/** the actual message */
msg: string;
}

/**
* What's a sink?
*
* Well you can kind of think of a Sink as an {@link https://nodejs.org/en/learn/asynchronous-work/the-nodejs-event-emitter EventEmitter}.
*
* - Emitting an event using the {@linkcode log log()} method.
* - You can add a listener using the {@linkcode addSink addSink()} method.
*
* @template msg The type of message that this sink can accept
*
* @example
* class MySink extends BaseSink<string> {
* public override log(msg) {
* console.log(msg);
* }
* }
* // prints "Hello World"
* new MySink.log("Hello World");
*
* @see {@linkcode BaseSink.log BaseSink.log()}
* @see {@linkcode BaseSink.addSink BaseSink.addSink()}
*/
export class BaseSink<M> {
protected sinks: Array<BaseSink<M>> = [];

/**
* Runs the {@linkcode log log()} method of all sinks added to this sink via the {@linkcode addSink addSink()} method
* @param msg message that will be sent to the other sinks
*
* @see {@linkcode BaseSink.addSink BaseSink.addSink()}
* @see {@linkcode BaseSink}
*/
public log(msg: M): void {
this.sinks.forEach((sink) => {
sink.log(msg);
});
}

/**
* Add sinks that will also be logged to when this sink is logged to
* @param sinks will be logged to when this sink is logged to
*
* @see {@linkcode BaseSink.log BaseSink.log()}
* @see {@linkcode BaseSink}
*/
public addSink(...sinks: Array<BaseSink<M>>): void {
sinks.push(...sinks);
}
}

/**
* Any messages sent to an instance of Logger will automatically be sent to the {@linkcode ExternalLogger}
*
* @template Source where is the logger being used?
*
* @example
* new Logger("lemlink.package-manger.install").log("fatal", 'could not retrieve package "ExampleLib"')
* @see {@linkcode BaseSink}
* @see {@linkcode Logger.log Logger.log()}
*
* @internal
*/
export class Logger<Source extends Lowercase<string>> extends BaseSink<
LogMessage<Source>
> {
/**
* Any messages sent to an instance of `Logger` will automatically be sent to the {@linkcode ExternalLogger}
*
* @param {Source} source where is the logger being used?
* @see {@linkcode BaseSink}
* @see {@linkcode Logger}
*
* @internal
*/
constructor(private readonly source: Source) {
super();
this.addSink(ExternalLogger.getInstance());
}

/**
* @internal
*
* Sends a message to the {@linkcode ExternalLogger}
*
* @param level the severity of the log message
* @param msg message to send to {@linkcode ExternalLogger}
*
* @see {@linkcode Logger}
* @see {@linkcode BaseSink.log BaseSink.log()}
*/
public override log(level: LOG_LEVEL, msg: string): void;
/**
* Sends a message to the {@linkcode ExternalLogger}
*
* @param msg message to send to {@linkcode ExternalLogger}
*
* @see {@linkcode Logger}
* @see {@linkcode BaseSink.log BaseSink.log()}
*
* @internal
*/
public override log(msg: LogMessage<Source>): void;
public override log(
a: LOG_LEVEL | Omit<LogMessage<Source>, "source">,
b?: string,
): void {
let msg: LogMessage<Source>;
if (typeof a === "number") {
if (b !== undefined) msg = { level: a, msg: b, source: this.source };
else return;
} else msg = { ...a, source: this.source };
super.log(msg);
}
}
/**
* Used to listen to the logs output by LemLink
* @example
* class MyLogSink extends BaseSink<string> {
* public override log(msg) {
* console.log(msg);
* }
* }
* ExternalLogger.addSink(new MyLogSink());
* // Now, whenever a log is made from LemLink,
* // it will be logged to the terminal!
*
* @see {@linkcode ExternalLogger.addSink ExternalLogger.addSink()}
*/
export class ExternalLogger extends BaseSink<LogMessage<string>> {
/** singleton instance */
private static readonly instance: ExternalLogger;

/** only one instance of ExternalLogger will ever be constructed */
private constructor() {
super();
}

/**
* Used in {@linkcode Logger} to added as a listening sink
* @see {@linkcode Logger} constructor
*
* @internal
*/
public static getInstance(): ExternalLogger {
return this.instance;
}

/**
* Messages are sent from {@link Logger Loggers} to this logger using this method.
* This method serves as a wrapper for {@linkcode BaseSink.log() ExternalLogger.instance.log()}
*
* @param msg sent from {@link Logger Loggers}
*
* @see {@linkcode Logger} constructor
* @see {@linkcode ExternalLogger}
* @see {@linkcode BaseSink.log BaseSink.log()}
*
* @internal
*/
public static log(msg: LogMessage<string>): void {
this.instance.log(msg);
}

/**
* Add sinks that will also be logged to when this sink is logged to
* @param sinks will be logged to when this sink is logged to
*
* @see {@linkcode ExternalLogger}
* @see {@linkcode BaseSink.addSink BaseSink.addSink()}
*/
public static addSink(...sinks: Array<BaseSink<LogMessage<string>>>): void {
this.instance.addSink(...sinks);
}
}
1 change: 0 additions & 1 deletion src/main.ts

This file was deleted.

4 changes: 2 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */

/* Modules */
"module": "commonjs" /* Specify what module code is generated. */,
"module": "node16" /* Specify what module code is generated. */,
// "rootDir": "./", /* Specify the root folder within your source files. */
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
Expand All @@ -41,7 +41,7 @@
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
"resolveJsonModule": true /* Enable importing .json files. */,
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */

Expand Down

0 comments on commit bafc61f

Please sign in to comment.