Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

metaory/pcall.js

Open more actions menu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

187 Commits
187 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

logo-of-pcall

Ƥ𝖢𐤠LL.ᴊꜱ

Result/Monad like tuples for JS

unwrap promises safely with minimum footprint

── ╶╴╶╴╶╴╶╴╶╴╶╴╶╴ ──

📦 Extremely Small

🧬 Lifecycle Hooks

🎯 Concise Signature

💠 Group Side Effects

try/catch HELL 👹

🌟 Better Visibility and Control

🌐 Works in ESM & CJS

✱ Minimal Obsessive Disorder



Inspiration

pcall.js is heavily inspired by

🔹 Lua pcall status, res

🔹 Elixir/Erlang Result Monad {:ok/:error, reason/value}

🔹 Rust Result<T, E>

🔹 Go []error

with superpowers 🦄!


SYNOPSIS

pcall({f}, {arg1}, {...})

[err, res]

pcall() Calls function {f} with the given arguments in protected mode.

This means that any error inside {f} is not propagated;

Instead, pcall catches the error and returns a tuple.

Its first element is the err object,

Which is null if the call succeeds without errors.

And all results from the call, on second element; [null, {res}]


Usage

# install
npm install pcall.js
// ESM
import Pcall from 'pcall.js'

// CJS
const Pcall = require('pcall.js')
const [err, res] = await Pcall(asyncFn, a, b, c, /* ··· */)
const pcall = new Pcall({
  onSuccess: console.log,
  onFailure: console.error,
  onFinally: console.info,
  timeout: 30_000,
  transformOnSuccess: (res) => res,
  transformOnFailure: (err) => err,
  noTrace: false
})
const [err, res] = await pcall(asyncFn, a, b, c, /* ··· */)
:Fulfill [null, res]
:Reject  [err, null]

Convert

import { readFile } from 'node:fs/promises'

// 🔻 BEFORE
try {
  const res = await readFile('./package.json', { encoding: 'utf8' })
} catch(error) {
  console.error(error, '🔥')
}

// ─────────────────
// 🔹AFTER
import Pcall from 'pcall.js'
const [err, res] = await Pcall(readFile, './package.json', { encoding: 'utf8' })

// 🔸THROW
err && throw new Error("XYZZY", { cause: err });

// ─────────────────
// 🔸 MOCK
// const readJson = new Pcall({
//   fn: readFile,
//   args: [{ encoding: 'utf8' }],
//   transformOnSuccess: (res) => JSON.parse(res),
//   transformOnFailure: (err) => err.message,
// })
// const path = 'test/sample-good.json'
//
// const res = await readJson(path)
// log(res.hogo) // fuga

Options

import { readFile } from 'node:fs/promises'
import Pcall from 'pcall.js'

const pcall = new Pcall({
  onSuccess: console.log,
  onFailure: console.error,
  onFinally: (args, func, span) => { /* 💣 💣 💥 */ },
  transformOnSuccess: (res) => res,
  transformOnFailure: (err) => err,
  timeout: 30_000,
  noTrace: false,
})

const path = './package.json'
const opts = { encoding: 'utf8' }

const [err, res] = await pcall(readFile, path, opts)

💡 Check test/ files for more examples


Development

# run test playground in watch mode
npm run dev

# build production
npm run build

# build stub
npm run build:stub

TODO

  • 🌀 Lifecycle Hooks
  • [.] 🔌 Serializer
  • [.] 🧬 Parser
  • [.] 📜 JSDoc
  • [.] 🔧 ESLint
  • [o] 📖 Docs
  • [o] ⚠️ Tests
  • [o] 💡 Examples

License

MIT

About

Minimal Result/Monad library inspired by Lua pcall, Elixir Result, and Rust Result with lifecycle hooks and zero dependencies

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Used by

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.