Plugin System

import { type BlobType, type Fn, createPlugin } from '@sirutils/core'

const cronPlugin = createPlugin(
  {
    name: 'cron',
    version: '0.0.1',
  },
  () => {
    const $store = new Map<string, Fn<BlobType, BlobType>[]>()

    return {
      $store,
      add(duration: string, cb: Fn<BlobType, BlobType>) {
        const found = $store.get(duration)

        if (!found) {
          $store.set(duration, [cb])

          return true
        }

        $store.set(duration, [...found, cb])

        return false
      },
    }
  },
  '?cron-plugin',
  { a: 5 as number }
)

This code demonstrates how to create a plugin system using TypeScript. The system allows for defining and registering plugins and their associated actions. The primary components include CronApi, cronActions, cronPlugin, and the createPlugin utility function. Below is a detailed explanation of the code:

Interfaces and Types

interface CronApi {
  $store: Map<string, Fn<BlobType, BlobType>[]>
  add(duration: string, cb: Fn<BlobType, BlobType>): boolean
}
  • CronApi: Defines an interface for a simple cron-like API.
    • $store: A map that stores cron jobs, where the key is a cron expression (e.g., * * * * *), and the value is an array of callback functions.
    • add: A method that adds a new cron job to the store. It returns true if the cron job is newly added, and false if it already existed.

Creating Actions

const cronActions = createActions(
  (ctx: Sirutils.PluginSystem.Context<unknown, CronApi>) => ({
    delete(duration: string) {
      ctx.api.$store.delete(duration)
      return true
    },
  }),
  '?cron-actions'
)
  • cronActions: Defines actions for the cron system.
    • delete: Removes a cron job from the $store based on the duration (cron expression).

Creating the Cron Plugin

const cronPlugin = createPlugin(
  {
    name: 'cron',
    version: '0.0.1',
  },
  () => {
    const $store = new Map<string, Fn<BlobType, BlobType>[]>()

    return {
      $store,
      add(duration: string, cb: Fn<BlobType, BlobType>) {
        const found = $store.get(duration)

        if (!found) {
          $store.set(duration, [cb])
          return true
        }

        $store.set(duration, [...found, cb])
        return false
      },
    }
  },
  '?cron-plugin',
  { a: 5 as number }
).register(cronActions)
  • cronPlugin: Uses createPlugin to define a plugin with a cron API.
    • name and version: Metadata for the plugin.
    • pluginInitiator: Initializes the plugin by creating a $store to hold cron jobs and providing the add method to add jobs to the store.
    • defaultOptions: Specifies a default option ({ a: 5 }) which can be overridden when the plugin is instantiated.
    • register: Registers the cronActions with the plugin, adding the delete action to the plugin's API.

Using the Plugin

const cron = await cronPlugin({
  a: 56,
})

cron.api.add('* * * * *', () => {
  console.log('here')
})
  • cron: Instantiates the plugin with options ({ a: 56 }).
  • add: Adds a new cron job with the expression * * * * * that logs "here" to the console every minute.