Skip to content

Commit

Permalink
feat: extend concept to add application pre and action
Browse files Browse the repository at this point in the history
  • Loading branch information
kamaz committed Jun 12, 2020
1 parent f6fae7f commit 510350d
Show file tree
Hide file tree
Showing 13 changed files with 411 additions and 53 deletions.
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"typescript.tsdk": "node_modules/typescript/lib"
}
13 changes: 0 additions & 13 deletions packages/sls-app/babel.config.js

This file was deleted.

5 changes: 5 additions & 0 deletions packages/sls-app/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
setupFilesAfterEnv: ['jest-extended']
}
9 changes: 8 additions & 1 deletion packages/sls-app/package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
{
"name": "sls-app",
"name": "@cabiri-io/sls-app",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"test": "jest"
},
"devDependencies": {
"@types/jest": "^26.0.0",
"jest": "^26.0.1",
"jest-extended": "^0.11.5",
"ts-jest": "^26.1.0",
"typescript": "^3.9.5"
}
}
8 changes: 0 additions & 8 deletions packages/sls-app/src/index.test.ts

This file was deleted.

25 changes: 17 additions & 8 deletions packages/sls-app/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
type ActionFunction<P, D, R> = (payload: P, dependencies: D) => R

// configuration I want to be able to debug invocation
type Application<P, D, R> = {
pre(actionContextFunction: ActionContextFunction<P, D>): Application<P, D, R>
action(): Application<P, D, R>
action(actionFunction: ActionFunction<P, D, R>): Application<P, D, R> | never
post(): Application<P, D, R>
run(payload: P, dependencies: D): Promise<R>
}
Expand All @@ -18,35 +20,42 @@ type PreAction<P, D> = {
// maybe we have type
}

export class ApplicationError extends Error {
public type: string = 'ApplicationError'
}

// allow to configure the application e.g. log each entry
export function Application<P, D, R>(): Application<P, D, R> {
export function application<P, D, R>(): Application<P, D, R> {
// maybe instead of using array we an explore using Task concept and
// and instead we can just compose function

const preActions: Array<PreAction<P, D>> = []
let mainAction: ActionFunction<P, D, R>
return {
pre(actionFunction) {
// allow to push logger
preActions.push({ func: actionFunction })
return this
},
action() {

action(actionFunction) {
//@ts-ignore
if (mainAction) throw new ApplicationError('you can only have a single action')
mainAction = actionFunction
return this
},

post() {
return this
},

run(payload, dependencies) {
return (
preActions
// we work with promises because this allows us easy capture all the async stuff
.reduce((acc, v) => acc.then(r => (v.func(r), r)), Promise.resolve({ payload, dependencies }))
.then
// do action now will work with pre
()
.then
// do post actions
()
.then(({ payload, dependencies }) => mainAction(payload, dependencies))
)
}
}
Expand Down
60 changes: 60 additions & 0 deletions packages/sls-app/tests/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { application, ApplicationError } from '../src'

describe('application flow', () => {
describe('action', () => {
it('creates an application with an action only', () =>
application<string, { appendString: string }, string>()
.action((payload, { appendString }) => `${payload} ${appendString}`)
.run('hello', { appendString: 'world' })
.then(result => {
expect(result).toBe('hello world')
}))

it('throws an error when multiple actions are created', () =>
expect(() =>
application<string, { appendString: string }, string>()
.action((payload, { appendString }) => `${payload} ${appendString}`)
.action((payload, { appendString }) => `${payload} ${appendString}`)
.run('hello', { appendString: 'world' })
).toThrowError(new ApplicationError('you can only have a single action')))
})

describe('pre action', () => {
it('execute pre action before main action', async () => {
const preAction = jest.fn()
const action = jest.fn()

return application<string, { appendString: string }, void>()
.pre(preAction)
.action(action)
.run('hello', { appendString: 'world' })
.then(() => {
expect(preAction).toHaveBeenCalledWith({ payload: 'hello', dependencies: { appendString: 'world' } })
expect(action).toHaveBeenCalledWith('hello', { appendString: 'world' })
//@ts-ignore
expect(preAction).toHaveBeenCalledBefore(action)
})
})

it('executes pre actions in order of definition', async () => {
const preAction1 = jest.fn()
const preAction2 = jest.fn()
const action = jest.fn()

return application<string, { appendString: string }, void>()
.pre(preAction1)
.pre(preAction2)
.action(action)
.run('hello', { appendString: 'world' })
.then(() => {
expect(preAction1).toHaveBeenCalledWith({ payload: 'hello', dependencies: { appendString: 'world' } })
expect(preAction2).toHaveBeenCalledWith({ payload: 'hello', dependencies: { appendString: 'world' } })
expect(action).toHaveBeenCalledWith('hello', { appendString: 'world' })
//@ts-ignore
expect(preAction1).toHaveBeenCalledBefore(preAction2)
//@ts-ignore
expect(preAction2).toHaveBeenCalledBefore(action)
})
})
})
})
2 changes: 1 addition & 1 deletion packages/sls-app/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
"outDir": "./dist",
"declaration": true
},
"include": ["src/**/*"],
"include": ["src/**/*", "tests/**/*"],
"exclude": ["dist/**/*"]
}
5 changes: 5 additions & 0 deletions packages/sls-env/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
setupFilesAfterEnv: ['jest-extended']
}
16 changes: 16 additions & 0 deletions packages/sls-env/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "@cabiri-io/sls-env",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"test": "jest"
},
"devDependencies": {
"@types/jest": "^26.0.0",
"jest": "^26.0.1",
"jest-extended": "^0.11.5",
"ts-jest": "^26.1.0",
"typescript": "^3.9.5"
}
}
1 change: 1 addition & 0 deletions packages/sls-env/tests/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
describe('serverless environment', () => {})
9 changes: 9 additions & 0 deletions packages/sls-env/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"declaration": true
},
"include": ["src/**/*", "tests/**/*"],
"exclude": ["dist/**/*"]
}
Loading

0 comments on commit 510350d

Please sign in to comment.