Git Product home page Git Product logo

promise's Introduction

promise

This is a simple implementation of Promises. It is a super set of ES6 Promises designed to have readable, performant code and to provide just the extensions that are absolutely necessary for using promises today.

For detailed tutorials on its use, see www.promisejs.org

N.B. This promise exposes internals via underscore (_) prefixed properties. If you use these, your code will break with each new release.

Build Status Rolling Versions NPM version Downloads

Installation

Server:

$ npm install promise

Client:

You can use browserify on the client, or use the pre-compiled script that acts as a polyfill.

<script src="https://www.promisejs.org/polyfills/promise-6.1.0.js"></script>

Note that the es5-shim must be loaded before this library to support browsers pre IE9.

<script src="https://cdnjs.cloudflare.com/ajax/libs/es5-shim/3.4.0/es5-shim.min.js"></script>

Usage

The example below shows how you can load the promise library (in a way that works on both client and server using node or browserify). It then demonstrates creating a promise from scratch. You simply call new Promise(fn). There is a complete specification for what is returned by this method in Promises/A+.

var Promise = require('promise');

var promise = new Promise(function (resolve, reject) {
  get('http://www.google.com', function (err, res) {
    if (err) reject(err);
    else resolve(res);
  });
});

If you need domains support, you should instead use:

var Promise = require('promise/domains');

If you are in an environment that implements setImmediate and don't want the optimisations provided by asap, you can use:

var Promise = require('promise/setimmediate');

If you only want part of the features, e.g. just a pure ES6 polyfill:

var Promise = require('promise/lib/es6-extensions');
// or require('promise/domains/es6-extensions');
// or require('promise/setimmediate/es6-extensions');

Unhandled Rejections

By default, promises silence any unhandled rejections.

You can enable logging of unhandled ReferenceErrors and TypeErrors via:

require('promise/lib/rejection-tracking').enable();

Due to the performance cost, you should only do this during development.

You can enable logging of all unhandled rejections if you need to debug an exception you think is being swallowed by promises:

require('promise/lib/rejection-tracking').enable(
  {allRejections: true}
);

Due to the high probability of false positives, I only recommend using this when debugging specific issues that you think may be being swallowed. For the preferred debugging method, see Promise#done(onFulfilled, onRejected).

rejection-tracking.enable(options) takes the following options:

  • allRejections (boolean) - track all exceptions, not just reference errors and type errors. Note that this has a high probability of resulting in false positives if your code loads data optimistically
  • whitelist (Array<ErrorConstructor>) - this defaults to [ReferenceError, TypeError] but you can override it with your own list of error constructors to track.
  • onUnhandled(id, error) and onHandled(id, error) - you can use these to provide your own customised display for errors. Note that if possible you should indicate that the error was a false positive if onHandled is called. onHandled is only called if onUnhandled has already been called.

To reduce the chance of false-positives there is a delay of up to 2 seconds before errors are logged. This means that if you attach an error handler within 2 seconds, it won't be logged as a false positive. ReferenceErrors and TypeErrors are only subject to a 100ms delay due to the higher likelihood that the error is due to programmer error.

API

Detailed API reference docs are available at https://www.promisejs.org/api/.

Before all examples, you will need:

var Promise = require('promise');

new Promise(resolver)

This creates and returns a new promise. resolver must be a function. The resolver function is passed two arguments:

  1. resolve should be called with a single argument. If it is called with a non-promise value then the promise is fulfilled with that value. If it is called with a promise (A) then the returned promise takes on the state of that new promise (A).
  2. reject should be called with a single argument. The returned promise will be rejected with that argument.

Static Functions

These methods are invoked by calling Promise.methodName.

Promise.resolve(value)

(deprecated aliases: Promise.from(value), Promise.cast(value))

Converts values and foreign promises into Promises/A+ promises. If you pass it a value then it returns a Promise for that value. If you pass it something that is close to a promise (such as a jQuery attempt at a promise) it returns a Promise that takes on the state of value (rejected or fulfilled).

Promise.reject(value)

Returns a rejected promise with the given value.

Promise.all(array)

Returns a promise for an array. If it is called with a single argument that Array.isArray then this returns a promise for a copy of that array with any promises replaced by their fulfilled values. e.g.

Promise.all([Promise.resolve('a'), 'b', Promise.resolve('c')])
  .then(function (res) {
    assert(res[0] === 'a')
    assert(res[1] === 'b')
    assert(res[2] === 'c')
  })

Promise.any(array)

