Skip to content

Instantly share code, notes, and snippets.

type LogMessage = (message: string | JSON) => void;
/**
* This is a defined interface for logging that closely resembles the winston logging methods. It is unlikely we will want the
* interface itself to change (ie calling static logger.info/error/debug/etc methods) but we may want to be able
* to swap out winston should we decide we want a different framework. With this we will
* not depend on exposed details of the winston interface when using our logger elsewhere in the application,
* and if we swap it out in the future it will be as simple as calling the underlying logger via the static method
* declarations
*/
class logger {
export const Retry = (count: number, waitMS: number) => {
return function repeater(
originalMethod: Function,
_context: ClassMethodDecoratorContext
) {
function ReplacementMethod(this: any, ...args: any[]) {
let tries = 0;
const attempt = () => {
tries++;
try {
import { DataAccessLayer } from "./DataAccessLayer";
import { Service } from "./Service";
import { CacheEject, CacheFlush, CacheKeys } from "./cached";
const service = new Service(new DataAccessLayer());
const id1 = service.register({ firstName: "Chris", lastName: "Bauer" });
const id2 = service.register({ firstName: "John", lastName: "Tomson" });
const id3 = service.register({ firstName: "Tom", lastName: "Johnson" });
/**
* Class method decorator for counting the number of calls
* @param originalMethod
* @param context
* @returns Decorator function
*/
export const Counter = (
originalMethod: Function,
context: ClassMethodDecoratorContext
) => {
import { DataAccessLayer } from "./DataAccessLayer";
import { Service } from "./Service";
import { CacheEject, CacheFlush, CacheKeys } from "./cached";
const service = new Service(new DataAccessLayer());
const id1 = service.register({ firstName: "Chris", lastName: "Bauer" });
const id2 = service.register({ firstName: "John", lastName: "Tomson" });
const id3 = service.register({ firstName: "Tom", lastName: "Johnson" });
/**
* Type Branding
*/
type Brand<K, T> = K & { __type: T };
/**
* CacheKey branded type
*/
export type CacheKey = Brand<string, "CacheKey">;
import { DataAccessLayer } from "./DataAccessLayer";
import { Service } from "./Service";
const service = new Service(new DataAccessLayer());
const id1 = service.register({ firstName: "Chris", lastName: "Bauer" });
const id2 = service.register({ firstName: "John", lastName: "Tomson" });
const id3 = service.register({ firstName: "Tom", lastName: "Johnson" });
console.log(service.getUserInfo(id1));
import { DataAccessLayer, User } from "./DataAccessLayer";
export class Service {
constructor(readonly dal: DataAccessLayer) {}
register(user: User) {
return this.dal.insertUser(user);
}
getUserInfo(id: number) {
import { DataAccessLayer, User } from "./DataAccessLayer";
export class Service {
constructor(readonly dal: DataAccessLayer) {}
register(user: User) {
return this.dal.insertUser(user);
}
getUserInfo(id: number) {
export interface User {
firstName: string;
lastName: string;
}
class NotFoundError extends Error {}
export class DataAccessLayer {
users: Record<number, User> = {};
findUser(id: number): User {
return this.users[id];
}