summaryrefslogtreecommitdiff
path: root/apps/web/src/actions/registry.ts
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2026-04-20 11:31:17 +0200
committerMaze Winther <mazewinther@gmail.com>2026-04-20 11:31:17 +0200
commit3e89d2998588f8e35c524e523ba2ee853f0f6475 (patch)
tree57221f96c1259b3b07e3ddf8c1adefc502b9d8eb /apps/web/src/actions/registry.ts
parent729d10592f4e802f91c555c309ff3ba4b119f843 (diff)
downloadopencut-3e89d2998588f8e35c524e523ba2ee853f0f6475.tar.gz
refactor: restructure files to their domains, new preview overlay system, and dep graph
Diffstat (limited to 'apps/web/src/actions/registry.ts')
-rw-r--r--apps/web/src/actions/registry.ts63
1 files changed, 63 insertions, 0 deletions
diff --git a/apps/web/src/actions/registry.ts b/apps/web/src/actions/registry.ts
new file mode 100644
index 00000000..e69b3b9f
--- /dev/null
+++ b/apps/web/src/actions/registry.ts
@@ -0,0 +1,63 @@
+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);
+ });
+};