Skip to content

Instantly share code, notes, and snippets.

@kylejeske
Last active June 23, 2023 15:09
Show Gist options
  • Save kylejeske/d7cb2dd579b238ed7a4c5eca299aaf94 to your computer and use it in GitHub Desktop.
Save kylejeske/d7cb2dd579b238ed7a4c5eca299aaf94 to your computer and use it in GitHub Desktop.
Monad Composition to handle async ACL checks during a file upload

Monad Composition in JavaScript

Design Pattern: Inversion of control

References

  • Discrete Math
  • Decoupling Dependencies
  • Monad Transformers
  • Monad Functions
    • Closure operators on partially ordered sets

Purpose

I personally find it important to understand the background in the tools I use.

Concept

Using category theory, create a monad to execute a series of functions and yield a product without tight coupling of the fuctions.

Example

export const asyncPipe = (...fns) => x => (
  fns.reduce(async (y, f) => f(await y), x)
);

Notation Explination

/** @todo **/

/**
* asyncPipe
* @description allows for a Monad Composition, using Promises
*/
export const asyncPipe = (...fns) => x => (
fns.reduce(async (y, f) => f(await y), x)
);
import { asyncPipe } from './example-asyncPipe.js';
import { default as MockedServices } from './mocked-services.js';
/**
* UserFileUpload
* @params user
* @params folder
* @params files
* @description UserFileUpload, with internal checks (ACL) using asyncPipe
*/
export default const UserFileUpload = async (user, folder, files) => {
// go through each method, async and check and then finish with (sendFileToDiretory)
const placeUploadedFiles = asyncPipe(
MockedServices.userExists,
MockedServices.canWriteAccess,
MockedServices.canReadAccess,
MockedServices.sendFileToDirecotry
);
return await placeUploadedFiles({
user,
folder,
files
});
};
// Mock External Services
export const userExists = () => Promise.resolve({ true });
export const canWriteAccess = () => Promise.resolve({ true });
export const canReadAccess = () => Promise.resolve({ true });
export const sendFileToDirectory = () => Promise.resolve({ status: 'success' });
export default {
userExists,
canWriteAccess,
canReadAccess,
sendFileToDirectory
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment