Giter Site home page Giter Site logo

react-resolver's Introduction

React Resolver https://img.shields.io/npm/v/react-resolver.svg

Async-rendering & data-fetching for universal React applications.

React Resolver lets you define data requirements per-component and will handle the nested, async rendering on both the server & client for you.

For example, the following will load & provide this.props.user for the UserProfile component:

import { resolve } from "react-resolver";

@resolve("user", function(props) {
  return http.get(`/api/users/${props.params.userId}`);
})
class UserProfile extends React.Component {
  render() {
    const { user } = this.props;
    ...
  }
}

This is the equivalent to asynchronously loading user and providing it to the component as if it were provided directly:

<UserProfile user={user} />

This makes components pure, stateless, and easy to test as a result.


Installation

For environments that don't have native Promise support, install ES6 Promise.

$ npm install --save react-resolver

For React v0.13 support, install v2.x.x.

$ npm install --save react-resolver@2

Documentation

Complete documentation can be found here:

http://ericclemmons.github.io/react-resolver/


Development

If you'd like to contribute to this project, all you need to do is clone this project and run:

$ npm install
$ npm test

Internet Systems Consortium license

Copyright (c) 2015 Eric Clemmons

Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Collaboration

If you have questions or issues, please open an issue!

react-resolver's People

Contributors

adri avatar bioball avatar daniel15 avatar didi0613 avatar ericclemmons avatar frederickfogerty avatar goatslacker avatar iamdustan avatar jabher avatar jasonphillips avatar lucasperso avatar monder avatar ratson avatar srph avatar tripss avatar waldyrious 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

react-resolver's Issues

Share Props between Components

You know what, I'm an opinionated guy, so here comes an opinion!

Sharing based off of key (e.g. user) is not smart by default, because there's no guarantee both components are referencing the same thing.

var JoeComponent = React.createClass({
  statics: {
    resolve: {
      user: function() {
        return UserService.findByName('Joe');
      }
    }
  }
  ...
});

var MoeComponent = React.createClass({
  statics: {
    resolve: {
      user: function() {
        return UserService.findByName('Moe');
      }
    }
  }
  ...
});

Perhaps the user can explicitly opt-in to certain keys to avoid the mess that is context...

Suppose a top level AppHandler can share the following:

flux: function() {
  return new Alt();
},

propTypes: {
  flux: React.PropTypes.object.isRequired
}

Then any any component that wants to utilize this can use a custom PropType:

http://facebook.github.io/react/docs/reusable-components.html

propTypes: {
  flux: Resolver.PropTypes.shared.isRequired
}

This feels very similar to context, now that I write it.... :)

Idea: Provide a dependency-less build

I believe there is value in keeping bluebird, however if you're running in an ES6-shimmed environment then you already having promises support making bluebird redundant. It would be great to provide a build that has no dependencies this way you get a minimal react-resolver.

why markup different on server and client

any pointers as to how I could debug this?

Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:
(client) <noscript data-reacti
(server) <div data-reactid=".1

Symbol is not defined

@goatslacker Didn't you stop using Symbol in Alt? What was the reason behind that again?

It works pretty well with anything using the Babel Polyfill, but with ES5 users in mind, should I just drop it & use local constants instead?

Aborting promise

Anybody have ideas how to abort the promise from route A from resolving when I transition to route B while the promise hasn't been resolved yet?

To further illustrate this (I find my explanation a bit confusing), given that this is the normal flow:
transition to route A -> run route A promise -> [waiting.. do anything ] -> resolve

And if I try to go to route B, I expect:
transition to route A -> run route A promise -> go to route B -> abort route A promise -> run route B promise

What happens is:
transition to route A -> run route A promise -> go to route B -> [route A promise may resolve here] run route B promise -> [route A promise may resolve here] resolve route B promise.

route A's promise should be aborted like Angular. Any thoughts in this? Thanks.

Resolver exists twice with Browserify

Everything looks fine to me

// app.js
import {Resolver} from "react-resolver";

window.router = ReactRouter.create({
  routes: routes,
  location: HistoryLocation
});

window.router.run((Handler, state) => {
  Resolver.render(<Handler/>, document.getElementById("main")));
});

