Read-only mirror of https://github.com/DCC-BS/event-system.bs.js — Basel-Stadt. Issues & pull requests at the source.
  • TypeScript 96.8%
  • Vue 3.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
renovate[bot] 6775fad0aa
chore(deps): lock file maintenance (#71)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-24 06:50:34 +00:00
.github/workflows Sec/add bunfig (#46) 2026-03-27 12:42:47 +01:00
.vscode Use centralized CI/publish workflows and Biome 2026-01-02 11:33:45 +01:00
playground Sec/add bunfig (#46) 2026-03-27 12:42:47 +01:00
src Use centralized CI/publish workflows and Biome 2026-01-02 11:33:45 +01:00
tests Use centralized CI/publish workflows and Biome 2026-01-02 11:33:45 +01:00
.editorconfig chore(release): v1.0.3 2025-02-18 09:43:49 +01:00
.gitignore Use centralized CI/publish workflows and Biome 2026-01-02 11:33:45 +01:00
.npmignore chore: remove CI and publish workflows; add .npmignore and update module imports 2025-02-17 15:10:56 +01:00
biome.json Compact JSON arrays in config files 2026-01-02 11:36:34 +01:00
bun.lock chore(deps): lock file maintenance (#71) 2026-08-24 06:50:34 +00:00
bunfig.toml Sec/add bunfig (#46) 2026-03-27 12:42:47 +01:00
codecov.yml Use centralized CI/publish workflows and Biome 2026-01-02 11:33:45 +01:00
LICENSE Create LICENSE 2025-02-19 10:29:56 +01:00
package.json 1.4.4 2026-03-24 12:07:54 +01:00
README.md Updated the Readme 2026-07-01 13:27:41 +02:00
renovate.json Compact JSON arrays in config files 2026-01-02 11:36:34 +01:00
tsconfig.json Compact JSON arrays in config files 2026-01-02 11:36:34 +01:00
vitest.config.ts Use centralized CI/publish workflows and Biome 2026-01-02 11:33:45 +01:00

event-system.bs.js

GitHub License NPM Version Checked with Biome

event-system.bs.js is a package that provides a Command Bus for handling commands in your application. This package is designed to be used to manage and execute commands in a structured and efficient manner. It also supports undo/redo functionality for reversible commands.

Quick Setup

Install the module to your Nuxt application with your preferred package manager:

# bun
bun add @dcc-bs/event-system.bs.js

# npm
npm install @dcc-bs/event-system.bs.js

# pnpm
pnpm add @dcc-bs/event-system.bs.js

# yarn
yarn add @dcc-bs/event-system.bs.js

Add the module to your nuxt.config.ts:

export default defineNuxtConfig({
  modules: [
    '@dcc-bs/event-system.bs.js'
  ]
})

That's it! You can now use event-system.bs.js in your Nuxt app

Usage

Defining a Command

Commands are plain objects that implement the ICommand interface:

import type { ICommand } from '#build/types/commands';

class MyCommand implements ICommand {
    readonly $type = 'MyCommand';

    constructor(public myProperty: string) {}
}

Registering a Command Handler

The recommended way to register a handler is via onCommand, which automatically unregisters the handler when the component unmounts:

const { onCommand, executeCommand } = useCommandBus();

onCommand<MyCommand>('MyCommand', async (command) => {
    // Handle the command
});

executeCommand(new MyCommand('prop value'));

Alternatively, you can manually register and unregister handlers using registerHandler / unregisterHandler:

const { registerHandler, unregisterHandler } = useCommandBus();

onMounted(() => {
    registerHandler('MyCommand', handleCommand);
});

onUnmounted(() => {
    unregisterHandler('MyCommand', handleCommand);
});

async function handleCommand(command: MyCommand) {
    // Handle the command
}

Executing a Command

To execute a command, use the executeCommand method:

const { executeCommand } = useCommandBus();

executeCommand(new MyCommand('prop value'));

By default, executed commands that implement IReversibleCommand are automatically added to the command history. You can disable this by passing false as the second argument:

executeCommand(new MyCommand('prop value'), false);

Best Practice

The CommandBus relies on a string to identify the right Command type, to prevent misspelling in the command type it is best practice to create Map with all the types:

export const Cmds = {
    MyCommand: "MyCommand",
}

class MyCommand implements ICommand {
    readonly $type = Cmds.MyCommand;

    constructor(public myProperty: string) {}
}

onCommand<MyCommand>(Cmds.MyCommand, async (command) => {
    // Handle the command
});

This also enables easier refactoring of the command types.

Undo / Redo (Command History)

Commands that implement the IReversibleCommand interface are automatically tracked in the command history, enabling undo and redo operations.

Defining a Reversible Command

A reversible command includes an $undoCommand property that holds the command used to reverse its effect:

import type { IReversibleCommand } from '#build/types/commands';

class MyReversibleCommand implements IReversibleCommand {
    readonly $type = 'MyReversibleCommand';
    readonly $undoCommand: ICommand | undefined;

    constructor(public myProperty: string, undoCommand?: ICommand) {
        this.$undoCommand = undoCommand;
    }
}

Using the Command History

Use the useCommandHistory composable to access undo/redo functionality:

const {
    undoStack,
    redoStack,
    undo,
    redo,
    canUndo,
    canRedo,
    clearHistory,
} = useCommandHistory();

// Undo the most recent command
await undo();

// Redo the most recently undone command
await redo();

// Clear all history
clearHistory();
Property / Method Description
undoStack Read-only stack of commands that can be undone
redoStack Read-only stack of commands that can be redone
undo() Undoes the most recent command
redo() Redoes the most recently undone command
canUndo Computed boolean indicating whether undo is available
canRedo Computed boolean indicating whether redo is available
clearHistory() Clears the undo and redo stacks