Returns a single promise that fulfills as soon as any of the promises in the iterable fulfills, with the value of the fulfilled promise. If no promises in the iterable fulfill (if all of the given promises are rejected), then the returned promise is rejected with an AggregateError

var rejected = Promise.reject(0);
var first = new Promise(function (resolve){ setTimeout(resolve, 100, 'quick') });
var second = new Promise(function (resolve){ setTimeout(resolve, 500, 'slow') });

var promises = [rejected, first, second];

Promise.any(promises) // => succeeds with `quick`

Promise.allSettled(array)

Returns a promise that resolves after all of the given promises have either fulfilled or rejected, with an array of objects that each describes the outcome of each promise.

Promise.allSettled([Promise.resolve('a'), Promise.reject('error'), Promise.resolve('c')])
  .then(function (res) {
    res[0] // { status: "fulfilled", value: 'a' }
    res[1] // { status: "rejected", reason: 'error' }
    res[2] // { status: "fulfilled", value: 'c' }
  })

Promise.race(array)

Returns a promise that resolves or rejects with the result of the first promise to resolve/reject, e.g.

var rejected = Promise.reject(new Error('Whatever'));
var fulfilled = new Promise(function (resolve) {
  setTimeout(() => resolve('success'), 500);
});

var race = Promise.race([rejected, fulfilled]);
// => immediately rejected with `new Error('Whatever')`

var success = Promise.resolve('immediate success');
var first = Promise.race([success, fulfilled]);
// => immediately succeeds with `immediate success`

Promise.denodeify(fn)

Non Standard

Takes a function which accepts a node style callback and returns a new function that returns a promise instead.

e.g.

var fs = require('fs')

var read = Promise.denodeify(fs.readFile)
var write = Promise.denodeify(fs.writeFile)

var p = read('foo.json', 'utf8')
  .then(function (str) {
    return write('foo.json', JSON.stringify(JSON.parse(str), null, '  '), 'utf8')
  })

Promise.nodeify(fn)

Non Standard

The twin to denodeify is useful when you want to export an API that can be used by people who haven't learnt about the brilliance of promises yet.

module.exports = Promise.nodeify(awesomeAPI)
function awesomeAPI(a, b) {
  return download(a, b)
}

If the last argument passed to module.exports is a function, then it will be treated like a node.js callback and not parsed on to the child function, otherwise the API will just return a promise.

Prototype Methods

These methods are invoked on a promise instance by calling myPromise.methodName

Promise#then(onFulfilled, onRejected)

This method follows the Promises/A+ spec. It explains things very clearly so I recommend you read it.

Either onFulfilled or onRejected will be called and they will not be called more than once. They will be passed a single argument and will always be called asynchronously (in the next turn of the event loop).

If the promise is fulfilled then onFulfilled is called. If the promise is rejected then onRejected is called.

The call to .then also returns a promise. If the handler that is called returns a promise, the promise returned by .then takes on the state of that returned promise. If the handler that is called returns a value that is not a promise, the promise returned by .then will be fulfilled with that value. If the handler that is called throws an exception then the promise returned by .then is rejected with that exception.

Promise#catch(onRejected)

Sugar for Promise#then(null, onRejected), to mirror catch in synchronous code.

Promise#done(onFulfilled, onRejected)

Non Standard

The same semantics as .then except that it does not return a promise and any exceptions are re-thrown so that they can be logged (crashing the application in non-browser environments)

Promise#nodeify(callback)

Non Standard

If callback is null or undefined it just returns this. If callback is a function it is called with rejection reason as the first argument and result as the second argument (as per the node.js convention).

This lets you write API functions that look like:

function awesomeAPI(foo, bar, callback) {
  return internalAPI(foo, bar)
    .then(parseResult)
    .then(null, retryErrors)
    .nodeify(callback)
}

People who use typical node.js style callbacks will be able to just pass a callback and get the expected behavior. The enlightened people can not pass a callback and will get awesome promises.

Enterprise Support

Available as part of the Tidelift Subscription

The maintainers of promise and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. Learn more.

License

MIT

promise's People

Contributors

artskydj avatar calvinmetcalf avatar cbargren avatar chrissrogers avatar cpojer avatar debopamsengupta avatar denis-sokolov avatar denisx avatar domenic avatar edef1c avatar eyesonly88 avatar forbeslindesay avatar georules avatar henryqdineen avatar jackmoore avatar johntron avatar ljharb avatar maxkorp avatar mjethani avatar mkows avatar motiz88 avatar nhducit avatar nhunzaker avatar patrickjs avatar rangermauve avatar retyui avatar ryuever avatar tarqd avatar tehshrike avatar tootallnate avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