// home.js
class Home extends React.Component {
  static displayName = "Home"

  render() {
    return <div>Home</div>;
  }
}

export default Resolver.createContainer(Home, {
  resolve: {}
});

Getting Resolver is not defined in either context or props. (Perhaps missing a root <Container resolver={new Resolver()} />?)

React: 0.13.1
React-Resolver: 0.1.1

Examples need a build step

Both examples is missing a client.min.js build and express handling of requests to this file.

... or am I missing somthing?

A callback interface

Promises are nice but I like flexibility, can we have a react-resolver core and then we choose whether we want promises, callbacks, generators, thunks, or whatever emerges next.

Routes break after clicking first link

I have an issue where the client side routes break after navigating to a single link. From then on the path changes in the address bar but nothing gets updated on the screen. All the Handlers are returning standard React components without wrapping with Resolvers.

package.json

    "react": "0.13.3",
    "react-router": "0.13.3",
    "react-resolver": "^2.0.4",
    "react-router-server-location": "^2.0.0",

Routes.js

    <Route path="/" handler={Main}>
        <DefaultRoute handler={Home} />
        <Route name="signin" path="/signin" handler={Signin}/>
        <Route name="signup" path="/signup" handler={Signup}/>
        <Route name="forgot_password" path="/users/password" handler={ForgotPassword}/>
        <Route name="reset_password" path="/users/password/edit" handler={ResetPassword}/>
        <Route name="account" path="/account/profile" handler={AccountNavigation}>
            <DefaultRoute name="account_profile" handler={AccountProfile} />
            <Route name="account_settings" path="/account/settings" handler={AccountSettings} />
        </Route>
    </Route>

client.js

Router.run(routes, Router.HistoryLocation, (Root) => {
    Resolver.render(() => <Root />, document.getElementById("react-root"));
});

Add hooks for props, pre-resolve, post-resolve, and rejected

I'd love to know when all props have resolved or rejected so I can hook into this and add some nice alt support for caching resolver data.

Example API:

@resolve({
  props: {
    users(props) {
      const url = `https://api.github.com/repos/${props.user}/${props.repo}/stargazers`;
      return axios.get(url).then(response => response.data);
    },
  },

  onResolved(props) {
    AltActions.resolved(props);
  },

  onRejected(props) {
    AltActions.failed(props);
  }
}

Async streaming data updates (eg Flux)

Since react-resolver uses promise wrappers around callbacks, it may have a problem with wiring up with Flux stores that have callbacks that could be called multiple times with data.

I have a Flux library Hoverboard that works with subscribing to a callback function. As changes come through the store via user actions, the data updates asynchronously. This works well with solve (I built them to work together in a Flux framework).

Put more simply, react-resolver may need to be modified to work with the following code:

statics: {
    resolve: {
        count: function(done) {
            var count = 1;
            setInterval(function(){
                done(count++);
            }, 1000);
        }
    }
}

Thoughts?

Support for custom renderers

Because Resolver.render has an hard dependency on React.render it cannot be used with (for example) react-titanium or react-blessed.

An initial thought is to transform

class Resolver {
  static render(element, node, instance = new Resolver()) {
    React.render((
      <Container resolver={instance}>
        {element}
      </Container>
    ), node);

    return instance;
  }
}

to

class Resolver {
  static wrap(element, instance = new Resolver()) {
    return (
      <Container resolver={instance}>
        {element}
      </Container>
    );
  }
  static render(element, node, instance = new Resolver()) {
    React.render(Resolver.wrap(element, instance), node);

    return instance;
  }
}

so that I can use it with my renderer, such as

import { render } from 'react-titanium';
import { wrap } from 'react-resolver';

class App extends Component { /*...*/ }

render(wrap(<App />));

Cannot resolve 'file' or 'directory' ./Resolver

Module not found: Cannot resolve 'file' or 'directory' ./Resolver in <path/to/dist>

I just switched to Ubuntu Server 14.04. I just checked /dist/, and it doesn't seem to have the Resolver.js file, but only resolver.js

React Transmit

Though this project (which started internally @ work) was made public a couple months before @RickWong's react-transmit's initial commit, Transmit's comparison to Relay, React Native support, and continued development looks like it may have superseded this project.

Our goals are similar, although with v1 I dropped the comparisons to Relay, since lack of GraphQL made the comparison to Relay tenuous at best, in my opinion. Really, this project's goals were always to support isomorphic lazy-loading of data, primarily for work.

I've continued development of this project internally, since a major relaunch @ work greatly depends on this (there's even a sibling Flux implementation that gets around dispatcher issues), but I'm curious if it's best to let @RickWong's project be endorsed rather than risk fragmentation, stagnation of this project, or competing over the same problems.

I've tagged @RickWong several times, mainly to get his feedback :)

Not all Promises are created equal

Currently the Resolver tests that a @resolve Promise is instanceof Promise. Promises seem to be a bit fickle in that there are many different implementations and ways to get a global Promise object.

A few possibilities:

The question is should we expect one global Promise object or provide a duckpunch to interop with the different methods?

Alternatively, we could ignore Promises and use a callback which the consumer is responsible for calling in whatever async control flow implementation they should choose.

React Native support

I havenโ€™t peaked behind the covers of react-native too much yet so I have no idea on the effort involved. Is this something youโ€™d be interested in this project supporting?

Issue with nested routes (React Router 1.0)

I'm using React Router v1.0.3.


I'm trying this kind of route hierarchy:

-/ (top-level)
--/ (home page)
--/about (about page)
--/friends (/friends route top-level, fetching of friends)
----/ (friends index; /friends)
----/list (friends list; /friends/list)

(to code)

      <Route path="friends" component={Friends}>
        <Route path="/" component={FriendsIndex} />
        <Route path="list" component={FriendsList} />
      </Route>

Where I am putting the Resolver container on the friends top-level component (Friends).

Here's the stack trace:

Uncaught (in promise) TypeError: Cannot read property 'ref' of undefined
    at cloneWithProps (http://localhost:1111/bundle.js:20673:13)
    at Friends.render (http://localhost:1111/bundle.js:23549:49)
    at ReactCompositeComponentMixin._renderValidatedComponentWithoutOwnerOrContext (http://localhost:1111/bundle.js:10462:34)
    at ReactCompositeComponentMixin._renderValidatedComponent (http://localhost:1111/bundle.js:10489:14)
    at ReactPerf.measure.wrapper (http://localhost:1111/bundle.js:16948:21)
    at ReactCompositeComponentMixin.mountComponent (http://localhost:1111/bundle.js:9910:30)
    at ReactPerf.measure.wrapper [as mountComponent] (http://localhost:1111/bundle.js:16948:21)
    at Object.ReactReconciler.mountComponent (http://localhost:1111/bundle.js:17763:35)
    at ReactCompositeComponentMixin._updateRenderedComponent (http://localhost:1111/bundle.js:10437:40)
    at ReactCompositeComponentMixin._performComponentUpdate (http://localhost:1111/bundle.js:10399:10)

Check this repo http://srph.github.io/rrt/#/friends (now https://github.com/srph/playground/tree/master/react/react-resolver-prop-bug)

Not sure what I'm doing wrong haha.

Edit (8/27/2014): Repository transferred to https://github.com/srph/playground/tree/master/react/react-resolver-prop-bug (link to demo)

passing normal props with create container

link and linkName are just normal non async props. - is there/could there be a better way to pass them than..

export var YoAlt = Resolver.createContainer(InnerComponent, {
  resolve: {
    linkName:()=>"APPPPPP",
    link:()=>'app1',  
    list: (props, context)=> 
     new Promise(
        resolve=>
          setTimeout(
            (()=>
              resolve(new List([{id:0,content:"ahhhh"}]))
              ),
            1000)
        )
  }
});

for example maybe

export var YoAlt = Resolver.createContainer(InnerComponent, {
  props:{
    linkName:'APPPPP',
    link:'app1'
  },
  resolve: {
     list: (props, context)=> 
     new Promise(
        resolve=>
          setTimeout(
            (()=>
              resolve(new List([{id:0,content:"ahhhh"}]))
              ),
            1000)
        )
  }
});

Nested containers

I'm in bed right now, but the gist is that I need to ensure nested resolvers (like those in the form project) get re-resolved when the parent does.

render called twice on server

I've been noticing an issue where the componentWillMount/render methods inside my root component get called twice when rendering on the server. Attached below are some code snippets from the important parts.

Routes.js

    <Route path="/" handler={Main}>
        <DefaultRoute handler={Home} />
        <Route name="signin" path="/signin" handler={Signin}/>
        <Route name="signup" path="/signup" handler={Signup}/>
        <Route name="forgot_password" path="/users/password" handler={ForgotPassword}/>
        <Route name="reset_password" path="/users/password/edit" handler={ResetPassword}/>
        <Route name="account" path="/account/profile" handler={AccountNavigation}>
            <DefaultRoute name="account_profile" handler={AccountProfile} />
            <Route name="account_settings" path="/account/settings" handler={AccountSettings} />
        </Route>
    </Route>

server.js

const location = new ServerLocation({ request, reply });
    Router.create({ location, routes }).run(function(Handler, state) {
        Resolver.resolve(() => <Handler {...state} />).then(({Resolved, data}) => {
            reply(`
                <!DOCTYPE html>
                <html lang="en-us">
                    <head>
                                                ...
                    </head>
                    <body>
                        <div id="react-root">${React.renderToString(<Resolved />)}</div>
                        <script src="${webserver}/dist/client.js" async defer></script>
                    </body>
                </html>
            `);
        }).catch((error) => reply(error.stack).type("text/plain").code(500)); // Just in case!
    });

Main.js

...
    componentWillMount () {
        if (__SERVER__) {
            console.log("Hello server");
        }

        if (__CLIENT__) {
            console.log("Hello client");
        }
    }
...

logs

[1] ==> โœ…  Server is listening
[1] ==> ๐ŸŒŽ  Go to http://0.0.0.0:8000
[1] onPreResponse
[1] Hello server
[1] Hello server

Is anyone else seeing this issue? The issue goes away when I remove the react-resolver from the equation.

Idea: remove lodash dependency

In an effort to reduce library size and dependencies lodash is a good candidate for removal.

You can get away with using ES5 for most of your lodash uses, for the rest perhaps you can include the lodash single function from npm.

Bootstrap client-side data

  • Need to expose resolver.states for serialization and output on the server.
  • Client needs to bootstrap new Resolver(window.__resolver__) or something .

Publish @loading component

(So that other users can take advantage of this)

  • Provides the following props:
    • Boolean(loaded)
    • Array(promises)
  • Used via @loading(MyLoader)

How does this fit in with flux?

My impression is that 'isomorphic' flux implementations tend to associate data fetching requirements with the router which imo is the wrong place - they should be associated with components - so I can change the set of components displayed on a route - or indeed in an app without routing and the data requirements change.

Whereas react-resolver is associating data requirements with the components. My question is (if this makes sense) can the two be combined to make a flux architecture which recursively loads data on the serer and client ar react-resolver does + data requirements are defined by components themselves. I think this is what https://www.npmjs.com/package/react-nexus might be but I didn't get it to work.

What I am thinking is that the promises configured by the resolve parameter could trigger actions and wait for store results something like:

Resolver.createContainer(InnerComponent, { 
    resolve:
        {
            data:async (props,context)=>{
                await context.flux.getActions("data-action").goGetData(props.id);
                return context.flux.getStore("data-store").getData();
            }
        }
  }

I am also thinking you could have isomorphic forms...

Resolver.createContainer(InnerComponent, { 
    resolve:
        {
            data:async (props,context)=>{
                await context.flux.getActions("data-action").goPostData(props.id);
                return context.flux.getStore("data-store").getAcknowledgement();
             }
        }
  }

Use statics and decorators

Somehow, this is preferable:

@resolve
class SomeComponent extends React.Component {
  static resolve = {
    user() => {
    }
  };
}

Nested promises in server rendering

I'm running into a problem with server rendering that may simply reflect a misunderstanding of the server capabilities of Resolver.renderToString.

My project uses react-router and has nested Resolver containers, so that /category/[x] might use a container to fetch a list of items under category x, and then /category/[x]/item/[y] would fetch a particular item in full detail, and so on with further nesting. All of this runs smoothly on the client.

When server rendering with Resolver.renderToString, it appears only to work through one level of Resolver containers; subsequent containers that create promises down the tree after the first one resolves will end up giving me a variant on this error:

Resolver is frozen for server rendering. 
ResolverContainer (#.0.0.0) should have already resolved "item". 

Is there a strategy that can be used for this scenario, forcing Resolver to wait for all promises and resolutions down the tree before freezing itself? Or should I be approaching it from a different angle?

Decorators

Pretty neat.

@resolve
class SomeComponent extends React.Component {
  static resolve = {
    user() => {
    }
  };
}

Error handling with async resolution

Hey awesome to be collaborating. react-resolver and solve have a different syntax for callbacks, so we should consider which syntax to use.

solve doesn't use node-style callbacks (function(error, data)). My thinking here is that if data is being resolved as an object or arrays etc., then only a single value can be emitted from an async resolution, so the callback only takes a single argument. So error handling has to be somehow resolved into the props object.

One option might be to have multiple types on a single data point, eg.

{ 
    value: function(done) {
       request.get('/api/data', function(error, result) {
            if (error) {
                return done(new Error("Failed to load"));
            }
            return done(result);
       });
    }
}

// later in render
if (this.props.value instanceof Error) {
    return <Error error={this.props.value} />;
}
// otherwise
return <Component value={this.props.value} />;

another option might be to resolve to multiple properties of an object, eg.

{ 
    value: function(done) {
       request.get('/api/data', function(error, result) {
            if (error) {
                return done({ error: new Error("Failed to load"), data: null });
            }
            return done({ error: null, data: result });
       });
    }
}

// later in render
if (this.props.value.error !== null) {
    return <Error error={this.props.value.error} />;
}
// otherwise
return <Component value={this.props.value.data} />;

Thoughts on this? Do you think the node/async (error, data) callback syntax is important to maintain? Or do you agree that it make sense to force the user to think about how to translate the errors into a props object in a more deliberate way?

Props not provided to functions

Odd how this regression showed up:

Resolver.createContainer(Fixture, {
  resolve: {
    user: (props) => console.log(props),
  }
});

// component, resolve

Whoops!

React resolver usage with nested components

This seems pretty cool, but I am still a little unclear as to how to best utilize this.

If I have route that is something like:

<Route name='user' path='/user/:username/?' handler={UserView}>
   <DefaultRoute handler={UserAboutSubview} />
   <Route name='user-activity' path='activity/?' handler={UserActivitySubview} />
   <Route name='user-favorites' path='favs/?' handler={UserFavsSubview} />
</Route>

Normally, I would think:

  • UserView, calls an action to initialize the UsersStore, on componentDidMount, and then setState upon store update. Then pass the state as props to UserAboutSubview, and then listen to any changes on UsersStore.

But if you use react-resolver, would you would still initialize the the UsersStore, at UserView, and then instead of passing down props, the Subviews, fetch the data from the store?

How would updates from the UsersStore be propagated?

Use peerDependencies

This should resolve the issue with react-router being part of package.json.

Also, it would be best if the examples/ had their own package.json.

Should props should propagate?

This would technically be a BC break, but I encountered a situation today where "hiding" props didn't help.

Take Stargazers.js, for example:

Stargazers.propTypes = {
users: React.PropTypes.array.isRequired,
};
export default Resolver.createContainer(Stargazers, {
resolve: {
users: function(props) {
const url = `https://api.github.com/repos/${props.user}/${props.repo}/stargazers`;
return axios.get(url).then(response => response.data);
},
},
});

<Stargazers /> requires a users prop, but the <StargazersContainer /> requires user and repo to fetch the data for users.

As a result, <Stargazers /> does not have access to user or repo.

This gets slightly annoying when composing multiple containers, as you pass parent props down the chain:

resolve: {
  something: (props) => props.something
}

My gut says that this mild inconvenience can be solved through another means, and that the base component shouldn't expect parent props to be leaked through...

Batching of in-flight requests

Lets take the stargazer example. Say I have stargazers and a count, I want to resolve the same data for both of them. There are two ways I can go about this:

  • Put it in a store.
  • Use resolver.

Here's an example:

class App extends React.Component {
  render() {
    return ( 
      <div>
        <Count />
        <Stargazer />
      </div>
    )
  }
}
@resolve({
  props: {
    users(props) {
      const url = `https://api.github.com/repos/${props.user}/${props.repo}/stargazers`;
      return axios.get(url).then(response => response.data);
    },
  },
})
class Stargazer extends React.Component {
  render() {
    return (
      <div>{this.props.users.map(user => <User user={user} />)}</div>
    )
  }
}
@resolve({
  props: {
    users(props) {
      const url = `https://api.github.com/repos/${props.user}/${props.repo}/stargazers`;
      return axios.get(url).then(response => response.data);
    },
  },
})
class Count extends React.Component {
  render() {
    return (
      <div>The number of people are: {this.props.user.length}</div>
    )
  }
}

This would fire off two remote requests. Ideally this would only fire a single request and the response would be handled by both resolvers.

Cannot find module 'babel/register'

Sorry to bother on this one;
I was interested in your tool, without being able to run the examples, stuck with the following error :

[piping] can't execute file: /Users/xx/Desktop/react-resolver/examples/react-v0.13/watch.js
[piping] error given was: Error: Cannot find module 'babel/register'
    at Function.Module._resolveFilename (module.js:336:15)
    at Function.module._load (/Users/xx/Desktop/react-resolver/examples/react-v0.13/node_modules/piping/lib/launcher.js:24:23)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at Object.<anonymous> (/Users/xx/Desktop/react-resolver/examples/react-v0.13/src/server.js:1:63)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Module._load (module.js:310:12)
    at Function.module._load (/Users/xx/Desktop/react-resolver/examples/react-v0.13/node_modules/piping/lib/launcher.js:32:16)
[piping] further repeats of this error will be suppressed...

I wonder if that would be an easy answer;
thanks for your time

Stargazers instructions / first install

The README file in the Stargazers example project still references the old folder name (examples/contacts) and includes instructions for npm link that were no longer needed since the addition of the pre/postinstall copying.

I also found that an initial npm install in the stargazers directory produces an error, since the preinstall script expects the node_modules and node_modules/react-resolver folders to already exist. That's not a problem for subsequent installs, but requires intervention to work on a freshly cloned repo.

/examples/stargazers$ npm install

> @ preinstall ~/resolver-dev/examples/stargazers
> rm -rf node_modules/react-resolver && cp -R ../../dist node_modules/react-resolver

cp: node_modules/react-resolver: No such file or directory
cp: ../../dist: unable to copy extended attributes to node_modules/react-resolver: No such file or directory
cp: node_modules/react-resolver/Container.js: No such file or directory
cp: node_modules/react-resolver/index.js: No such file or directory
cp: node_modules/react-resolver/Resolver.js: No such file or directory
cp: node_modules/react-resolver/ResolverError.js: No such file or directory

npm ERR! @ preinstall: `rm -rf node_modules/react-resolver && cp -R ../../dist node_modules/react-resolver`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the @ preinstall script.
npm ERR! This is most likely a problem with the  package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     rm -rf node_modules/react-resolver && cp -R ../../dist node_modules/react-resolver
npm ERR! You can get their info via:
npm ERR!     npm owner ls 
npm ERR! There is likely additional logging output above.
npm ERR! System Darwin 13.4.0
npm ERR! command "~/.nvm/v0.10.38/bin/node" "/Users/jason/.nvm/v0.10.38/bin/npm" "install"
npm ERR! cwd ~/resolver-dev/examples/stargazers
npm ERR! node -v v0.10.38
npm ERR! npm -v 1.4.28
npm ERR! code ELIFECYCLE
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     ~/resolver-dev/examples/stargazers/npm-debug.log
npm ERR! not ok code 0

So in addition to the README cleanup, the post- and preinstall need a minor adjustment to run without error on first attempt.

Clarify if a mixin is needed

From the usage description in the readme it seems like there is no mixin needed, but the examples use the Resolver.mixin. In my tests the resolve callbacks are not called without the mixin.

Is there a way to use react-resolver without any mixins? If not it would be nice to mention that in the readme.

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.