ワンクリックで
add-sequential
Add sequential queue processing to ensure Cubit method calls execute one after another in order
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Add sequential queue processing to ensure Cubit method calls execute one after another in order
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Add custom error handling with catchError to a mix() call for logging, error conversion, or suppression
Add internet connectivity checking before executing a Cubit method with optional retry
Add debounce to delay method execution until after a period of inactivity for search or validation
Add EffectQueue to state for triggering multiple sequential one-time UI effects
Add Effect fields to state class for one-time UI notifications like snackbars, navigation, or form clearing
Add error state handling to widgets using context.isFailed() and context.getException()
| name | add-sequential |
| description | Add sequential queue processing to ensure Cubit method calls execute one after another in order |
This skill queues Cubit method calls and processes them one after another in order.
Adds the sequential parameter to a mix() call so that:
Ask the user which Cubit method needs sequential processing, or identify methods that:
Add sequential: sequential to the mix() call:
import 'package:bloc_superpowers/bloc_superpowers.dart';
class ChatCubit extends Cubit<ChatState> {
ChatCubit() : super(const ChatState());
void sendMessage(String text) => mix(
key: this,
sequential: sequential, // Add this line
() async {
final message = await api.sendMessage(text);
emit(state.copyWith(
messages: [...state.messages, message],
));
},
);
}
With sequential:
// User sends 3 messages rapidly
cubit.sendMessage('Hello'); // Executes immediately
cubit.sendMessage('How'); // Queued (waits for first)
cubit.sendMessage('Are you?'); // Queued (waits for second)
// Result: Messages sent in order: "Hello", "How", "Are you?"
sequential(
key: null, // Uses mix key by default
maxQueueSize: null, // Unlimited queue
queueTimeout: null, // No timeout
dropOldest: false, // Drop newest when queue full
)
Prevent memory issues with large queues:
void processItem(Item item) => mix(
key: this,
sequential: sequential(maxQueueSize: 10),
() async {
await api.process(item);
},
);
When queue is full:
dropOldest: true: Oldest queued call is droppedDiscard calls that wait too long:
void sendMessage(String text) => mix(
key: this,
sequential: sequential(queueTimeout: 30.sec),
() async {
await api.sendMessage(text);
},
);
Calls waiting longer than 30 seconds are discarded.
For operations where only the final value matters:
void updateSettings(Settings settings) => mix(
key: this,
sequential: sequential.latestWins,
() async {
await api.saveSettings(settings);
},
);
sequential.latestWins is shorthand for:
sequential(maxQueueSize: 1, dropOldest: true)
Different items can have separate queues:
void sendMessage(String chatId, String text) => mix(
key: this,
sequential: sequential(key: (ChatCubit, chatId)),
() async {
await api.sendMessage(chatId, text);
},
);
With this setup:
void processOrder(Order order) => mix(
key: this,
sequential: sequential,
() async {
await api.processOrder(order);
emit(state.copyWith(
processedOrders: [...state.processedOrders, order],
));
},
);
void sendMessage(String text) => mix(
key: this,
sequential: sequential(queueTimeout: 30.sec),
retry: retry,
() async {
final message = await api.sendMessage(text);
emit(state.copyWith(messages: [...state.messages, message]));
},
);
void sendMessage(String chatId, String text) => mix(
key: (SendMessage, chatId),
sequential: sequential, // Inherits key from mix
() async {
await api.sendMessage(chatId, text);
},
);
void saveSettings(Settings settings) => mix(
key: this,
sequential: sequential.latestWins,
() async {
await api.saveSettings(settings);
emit(settings);
},
);
Use mix.ctx to access queue information:
void processItem(Item item) => mix.ctx(
key: this,
sequential: sequential,
(ctx) async {
final wasQueued = ctx.sequential!.wasQueued; // Was this call queued?
final index = ctx.sequential!.index; // Position in queue
if (wasQueued) {
print('Processing queued item at position $index');
}
await api.process(item);
},
);
| Feature | Duplicate Calls | Use Case |
|---|---|---|
sequential | Queued and executed in order | Every call matters |
nonReentrant | Dropped/ignored | Only first call matters |
Use sequential for:
Use nonReentrant for:
class OrderCubit extends Cubit<OrderState> {
OrderCubit() : super(const OrderState());
// Queue all orders for sequential processing
void submitOrder(Order order) => mix(
key: this,
sequential: sequential(
maxQueueSize: 100,
queueTimeout: 60.sec,
),
retry: retry,
() async {
emit(state.copyWith(processingOrder: order));
final result = await api.submitOrder(order);
emit(state.copyWith(
processingOrder: null,
completedOrders: [...state.completedOrders, result],
));
},
);
}
Ask the user: