npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

airsync

v2.0.6

Published

⚡ Streamline your code by replacing multiple `await` calls with a single `await` using ༄AirSync, and fully leverage the power of asynchronous, non-blocking I/O.

Downloads

8

Readme

Getting Started

Installation

npm i airsync -S
# or
yarn add airsync

Import

You can use any of these methods to use airsync in your application

// using modules
import { convertFn, resolve } from "airsync";

// or using package
import airsync from "airsync";

// using require

const { convertFn, resolve } = require("airsync");

const airsync = require("airsync");

Introduction

AirSync is a powerful javascript library that you can use when using async.

The easiest way to see the power of this library is to checkout performance.js file.

AirSync helps you:

  • Create JSON from promises without extracting functions or multiple await
  • Convert your existing functions that take promises as parameters, you do not need to wait for promises to fulfil in order to pass them to the function. You can just pass them in as is.

The best part is that AirSync makes your code readable while using full power of non-blocking event based I/O that Node.js is known for.

1. JSON

Problem

const calcAge = async () => 65; // note the async

// this will not result in correct `age`
const props = {
  age: calcAge(),
}

// output:
// {age: Promise}
// Promise {<fulfilled>: undefined}

Existing Solution

Either you can write await for each one of the promises, like:

const props = {
  age: await calcAge(),
}

Problems with this solution

  • This is going to blow out very soon, meaning, as you introduce new calls or fields in this JSON, it will become very unreadable
  • The biggest problem with this is performance. This is becoming blocking calls as we are going to await for the results from functions

AirSync Solution

You can use AirSync to solve this issue

const { resolve } = require("airsync");

const props = resolve({
  age: calcAge(),
})

Spread Operator

Problem

Lets say you have a code

const encodeKey = async () => {
  return { keyId: 123 }
}

and you want to create JSON like:

{
  keyId: 123
}

the following WILL NOT create desired result

const result = await resolve({
  keyId: encodeKey(),
})

what about this?

const result = await resolve({
  ...encodeKey(),
})

This is also not going to work because encodeKey() is an async function.

Existing Solution

We have a solution

const result = await resolve({
  ...await encodeKey(),
})

Problems with this solution

All of a sudden, our code has to wait for encodeKey to finish, and if the JSON being produced is long with a lot of await like this, this is going to be very slow.

AirSync Solution

Luckily, we have spread()

const { spread, resolve } = require('airsync');

const result = await resolve({
  [spread()]: encodeKey(),
})

This will result in correct JSON + this code will run asynchronously no matter how many objects are "spreaded".

Try it on RunKit

Max depth

Default object depth supported by airsync is 64.

2. Async Function

Problem

const getAge = async () => 123;
const getDetail = async (age) => `The age is ${age}`;
await getDetail(getAge());

// output:
// The age is [object Promise]
// Promise {<fulfilled>: undefined}

Existing Solution

Either you can wait for the getAge() to be resolved first and then pass it to getDetail() like this:

await getDetail(await getAge());

or you can extract out it to variable.

Problems with this solution

  • This is going to blow out very soon, meaning, as you introduce new calls, it will become very unreadable
  • The biggest problem with this is performance. This is becoming blocking calls as we are going to await for the results from functions

AirSync Solution

const { convertFn } = require("airsync");
// or you can import using 
// const airsync = require('airsync') 
// and use airsync.convertFn(...)

const getAge = async () => 123;
const getDetail = convertFn(async (age) => `The age is ${age}`); // notice the wrap around "convertFn"

const result = await getDetail(getAge());

Try it on RunKit

Misc Features

Options

If the first parameter is an object for the convertFn(), that object is used for setting up the options.

For example:

const getNumb = convertFn(() => 123, {
  startTime: res.startTime,
  endTime: res.endTime,
});

You can also override the options for a crafted function later.

getNumb.setOptions({
  // hint: server-timing
  startTime: res.startTime,
  endTime: res.endTime,

  name: "getNumb",
  description: "Get number",

  debug: false, // to enable airsync debugging
});

Following are the possible options

| Option | Description | | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | name | An identity for the function. Defaults to <function>.name - IT MUST NOT CONTAIN SPACE | | description | A description for the function | | startTime | Function for server timing - (name, description) => {} - the name and description is passed back to this function | | endTime | Function for server timing - (name) => {} - the name is passed back to this function | | debug | Boolean value to tell airsync whether debug logging is enabled or not. It will use a global logger.debug() object. If no such object exists, it will use console.debug() |

Bulk Export (Advanced)

Converting existing exports to crafted functions is easy, either using convertFn for each function which can be cumbersome depending on number of functions; or you can simply convert the whole object using a helper function exportFns.

Let's say you have:

const function1 = () => {};
const function2 = () => {};

module.exports = {
  function1,
  function2,
};

Just use exportFns when exporting

const { exportFns } = require("airsync");

const function1 = () => {};
const function2 = () => {};

module.exports = exportFns({
  function1,
  function2,
});

Alternatively, you can do it when importing like in example of /examples/resolve.js. Doing it multiple times does not harm.

Get Object Value

If you have a function that returns an object, and you want to grab just one specific value from the object, you can use following get function to do that.

This function used to be part of library. Since 1.0.4, the get() function is removed (see CHANGELOG). However, if you need it, you can add it as utility in your project.

const { get } = require('airsync/get');

This function has peer dependency of lodash.get


const getProfile = async (uid) => ({
  name: "John",
  age: 45,
  father: {
    name: "Peter",
  },
});

(async () => {
  console.log(await get(getProfile(), "father.name")); // output: Peter
  console.log(await get(getProfile(), "mother.name", "Steph")); // output: Steph
  console.log(await get(getProfile(), "brother.name")); // output: undefined
})();

License

Copyright (c) 2020-present @abumq (Majid Q.)

https://github.com/abumq/airsync

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.