A minimal, yet flexible I/O for browser and Node with promises. A thin wrapper on top of XMLHttpRequest, and fetch(), with numerous callbacks to simplify and automate all aspects of I/O especially using JSON as an envelope, including to add more transports, and I/O orchestration plugin services.
It can run on Node using a specialized transport: heya-io-node. It greatly simplifies I/O on Node by leveraging enhanced features of heya-io
in the server environment.
The following services are included:
io.cache
— a transparent application-level cache (supports sessionStorage and localStorage out of the box).io.bundle
— a transparent service to bundle requests into one package passing it to a server, and unbundling a result. It requires a simple server counterpart. heya-bundler is a reference implementation for node.js/express.js.io.track
— a simple plugin to track I/O requests to eliminate duplicates, register an interest without initiating I/O requests, and much more.io.mock
— a way to mock I/O requests without writing a special server courtesy of Mike Wilcox. Very useful for rapid prototyping and writing tests.io.bust
— a simple plugin to generate a randomized query value to bust browser's cache.io.retry
— a plugin to retry unreliable services or watch changes over time.
The following additional transports are provided:
io.fetch()
— replacesXHR
withfetch()
-based transport.io.jsonp()
— JSON-P requests.io.load()
— generates<script>
tags to include JavaScript files.
Utilities:
url()
— uses ES6 tagged literals to form properly sanitized URLs.
As is heya-io
uses the standard Promise.
Given that not all browsers provide it, heya-io
can be used with any then-able, but it was especially tested with implementations provided by heya-async:
FastDeferred and Deferred.
With those modules an extended API is supported: I/O progress reports, and cancellation of I/O requests.
Plain vanilla GET:
heya.io.get('http://example.com/hello').then(function (value) {
console.log(value);
});
heya.io.get('/hello', {to: 'world', times: 5}).then(function (value) {
// GET /hello?to=world×=5
console.log(value);
});
POST a form (can include files or any other form elements):
var formElement = document.querySelector('form');
heya.io.post('/form', new FormData(formElement));
Some other verbs (REST example):
function done() { console.log('done'); }
heya.io.post('/things', {name: 'Bob', age: 42}).then(done);
heya.io.put('/things/5', {name: 'Alice', age: 33}).then(done);
heya.io.patch('/things/7', {age: 14}).then(done);
heya.io.remove('/things/3').then(done);
Modern browsers:
const doIO = async query => {
const result = await heya.io.get('/hello', {q: query});
await heya.io.post('/things', {name: 'Bob', age: 42, friendly: result});
}
Other transports:
// let's make a JSON-P call:
heya.io.jsonp('/planets', {query: 'name'}).then(function (values) {
// GET /planets?query=name
console.log('We have ' + values.length + ' planets:', values);
});
Mock:
// set up a mock handler
heya.io.mock('/a*', function (options, prep) {
console.log('Got call: ' + options.method + ' ' + prep.url);
return 42;
});
// let's make a call
heya.io.get('/a/x').then(function (value) {
console.log(value); // 42
});
// set up a redirect /b => /a/b
heya.io.mock('/b', function (options) {
return heya.io.get('/a/b', options.query || options.data || null);
});
// let's make another call
heya.io.get('/b', {q: 1}).then(function (value) {
console.log(value); // 42
});
Using url
template to sanitize URLs (ES6):
const client = 'Bob & Jordan & Co';
heya.io.get(url`/api/${client}/details`).then(function (value) {
// GET /api/Bob%20%26%20Jordan%20%26%20Co/details
console.log(value);
});
See more examples in the cookbooks:
- Cookbook: main
- Services:
- Transports:
With npm:
npm install --save heya-io
With bower:
bower install --save heya-io
heya-io
can be installed with npm
or bower
with files available from node_modules/
or bower_components/
. By default, it uses AMD:
define(['heya-io'], function (io) {
io.get('/hello').then(function (value) {
console.log(value);
});
});
But it can be loaded with <script>
tag from dist/
:
<script src='node_modules/heya-io/dist/io.js'></script>
And used with globals like in examples above:
heya.io.get('/hello').then(function (value) {
console.log(value);
});
To support browsers without the standard Promise
, you may want to use heya-async.
AMD:
define(['heya-io', 'heya-async/FastDeferred'], function (io, Deferred) {
// instrument
io.Deferred = Deferred;
// now we are ready for all browsers
io.get('/hello').then(function (value) {
console.log(value);
});
});
Globals:
<script src='node_modules/heya-io/dist/io.js'></script>
<script src='node_modules/heya-async/dist/Micro.js'></script>
<script src='node_modules/heya-async/dist/FastDeferred.js'></script>
// instrument
heya.io.Deferred = heya.async.FastDeferred;
// now we are ready for all browsers
heya.io.get('/hello').then(function (value) {
console.log(value);
});
See How to include for more details.
All documentation can be found in project's wiki.
In order to run tests in a browser of your choice, so you can debug interactively, start the test server:
npm start
Then open this URL in a browser: http://localhost:3000/tests/tests.html It will show a blank screen, but the output will appear in the console of your developer tools.
The server runs indefinitely, and can be stopped by Ctrl+C.
- 1.9.3 Refreshed dev dependencies.
- 1.9.2 Switched
retry
to the UMD loader so it can be used in Node directly. - 1.9.1 Minor improvements of the
retry
service. - 1.9.0 Bugfixes and refactoring in the
retry
service. - 1.8.0 Added
retry
service. Thx Jason Vanderslice! - 1.7.1 Refreshed dev dependencies.
- 1.7.0 Added
AbortRequest
. - 1.6.2 Added separate
options.onDownloadProgress()
andoptions.onUploadProgress()
. - 1.6.1 Added extra properties to progress data.
- 1.6.0 Added
options.onProgress()
and tests on Firefox Puppeteer. - 1.5.0 Added cache removal by a function.
- 1.4.2 Added
ignoreBadStatus
flag whenreturnXHR
. - 1.4.1 Technical release. No changes.
- 1.4.0 Added mocks by regular expressions and matcher functions.
- 1.3.0 Added cache removal by regular expressions and wildcards.
- 1.2.6 Bugfixes:
getHeaders()
behaves like on Node, empty object queries are supported. - 1.2.5 Exposed
io.getData(xhr)
andio.getHeaders(xhr)
. - 1.2.4 Relaxed cache's detection of Result().
- 1.2.3 Regenerated dist.
- 1.2.2 Moved tests to Puppeteer, bugfixes, improved docs.
- 1.2.1 Added Ignore type for data processors, bugfixes.
- 1.2.0 Clarified DELETE, added more well-known types.
- 1.1.7 Refreshed dependencies.
- 1.1.6 Bugfix:
processFailure
could be skipped. - 1.1.5 Bugfix: MIME processors. Thx Bryan Pease!
- 1.1.4 Added custom data and MIME processors.
- 1.1.3 Formalized requests and responses with no bodies.
- 1.1.2 Minor fixes for non-browser environments. New alias and verb.
- 1.1.1 Added
url
tagged literals (an ES6 feature). - 1.1.0 Added fetch() as an alternative default transport.
- 1.0.9 Correcting typos in README. New version of a test server.
- 1.0.8 Add a helper for busting browser cache.
- 1.0.7 Regenerated dist.
- 1.0.6 Added a helper to extract data from XHR in case of errors.
- 1.0.5 XHR can be reinstated from a JSON object, not just a string.
- 1.0.4 Regenerated dist.
- 1.0.3 Bugfix: cache XHR object directly.
- 1.0.2 Fixed formatting errors in README.
- 1.0.1 Improved documentation.
- 1.0.0 The initial public release as heya-io. Sunset of heya-request. Move from bitbucket.
BSD or AFL — your choice.