dependsOn<S extends HypenGeneratedData, I, O> method
O
dependsOn<S extends HypenGeneratedData, I, O>(})
Implementation
O dependsOn<S extends HypenGeneratedData, I, O>(
Object key,
S Function() build, {
required O Function(S origin, I snapshot) select,
Stream<O> Function(Stream<O> source)? pipe,
Object? actionKey,
}) {
final data = _addDependency(key, build, actionKey: actionKey);
if (!isBuilding) {
return select(data, data.$snapshot() as I);
}
final currentLinearIndex = linearDependencyIndex;
final currentNestedIndex = _resetOrIncNestedDepIdx();
final Object? prevRootKey = _changeRootkey(key);
final rootKey = _rootKey;
linearDependencyIndex++;
if (_isNewSelection(rootKey, currentNestedIndex) &&
depStreams.length <= currentLinearIndex) {
final source = data.$stream as HypenStream<I>;
final selectedStream = source.map<O>((s) {
// setup selected item key
_rootKey = rootKey;
nestedDependencyIndex = currentNestedIndex;
isBuilding = true;
final ret = select(data, s);
isBuilding = false;
return ret;
});
final piped = (pipe ?? (s) => s)(selectedStream);
depStreams.add(
piped.listen((s) {
preventAccess[rootKey]![currentNestedIndex] = null;
_changeSelectedData(rootKey, currentNestedIndex, s);
_markParentsNeedRebuild(rootKey, currentNestedIndex);
_resetSelf();
}),
);
}
O? ret;
try {
if (_isNewSelection(rootKey, currentNestedIndex)) {
// increase the cache size
final needsRebuild = this.needsRebuild[rootKey] ??= [];
final selectedData = this.selectedData[rootKey] ??= [];
final preventAccess = this.preventAccess[rootKey] ??= [];
needsRebuild.add(true);
selectedData.add(null);
preventAccess.add(null);
}
if (preventAccess[rootKey]?[currentLinearIndex] case Object e) {
throw e;
}
if (_needsRebuild(rootKey, currentNestedIndex)) {
ret = select(data, data.$snapshot() as I);
_changeSelectedData(rootKey, currentNestedIndex, ret);
} else {
ret = selectedData[rootKey]![currentNestedIndex] as O;
}
_resetRootKey(prevRootKey);
} catch (e) {
preventAccess[rootKey]![currentNestedIndex] = e;
_initializeFlags();
rethrow;
}
return ret as O;
}