promise's Issues

Bare bones Promises/A+ implementation

This is just not true, you should separate the pure spec implementation in one project and your custom .done, denodify etc. methods into another.

Its just weird to learn your code and then to recognize .done is actually not in spec and not in native implementations. This should be much more clear.

denodeify runs with undefined this

var O = function() {
  this.test = 'hi';
};

O.prototype.aFunction = function() {
  this.test = 'bye';
};

var o = new O();
Promise.denodeify(o.aFunction)();

The promise fails with this being undefined. It does work however using call and specifying this yourself:

Promise.denodeify(o.aFunction).call(o);

To my knowledge there wouldn't be a way of working out what this is supposed to be but maybe the API could be a bit nicer by accepting an optional parameter that would be used as this.

Promise.denodeify(o, o.aFunction)();

Happy to submit a pull req with a fix if you agree with the proposed solution. Otherwise it'd good to update the docs to point out this potential issue as it'll probably catch out a lot of people using this to wrap third party functions.

Latest changes

Among other things, I've switched to using @kriskowal's ASAP as a replacement for our basic next-tick implementation. Running the benchmarks before and after gives:

before and after

In particular, the last 2 tests, which are the most realistic tests anyway, see enormous improvement. then.promise is now the fastest for the resolve-sequence, and back very much in the game for the resolved-sequence.

Using in ES6 environment

I'm interested in using this library purely for the superset features. I have an ES6 environment running with Traceur, so I do not need the polyfill.

I notice the extensions are in a separate module but they extend the polyfill’d Promise object. In my case, this object has already been polyfill’d and is available at global.Promise.

Should I be able to apply these extensions to my existing Promise object?

How to handle Throw e at asap/asap.js:45

Hello everyone im new using promises and Promise and i was trying to implement some stuff according to the documentation, but im getting this output in console.

localpath\myprojectI\node_modules\promise\node_modules\asap\asap.js:45
throw e;                      ^
[object Object]

When im trying to run this code:

Following the documentation i did this, that maybe is totally wrong:

var getRequest = function(url){
    return new Promise(function(resolve, reject){
        request(url, function(e, res, body){
            if(e){
                reject(e);
            }else{
                if(res.statusCode == 200) resolve(body);
                else reject({error: true, errorStatusCode: res.statusCode});
            }
        });
    });
};

var info = function(user){
    var url = 'http://someweb.com/api/';
    return new Promise(function(resolve, reject){
        getRequest(url.concat(user)).done(function(res){
            try{
                resolve(res);
            }catch(ex){
                reject(ex);
            }
        }, reject);
    }); 
};

info('erick').done(function(res){
    console.log(res);
});

It works perfect when the res.statusCode == 200 is true, but when for example the statusCode is 404 it shows in console just :

localpath\myprojectI\node_modules\promise\node_modules\asap\asap.js:45
throw e;                      ^
[object Object]

And i dont know what to do next. I know this could be basic but im new using promises.

Thank you for advance,

License

Could you add an explicit license file with the full text rather than just saying it's MIT?

Default THEN?

It's more of a question, because I don't quite understand the logic of the code below:

promise.resolve()
    .then(function () {
        console.log('then-1');
    })
    .then(function () {
        console.log('then-2');
    })
    .then(function () {
        console.log('then-3');
    });

produces the following output:

then-1
then-2
then-3

as opposed to:

then-1

I mean, we do not resolve anything pass the first then function, so why do we still get into every then that follows? Please explain, 'cos I feel dumb right now :)

use with mysql

Hi, tell me how it is used in conjunction with https://www.npmjs.com/package/mysql
I need a method to back results

    var tasks = null;
    tasks = GetTasks();
//....
function GetTasks() {
    return new Promise(function (resolve, reject) {
        connection.query('SELECT * FROM tasks', function (err, rows) {
            if (err)
                reject(err);
            else
                resolve(rows);              
        });
    });
}

resprom2

Release 6.0.0 breaks Component support

Using component with the latest release raises an error at runtime.

Uncaught Error: Failed to require "./lib/core.js" from "then-promise/index.js"

Version of component used was 0.19.9 in case that matters.

alternative for Q.delay and Q.finally

I want to rewrite a library which using Q. I need it for the browser and using component, so I want to replace kriskowal/q with then/promise.

The code I want to rewrite uses Q.delay() and Q.finally(), do you know how I can rewrite it?

Avoid Array.isArray in Promise.all

The one usage in Promise.all makes this library incompatible with ie8 - but only if called with an array of promises; it works fine if called with an argument list of promises.

Chaining doesn't work properly

function run() {
    a().then(b).then(c);
}

function a() {
    return new Promise(function (resolve) {
        console.log('a()');

        setTimeout(function () {
            console.log('a resolved');
            resolve();
        }, 100);
    });
}

function b() {
    return new Promise(function (resolve) {
        console.log('b()');

        setTimeout(function () {
            console.log('b resolved');
            resolve();
        }, 100);
    });
}
function c() {
    return new Promise(function (resolve) {
        console.log('c()');

        setTimeout(function () {
            console.log('c resolved');
            resolve();
        }, 100);
    });
}

output:
a()
a resolved
b()
c()
b resolved
c resolved

expected output:
a()
a resolved
b()
b resolved
c()
c resolved

finally()

You are still missing finally() in your library. Any plans to finally add it? :)

Please see the following discussion that's very relevant to this issue: tildeio/rsvp.js#373 (comment)

Promise.all doesn't support multiple arguments

The usage in document

Promise.all(Promise.resolve('a'), 'b', Promise.resolve('c'))
  .then(function (res) {
    assert(res[0] === 'a')
    assert(res[1] === 'b')
    assert(res[2] === 'c')
  })

is actually not supported, according to source code of /lib/es6-extensions.js.
As ES6 only support Promise.all(iterable) usage, maybe it's README file which should be updated.

Example code cause lint error

Promise is part of the ES6 proposal, this is why the following code cause an error, when esnext is enabled in jshint config:

var Promise = require('promise');
^ Redefinition of 'Promise'.

Maybe you should change example codes, to avoid future problems/confusion.

promise.any()

I've been using promise in my every project, including this one: pg-promise, until I ran into the necessity of using promise.any() logic in my test cases, so I had to use Bluebird for testing, while keeping Promise for the production, which is awkward.

And now that I find I need promise.any in more than one case, it is becoming unfortunate that I have to move to Bluebird completely.

Please, add promise.any, it is a very important promise function!

Making the Promise object easily extendable with a simple `.use` function

For example if we had a get module

module.exports = function get(promise, name) {
   return promise.then(function(value){
         return value[name]
   })
}

Now that function works fine as a standalone that we can use with any valid promise like so

var get = require('then/get')

get(somePromiseObject, 'foo').then(doSomethingWithFoo)

What I'd like to see is a use function that works like this:

var get = require('then/get')
var Promise = require('then/promise')

Promise.use('get', get)
new Promise(someResolver).get('foo').then(doSomethingWithFoo)

I'm a fan of this because it gives me the option of extending promises in my own applications, but still having access to all those great functions if I wanted to use them in a library and wanted to avoid extending the prototype

Maybe something along these lines

// maybe allow name to be optional and use fn.name by default
Promise.use = function(name, fn) {
  Promise.prototype[name] = function() {
        fn.apply(this, arguments)
  }
}

Promise.prototype.use = function(name, fn) {
// make the extension usable in this promise chain only
}

Act as polyfill

We may want to consider using native promises when available in the near future. We would still need to provide Promise.prototype.done and the node.js extensions though.

We would have two options:

  1. Extend the built-in Promise constructor when available and export that, export our custom implementation otherwise.
  2. Inherit from the built in Promise constructor when available, inherit from /lib/core.js otherwise.

We also have a few options when there is no built in promise constructor:

  1. Define Promise globally (in addition to exporting it). Effectively making this library a true polyfill but with some extensions.
  2. Define Promise globally, but only add our special extensions to a copy that inherits from the globally defined Promse.
  3. Continue as we are at the moment.

Doesn't implement §2.3.3.3 of A+ Promises spec

I ran the latest tests from the A+ test suite. It reports 60 failures, but they're all the same thing: Not implementing §2.3.3.3 of the promise resolution procedure.

Here's the test I used, in case I have an error in the adapter: https://gist.github.com/tjcrowder/8912323

I also tried a simplified test case, which did seem to confirm the result: https://gist.github.com/tjcrowder/8912340 With that, I get the message saying we're resolving, but no calls to the then method.

event loop starving with promise 4.0

Hello,
I upgraded to promise 4.0. This new version (with node.js) uses asapto async the resolution instead of the previous next-tick.js.

  • asap => nextTick
  • next-tick.js => setImmediate

I hit a problem of a starving event loop leading to the asap(task) never called in my server, in relation to node-sqlite3.

you can check TryGhost/node-sqlite3#184 (comment) for more information on where this comes from.

The problem does not appear when using setImmediate (reverting to promise 3.2).

I am trying to gather information as to how the problem should be fixed. Any idea will be welcome.

Have denodeify() support multiple response parameters?

I was currently about to wrap the request module with denodeify(), but the request() returns two parameters in its response and denodeify() only forwards the first parameter – therefore it doesn't work.

Is there a reason for denodeify() to only return the first parameter? I think it could resolve the promise with them all in array if it finds that there are more than one response parameter.

That would make these two equal:

function callback (err, param1, param2) {
};
denodeify().then(function (result) {
  var param1 = result[0]
    , param2 = result[1];
});

Does Promise.from works correctly?

Promise.from(1).then(Promise.from(2)).then(Promise.from(3)).then(console.log); gives 1.

Is that by design?

I had impression it should resolve to last .then as 3.

needed shim, IE8 support

I love then/promise and wants to use it in a JavaScript REST API client I am working on.

I need to support IE8 and was wondering what parts of es5-shim were really needed for then/promise?

Do you think we could make it old-browsers compatible with IE8 with little changes? Thanks

Chaining promises in version 7+

I'm trying to just do a simple chaining of promises, by first pushing promises to an array and then do Promise.all(array).then(function(results) { console.log(results); }). This used to work just fine in v6.x, but since upgrading to the latest version, it fails.

At the essence, what seems to differ from before is:

console.log(new Promise(function (resolve, reject) {
  resolve();
}));

Previously this would log: { then: [Function] }

Now on version 7.0.1, this results in: { _32: 0, _8: null, _89: [] }

Did I miss a change in API or am I messing things up? :)

Enable `Promise.all` to take an object.

Would it be possible to make Promise.All to take an object of promises and return a new one.

Here is almost the same example as in the doc.

Promise
    .all({
        a: Promise.resolve('a'),
        b: 'b',
        c: Promise.resolve('c')
    })
    .then(function (res) {
        assert(res.a === 'a')
        assert(res.b === 'b')
        assert(res.c === 'c')
    })

if thenable throws an error

According to the Promises/A+ spec, http://promises-aplus.github.io/promises-spec/#point-60

If evaluating then produces an error, the promise must be rejected with the error (e). But when an error is thrown inside of then(), the error is lost because it calls reject(e), which calls _reject(e) which doesn't do anything. The error is lost to the world, at this point.

Ex:

do.something = new Promise(function(resolve, reject) {
    resolve(val);
});

do.something.then(function(result) {
    // Do something that causes an error
    // ...
}, function(reason) {
    console.log(reason);   // I was hoping this would be called...
});

The problem is that the error which is thrown is lost. How can I capture that error and handle it appropriately without having to put the code inside its own try/catch.

denodeify breaks callback functionality

While writing a library to automatically wrap Node core methods to return promises, I came across this bug:

var Promise = require("promise");
var readFile = Promise.denodeify(require("fs").readFile);

// The callback here will never be called.
readFile("/etc/passwd", function(err, contents) {));

While this may be by design, and the method name alludes to, this is highly undesired behavior. I would expect that the intended behavior is to simply return a valid Promise and not break existing functionality.

Test and patch forthcoming.

Add changelog

I can't find a changelog and I don't know if I should worry about changes from v5 to v6 since you upped the major version?

Promise synchronous polling

I was wondering if I could change Promise to support something like bluebird's synchronous inspection. This would allow the user to inspect a promise to see if it's resolved and would not let them modify any internal values.

Originally I was going to do this as an extension but I think that'd I'd have to modify the lib/core.js file to really support this. I'd be willing to write this myself, it wouldn't be difficult.

Supported browsers

The readme doesn't mention which browsers this library supports. Does it support IE9? What about IE8? What about obsolete IE (IE 6 + 7)? Old Safari? Mobile browsers?

Promise.timer to create promise to complete within input timeout parameter

Just curious if it is feasible to define static method Promise.timer similar to Promise.all. It aims to create a promise of input promise to fulfill the promise within input timeout parameter in millisecond.

Promise.timer = (p, ms = env.promise.timeout) ->
    return new Promise (fulfill, reject) ->
        task = null 
        success = (result) ->
            clearTimeout task
            fulfill(result)
        error = ->
            reject 'timeout to complete the task'
        task = setTimeout error, ms
        p.then success, reject

Errors are suppressed

Here's an example which confuses me.

var Promise = require('promise');
new Promise(function(res, rej) {
    console.log(broken.invalid.imaginary);
});

When run this script exits without error and status 0

Intended behaviour? Perhaps I'm missing something?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.