summaryrefslogtreecommitdiff
path: root/apps/web/src/lib/actions/registry.ts
diff options
context:
space:
mode:
authorMaze <167211895+mazeincoding@users.noreply.github.com>2026-01-31 00:20:04 +0100
committerGitHub <noreply@github.com>2026-01-31 00:20:04 +0100
commit7bf0984698e43b9aa2dd879f65951318ed410390 (patch)
treeccf2cd590a47d550152afc07129cb55c71a9ec35 /apps/web/src/lib/actions/registry.ts
parent0173db99448d1c4c6415dcf15272e17551b48b04 (diff)
downloadopencut-7bf0984698e43b9aa2dd879f65951318ed410390.tar.gz
codebase overhaul (#697)
Diffstat (limited to 'apps/web/src/lib/actions/registry.ts')
-rw-r--r--apps/web/src/lib/actions/registry.ts61
1 files changed, 61 insertions, 0 deletions
diff --git a/apps/web/src/lib/actions/registry.ts b/apps/web/src/lib/actions/registry.ts
new file mode 100644
index 00000000..b9c84529
--- /dev/null
+++ b/apps/web/src/lib/actions/registry.ts
@@ -0,0 +1,61 @@
+import type {
+ TAction,
+ TActionFunc,
+ TActionWithArgs,
+ TActionWithOptionalArgs,
+ TActionArgsMap,
+ TArgOfAction,
+ TInvocationTrigger,
+} from "./types";
+
+type ActionHandler = (arg: unknown, trigger?: TInvocationTrigger) => void;
+const boundActions: Partial<Record<TAction, ActionHandler[]>> = {};
+
+export function bindAction<A extends TAction>(
+ action: A,
+ handler: TActionFunc<A>,
+) {
+ const handlers = boundActions[action];
+ const typedHandler = handler as ActionHandler;
+ if (handlers) {
+ handlers.push(typedHandler);
+ } else {
+ boundActions[action] = [typedHandler];
+ }
+}
+
+export function unbindAction<A extends TAction>(
+ action: A,
+ handler: TActionFunc<A>,
+) {
+ const handlers = boundActions[action];
+ if (!handlers) return;
+
+ const typedHandler = handler as ActionHandler;
+ boundActions[action] = handlers.filter((h) => h !== typedHandler);
+
+ if (boundActions[action]?.length === 0) {
+ delete boundActions[action];
+ }
+}
+
+type InvokeActionFunc = {
+ (
+ action: TActionWithOptionalArgs,
+ args?: undefined,
+ trigger?: TInvocationTrigger,
+ ): void;
+ <A extends TActionWithArgs>(
+ action: A,
+ args: TActionArgsMap[A],
+ trigger?: TInvocationTrigger,
+ ): void;
+};
+
+export const invokeAction: InvokeActionFunc = <A extends TAction>(
+ action: A,
+ args?: TArgOfAction<A>,
+ trigger?: TInvocationTrigger,
+) => {
+ boundActions[action]?.forEach((handler) => handler(args, trigger));
+};