File size: 3,197 Bytes
61d39e2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# 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:

```javascript

const {

    Kernel,

    CoreModule,

    DatabaseModule,

    LocalDiskStorageModule,

    SelfHostedModule

} = (await import('@heyputer/backend')).default;



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](../../../putility/README.md)
and implements
an `install` method. The install method has one parameter, a
[Context](../../src/util/context.js)
object containing all the values kernel modules have access to. This
includes the `services`
[Container](../../src/services/Container.js`).

A module adds services to Puter.eA typical module may look something
like this:

```javascript

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](../../src/services/BaseService.js)
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](./boot-sequence.md)

A typical service may look like this:

```javascript

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'] () {}

}

```