next
Version:
The React Framework
66 lines (65 loc) • 2.66 kB
JavaScript
/**
* Vary Params Decoding
*
* This module is shared between server and client.
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "readVaryParams", {
enumerable: true,
get: function() {
return readVaryParams;
}
});
/**
* Synchronously drains a vary params `AsyncIterable`, adding each yielded name
* to `target`.
*
* By the time this runs (on the client, or in collectSegmentData), the Flight
* stream has been fully buffered, so every yielded value is already
* materialized and can be read without awaiting. We force each iterator result
* to resolve synchronously using the same `.then(noop)` trick React uses
* internally, then read its `status`/`value` directly.
*
* We add "every param yielded up to the point the stream suspends": a
* normally-closed iterable drains fully, while one left hanging (a sync-I/O
* abort, or a `close()` whose row hasn't flushed yet) drains to the prefix
* already in the stream. Both are correct — a segment's param accesses are all
* flushed as they happen during its render, so the prefix is exactly the set
* the response depends on. We therefore never need the terminating `done` row
* to be present; it's only stream hygiene.
*/ function drainVaryParams(iterable, target) {
const iterator = iterable[Symbol.asyncIterator]();
while(true){
const chunk = iterator.next();
// Attach a no-op listener to force Flight to synchronously resolve the
// chunk. A freshly-arrived result may be in an intermediate
// 'resolved_model' state (data received but not unwrapped); calling
// .then() transitions it to 'fulfilled', making the value available
// synchronously. (A native Promise has no `status` and simply reads as
// not-fulfilled below, so this can never hang.)
chunk.then(noop, noop);
if (chunk.status !== 'fulfilled' || chunk.value === undefined) {
// The stream suspended here. Everything yielded before this point has
// already been added.
return;
}
const step = chunk.value;
if (step.done) {
return;
}
target.add(step.value);
}
}
function readVaryParams(iterable, rootIterable) {
if (iterable === null || iterable === undefined || rootIterable === null || rootIterable === undefined) {
return null;
}
const varyParams = new Set();
drainVaryParams(iterable, varyParams);
drainVaryParams(rootIterable, varyParams);
return varyParams;
}
const noop = ()=>{};
//# sourceMappingURL=vary-params-decoding.js.map