@sanity/document-store
Version:
Sanity / gradient document store
156 lines (119 loc) • 6.44 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createObservableBufferedDocument = exports.snapshotEventFrom = void 0;
var _mutator = require("@sanity/mutator");
var _rxjs = require("rxjs");
var _operators = require("rxjs/operators");
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
var snapshotEventFrom = snapshot => ({
type: 'snapshot',
document: snapshot
}); // This is an observable interface for BufferedDocument in an attempt
// to make it easier to work with the api provided by it
exports.snapshotEventFrom = snapshotEventFrom;
var createObservableBufferedDocument = (serverEvents$, doCommit) => {
// Incoming local actions (e.g. a request to mutate, a request to commit pending changes, etc.)
var actions$ = new _rxjs.Subject(); // Stream of events that has happened with documents (e.g. a mutation that has been applied, a rebase).
// These are "after the fact" events and also includes the next document state.
var updates$ = new _rxjs.Subject(); // Stream of commit requests. Must be handled by a commit handler
var commits$ = new _rxjs.Subject();
var createInitialBufferedDocument = snapshot => {
var bufferedDocument = new _mutator.BufferedDocument(snapshot);
bufferedDocument.onMutation = (_ref) => {
var mutation = _ref.mutation,
remote = _ref.remote;
updates$.next({
type: 'mutation',
document: bufferedDocument.LOCAL,
mutations: mutation.mutations,
origin: remote ? 'remote' : 'local'
});
};
bufferedDocument.onRebase = edge => {
updates$.next({
type: 'rebase',
document: edge
});
};
bufferedDocument.commitHandler = opts => {
var _opts$mutation$params = opts.mutation.params,
resultRev = _opts$mutation$params.resultRev,
mutation = _objectWithoutProperties(_opts$mutation$params, ["resultRev"]);
commits$.next({
onSuccess: opts.success,
onError: opts.failure,
payload: mutation
});
};
return bufferedDocument;
};
var bufferedDocument$ = serverEvents$.pipe((0, _operators.scan)((bufferedDocument, serverEvent) => {
if (serverEvent.type === 'snapshot') {
if (bufferedDocument) {
// we received a new snapshot and already got an old one. When we receive a snapshot again
// it is usually because the connection has been down. Attempt to save pending changes (if any)
bufferedDocument.commit();
}
return createInitialBufferedDocument(serverEvent.document || null);
}
if (!bufferedDocument) {
// eslint-disable-next-line no-console
console.warn('Ignoring event of type "%s" since buffered document has not yet been set up with snapshot', serverEvent.type);
return bufferedDocument;
}
if (serverEvent.type === 'mutation') {
bufferedDocument.arrive(new _mutator.Mutation(serverEvent));
} else if (serverEvent.type !== 'reconnect') {
// eslint-disable-next-line no-console
console.warn('Received unexpected server event of type "%s"', serverEvent.type);
}
return bufferedDocument;
}, null), (0, _operators.publishReplay)(1), (0, _operators.refCount)()); // this is where the side effects mandated by local actions actually happens
var actionHandler$ = actions$.pipe((0, _operators.withLatestFrom)(bufferedDocument$), (0, _operators.map)((_ref2) => {
var _ref3 = _slicedToArray(_ref2, 2),
action = _ref3[0],
bufferedDocument = _ref3[1];
if (action.type === 'mutation') {
bufferedDocument.add(new _mutator.Mutation({
mutations: action.mutations
}));
}
if (action.type === 'commit') {
bufferedDocument.commit();
}
return null;
}), (0, _operators.filter)(Boolean), (0, _operators.share)());
var emitAction = action => actions$.next(action);
var addMutations = mutations => emitAction({
type: 'mutation',
mutations
});
var addMutation = mutation => addMutations([mutation]);
var commit = () => (0, _rxjs.defer)(() => {
emitAction({
type: 'commit'
});
return (0, _rxjs.of)(null);
});
var snapshot$ = bufferedDocument$.pipe((0, _operators.distinctUntilChanged)((bufDoc, prevBufDoc) => bufDoc.LOCAL === prevBufDoc.LOCAL), (0, _operators.map)(buf => snapshotEventFrom(buf.LOCAL)));
var commitResults$ = commits$.pipe((0, _operators.concatMap)(commitReq => doCommit(commitReq.payload).pipe((0, _operators.tap)({
next: commitReq.onSuccess,
error: commitReq.onError
}))), (0, _operators.mapTo)({
type: 'committed'
}));
return {
updates$: (0, _rxjs.merge)(snapshot$, actionHandler$, updates$, commitResults$),
addMutation,
addMutations,
commit
};
};
exports.createObservableBufferedDocument = createObservableBufferedDocument;