Socket
Socket
Sign inDemoInstall

@hyperjump/browser

Package Overview
Dependencies
82
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    @hyperjump/browser

A generic hypermedia client


Version published
Weekly downloads
1.8K
increased by32.86%
Maintainers
1
Created
Weekly downloads
 

Readme

Source

Hyperjump Browser

The Hyperjump browser is an experimental generic hypermedia client. It aims to provide a uniform interface for working with hypermedia enabled media types. When you use a web browser, you don't interact with HTML, you interact with the UI that the HTML represents. The Hyperjump browser aims to do the same except with data. It abstracts away the hypermedia so you can work data as if it's just plain JSON data without having to leave the browser.

The Hyperjump browser allows you to plug in support for different media types, but it comes with support for and was initially designed for JSON Reference (JRef). The Hyperjump browser also has support for JSON, but you won't get support for the interesting things the browser supports.

Installation

npm install @hyperjump/browser --save

Contributing

Tests

Run the tests

npm test

Run the tests with a continuous test runner

npm test -- --watch

Bundlers

When using with the Rollup bundler, you will need to include the browser: true config option.

  plugins: [
    resolve({
      browser: true
    }),
    commonjs()
  ]

Usage

The following is short demo. See the API section below to see all of the things you can do.

This example uses the API at https://swapi.hyperjump.io. It's a variation of the Star Wars API (SWAPI) implemented using the JRef media type.

const Hyperjump = require("@hyperjump/browser");


const Film = {
  title: Hyperjump.pipeline([Hyperjump.get("#/title"), Hyperjump.value]),
  characters: Hyperjump.get("#/characters")
};

const Character = {
  name: Hyperjump.pipeline([Hyperjump.get("#/name"), Hyperjump.value]),
  mass: Hyperjump.pipeline([Hyperjump.get("#/mass"), Hyperjump.value]),
  gender: Hyperjump.pipeline([Hyperjump.get("#/gender"), Hyperjump.value]),
  homeworld: Hyperjump.get("#/homeworld")
};

const Planet = {
  name: Hyperjump.pipeline([Hyperjump.get("#/name"), Hyperjump.value])
}

const characterNames = Hyperjump.pipeline([
  Film.characters,
  Hyperjump.map(Character.name)
]);

const characterHomeworldName = Hyperjump.pipeline([
  Character.homeworld,
  Planet.name
])

const characterHomeworlds = Hyperjump.map(async (character) => {
  const name = await Character.name(character);
  const homeworld = await characterHomeworldName(character)

  return `${name} is from ${homeworld}`;
});

const ladies = Hyperjump.pipeline([
  Hyperjump.filter(async (character) => {
    const gender = await Character.gender(character);
    return gender === "female";
  }),
  Hyperjump.map(Character.name)
]);

const mass = Hyperjump.pipeline([
  Hyperjump.map(Character.mass),
  Hyperjump.reduce(async (acc, mass) => acc + (parseInt(mass, 10) || 0), 0)
]);

(async function () {
  const film = Hyperjump.get("https://swapi.hyperjump.io/api/films/1", Hyperjump.nil);
  const characters = Film.characters(film);

  await Film.title(film); // --> A New Hope
  await characterHomeworlds(characters); // --> [ 'Luke Skywalker is from Tatooine',
                                         // -->   'C-3PO is from Tatooine',
                                         // -->   'R2-D2 is from Naboo',
                                         // -->   ... ]
  await ladies(characters); // --> [ 'Leia Organa', 'Beru Whitesun lars' ]
  await mass(characters); // --> 1290
}());

In this example, we create functions using composition to get the data we want. The composition approach makes this code very resilient to changes. If something changes, you only have to change it in one function and all the functions that compose that function just work. The downside of this approach, however, is that it can be a bit verbose. That's why there's also the "Natural" API for the Hyperjump browser.

const Hyperjump = require("@hyperjump/browser/browser/natural");


const characterHomeworlds = Hyperjump.map(async (character) => {
  const name = await character.name;
  const homeworld = await character.homeworld.name;

  return `${name} is from ${homeworld}`;
});

const ladies = Hyperjump.pipeline([
  Hyperjump.filter(async (character) => (await character.gender) === "female"),
  Hyperjump.map((character) => character.name)
]);

const mass = Hyperjump.reduce(async (acc, character) => {
  return acc + (parseInt(await character.mass, 10) || 0);
}, 0);

(async function () {
  const film = Hyperjump.get("https://swapi.hyperjump.io/api/films/1", Hyperjump.nil);

  await film.title; // --> A New Hope
  await characterHomeworlds(film.characters); // --> [ 'Luke Skywalker is from Tatooine',
                                              // -->   'C-3PO is from Tatooine',
                                              // -->   'R2-D2 is from Naboo',
                                              // -->   ... ]
  await ladies(film.characters); // --> [ 'Leia Organa', 'Beru Whitesun lars' ]
  await mass(film.characters); // --> 1290
}());

Except for all the promises, this looks exactly like it might if you were working with a normal in-memory data structure. The "Natural" API is much more concise and readable than the standard API, but has less resiliency to change than the standard API. It also has the limitation that it is based on the JavaScript Proxy API which is not supported everywhere yet.

API

nil

Document

The nil document. This is like the blank page you see when you first open your browser.

get

(Url, Document|Promise<Document>, Options?) => Promise<Document>

Retrieve a document with respect to a context document. Options can be passed to set custom headers. If the value of the document is a link, it will be followed.

value

(Document|any) => any

The value of a document.

source

(Document) => string

The raw source of a document.

entries

(Document|Promise<Document>|any, Options) => Promise<[string, Document|any][]>

An array of key/value pairs from a document whose value is an Object.

step

(string, Document|Promise<Document>|any, Options) => Promise<Document|any>

Step into a document using the key given.

map

((Document|any, string) => T, Document|Promise<Document>|any, Options) => Promise<T[]>

A map function that works with promises and knows how to step into a document.

filter

((Document|any, string) => boolean, Document|Promise<Document>|any, Options) => Promise<(Document|any)[]>

A filter function that works with promises and knows how to step into a document.

reduce

((T, Document|any, string) => T, T, Document|Promise<Document>|any, Options) => Promise<T>

A reduce function that works with promises and knows how to step into a document.

some

((Document|any, string) => boolean, Document|Promise<Document>|any, Options) => Promise<T[]>

A some function that works with promises and knows how to step into a document.

every

((Document|any, string) => boolean, Document|Promise<Document>|any, Options) => Promise<T[]>

An every function that works with promises and knows how to step into a document.

pipeline

(Function[], Document|Promise<Document>|any) => Promise<any>

Compose an array of functions that call the next function with result of the previous function. It works with promises.

construct

(Url, Headers, string) => Document

Construct a document given a URL, headers, and body. For internal use.

extend

(Document, Object) => Document

Modify or add fields to a document. For internal use.

addContentType

(string, ContentTypeHandler) => void

Add support for a new content type. The ContentTypeHandler is an object with three functions: get, value, and step.

Keywords

FAQs

Last updated on 10 Jul 2019

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc