EventChannel.of constructor
EventChannel.of({})
Implementation
factory EventChannel.of({
required List<Map<String, Object?>> base,
required List<Map<String, Object?>> head,
}) {
var deltas = <EventDelta>[];
var unpairedBase = <(int, Map<String, Object?>)>[];
var unpairedHead = <(int, Map<String, Object?>)>[];
for (var (left, right) in _fuse(_align(base, head))) {
if (left != null && right != null) {
deltas.addAll(_diffPair(left.$2, right.$2));
} else if (left != null) {
unpairedBase.add(left);
} else if (right != null) {
unpairedHead.add(right);
}
}
// What is left over and appears on *both* sides did not come or go — it
// moved. FakeAsync makes a transition's ordering deterministic, so an auth
// call that now happens after a data fetch is a real finding rather than a
// flake, and reporting it as one removal plus one addition of the same
// string is the nonsense the alignment exists to avoid. An event fed by
// real I/O is not under FakeAsync, and its order can be the host's; `fw
// compare` asks a second replay before believing a step that only moved.
var stillBase = <(int, Map<String, Object?>)>[];
var byKey = <String, List<(int, Map<String, Object?>)>>{};
for (var entry in unpairedHead) {
byKey.putIfAbsent(_key(entry.$2), () => []).add(entry);
}
var moved = <(int, Map<String, Object?>)>{};
for (var entry in unpairedBase) {
var twins = byKey[_key(entry.$2)];
if (twins == null || twins.isEmpty) {
stillBase.add(entry);
continue;
}
var twin = twins.removeAt(0);
moved.add(twin);
deltas.add(
EventDelta(
kind: EventDeltaKind.moved,
subchannel: _subchannel(entry.$2),
title: _title(entry.$2),
property: 'order',
base: '#${entry.$1}',
head: '#${twin.$1}',
origin: _origin(twin.$2),
),
);
}
// `system` after everything else before the cap bites. The doc on
// [maxEventDeltas] promised the allowance to the channels that earn it,
// and a plain `take` broke that promise *within* events: a step whose
// system chatter produced its deltas first evicted the one network delta
// the step was worth reading for. Order inside each half is preserved —
// this is a partition, not a sort.
var ranked = [
for (var delta in deltas)
if (delta.subchannel != systemSubchannel) delta,
for (var delta in deltas)
if (delta.subchannel == systemSubchannel) delta,
];
return EventChannel(
added: [
for (var entry in unpairedHead)
if (!moved.contains(entry)) mask(entry.$2),
],
removed: [for (var entry in stillBase) mask(entry.$2)],
deltas: ranked.take(maxEventDeltas).toList(),
deltasDropped: ranked.length > maxEventDeltas
? ranked.length - maxEventDeltas
: 0,
);
}