Skip to content

@sodacore/core

The @sodacore/core package is the main package of Soda Core framework. It provides the core functionality and features required to build applications using Sodacore.

WARNING

This section of the documentation simply goes over the core framework information that isn't specified in other places like the guides, or concepts, most of the information you need to get started can be found in the Concepts section.

Installation

You can install the @sodacore/core package using bun:

bash
bun install @sodacore/core

Or you can use our Create package.

Quickstart

To create an instance of the Sodacore application, you can simply:

ts
import { Application } from '@sodacore/core';

// Initialise application.
const app = new Application({
	autowire: true,
	password: 'test123',
	hostname: '127.0.0.1',
	enableCli: true,
});

// Start the application.
app.start().catch(console.error);

Configuration

The configuration options only focus on the core framework, each plugin will implement it's own settings.

ts
export type IConfig = {
	name?: string,			// Name of the application.
	logger?: Logger,		// * A custom logger instance, should implement the ILogger interface.
	autowire?: boolean,		// ** Whether to enable autowiring of dependencies, default: true.
	basePath?: string,		// *** Base path for the application, default: process.cwd().
	enableCli?: boolean,	// Whether to enable the CLI, default: true.
	password?: string,		// Password used for connecting to the CLI.
	hostname?: string, 		// Hostname used to bind the CLI to, default: 'localhost'.
	port?: number,			// Port used to bind the CLI to, default: 4000.
};

NOTE

* Autowiring allows the framework to automatically resolve and inject dependencies into your classes and services alongside regisering your business logic, making it easier to manage and scale your application. If you do not wish to use this feature, you will need to manually register and manage your dependencies, you can do this by calling: app.register(MyClass) ensure you pass the class and NOT an instance of the class.

NOTE

** If you don't provide a custom logger, a default console logger will be used, this simply logs to the console and does not write to any files.

NOTE

*** The base path is used to resolve relative paths for autowiring, by default we will look at the src folder, but you can change this by setting the basePath option, and ensure for production you use an ENV variable to set it to the correct folder, for example dist.

Base Classes

The core framework contains a set of base classes, that other packages build upon, these include:

  • BaseModule - Similar to BaseService but used internally for all non-service features.
  • BasePlugin - The base class for all plugins class definitions, implements a setup function to deal with register your configuration.
  • BaseService - The base class for all service class definitions, adds the logger and sets up fallbacks for the init, start and stop lifecycle methods.
  • BaseTask - The base class for all task class definitions, adds the logger and sets up fallbacks for the init and run methods.
  • BaseWorker - The base class for all worker class definitions, adds a way of getting the thread ID.

Bootstrap

The core framework also provides a Worker bootstrap file, this is used by the Worker feature to start a new worker thread, and is the entry point for the worker thread, it simply handles getting the worker class up and running and then initialising a wrapper for IPC.

Context

The core framework provides the Script features, for example with handling logging, prompts and session information for the interactive CLI, and of course the ScriptContext that is used to provide context to scripts when they are run.

Decorators

There are many decorators provided by the framework that plugins (or applications) can use:

  • @Autoload(priority: number) - This can be added to classes to set the autoload priority, higher numbers load later, default is 50 (without the decorator).
  • @Catch(response: CatchResponseType = 'error', customResponse?: unknown) - This can be added to methods to catch errors and return a specific response instead (cleaner way of handling try/catch).
  • @Expose() - This method is used to expose worker methods to be callable via IPC, by default, calling a worker method from the main thread will just call it in the same process, but with this decorator, it will be called in the worker thread.
  • @Hook(type: IHookType) - This can be added to methods to register them as hooks for specific events.
  • @Script(name: string) - This can be added to classes to register them as scripts that can be run from the CLI.
  • @Service() - This can be added to classes to register them as services that can be autowired and injected into other classes.
  • @Task(schedule?: string, settings?: ITaskSettings) - This can be added to classes to register them as tasks that can be scheduled and run by the Task feature.
  • @Worker(filename: string, options?: IWorkerOptions) - This can be added to classes to register them as workers that can be run in separate threads.

Helper Functions

The core framework provides several helper functions that can be used throughout your application, and can be imported as:

ts
import { Utils } from '@sodacore/core';

Utils.normalise('Some\\Path/To\\Normalise'); // 'Some/Path/To/Normalise'
  • normalise(path: string): string - Normalises a file path to use forward slashes.
  • resolve(base: string, ...paths: string[]): string - Resolves a file path relative to a base path. (similar to path.resolve).
  • isJson(data: string): boolean - Checks if a string is valid JSON.
  • isConvertable(value: any): boolean - Checks if a value can be converted to a primitive for transfer.
  • formatBytes(bytes: number, decimals = 2, isBinary = false): string - Formats a number of bytes into a human-readable string.

Internal Modules

The core framework uses a lot of internal modules to handle various features, these include:

  • Application - The main application class that handles starting and stopping the application, as well as managing plugins and services.
  • Autowire - The autowiring module that handles resolving and importing application modules, like services, controllers, etc.
  • Events - The event module that handles registering and emitting events throughout the application, used for hooks and event listeners.
  • Scripts - The script module that handles registering and running scripts from the CLI.
  • Services - The service module that handles registering and managing services within the application.
  • Tasks - The task module that handles registering and scheduling tasks to be run.
  • Worker - The worker wrapper that wraps worker threads and handles IPC communication, allows your code to focus on business logic.
  • Workers - The worker module that handles registering and managing worker threads.

Providers

The core framework also provides several providers that can be used to access common functionality, these include:

  • Logger - The default console logger.
  • Tasks - The task provider that allows you to access and execute registered tasks.
  • Workers - The worker provider that allows you to access and communicate with registered workers.

Scripts

The core framework provides several built-in scripts that can be run from the CLI, these include:

  • core:logs:watch - Watches the application logs in real-time.
  • core:usage:info - Displays information about the application's resource usage.
  • core:task:run - Allows you to run a specific task, is interactive and will prompt you to select a task to run.

Released under the Apache-2.0 License.