Ver código fonte

dev: add an example module and service

KernelDeimos 5 meses atrás
pai
commit
e301247bfc

+ 2 - 0
src/backend/exports.js

@@ -30,6 +30,7 @@ const { PuterAIModule } = require("./src/modules/puterai/PuterAIModule.js");
 const { BroadcastModule } = require("./src/modules/broadcast/BroadcastModule.js");
 const { WebModule } = require("./src/modules/web/WebModule.js");
 const { Core2Module } = require("./src/modules/core/Core2Module.js");
+const { TemplateModule } = require("./src/modules/template/TemplateModule.js");
 
 
 module.exports = {
@@ -49,6 +50,7 @@ module.exports = {
         Core2Module,
         CoreModule,
         WebModule,
+        TemplateModule,
     ],
 
     // Pre-built modules

+ 56 - 0
src/backend/src/modules/template/README.md

@@ -0,0 +1,56 @@
+# TemplateModule
+
+This is a template module that you can copy and paste to create new modules.
+
+This module is also included in `EssentialModules`, which means it will load
+when Puter boots. If you're just testing something, you can add it here
+temporarily.
+
+## Services
+
+### TemplateService
+
+This is a template service that you can copy and paste to create new services.
+You can also add to this service temporarily to test something.
+
+#### Listeners
+
+##### `install.routes`
+
+TemplateService listens to this event to provide an example endpoint
+
+##### `boot.consolidation`
+
+TemplateService listens to this event to provide an example event
+
+##### `boot.activation`
+
+TemplateService listens to this event to show you that it's here
+
+##### `start.webserver`
+
+TemplateService listens to this event to show you that it's here
+
+## Libraries
+
+### hello_world
+
+#### Functions
+
+##### `hello_world`
+
+This is a simple function that returns a string.
+You can probably guess what string it returns.
+
+## Notes
+
+### Outside Imports
+
+This module has external relative imports. When these are
+removed it may become possible to move this module to an
+extension.
+
+**Imports:**
+- `../../util/context.js`
+- `../../services/BaseService` (use.BaseService)
+- `../../util/expressutil`

+ 53 - 0
src/backend/src/modules/template/TemplateModule.js

@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2024 Puter Technologies Inc.
+ *
+ * This file is part of Puter.
+ *
+ * Puter is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+const { AdvancedBase } = require("@heyputer/putility");
+
+/**
+ * This is a template module that you can copy and paste to create new modules.
+ * 
+ * This module is also included in `EssentialModules`, which means it will load
+ * when Puter boots. If you're just testing something, you can add it here
+ * temporarily.
+ */
+class TemplateModule extends AdvancedBase {
+    async install (context) {
+        // === LIBS === //
+        const useapi = context.get('useapi');
+
+        const lib = require('./lib/__lib__.js');
+        
+        // In extensions: use('workinprogress').hello_world();
+        // In services classes: see TemplateService.js
+        useapi.def(`workinprogress`, lib, { assign: true });
+        
+        useapi.def('core.context', require('../../util/context.js').Context);
+        
+        // === SERVICES === //
+        const services = context.get('services');
+
+        const { TemplateService } = require('./TemplateService.js');
+        services.registerService('template-service', TemplateService);
+    }
+
+}
+
+module.exports = {
+    TemplateModule
+};

+ 99 - 0
src/backend/src/modules/template/TemplateService.js

@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2024 Puter Technologies Inc.
+ *
+ * This file is part of Puter.
+ *
+ * Puter is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+// TODO: import via `USE` static member
+const BaseService = require("../../services/BaseService");
+const { Endpoint } = require("../../util/expressutil");
+
+/**
+ * This is a template service that you can copy and paste to create new services.
+ * You can also add to this service temporarily to test something.
+ */
+class TemplateService extends BaseService {
+    static USE = {
+        // - Defined by lib/__lib__.js,
+        // - Exposed to `useapi` by TemplateModule.js
+        workinprogress: 'workinprogress'
+    }
+    
+    _construct () {
+        // Use this override to initialize instance variables.
+    }
+    
+    async _init () {
+        // This is where you initialize the service and prepare
+        // for the consolidation phase.
+        this.log.info("I am the template service.");
+    }
+    
+    /**
+     * TemplateService listens to this event to provide an example endpoint
+     */
+    ['__on_install.routes'] (_, { app }) {
+        this.log.info("TemplateService get the event for installing endpoint.");
+        Endpoint({
+            route: '/example-endpoint',
+            methods: ['GET'],
+            handler: async (req, res) => {
+                res.send(this.workinprogress.hello_world());
+            }
+        }).attach(app);
+        // ^ Don't forget to attach the endpoint to the app!
+        //   it's very easy to forget this step.
+    }
+    
+    /**
+     * TemplateService listens to this event to provide an example event
+     */
+    ['__on_boot.consolidation'] () {
+        // At this stage, all services have been initialized and it is
+        // safe to start emitting events.
+        this.log.info("TemplateService sees consolidation boot phase.");
+        
+        const svc_event = this.services.get('event');
+        
+        svc_event.on('template-service.hello', (_eventid, event_data) => {
+            this.log.info('template-service said hello to itself; this is expected', {
+                event_data,
+            });
+        });
+        
+        svc_event.emit('template-service.hello', {
+            message: 'Hello all you other services! I am the template service.'
+        });
+    }
+    /**
+     * TemplateService listens to this event to show you that it's here
+     */
+    ['__on_boot.activation'] () {
+        this.log.info("TemplateService sees activation boot phase.");
+    }
+
+    /**
+     * TemplateService listens to this event to show you that it's here
+     */
+    ['__on_start.webserver'] () {
+        this.log.info("TemplateService sees it's time to start web servers.");
+    }
+}
+
+module.exports = {
+    TemplateService
+};
+

+ 3 - 0
src/backend/src/modules/template/lib/__lib__.js

@@ -0,0 +1,3 @@
+module.exports = {
+    hello_world: require('./hello_world.js'),
+};

+ 10 - 0
src/backend/src/modules/template/lib/hello_world.js

@@ -0,0 +1,10 @@
+
+/**
+ * This is a simple function that returns a string.
+ * You can probably guess what string it returns.
+ */
+const hello_world = () => {
+    return "Hello, world!";
+}
+
+module.exports = hello_world;