emit method
Emits an event, executing all registered hooks for that event.
Implementation
@override
Future<dynamic> emit(
String eventName, {
Future Function(HHCtxI ctx)? action,
bool handleCtrlException = false,
}) async {
dynamic result;
bool skipNextBatch = false;
try {
// Execute pre-action hooks
if (!skipNextBatch) {
final preHooks = ctx.config.preActionHooks[eventName] ?? [];
// print(
// 'DEBUG: Executing $eventName - preHooks count: ${preHooks.length}',
// );
for (var hook in preHooks) {
try {
await invoke(hook.action, handleCtrlException);
} on HHCtrlException catch (e) {
if (e.nextPhase == NextPhase.f_skip) {
// Skip the next batch (main action)
skipNextBatch = true;
break;
}
rethrow;
}
}
}
// Execute the main action if provided
if (action != null && !skipNextBatch) {
try {
result = await invoke(action, handleCtrlException);
} on HHCtrlException catch (e) {
if (e.nextPhase == NextPhase.f_skip) {
// Skip the next batch (post hooks)
skipNextBatch = true;
} else {
rethrow;
}
}
}
// Execute post-action hooks
if (!skipNextBatch) {
final postHooks = ctx.config.postActionHooks[eventName] ?? [];
for (var hook in postHooks) {
try {
await invoke(hook.action, handleCtrlException);
} on HHCtrlException catch (e) {
if (e.nextPhase == NextPhase.f_skip) {
// No more batches after post hooks
break;
}
rethrow;
}
}
}
} on HHCtrlException catch (e) {
// Handle phase control that affects the entire emit
switch (e.nextPhase) {
case NextPhase.f_break:
// Break out of hook execution - return value
return e.returnValue;
case NextPhase.f_delete:
// Delete the key
if (ctx.payload.key != null) {
await ctx.access.storeDelete(ctx.payload.key!);
if (ctx.config.usesMeta) {
await ctx.access.metaDelete(ctx.payload.key!);
}
}
return e.returnValue;
case NextPhase.f_pop:
// Pop the key and return its value
if (ctx.payload.key != null) {
final value = await ctx.access.storePop(ctx.payload.key!);
return value ?? e.returnValue;
}
return e.returnValue;
case NextPhase.f_skip:
case NextPhase.f_continue:
case NextPhase.f_panic:
// These shouldn't reach here, but rethrow if they do
rethrow;
}
}
return result;
}