3.1 KiB
Puter Kernel Moduels and Services
Modules
A Puter kernel module is simply a collection of services that run when
the module is installed. You can find an example of this in the
run-selfhosted.js
script at the root of the Puter monorepo.
Here is the relevant excerpt in run-selfhosted.js
at the time of
writing this documentation:
const {
Kernel,
CoreModule,
DatabaseModule,
LocalDiskStorageModule,
SelfHostedModule
} = (await import('@heyputer/backend')).default;
console.log('kerne', Kernel);
const k = new Kernel();
k.add_module(new CoreModule());
k.add_module(new DatabaseModule());
k.add_module(new LocalDiskStorageModule());
k.add_module(new SelfHostedModule());
k.boot();
A few modules are added to Puter before booting. If you want to install your own modules into Puter you can edit this file for self-hosted runs or create your own script that boots Puter. This makes it possible to have deployments of Puter with custom functionality.
To function properly, Puter needs CoreModule, a database module, and a storage module.
A module extends
AdvancedBase
and implements
an install
method. The install method has one parameter, a
Context
object containing all the values kernel modules have access to. This
includes the services
Container.
A module adds services to Puter.eA typical module may look something like this:
class MyPuterModule extends AdvancedBase {
async install (context) {
const services = context.get('services');
const MyService = require('./path/to/MyService.js');
services.registerService('my-service', MyService, {
some_options: 'for-my-service',
});
}
}
Services
Services extend BaseService and provide additional functionality for Puter. They can add HTTP endpoints and register objects with other services.
When implementing a service it is important to understand Puter's boot sequence
A typical service may look like this:
class MyService extends BaseService {
static MODULES = {
// Use node's `require` function to populate this object;
// this makes these available to `this.require` and offers
// dependency-injection for unit testing.
['some-module']: require('some-module')
}
// Do not override the constructor of BaseService - use this instead!
async _construct () {
this.my_list = [];
}
// This method is called after _construct has been called on all
// other services.
async _init () {
const services = this.services;
// We can get the instances of other services here
const svc_otherService = services.get('other-service');
}
// The service container can listen on the "service event bus"
async ['__on_boot.consolidation'] () {}
async ['__on_boot.activation'] () {}
async ['__on_start.webserver'] () {}
async ['__on_install.routes'] () {}
}