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

jap

v1.2.1

Published

JSON Action Protocol

Downloads

23

Readme

JSON Action Protocol

An idea

You may use it on server and browser side or native apps, anywhere.
This is just an idea how we can run actions of other apps from our.
J.A.P. provides you running of all actions you need in one request via json.
####Request example

{
  "user": {
    "icon": "small",
    "balance": "all",
    "properties": ["name", "age"],
    "test": false
  },
  "payment": {
    "methods": [0, 2]
  },
  "cart": {
    "count": null,
    "items": 4
  }
}

Response for the example

{
  "user": {
    "icon": {
      "success": true,
      "data": "/img/...jpg"
    },
    "balance": {
      "success": true,
      "data": {
        "cash": 420,
        "points": 13
      }
    },
    "properties": {
      "success": true,
      "data": {
        "name": "Mike",
        "age": 42
      }
    },
    "test": {
      "error": "Undeclared handler",
      "data": false
    }
  },
  "payment": {
    "methods": {
      "success": true,
      "data": [
        {"id": 7, "type": "html"},
        {"id": 12, "type": "iframe"}
      ]
    }
  },
  "cart": {
    "count": {
      "success": true,
      "data": 4
    },
    "items": {
      "error": "The item is not found",
      "data": 4
    }
  }
}

About jap function

The function helps you handle any J.A.P. request.
jap (

  1. [ primitiveHandler: json primitive | handler: function | handlerCollection: array | handlerList: object ]: parsed JSON with functions
  2. [, request: json primitive | requestCollection: array | requestList: object ]: parsed JSON
  3. [, resolve: function ]
  4. [, reject: function ]
  5. [, promises: array ]
  6. [, context: any ]

)

Resolve

If all rules are followed and handler is finished without errors then the result will go through resolve callback function. You will see all rules in this section.

jap(primitiveHandler)

primitiveHandler is any primitive value of json null, boolean, number or string.
jap with primitiveHandler always returns the handler.

jap(null) // returns {success: true, data: null}
jap(false) // returns {success: true, data: false}
jap(1) // returns {success: true, data: 1}
jap(1.1) // returns {success: true, data: 1.1}
jap('string') // returns {success: true, data: 'string'}

jap(handler)

handler is a function.
jap with handler always returns result of handler's call.

jap(() => 1) // returns {success: true, data: 1}
jap(() => {}) // returns {success: true, data: null}

jap(handler, request)

request is a parsed json from another app.
You may handle request by handler.
handler gets request as the first argument.

jap(x => x + x, 1) // returns {success: true, data: 2}
jap(x => !x, true) // returns {success: true, data: false}
jap(x => x.test, {test: 1}) // returns {success: true, data: 1}

jap(handler, requestCollection)

You may provide any count of arguments to handler by requestCollection.
requestCollection just is an array of arguments.

const sum = (x, y) => x + y

jap(sum, [1, 2]) // returns {success: true, data: 3}
jap(sum, [3, 5]) // returns {success: true, data: 8}

jap(handler, request, resolve)

Default resolve is data => ({success: true, data}).
But you can change it as you wish

const sum = (x, y) => x + y

jap(sum, [1, 2], data => data) // returns 3

You may use true if you want to set default resolve function and false if you want to return only request data

const sum = (x, y) => x + y

jap(sum, [1, 2], true) // returns {success: true, data: 3}
jap(sum, [1, 2], false) // returns 3

jap(handlerCollection, request, resolve)

You may use an array of any handlers type as handlerCollection.
Each next handler gets result of handle before.

const sum = (x, y) => x + y
const square = x => x * x

jap([sum, square], [1, 2]) // returns {success: true, data: 9}

jap(handlerList, requestList)

handlerList works only with requestList. They booth are objects.
You may see whats happen if handlerList runs without requestList here
Fields of handlerList are any handler type and fields of requestList are any request type.

const sum = (x, y) => x + y
const square = x => x * x
const math = {sum, square}

jap(math, {square: 4}, false) // returns {square: 16}
jap(math, {square: 3, sum: [3, 4]}, false) // returns {square: 9, sum: 7}

const core = {math, version: '1.0.0'}

jap(core, {math: {square: 5}}, false) // returns {math: {square: 25}}
jap(core, {math: {sum: [5, 7]}, version: null}, false) // returns {math: {sum: 12}, version: '1.0.0'}

resolve is using only for primitiveHandler or handler

const response = JSON.stringify(jap(core, {math: {sum: [5, 7]}, version: null}))

returns

{
  "math": {
    "sum": {
      "success": true,
      "data": 12
    }
  },
  "version": {
    "success": true,
    "data": "1.0.0"
  }
}

You may pass it to response and handle the response on client by jap

jap({
  math: {
    sum ({success, data}) {
      if (success) {
        console.log('set sum and update this information on the page', data)
      }
    }
  },
  version ({success, data}) {
    if (success) {
      console.log('update version and run all actions you need', data)
    }
  }
}, JSON.parse(response))

jap does not create new object, it changes requestList

all keys starts from _ or $ are private and unavailable outside

Reject

If any rules are failed or handler is finished with an error then the result will go through reject callback function. You will see all rules for that in this section.
Default reject callback function is (data, error, handler) => ({error: error.message, data}).
data is data from request
error is an instance of Error handler is a handler which threw the error

Wrong handler

If your handler is not matched with primitiveHandler, handler, handlerCollection or handlerList Then jap returns reject (null is default request)
And you get an error with message Undeclared handler

jap() // returns {error: 'Undeclared handler', data: null}
jap(undefined) // returns {error: 'Undeclared handler', data: null}
jap(Symbol()) // returns {error: 'Undeclared handler', data: null}
jap(NaN, 'test') // returns {error: 'Undeclared handler', data: 'test'}

Wrong request

If your handler is handlerList and request is not requestList then you get an error with message Undeclared request

jap({}) // returns {error: 'Undeclared request', data: null}

Wrong handlerCollection

If handlerCollection contains wrong handler then jap stops handling on wrong element and returns request or the last result of success handlerCollection's element as request

jap([1, undefined], 2, true, (data, error, handler) => ({data, error, handler}))
// returns {data: 1, error: Error('Undeclared handler'), handler: undefined}

empty handlerCollection is legal handler which goes through resolve

Promises

You may use async handlers, all promises returned the handlers will be added to the promises argument of jap

const handler = {
  test1: async e => {
      await new Promise(resolve => setTimeout(resolve, 10))
      return e
    },
  test2: async () => {
    throw Error('test')
  }
}

const promises = []

const result = jap(handler, {test1: 1, test2: 2}, true, true, promises)

// promises.length equals 2
// result.test1 is promise
// result.test1 === promises[0]

Promise.all(promises).then(() => {
  // result.test1 is {success: true, data: 1}
  // result.test2 is {error: 'test', data: 2}
})

TODO example

You may look at real example with:

git clone https://github.com/d8corp/jap.git
cd jap
npm i
npm start