relay-runtime
Version:
A core runtime for building GraphQL-driven applications.
150 lines (149 loc) • 6.09 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
var _asyncToGenerator = require("@babel/runtime/helpers/asyncToGenerator").default;
var _createForOfIteratorHelper2 = _interopRequireDefault(require("@babel/runtime/helpers/createForOfIteratorHelper"));
var Observable = require('../network/RelayObservable');
var _require = require('../query/fetchQueryInternal'),
getObservableForActiveRequest = _require.getObservableForActiveRequest;
var _require2 = require('../query/GraphQLTag'),
getFragment = _require2.getFragment;
var _require3 = require('../util/handlePotentialSnapshotErrors'),
handlePotentialSnapshotErrors = _require3.handlePotentialSnapshotErrors;
var _require4 = require('./RelayModernSelector'),
getSelector = _require4.getSelector;
var invariant = require('invariant');
function waitForFragmentData(_x, _x2, _x3) {
return _waitForFragmentData.apply(this, arguments);
}
function _waitForFragmentData() {
_waitForFragmentData = _asyncToGenerator(function* (environment, fragment, fragmentRef) {
var subscription;
try {
var _subscription;
var data = yield new Promise(function (resolve, reject) {
subscription = observeFragment(environment, fragment, fragmentRef).subscribe({
next: function next(val) {
if (val.state === 'ok') {
resolve(val.value);
} else if (val.state === 'error') {
reject(val.error);
}
}
});
});
(_subscription = subscription) === null || _subscription === void 0 ? void 0 : _subscription.unsubscribe();
return data;
} catch (e) {
var _subscription2;
(_subscription2 = subscription) === null || _subscription2 === void 0 ? void 0 : _subscription2.unsubscribe();
throw e;
}
});
return _waitForFragmentData.apply(this, arguments);
}
function observeFragment(environment, fragment, fragmentRef) {
var _fragmentNode$metadat;
var fragmentNode = getFragment(fragment);
var fragmentSelector = getSelector(fragmentNode, fragmentRef);
!(((_fragmentNode$metadat = fragmentNode.metadata) === null || _fragmentNode$metadat === void 0 ? void 0 : _fragmentNode$metadat.hasClientEdges) == null) ? process.env.NODE_ENV !== "production" ? invariant(false, "Client edges aren't supported yet.") : invariant(false) : void 0;
!(fragmentSelector != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected a selector, got null.') : invariant(false) : void 0;
switch (fragmentSelector.kind) {
case 'SingularReaderSelector':
return observeSingularSelector(environment, fragment, fragmentSelector);
case 'PluralReaderSelector':
{
return observePluralSelector(environment, fragment, fragmentSelector);
}
}
!false ? process.env.NODE_ENV !== "production" ? invariant(false, 'Unsupported fragment selector kind') : invariant(false) : void 0;
}
function observeSingularSelector(environment, fragmentNode, fragmentSelector) {
var snapshot = environment.lookup(fragmentSelector);
return Observable.create(function (sink) {
sink.next(snapshotToFragmentState(environment, fragmentNode, fragmentSelector.owner, snapshot));
var subscription = environment.subscribe(snapshot, function (nextSnapshot) {
sink.next(snapshotToFragmentState(environment, fragmentNode, fragmentSelector.owner, nextSnapshot));
});
return function () {
return subscription.dispose();
};
});
}
function observePluralSelector(environment, fragmentNode, fragmentSelector) {
var snapshots = fragmentSelector.selectors.map(function (selector) {
return environment.lookup(selector);
});
return Observable.create(function (sink) {
var states = snapshots.map(function (snapshot, index) {
return snapshotToFragmentState(environment, fragmentNode, fragmentSelector.selectors[index].owner, snapshot);
});
sink.next(mergeFragmentStates(states));
var subscriptions = snapshots.map(function (snapshot, index) {
return environment.subscribe(snapshot, function (latestSnapshot) {
states[index] = snapshotToFragmentState(environment, fragmentNode, fragmentSelector.selectors[index].owner, latestSnapshot);
sink.next(mergeFragmentStates(states));
});
});
return function () {
return subscriptions.forEach(function (subscription) {
return subscription.dispose();
});
};
});
}
function snapshotToFragmentState(environment, fragmentNode, owner, snapshot) {
var missingLiveResolverFields = snapshot.missingLiveResolverFields != null && snapshot.missingLiveResolverFields.length > 0;
var missingClientEdges = snapshot.missingClientEdges != null && snapshot.missingClientEdges.length > 0;
if (missingLiveResolverFields || missingClientEdges) {
return {
state: 'loading'
};
}
if (snapshot.isMissingData) {
if (getObservableForActiveRequest(environment, owner) != null || environment.getOperationTracker().getPendingOperationsAffectingOwner(owner) != null) {
return {
state: 'loading'
};
}
}
try {
handlePotentialSnapshotErrors(environment, snapshot.fieldErrors);
} catch (error) {
return {
error: error,
state: 'error'
};
}
!(snapshot.data != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected data to be non-null.') : invariant(false) : void 0;
return {
state: 'ok',
value: snapshot.data
};
}
function mergeFragmentStates(states) {
var value = [];
var _iterator = (0, _createForOfIteratorHelper2["default"])(states),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var state = _step.value;
if (state.state === 'ok') {
value.push(state.value);
} else {
return state;
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
return {
state: 'ok',
value: value
};
}
module.exports = {
observeFragment: observeFragment,
waitForFragmentData: waitForFragmentData
};
;