From f1d473c2f3b8512bf42ab1928f5cf2755eb00ab0 Mon Sep 17 00:00:00 2001 From: Nicolas Froidure Date: Wed, 20 Apr 2022 16:52:24 +0200 Subject: [PATCH] refactor(api): remove handlers types --- API.md | 61 -------------------------- ARCHITECTURE.md | 12 +++--- README.md | 65 ---------------------------- src/index.ts | 6 --- src/util.test.ts | 86 ------------------------------------- src/util.ts | 108 ----------------------------------------------- 6 files changed, 6 insertions(+), 332 deletions(-) diff --git a/API.md b/API.md index a95bbeb..ca3cb26 100644 --- a/API.md +++ b/API.md @@ -32,12 +32,6 @@ builder by automatically detecting its name and dependencies

-
handler(handlerFunction, [name], [dependencies], [options])function
-

Shortcut to create an initializer with a simple handler

-
-
autoHandler(handlerFunction)function
-

Allows to create an initializer with a simple handler automagically

-
parseDependencyDeclaration(dependencyDeclaration)Object

Explode a dependency declaration an returns its parts.

@@ -352,61 +346,6 @@ Decorator that creates an initializer from a provider | --- | --- | --- | | providerBuilder | function | An async function to build the service provider | - - -## handler(handlerFunction, [name], [dependencies], [options]) ⇒ function -Shortcut to create an initializer with a simple handler - -**Kind**: global function -**Returns**: function - Returns a new initializer - -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| handlerFunction | function | | The handler function | -| [name] | String | | The name of the handler. Default to the DI prop if exists | -| [dependencies] | Array.<String> | [] | The dependencies to inject in it | -| [options] | Object | | Options attached to the built initializer | - -**Example** -```js -import Knifecycle, { handler } from 'knifecycle'; - -new Knifecycle() -.register(handler(getUser, 'getUser', ['db', '?log'])); - -const QUERY = `SELECT * FROM users WHERE id=$1` -async function getUser({ db }, userId) { - const [row] = await db.query(QUERY, userId); - - return row; -} -``` - - -## autoHandler(handlerFunction) ⇒ function -Allows to create an initializer with a simple handler automagically - -**Kind**: global function -**Returns**: function - Returns a new initializer - -| Param | Type | Description | -| --- | --- | --- | -| handlerFunction | function | The handler function | - -**Example** -```js -import Knifecycle, { autoHandler } from 'knifecycle'; - -new Knifecycle() -.register(autoHandler(getUser)); - -const QUERY = `SELECT * FROM users WHERE id=$1` -async function getUser({ db }, userId) { - const [row] = await db.query(QUERY, userId); - - return row; -} -``` ## parseDependencyDeclaration(dependencyDeclaration) ⇒ Object diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index cdbda08..83e3b75 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -37,7 +37,7 @@ It is designed to have a low footprint on services code. In fact, the Knifecycle API is aimed to allow to statically build its services load/unload code once in production. -[See in context](./src/index.ts#L201-L220) +[See in context](./src/index.ts#L197-L216) @@ -52,7 +52,7 @@ A service provider is full of state since its concern is [encapsulate](https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)) your application global states. -[See in context](./src/index.ts#L222-L231) +[See in context](./src/index.ts#L218-L227) @@ -92,7 +92,7 @@ The `?` flag indicates an optional dependency. It allows to write generic services with fixed dependencies and remap their name at injection time. -[See in context](./src/util.ts#L1304-L1313) +[See in context](./src/util.ts#L1196-L1205) @@ -121,7 +121,7 @@ Initializers can be of three types: instanciated once for all for each executions silos using them (we will cover this topic later on). -[See in context](./src/index.ts#L311-L335) +[See in context](./src/index.ts#L307-L331) @@ -137,7 +137,7 @@ Depending on your application design, you could run it in only one execution silo or into several ones according to the isolation level your wish to reach. -[See in context](./src/index.ts#L644-L654) +[See in context](./src/index.ts#L640-L650) @@ -173,5 +173,5 @@ Sadly TypeScript does not allow to add generic types For more details, see: https://stackoverflow.com/questions/64948037/generics-type-loss-while-infering/64950184#64950184 -[See in context](./src/util.ts#L1374-L1385) +[See in context](./src/util.ts#L1266-L1277) diff --git a/README.md b/README.md index f00a688..c3fd034 100644 --- a/README.md +++ b/README.md @@ -455,12 +455,6 @@ is maybe the best feature of this library 😉. builder by automatically detecting its name and dependencies

-
handler(handlerFunction, [name], [dependencies], [options])function
-

Shortcut to create an initializer with a simple handler

-
-
autoHandler(handlerFunction)function
-

Allows to create an initializer with a simple handler automagically

-
parseDependencyDeclaration(dependencyDeclaration)Object

Explode a dependency declaration an returns its parts.

@@ -813,65 +807,6 @@ detecting its name and dependencies | --------------- | --------------------- | ----------------------------------------------- | | providerBuilder | function | An async function to build the service provider | - - -## handler(handlerFunction, [name], [dependencies], [options]) ⇒ function - -Shortcut to create an initializer with a simple handler - -**Kind**: global function -**Returns**: function - Returns a new initializer - -| Param | Type | Default | Description | -| --------------- | --------------------------------- | --------------- | --------------------------------------------------------- | -| handlerFunction | function | | The handler function | -| [name] | String | | The name of the handler. Default to the DI prop if exists | -| [dependencies] | Array.<String> | [] | The dependencies to inject in it | -| [options] | Object | | Options attached to the built initializer | - -**Example** - -```js -import Knifecycle, { handler } from 'knifecycle'; - -new Knifecycle().register(handler(getUser, 'getUser', ['db', '?log'])); - -const QUERY = `SELECT * FROM users WHERE id=$1`; -async function getUser({ db }, userId) { - const [row] = await db.query(QUERY, userId); - - return row; -} -``` - - - -## autoHandler(handlerFunction) ⇒ function - -Allows to create an initializer with a simple handler automagically - -**Kind**: global function -**Returns**: function - Returns a new initializer - -| Param | Type | Description | -| --------------- | --------------------- | -------------------- | -| handlerFunction | function | The handler function | - -**Example** - -```js -import Knifecycle, { autoHandler } from 'knifecycle'; - -new Knifecycle().register(autoHandler(getUser)); - -const QUERY = `SELECT * FROM users WHERE id=$1`; -async function getUser({ db }, userId) { - const [row] = await db.query(QUERY, userId); - - return row; -} -``` - ## parseDependencyDeclaration(dependencyDeclaration) ⇒ Object diff --git a/src/index.ts b/src/index.ts index c6de224..3b89332 100644 --- a/src/index.ts +++ b/src/index.ts @@ -29,8 +29,6 @@ import { provider, autoProvider, wrapInitializer, - handler, - autoHandler, parseDependencyDeclaration, stringifyDependencyDeclaration, unwrapInitializerProperties, @@ -66,7 +64,6 @@ import type { Initializer, ServiceInitializerWrapper, ProviderInitializerWrapper, - HandlerFunction, Parameters, } from './util.js'; import type { BuildInitializer } from './build.js'; @@ -98,7 +95,6 @@ export type { Initializer, ServiceInitializerWrapper, ProviderInitializerWrapper, - HandlerFunction, Parameters, BuildInitializer, FatalErrorService, @@ -1302,8 +1298,6 @@ export { autoService, provider, autoProvider, - handler, - autoHandler, parseDependencyDeclaration, stringifyDependencyDeclaration, unwrapInitializerProperties, diff --git a/src/util.test.ts b/src/util.test.ts index e6f3eba..6230dc2 100644 --- a/src/util.test.ts +++ b/src/util.test.ts @@ -24,8 +24,6 @@ import { autoService, provider, autoProvider, - handler, - autoHandler, SPECIAL_PROPS, } from './util.js'; import type { Provider } from './util.js'; @@ -890,90 +888,6 @@ describe('autoProvider', () => { }); }); -describe('handler', () => { - test('should work', async () => { - const baseName = 'sampleHandler'; - const injectedServices = ['kikooo', 'lol']; - const services = { - kikooo: 'kikooo', - lol: 'lol', - }; - const theInitializer = handler(sampleHandler, baseName, injectedServices); - - assert.deepEqual((theInitializer as any).$name, baseName); - assert.deepEqual((theInitializer as any).$inject, injectedServices); - - const theHandler = await theInitializer(services); - const result = await theHandler('test'); - assert.deepEqual(result, { - deps: services, - args: ['test'], - }); - - async function sampleHandler(deps, ...args) { - return { deps, args }; - } - }); - - test('should fail with no name', () => { - assert.throws(() => { - handler(async () => undefined); - }, /E_NO_HANDLER_NAME/); - }); -}); - -describe('autoHandler', () => { - test('should work', async () => { - const services = { - kikooo: 'kikooo', - lol: 'lol', - }; - const theInitializer = autoHandler(sampleHandler); - - assert.deepEqual((theInitializer as any).$name, sampleHandler.name); - assert.deepEqual((theInitializer as any).$inject, ['kikooo', 'lol']); - - const theHandler = await theInitializer(services); - const result = await theHandler('test'); - assert.deepEqual(result, { - deps: services, - args: ['test'], - }); - - async function sampleHandler({ kikooo, lol }, ...args) { - return { deps: { kikooo, lol }, args }; - } - }); - - test('should work with spread services', async () => { - const services = { - kikooo: 'kikooo', - lol: 'lol', - }; - const theInitializer = autoHandler(sampleHandler); - - assert.deepEqual((theInitializer as any).$name, sampleHandler.name); - assert.deepEqual((theInitializer as any).$inject, ['kikooo', 'lol']); - - const theHandler = await theInitializer(services); - const result = await theHandler('test'); - assert.deepEqual(result, { - deps: services, - args: ['test'], - }); - - async function sampleHandler({ kikooo, lol, ...services }, ...args) { - return { deps: { kikooo, lol, ...services }, args }; - } - }); - - test('should fail for anonymous functions', () => { - assert.throws(() => { - autoHandler(async () => undefined); - }, /E_AUTO_NAMING_FAILURE/); - }); -}); - describe('parseDependencyDeclaration', () => { test('should work', () => { assert.deepEqual(parseDependencyDeclaration('db>pgsql'), { diff --git a/src/util.ts b/src/util.ts index 20b1653..2b643f9 100644 --- a/src/util.ts +++ b/src/util.ts @@ -146,15 +146,6 @@ export type ProviderInitializerWrapper< > = (dependencies: D, baseService: Provider) => Promise>; export type Parameters = { [name: string]: V }; -export type HandlerFunction< - D extends Dependencies, - V, - P extends Parameters, - U extends any[], - R, -> = - | ((dependencies: D, parameters: P, ...args: U) => Promise) - | ((dependencies: D, parameters?: P, ...args: U) => Promise); export const SPECIAL_PROPS_PREFIX = '$'; export const SPECIAL_PROPS = { @@ -1202,105 +1193,6 @@ export function initializer, S>( return uniqueInitializer as ServiceInitializer; } -/** - * Shortcut to create an initializer with a simple handler - * @param {Function} handlerFunction - * The handler function - * @param {String} [name] - * The name of the handler. Default to the DI prop if exists - * @param {Array} [dependencies=[]] - * The dependencies to inject in it - * @param {Object} [options] - * Options attached to the built initializer - * @return {Function} - * Returns a new initializer - * @example - * import Knifecycle, { handler } from 'knifecycle'; - * - * new Knifecycle() - * .register(handler(getUser, 'getUser', ['db', '?log'])); - * - * const QUERY = `SELECT * FROM users WHERE id=$1` - * async function getUser({ db }, userId) { - * const [row] = await db.query(QUERY, userId); - * - * return row; - * } - */ -export function handler< - D extends Dependencies, - V, - P extends Parameters, - U extends unknown[], - R, ->( - handlerFunction: HandlerFunction, - name?: ServiceName, - dependencies?: DependencyDeclaration[], - singleton?: boolean, - extra?: ExtraInformations, -): ServiceInitializer Promise> { - name = name || handlerFunction[SPECIAL_PROPS.NAME]; - dependencies = dependencies || handlerFunction[SPECIAL_PROPS.INJECT] || []; - - if (!name) { - throw new YError('E_NO_HANDLER_NAME', handlerFunction); - } - - return initializer( - { - name, - type: 'service', - inject: dependencies, - singleton, - extra, - }, - async (dependencies: D) => handlerFunction.bind(null, dependencies), - ); -} - -/** - * Allows to create an initializer with a simple handler automagically - * @param {Function} handlerFunction - * The handler function - * @return {Function} - * Returns a new initializer - * @example - * import Knifecycle, { autoHandler } from 'knifecycle'; - * - * new Knifecycle() - * .register(autoHandler(getUser)); - * - * const QUERY = `SELECT * FROM users WHERE id=$1` - * async function getUser({ db }, userId) { - * const [row] = await db.query(QUERY, userId); - * - * return row; - * } - */ -export function autoHandler< - D extends Dependencies, - V, - P extends Parameters, - U extends unknown[], - R, ->( - handlerFunction: HandlerFunction, -): ServiceInitializer Promise> { - const name = readFunctionName(handlerFunction); - const source = handlerFunction.toString(); - const dependencies = parseInjections(source); - - return initializer( - { - name, - type: 'service', - inject: dependencies, - }, - async (dependencies: D) => handlerFunction.bind(null, dependencies), - ); -} - /* Architecture Note #1.2.1: Dependencies declaration syntax The dependencies syntax is of the following form: