@apie/pipe v2.4.2
What is @apie and @apie/pipe?
An eco-system for infrastructure around REST API. It's worth noting that it is designed so that it can be used in all applications besides a REST API.
@apie/pipe provides a way to create a pipe-function that has an event input. An event is considered a stateful object, that is passed through all functions, inspired by SvelteKits RequestEvent. This provides dependency injection and access to important information for each eventful trigger.
That means, this is useful for any serverless-functions, such as AWS lambdas etc.
createEventPipe<T> options
| Option | Description | Type |
|---|---|---|
| before? | Functions that will be run before the pipeline | MaybeArray<(event: T) => unknown> |
| after? | Functions that will be run before the pipeline(does not run if an exception is thrown) | MaybeArray<(event: T, result: unknown) => unknown> |
| finally? | Functions that will be run before the pipeline | MaybeArray<(event: T, result?: unknown, error?: unknown) => unknown> |
| catch? | A function that returns a response in relation to an error being thrown(default: throw error) | catch?(event: T, error: unknown): APIResponse |
Pipes and pipelines
A pipe a function that accepts an array functions. These functions may look like
(state: T, input: any) => any
The state/event defines requirements. An example of such a state/event is SvelteKit's RequestEvent We define the state upon creating the pipe:
import { createEventPipe } from '@apie/pipe'
type State = {
value: number
}
const pipe = createEventPipe<State>()Now each function inside the pipe will have access to State:
const pipeline = pipe(
(state) => {
console.log(state.value)
return state.value * 2
},
(state, input) => {
console.log(input)
return input * 2
}
)
const result = pipeline({ value: 2 })
// result: 2 * 2 * 2 = 8A pipeline requiring an input
For consistency, you can create functions by using your pipe with just one function
const double = pipe((state) => state.value * 2)
double({ value: 2 }) // 4If we want to multiple it by an arbitrary number, we can define the input:
const multiply = pipe((state, input: number) => state.value * input)
multiply({ value: 5 }, 2) // 10Returning Early
Our pipelines are designed around HTTP Responses. That means, if you EVER return an HTTP Response using @apie/responses, then the pipeline will exit early, resulting in that response.
import { OK } from '@apie/responses'
const fn = pipe(
() => {
return OK('Hi mom')
},
() => {
// This will never run
while(true) {}
}
)
const result = fn({ value: 2 }) // OK<'Hi mom'>Nesting Pipes
Sometimes we might want to re-use variables across multiple operations within our pipe.
In this example we use (e,v) => pipe(...) to access the variable v, within our pipe function.
const Input = z.object({...})
const $bulkWriter = createBulkWriter(...)
const pipeline = pipe(
zodValidator(Input),
(e, v) => arrayChanges(
v.existingDocuments,
v.updatedDocuments,
t => t._id?.toString()
),
(e, v) => pipe(
v.newEntries,
$bulkWriter.insertMultiple,
v.removedEntries.map(v => v._id),
$bulkWriter.updateMany(
v => ({
filter: { _id: { $in: v } },
update: { _status: 'archived' }
})
),
v.persistedEntries,
$bulkWriter.updateMultiple(
v => ({
filter: { _id: v._id },
update: { name: v.name }
})
)
),
$bulkWriter.execute()
)Re-using a result of a function
Okay, let's say you want to re-use a result, but … we can't really declare variables here, can we?
Introducing… saveResult
import { saveResult } from '@apie/pipe'
const multiply = pipe((state, input: number) => state.value * input)
const [$multiply, get$multiply] = saveResult(multiply)
const pipeline = pipe(
2,
$multiply,
(state, input: number) => {
// ...
},
// ... Functions later
(state) => OK(get$multiply(state))
)
const result = pipeline({ value: 3 }) // OK<number> -> body: 6The result is saved within the state, so by referencing the state later, we can get access to the value.
If you use $multiply again, then it returns the past result it resolved, rather than re-initializing.
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago