mythix
v4.0.3
Published
Mythix is a NodeJS web-app framework
Downloads
32
Readme
mythix
Mythix is a NodeJS web-app framework. It is configured to have sane defaults so that you need not worry about configuration. However, it was designed such that any part of the default application can be overloaded to provide custom functionality for any components of the framework.
Install
To create a new empty mythix project:
$ npx mythix-cli create my_project_name
Or to install directly as a dependency:
$ npm i --save mythix
Application file structure
projectRoot/ ->
|-- app/
|---- commands/ (custom mythix-cli commands for your project)
|---- config/ (configuration for your web app)
|---- controllers/ (controller classes)
|---- middleware/ (custom middleware)
|---- migrations/ (migrations for your DB)
|---- models/ (all model definitions)
|---- seeders/ (database seeders)
|---- tasks/ (reoccuring/cron-type tasks)
|---- routes/ (route definitions for your web-app)
|---- application.js (application class definition)
|---- index.js (entry point for your application)
|-- .mythix-config.js (custom mythix RC)
|-- package.json
Creating the application
To create your own mythix
application, you simply need to inherit from the Mythix.Application
class:
Example:
import Path from 'node:path';
import Mythix from 'mythix';
import getRoutes from './routes/index.mjs';
import { authMiddleware } from './middleware.mjs';
export class Application extends Mythix.Application {
static getName() {
return 'my_app_name';
}
constructor(_opts) {
var opts = Object.assign({
httpServer: {
middleware: [
authMiddleware,
],
},
}, _opts || {});
super(opts);
}
getRoutes(...args) {
return getRoutes.apply(this, args);
}
}
Starting your server
All you need to do to start serving up content is to run the following command:
$ mythix-cli serve
Or, you can simply invoke your own entry point:
$ node app/index.js
Your index.js
simply needs to create an instance of your Application
class and call await appInstance.start()
on it to start your server.
Application configuration
Application configuration is defined as Javascript files under ./app/config
. To get configuration values, you use the application.getConfigValue
method. The getConfigValue
method accepts three arguments, only the first is recommended (if no arguments are passed to this method, then the entire application configuration is returned as an object).
The first argument is a full dot-notation path string to the configuration value you wish to fetch. For example: application.getConfigValue('logger.level')
.
The second argument is a "default value". If getConfigValue
doesn't find the key that you are looking for in the configuration, or if the value of the key it found is undefined
, then it will return the default value specified instead.
The final and third argument is the "type" of data you expect it to return. For example, you could specify integer
, and it would coerce the found value into an integer before returning it to you. Possible types are string
, integer
, number
, boolean
, and bigint
.
getConfigValue
can also accept template parameters for the key path. For example, you could do application.getConfigValue('database.{environment}.host')
, which would be equivilent to:
var environment = application.getConfigValue('environment');
var result = application.getConfigValue(`database.${environment}.host`);
Creating controllers
Creating new controllers is easy. All it requires is that you create a new file in the ./app/controllers
directory, and make sure you give the controller file name a -controller.js
suffix (i.e. my-controller.js
). When mythix
detects this file pattern in the ./app/controllers
directory it will load your new controller automatically (you don't even need to restart the web-server if it is currently running).
NOTE: The current version of mythix won't auto-reload your routes, so you still need to restart your application to load newly defined routes.
Once you have your new controller file created, you simply need to define your controller with a defineController
call from mythix
imports.
For example, a simple demo controller can be created by creating a new controller file named ./app/controllers/hello-world-controller.js
and placing the following contents in this file:
import { defineController } from 'mythix';
export const HelloWorld = defineController('HelloWorld', ({ Parent }) => {
return class HelloWorldController extends Parent {
async greet(params, query, body, models) {
return 'Hello World!';
}
};
});
Now, all you need to do is add your new controller to the routes:
Simply modify ./app/routes.js
to have the following content:
export function getRoutes({ path }) {
path('api', ({ path }) => {
path('v1', ({ endpoint }) => {
endpoint('greet', {
name: 'greet', // Name of the API method in Javascript
methods: [ 'GET', 'POST' ],
controller: 'UserController.showCurrentUser', // The controller to use
help: {
'description': 'Greet the user (example).',
'data': [
{
'property': 'name',
'type': 'string',
'description': 'Name to use to greet the user',
'required': true,
},
],
'params': [
{
'property': 'userID',
'type': 'string',
'description': 'ID of user to greet',
'required': true,
},
],
'example': 'await API.greet({ data: { name: \'My Name\' }, params: { userID: \'some-user-id\' } });',
'notes': [
'This is just an example help section',
'We don\'t really need a userID for params...',
'This help can be shown simply by accessing `API.greet.help` from the development console',
],
},
});
});
});
};
That is it! Now you can goto http://localhost:8001/api/v1/greet
and you will see Hello world!
in your browser.
Defining routes
Routes are defined using methods. The method getRoutes
is called on your application to build routes. When called, this method will be provided a context
as a single argument, which contains path
, endpoint
, and capture
methods used to build routes.
Example:
export function getRoutes({ path }) {
path('api', ({ path }) => {
path('v1', ({ endpoint, capture }) => {
path('user', ({ endpoint, capture }) => {
// Create a capture named "userID"
let userID = capture('userID', { type: 'integer' });
// GET /api/v1/user/{userID}
// By default the `methods` property for each endpoint is `[ 'GET' ]`
endpoint(userID, {
name: 'getUser',
controller: 'UserController.show',
});
// PATCH /api/v1/user/{userID}
endpoint(userID, {
name: 'updateUser',
methods: [ 'PATCH' ],
controller: 'UserController.update',
});
// PATCH /api/v1/user/{userID}
endpoint(userID, {
name: 'updateUser',
methods: [ 'PATCH' ],
controller: 'UserController.update',
});
// /api/v1/user/{userID}/
path(userID, ({ endpoint }) => {
// PUT /api/v1/user/{userID}/tags
endpoint('tags', {
name: 'addUserTags',
methods: [ 'PUT' ],
controller: 'UserController.addTags',
});
// DELETE /api/v1/user/{userID}/tags
endpoint('tags', {
name: 'removeUserTags',
methods: [ 'DELETE' ],
controller: 'UserController.removeTags',
});
});
});
});
});
};
Defining models
mythix
uses mythix-orm under the hood for its ORM. See the documentation for mythix-orm
for details.
First, you need to start by defining your models with the Mythix.defineModel
method. This method needs the name of your model as its first argument, a definer
method that will return your model class, and optionally a parent model to inherit from.
Model definition files need to be placed in ./app/models
, and need to have a -model.js
suffix to be auto-loaded by mythix
.
NOTE: Model files are auto-reloaded by mythix while it is running... so if you change your model (something other than the schema), then your model will automatically be reloaded without needing to restart the web-server. Schema changes will obviously require that you create and run migrations, so the web-server must be stopped and restarted if you modify a model's fields.
Example:
import { defineModel } from 'mythix';
export const Product = defineModel('Product', ({ Parent, Types }) => {
return class Product extends Parent {
// Define the model fields, using mythix-orm
static fields = {
...(Parent.fields || {}),
id: {
type: Types.UUIDV4,
defaultValue: Types.UUIDV4.Default.UUIDV4(),
primaryKey: true,
},
name: {
type: Types.STRING(32),
allowNull: false,
index: true,
},
price: {
type: Types.NUMERIC(),
allowNull: false,
index: true,
},
// Relationship to "Orders" table
orders: {
type: Types.Models('Order', async ({ self }, { Order, LineItem }, userQuery) => {
// Pull distinct orders
return Order
.$.DISTINCT
// Joining the Order table with the LineItem table
// where LineItem.orderID equals Order.id
.id
.EQ(LineItem.where.orderID)
.AND
// And the line item contains this
// product id
.LineItem.productID
.EQ(self.id)
// Now tack on any extra query the
// user specified
.MERGE(userQuery);
}),
},
};
// Optionally define model methods
// ...
};
});
Defining commands
The mythix-cli
can load commands from mythix
, as well as custom commands you define. For example, if you create a command named deploy
, then that command can be ran like so: mythix-cli deploy
. Commands can inherit from other commands in mythix
, including commands built directly into mythix
.
A static commandArguments
method is used to define the help
for your command, and to define a Runner
to gather arguments for your command. This Runner
is a CMDed Runner
, so please refer to the CMDed documentation for how to properly create a Runner
for your command.
You can optionally define a static runtimeArguments
object, defining an array of strings arguments for each runtime
. A runtime
would be something like node
, ts-node
, or babel-node
.
There is also the static property static applicationConfig
which can be an object specifying the options for your Application
class, or, if this is a method, should return the options for your Application
class. If this is a method, then the options it returns are the only options that will be passed to your Application
class upon instantiation. If this is an object, then the mythix-cli
will deliberately merge other options in (such as { httpServer: false, runTasks: false, autoReload: false }
), as most commands don't want an HTTP server, tasks, or auto-reloading running.
Any file placed in ./app/commands/
with a -command.js
suffix will be loaded automatically as a command.
Example:
import { defineCommand } from 'mythix';
export const Deploy = defineCommand('deploy', ({ Parent }) => {
return class DeployCommand extends Parent {
static runtimeArguments = {
'node': [ '--inspect' ],
};
static commandArguments() {
return {
// CMDed help
help: {
'@usage': 'mythix-cli deploy [options]',
'@title': 'Deploy the application to the specified target servers',
'-t={target} | -t {target} | --target={target} | --target {target}': 'Target server to deploy to',
},
// CMDed runner
runner: ({ $, store, Types }) => {
$('--target', Types.STRING(), { name: 'target' })
|| $('-t', Types.STRING(), { name: 'target' })
|| store({ target: 'production' }); // Default value
return true;
},
};
}
async execute(args) {
// args contains all your command line arguments parsed
// here you would write the code to deploy your application
}
};
});
This command can now be run as follows:
$ mythix-cli deploy --target ssh://host/path/
Migrations
Unfortunately the migration commands in mythix
are currently being developed. Right now it is possible to add models and fields... soon I hope to have complete migration functionality built-in. For now, you can run the command below to add models. A similar add fields
command can be ran to add specific fields to a model:
$ mythix-cli generate migration --name new-models add models Product Order LineItem
This will create a migration in the ./app/migrations
folder to add the models Product
, Order
, and LineItem
. These specified models must already exist, and be able to be loaded by mythix
for this to work.
To run migrations: Simply invoke the following command:
$ mythix-cli migrate
Note: If you would like to help improve the migration sitation in mythix
, please feel free to submit a PR!
Middleware
mythix
uses express under the hood. So Express middleware can be used drop-in style. Or, you can create your own custom middleware using Express middleware patterns.
mythix
only has one middleware that it ships with, called conditional
in Mythix.Middleware.conditional
. This simple middleware allows you to conditionally allow a request to proceed, or conditionally use per-endpoint middleware, depending on if it has the correct Content-Type
, target controller, URL pattern, or HTTP method verb.
To use middleware, you simply need to define a middlware
property key on the httpServer
options when instantiating a Mythix.Application
. This middleware
key needs to be an array of instantiated middlewares.
Example:
class Application extends Mythix.Application {
constructor(_opts) {
var opts = Object.assign({}, {
httpServer: {
middleware: [
myCustomMiddleware,
someOtherMiddleware,
],
},
}, _opts || {});
super(opts);
}
}
Tasks
Tasks are cron-like tasks that run at a given frequency, delay, or scheduled time. They can be defined using the Mythix.defineTask
method, and should be placed inside ./app/tasks
, in files with names that have a -task.js
suffix.
Like most mythix
classes, you can call this.getApplication()
to get the application instance, this.getLogger()
to get the tasks logger, this.getModel(name)
or this.getModels()
to get application models, and this.getConnection()
to get the database connection for the running application.
Example task:
./app/tasks/custom-task.js
const {
defineTask,
TaskBase,
} = require('mythix');
export const CustomTask = defineTask('CustomTask', ({ application, Parent, time }) => {
const workerCount = application.getConfigValue('tasks.CustomTask.workers', 1, 'integer');
return class CustomTask extends Parent {
// Number of workers this task should have
static workers = workerCount;
// Run every day
static frequency = time.days(1);
// Don't start running until 30 minutes has passed
// This can be useful to "interlace" your tasks,
// so they don't all fire at once.
static startDelay = time.minutes(30);
// If 'keepAlive` is not true, then the task class
// instance will be destroyed and recreated on each
// invocation of the task.
static keepAlive = true;
// Set 'enabled = false' to disable this task from
// running.
static enabled = true;
// Execute is called every time the task
// is scheduled to run
async execute() {
// ... do some task
}
// Optionally, you can define your own "nextRun" method.
// You could use this, for example, to have your task
// run at a scheduled time.
// 'lastTime', 'currentTime', and 'diff' are in seconds
// 'taskIndex' is the index of this worker.
// This should return a Luxon DateTime object
// specifying the exact time that the task should
// run next.
static nextRun(taskIndex, lastTime, currentTime, diff) {
if (meetsScheduledTime())
return true;
// We don't pass TaskClass here because it is bound to the method
return TaskBase.nextRun(taskIndex, lastTime, currentTime, diff);
}
};
});
Mythix RC
The primary purpose of the mythix
RC file is to let the mythix-cli
know how to fetch and instantiate your Application
class. By default, mythix-cli
will expect the application class to be exported from ./app/application.js
. If not found there, it will panic, unless you tell it how to load your mythix application.
{projectRoot}/.mythix-config.js
is the location searched for to load your mythix
RC. You can also specify a --mythixConfig
argument to any invocation of mythix-cli
to tell mythix-cli
where to load this configuration file.
There is only one required method that needs to be exported from .mythix-config.js
, and it is named getApplicationClass
. This method is expected to return your own custom Application
class that extends from Mythix.application
. This is all you ever really need in the mythix RC.
However, if you want to control how your application gets instantiated, you can also optionally define and export an async createApplication
method that will create your application. This method SHOULD NOT start your application, but simply instantiate it. This method receives two arguments: Application
, and options
. Application
is the application class itself, and options
are any options that should be passed to your Application.constructor
.
When the mythix-cli
is invoked, it will always pass a { cli: true }
option to your Application class. You can use this to know if your application is running in "CLI mode".
mythix-cli
A little bit should be mentioned about how the mythix-cli
command works. When it is invoked, the first thing it does is search for your Application
class. When it finds it, it will then create an instance of your application to fetch all your application defined paths. Once it has the paths you specified for your application, it will then load all commands it finds (both internal 'mythix' commands, and any custom commands you have defined).
When a command is invoked, the mythix-cli
will deliberately launch a new process using the specified runtime
(default is node
) to execute the command specified. This is so that each command can specify its own custom runtimeArguments
(if desired).
Because of the way this works, your application will be instantiated twice:
- Once, and first, to load your application configuration (specifically your defined paths). This part of the process will not start your application, but simply instantiate it.
- Second, your application will be instantiated again in the new spawned
runtime
(defaultnode
) process, and this time your application will also be started. Once your application has been successfully instantiated and started, then the command will run.
Most commands by default will start your application with the options { httpServer: false, autoReload: false, runTasks: false }
. This informs your application NOT to start the web-server, NOT to start the task worker, and to NOT auto-reload files on change (which often isn't desired for many commands).
If a command specifies static applicationConfig
as a method, then this method is expected to return ALL options for the application, and the default options that the CLI would normally set itself are bypassed. This allows a command to fully control the application, and its options. This is used for example by the serve
command, which wants the HTTP server, auto-reloading, tasks, and all other parts of the application fully running.
Customizing behavior
mythix
was defined with decent default behavior that will work fine for most users. However, there will be times when you want different behavior. The Application
class was deliberately designed to allow you to modify the behavior of mythix
. Though I won't go into great detail here (check the source code for now, until I can write better documentation), you can overload how the HTTP server is created by adding a createHTTPServer
method to your Application
class. You can modify how database connections are created by overloading the connectToDatabase
method. Etc...
There are many more things that can be customized as well (by overloading methods). Please refer to the Application
class source code until I can write better documentation.
API
function Mythix.defineController(controllerName <string>
,definer <function>(context <object>)
, [ ParentControllerClassToInheritFrom <class> ]
)
Description
Create a new controller class, giving your controller the name specified by the controllerName
argument. The definer
method will be invoked immediately upon the call to Mythix.defineController
, and is expected to return a new controller class that inherits from context.Parent
. context.Parent
by default (if no ParentControllerClassToInheritFrom
argument is specified) will be Mythix.ControllerBase
.
Arguments
- controllerName
<string>
- Specify the name of your controller. - definer
function(context <object>)
- Callback method that is used to create your controller class. This method is expected to return a new controller class.context
:Parent
- The parent class your controller should inherit from. If no parent controller class was specified as the third argumentParentControllerClassToInheritFrom
, then this defaults toMythix.ControllerBase
.application
- Themythix
application instance of the currently running application.server
- The HTTP server instance of the currently runningmythix
application.controllerName
- The controller name, as defined by thecontrollerName
argument.
- (optional) ParentControllerClassToInheritFrom
<class extends Mythix.ControllerBase>
- If specified, this this will be assigned tocontext.Parent
, which your controller class should always extend from.
Return
The return value will be a controller class, inherited from Mythix.ControllerBase
.
Example
import { defineController } from 'mythix';
export const HelloWorld = defineController(
'HelloWorld',
({ Parent, application }) => {
// Here we can load configuration values if we want
const someConfigValue = application.getConfigValue(
// Path of config value to fetch
'some.custome.config.value',
// Defualt value to return instead (if not found)
'defaultConfigValue',
// Type of value being fetched.
// The value will be coerced to this
// if specified.
'string',
);
return class HelloWorldController extends Parent {
async greet(params, query, body, models) {
return 'Hello World!';
}
};
}
);
function Mythix.defineModel(modelName <string>
,definer <function>(context <object>)
, [ ParentModelClassToInheritFrom <class> ]
)
Description
Create a new model class, giving your model the name specified by the modelName
argument. The definer
method will be invoked immediately upon the call to Mythix.defineModel
, and is expected to return a new model class that inherits from context.Parent
. context.Parent
by default (if no ParentModelClassToInheritFrom
argument is specified) will be Mythix.ModelBase
.
Static Class Properties
- static pluralName
<string>
- The plural name of of your model. If this is set, thenmythix
won't guess the plural name, and will use this as the model's plural name instead.
Arguments
- modelName
<string>
- Specify the name of your model. - definer
function(context <object>)
- Callback method that is used to create your controller class. This method is expected to return a new controller class.context
:Parent
- The parent class your model should inherit from. If no parent model class was specified as the third argumentParentModelClassToInheritFrom
, then this defaults toMythix.ModelBase
.application
- Themythix
application instance of the currently running application.Types
- A shortcut forMythixORM.Types
.connection
- The database connection used by the currently runningmythix
application. This is amythix-orm
connection.modelName
- The samemodelName
string given to the call todefineModel
.
- (optional) ParentModelClassToInheritFrom
<class extends Mythix.ModelBase>
- If specified, this this will be assigned tocontext.Parent
, which your model class should always extend from.
Return
The return value will be a model class, inherited from Mythix.ModelBase
.
Example
import { defineModel } from 'mythix';
export const Product = defineModel('Product', ({ Parent, Types }) => {
return class Product extends Parent {
// Define the model fields, using mythix-orm
static fields = {
...(Parent.fields || {}),
id: {
type: Types.UUIDV4,
defaultValue: Types.UUIDV4.Default.UUIDV4(),
primaryKey: true,
},
name: {
type: Types.STRING(32),
allowNull: false,
index: true,
},
price: {
type: Types.NUMERIC(),
allowNull: false,
index: true,
},
// Relationship to "Orders" table
orders: {
type: Types.Models('Order', async ({ self }, { Order, LineItem }, userQuery) => {
// Pull distinct orders
return Order
.$.DISTINCT
// Joining the Order table with the LineItem table
// where LineItem.orderID equals Order.id
.id
.EQ(LineItem.where.orderID)
.AND
// And the line item contains this
// product id
.LineItem.productID
.EQ(self.id)
// Now tack on any extra query the
// user specified
.MERGE(userQuery);
}),
},
};
// Optionally define model methods
// ...
};
});
function Mythix.defineCommand(commandName <string>
,definer <function>(context <object>)
, [ ParentCommandClassNameToInheritFrom <string> ]
)
Description
Note: This section is outdated... command arguments have been changed to use the cmded module. Refer to mythix
built-in commands for examples on the new command line argument interface.
Create a new command class, giving your command the name specified by the commandName
argument (all lower-case). The definer
method will be invoked immediately upon the call to Mythix.defineCommand
, and is expected to return a new controller class that inherits from context.Parent
. context.Parent
by default (if no ParentCommandClassNameToInheritFrom
argument is specified) will be Mythix.CommandBase
.
Static Class Properties
- static description
<string>
- The description to give to this command. If this is not provided, then your command's "help" will not be shown when you runmythix-cli --help
. - static runtimeArguments
{ [key: string]: <Array[<string>]> }
- An object containing runtime name keys, where each key value is an array of string arguments to use as command line arguments when invoking your command with the specified runtime. These are NOT your command's arguments, but rather the arguments to give to the specified runtime. For example, for the defaultnode
runtime, this might look something like{ node: [ '--inspect' ] }
. - static commandArguments
<string>
- A string containing your command arguments, their descriptions, their types, and their default values. simple-yargs is used to parse these command argument strings, so refer to its documentation for how to define your command arguments. - static applicationConfig
<object> | <function>
- Define the options passed to yourApplication.constructor
. If this is a simple object, then themythix-cli
will inject some default options that make sense for most commands. If this is a function, then it should return an options object. When this is a function, themythix-cli
will not inject any arguments, but instead will pass your options directly toApplication.constructor
without modification.
Arguments
- commandName
<string>
- Specify the name of your command (must be all lower-case). - definer
function(context <object>)
- Callback method that is used to create your command class. This method is expected to return a new command class.context
:Parent
- The parent class your controller should inherit from. If no parent controller class was specified as the third argumentParentCommandClassNameToInheritFrom
, then this defaults toMythix.CommandBase
.commandName
- The command name, as defined by thecommandName
argument (lower-cased).
- (optional) ParentCommandClassNameToInheritFrom
<string>
- If specified, this this will be the name of the class assigned tocontext.Parent
, which your command class should always extend from.Note: This is a string that is a command NAME. This is required, because the command class you want to inherit from is dynamically loaded at start, so the name of a command is used to inherit from instead of a class directly.
Return
The return value will be a command class, inherited from Mythix.CommandBase
.
Example
import { defineCommand } from 'mythix';
export const Deploy = defineCommand('deploy', ({ Parent }) => {
return class DeployCommand extends Parent {
static definition = 'Deploy application to servers';
static commandArguments = '<-target:string(Target server to deploy to)';
async execute(args) {
// args contains all your command line arguments parsed
// here you would write the code to deploy your application
}
};
});
function Mythix.defineTask(taskName <string>
,definer <function>(context <object>)
, [ ParentTaskClassToInheritFrom <class> ]
)
Description
Create a new task class, giving your task the name specified by the taskName
argument. The definer
method will be invoked immediately upon the call to Mythix.defineTask
, and is expected to return a new task class that inherits from context.Parent
. context.Parent
by default (if no ParentTaskClassToInheritFrom
argument is specified) will be Mythix.TaskBase
.
Tasks are cron-like, in that they are run every so-often. mythix
will wait on any running tasks before it stops, and will call the stop
method on all tasks when it is shutting down.
Static Class Properties
- static enabled
<boolean>
- If this isfalse
, then your task will never run. - static frequency
<number>
- The number of seconds of "frequency" to run this task. Specifying1
for example would run your task ever one second. - static startDelay
<number>
- The number of seconds of delay before first running this task. Specifying10
for example would run your task ten seconds after the application starts. This can be useful to interlace tasks, so they don't all run at once. - static workers
<number>
- The number of workers to run. For example, specifying a value of4
would mean that your task would be running four instances at any given time. - static keepAlive
<boolean>
- By default, tasks instances are destroyed and recreated upon every invocation of the task. If you specifystatic keepAlive = true
, then your task instances will instead be held in memory and re-used upon every invocation. This can be useful if you need expensive operations that run the first time the task is created.
Arguments
- taskName
<string>
- Specify the name of your task. - definer
function(context <object>)
- Callback method that is used to create your task class. This method is expected to return a new task class.context
:Parent
- The parent class your task should inherit from. If no parent task class was specified as the third argumentParentTaskClassToInheritFrom
, then this defaults toMythix.TaskBase
.application
- Themythix
application instance of the currently running application.Sequelize
-Sequelize
module that was loaded bymythix
.connection
- The database connection used by the currently runningmythix
application. This is an instance ofsequelize
.taskName
- The sametaskName
string given to the call todefineModel
.dbConfig
- The database config object, used to connect to the database withSequelize
.time
- This is an instance of the internal classTimeHelpers
. It is a simple interface to allow easily defining time based ondays
,hours
,minutes
, andseconds
. It is recommended that you use this for the static propertiesfrequency
andstartDelay
. i.e.static frequency = time.days(1).hours(8).minutes(30)
.
- (optional) ParentTaskClassToInheritFrom
<class extends Mythix.TaskBase>
- If specified, this this will be assigned tocontext.Parent
, which your task class should always extend from.
Return
The return value will be a task class, inherited from Mythix.TaskBase
.
Example
import { defineTask } from 'mythix';
export const CustomTask = defineTask('CustomTask', ({ Parent, time }) => {
return class CustomTask extends Parent {
static workers = 4;
static frequency = time.days(1);
static startDelay = time.minutes(30);
static keepAlive = true;
static enabled = true;
// Execute is called every time the task
// is scheduled to run
async execute() {
// ... do some task
}
};
});
TODO:
Continue writing documentation... Help would be appreciated!