@apie/pipe
TypeScript icon, indicating that this package has built-in type declarations

2.4.2 • Public • Published

@apie/pipe NPM Package

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 = 8


A 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 }) // 4

If 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) // 10


Returning 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: 6

The 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.

Package Sidebar

Install

npm i @apie/pipe

Weekly Downloads

41

Version

2.4.2

License

MIT

Unpacked Size

46.1 kB

Total Files

11

Last publish

Collaborators

  • refzlund