Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
function putValue(value, isChange) {
if (typeof value === 'undefined') return;
// console.log('Fill/subscribe: PutValue', value);
if (isChange) {
// console.log('Data before sieve', debug(data));
const sieved = sieve(data, value);
// console.log('Data after sieve', debug(data));
if (!sieved.length) return;
merge(payload, sieved);
} else {
merge(data, value);
// console.log('Payload before adding value', debug(payload));
if (raw) merge(payload, value);
// console.log('Payload after adding value');
}
let { known, unknown, extraneous } = slice(data, originalQuery);
data = known || [];
// console.log('After slice', debug(data), unknown && debug(unknown));
// console.log('Payload and value', debug(payload), value && debug(value));
if (isChange && value && unknown) {
// The sieve may have removed some necessary data (that we weren't aware
// was necessary). Get it back.
async putValue(value) {
/*
Merge value into cache, and get the change tree
extraChanges = await normalizeSubscriptions()
If raw, merge extraChanges into change and call listeners with that;
Othersiwe, call listeners with values from cache
*/
if (typeof value === 'undefined') value = {};
merge(this.data, value);
// console.log(this.id, 'value', value);
const gaps = getUnknown(this.data, this.sumQuery);
let fillData;
if (gaps) {
// The change added a link to some data we don't have in the cache.
// We need to fetch it and also resubscribe.
// console.log(
// 'Change caused gaps',
// value && value.visitorsByTime && value.visitorsByTime.__page__,
// this.data &&
// this.data.visitorsByTime &&
// this.data.visitorsByTime.__page__,
// );
// console.log('SumQuery', this.sumQuery);
// console.log('Gaps', gaps);
// this.data.visitorsByTime.__page__,
// );
// console.log('SumQuery', this.sumQuery);
// console.log('Gaps', gaps);
await this.resubscribe();
try {
fillData = await this.store.get(gaps, {
skipCache: true,
raw: true,
});
} catch (e) {
console.error('Error getting fillData for', gaps);
console.error(e);
}
if (fillData) {
merge(this.data, fillData);
merge(value, fillData);
}
}
for (const id in this.listeners) {
const { lastQuery = {}, originalQuery, push } = this.listeners[id];
const nextQuery = linkKnown(this.data, originalQuery);
const query = addQueries(lastQuery, nextQuery);
this.listeners[id].lastQuery = nextQuery;
const payload = getKnown(value, query);
if (payload) push(payload);
}
}
}
// );
// console.log('SumQuery', this.sumQuery);
// console.log('Gaps', gaps);
await this.resubscribe();
try {
fillData = await this.store.get(gaps, {
skipCache: true,
raw: true,
});
} catch (e) {
console.error('Error getting fillData for', gaps);
console.error(e);
}
if (fillData) {
merge(this.data, fillData);
merge(value, fillData);
}
}
for (const id in this.listeners) {
const { lastQuery = {}, originalQuery, push } = this.listeners[id];
const nextQuery = linkKnown(this.data, originalQuery);
const query = addQueries(lastQuery, nextQuery);
this.listeners[id].lastQuery = nextQuery;
const payload = getKnown(value, query);
if (payload) push(payload);
}
}
}
async pub(change) {
if (this.earlyChange) {
merge(this.earlyChange, change);
return;
}
const { query, options, data } = this;
// Returns early if the change does not have any overlap with the query.
// DO NOT getKnown the change to only those changes that overlap; when the
// overlapping portion includes a deletion in a range, the change set
// may contain additional items to make up.
if (!getKnown(change, linkKnown(data, query))) return;
merge(data, change);
const nextQuery = getUnknown(data, query);
if (nextQuery) {
const linked = await options.resolve(nextQuery);
merge(data, linked);
if (!options.values) merge(change, linked);
}
this.data = getKnown(data, query);
this.push(options.values ? graft(this.data, query) || {} : change);
}
}
const pub = async change => {
if (earlyChange) {
merge(earlyChange, change);
return;
}
// Returns early if the change does not have any overlap with the query.
// DO NOT getKnown the change to only those changes that overlap; when the
// overlapping portion includes a deletion in a range, the change set
// may contain additional items to make up.
if (!getKnown(change, linkKnown(data, query))) return;
merge(data, change);
const nextQuery = getUnknown(data, query);
if (nextQuery) {
const linked = await options.resolve(nextQuery);
merge(data, linked);
const { query, options, data } = this;
// Returns early if the change does not have any overlap with the query.
// DO NOT getKnown the change to only those changes that overlap; when the
// overlapping portion includes a deletion in a range, the change set
// may contain additional items to make up.
if (!getKnown(change, linkKnown(data, query))) return;
merge(data, change);
const nextQuery = getUnknown(data, query);
if (nextQuery) {
const linked = await options.resolve(nextQuery);
merge(data, linked);
if (!options.values) merge(change, linked);
}
this.data = getKnown(data, query);
this.push(options.values ? graft(this.data, query) || {} : change);
}
}
store.on('read', [], async (query, options, next) => {
if (options.skipCache) return next(query);
const { known, unknown } = slice(cache, query);
if (!unknown) return known;
const nextValue = await next(unknown);
merge(cache, nextValue);
return merge(known || [], nextValue);
});
};
function simulate() {
const change =
Math.random() < 0.9
? simulateUpdate()
: Math.random() < (id - freeIds.size) / 2 / TARGET
? simulateLeave()
: simulateEnter();
merge(state, change);
return change;
}