Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
overlookmotel committed Feb 15, 2020
1 parent 7db6493 commit a1d600e
Showing 1 changed file with 44 additions and 39 deletions.
83 changes: 44 additions & 39 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,18 @@ var LoadableDataComponent = function (_React$Component) {
// Get data from cache if it's there
var _this = _possibleConstructorReturn(this, (LoadableDataComponent.__proto__ || Object.getPrototypeOf(LoadableDataComponent)).call(this, props));

var _props$context$getDat = props.context.getData(),
var _props$context$getDat = props.context.getData(props.name),
loaded = _props$context$getDat.loaded,
data = _props$context$getDat.data;

// Client side or server-side and data not loaded yet


_this.loading = false;
_this.state = {
data: data,
error: null,
loaded: loaded,
loading: false
loaded: loaded
};
return _this;
}
Expand All @@ -66,7 +66,7 @@ var LoadableDataComponent = function (_React$Component) {
key: 'componentWillMount',
value: function componentWillMount() {
this._mounted = true;
if (this.state.loading || this.state.loaded) return;
if (this.loading || this.state.loaded) return;
this._load();
}
}, {
Expand All @@ -77,13 +77,12 @@ var LoadableDataComponent = function (_React$Component) {
}, {
key: 'load',
value: function load() {
if (this.state.loading) return;
if (this.loading) return;

this.setState({
data: null,
error: null,
loaded: false,
loading: false
loaded: false
});

this._load();
Expand All @@ -95,18 +94,19 @@ var LoadableDataComponent = function (_React$Component) {

//console.log('loading!');

this.setState({ loading: true });
this.loading = true;

// Run loader
var _props = this.props,
loader = _props.loader,
context = _props.context,
props = _props.props;
parentProps = _props.parentProps,
name = _props.name;

var promise = loader(props);
var promise = loader(parentProps);

// Report promise
promise = context.report(promise);
promise = context.report(promise, name);

// Update state once loaded
promise.then(function (data) {
Expand All @@ -120,10 +120,10 @@ var LoadableDataComponent = function (_React$Component) {
value: function _loaded(data) {
if (!this._mounted) return;

this.loading = false;
this.setState({
data: data,
error: null,
loading: false,
loaded: true
});
}
Expand All @@ -132,10 +132,10 @@ var LoadableDataComponent = function (_React$Component) {
value: function _errored(err) {
if (!this._mounted) return;

this.loading = false;
this.setState({
data: null,
error: err,
loading: false,
loaded: false
});
}
Expand All @@ -145,13 +145,11 @@ var LoadableDataComponent = function (_React$Component) {
var state = this.state,
props = this.props;

if (state.loading || state.error) {
return React.createElement(props.Loading, { loading: state.loading, error: state.error });
} else if (state.loaded) {
var componentProps = Object.assign({}, props.props, _defineProperty({}, props.dataPropName, state.data));
return React.createElement(props.component, componentProps);
if (!state.loaded) {
return React.createElement(props.Loading, { error: state.error });
} else {
return null;
var componentProps = Object.assign({}, props.parentProps, _defineProperty({}, props.dataPropName, state.data));
return React.createElement(props.component, componentProps);
}
}
}]);
Expand All @@ -168,6 +166,7 @@ var LoadableDataComponent = function (_React$Component) {
* @param {string} [options.dataPropName='data'] - Prop name to provide data on to component
*/

var counter = 0;

function LoadableData(options) {
var loader = options.loader,
Expand All @@ -179,6 +178,14 @@ function LoadableData(options) {
return null;
};

var name = options.name;

if (name == null) {
name = '_' + counter++;
} else if (typeof name != 'string') {
throw new Error('name must be a string if provided');
}

var dataPropName = options.dataPropName;

if (dataPropName == null) {
Expand All @@ -193,11 +200,12 @@ function LoadableData(options) {
null,
function (context) {
return React.createElement(LoadableDataComponent, {
name: name,
loader: loader,
Loading: Loading,
component: component,
dataPropName: dataPropName,
props: props,
parentProps: props,
context: context
});
}
Expand All @@ -216,15 +224,18 @@ module.exports = LoadableData;
* This is to ensure the cached data is only used for initial render.
*
* @param {Object} props - Props object
* @param {Array} [props.data=[]] - Data array (usually filled by server and passed to client)
* @param {Object} [props.data={}] - Data object (usually filled by server and passed to client)
*/
function ClientProvider(props) {
var datas = props.data || [];
var datas = props.data || {};

var context = {
getData: function getData() {
if (datas.length == 0) return { loaded: false, data: null };
return { loaded: true, data: datas.shift() };
getData: function getData(name) {
var data = datas[name];
if (!data) return { loaded: false, data: null };

delete datas[name];
return { loaded: true, data: data };
},
report: function report(promise) {
return promise;
Expand All @@ -248,37 +259,31 @@ LoadableData.ClientProvider = ClientProvider;
* state updates (unless since this is rendering on server).
*
* @param {Object} props - Props object
* @param {Array} [props.data=[]] - Data array (usually filled by server and passed to client)
* @param {Object} [props.data={}] - Data object (usually filled by server and passed to client)
* @param {Array} [props.promises=[]] - Promises array (must be provided empty)
*/
var fakePromise = {
then: function then() {}
};

function ServerProvider(props) {
var datas = props.data || [],
var datas = props.data || {},
promises = props.promises || [];

if (promises.length > 0) throw new Error('Promises array must be empty');

var datasLength = datas.length;

var getIndex = 0,
reportIndex = 0;

var context = {
getData: function getData(name) {
if (getIndex >= datasLength) return { loaded: false, data: null };
return { loaded: true, data: datas[getIndex++] };
var data = datas[name];
if (!data) return { loaded: false, data: null };
return { loaded: true, data: data };
},
report: function report(promise) {
var index = reportIndex++;

report: function report(promise, name) {
// Add promise to array
// When promise resolves, fetched data is added to data array
// When promise resolves, fetched data is added to data object
promise = promise.then(function (data) {
// Save to datas
datas[index + datasLength] = data;
datas[name] = data;

// Remove promise from array
promises.splice(promises.indexOf(promise), 1);
Expand Down

0 comments on commit a1d600e

Please sign in to comment.