Path Lifecycle Events
Every path in a stream passes through three observable moments:
pathstart → first patch arrives
change → fires on every data patch
pathcomplete → value is sealedpathstart
Fires once — the first time a path receives a data patch (add or insert). The value
argument is the initial type: {} for objects, [] for arrays, or the first string chunk.
collector.on('pathstart', (path, value) => {
console.log(`${path} started streaming`, value)
})Use pathstart to show a skeleton the moment a new value begins arriving:
collector.on('pathstart', (path) => {
if (/^sections\[\d+\]$/.test(path)) {
showSectionSkeleton(path)
}
})pathcomplete
Fires when a value is fully assembled. The value argument is a deep-snapshotted copy of
the assembled value — safe to store and render directly.
collector.on('pathcomplete', (path, value) => {
if (/^sections\[\d+\]$/.test(path)) {
replaceSkeletonWithSection(value)
}
})Ordering guarantee
Children always complete before parents:
sections[0].heading → pathcomplete
sections[0].body → pathcomplete
sections[0] → pathcomplete ← after all children
sections → pathcomplete ← after all elementsWith the React hook
const { data } = useJsonCurrent<Report>({
onPathStart: (path, value) => {
if (/^sections\[\d+\]$/.test(path)) showSkeleton(path)
},
onPathComplete: (path, value) => {
if (/^sections\[\d+\]$/.test(path)) replaceSkeleton(path, value)
},
})Snapshots are safe to store
Both pathstart and pathcomplete values are deep-snapshotted at the moment of emission.
Storing them in state or refs will not be affected by subsequent patches.
Disable completions
If pathcomplete is not used, suppress complete patches to reduce wire overhead:
// Python
emitter = Emitter(completions=False)
// Node
const emitter = new Emitter({ completions: false })Related
Last updated on