Ver código fonte

:tada: first commit

master
J 3 anos atrás
commit
0b4a363088

+ 1
- 0
.gitignore Ver arquivo

1
+node_modules

+ 3
- 0
README.md Ver arquivo

1
+# Final Countdown
2
+
3
+Bree job running with a small htmx gui

+ 16
- 0
jobs/heartbeat.js Ver arquivo

1
+const path = require('path')
2
+const jobDef = {
3
+    timeout: false,
4
+    interval: '10s'
5
+}
6
+
7
+/**
8
+ * Actual job instructions
9
+ */
10
+const jobRun = () => {
11
+    console.log('beep')
12
+    return 'boop'
13
+}
14
+jobRun()
15
+
16
+module.exports = { jobName: path.basename(__filename, '.js'), ...jobDef }

+ 46
- 0
jobs/index.js Ver arquivo

1
+const defs = [
2
+    require("./setup"),
3
+    require("./heartbeat")
4
+]
5
+
6
+class Job {
7
+    constructor({ jobName, timeout, interval }) {
8
+        this.name = jobName
9
+        this.timeout = timeout
10
+        this.interval = interval
11
+    }
12
+}
13
+
14
+class JobFactory {
15
+    constructor() {
16
+        this.jobs = []
17
+        this.addJobsFromDefs({ defs })
18
+    }
19
+    /**
20
+     * Force using of Job objects for validating
21
+     */
22
+    createJob({ jobName, timeout, interval }) {
23
+        return new Job({ jobName, timeout, interval })
24
+    }
25
+    /**
26
+     * Only store the job if it is
27
+     * a valid Job instance
28
+     */
29
+    addJobFromDef(jobDef) {
30
+        const job = this.createJob(jobDef)
31
+        if (job) {
32
+            this.jobs.push(job)
33
+        }
34
+    }
35
+    /**
36
+     * Take in job definitions from accompanying
37
+     * job files. Job files must include and
38
+     * execute a jobRun()
39
+     */
40
+    addJobsFromDefs({ defs }) {
41
+        defs.forEach(def => this.addJobFromDef(def))
42
+    }
43
+}
44
+
45
+const jobFactory = new JobFactory()
46
+module.exports = jobFactory

+ 16
- 0
jobs/setup.js Ver arquivo

1
+const path = require('path')
2
+const jobDef = {
3
+    timeout: '1s',
4
+}
5
+
6
+/**
7
+ * Actual job instructions
8
+ */
9
+const jobRun = () => {
10
+    console.log('---')
11
+    console.log('bree started...')
12
+    console.log('---')
13
+}
14
+jobRun()
15
+
16
+module.exports = { jobName: path.basename(__filename, '.js'), ...jobDef }

+ 35
- 0
lib/index.js Ver arquivo

1
+const Vision = require('@hapi/vision')
2
+const Pug = require('pug')
3
+
4
+const { all } = require('../plugins')
5
+
6
+/**
7
+ * A Hapi server instance
8
+ * @typedef {Object} Server
9
+ */
10
+
11
+/**
12
+ * A plugin for Hapi
13
+ * @typedef {Object} Plugin
14
+ */
15
+exports.plugin = {
16
+    name: 'main-app-plugin',
17
+
18
+    /**
19
+     * Main Hapi plugin that grabs all our
20
+     * other plugins to create the API app
21
+     * @param {Server} server
22
+     * @param {Object} options
23
+     */
24
+    register: async (server, options) => {
25
+        // My custom plugins
26
+        for(let plug of all) await server.register(plug, plug.opts)
27
+
28
+        await server.register(Vision)
29
+        server.views({
30
+            engines: { pug: Pug },
31
+            relativeTo: __dirname ,
32
+            path: 'templates'
33
+        })
34
+    },
35
+}

+ 12
- 0
lib/templates/index/index.pug Ver arquivo

1
+extends ../layouts/_layout.pug
2
+
3
+block header
4
+    h1 #{title}
5
+
6
+block content
7
+    section.container
8
+        p #{message}
9
+        button(hx-post="/client/clicked" hx-swap="outerHTML") click
10
+
11
+block footer
12
+    p footie

+ 11
- 0
lib/templates/index/partials/on_click.pug Ver arquivo

1
+button(hx-post="/client/clicked" hx-swap="outerHTML") #{msg}
2
+p #{h}
3
+ul
4
+  each job in jobs
5
+    li
6
+        p name: 
7
+            span= job.name
8
+        p timout: 
9
+            span= job.timeout ? job.timeout : 'false'
10
+        p interval: 
11
+            span= job.interval ? job.interval : 'false'

+ 13
- 0
lib/templates/layouts/_layout.pug Ver arquivo

1
+doctype html
2
+html(lang='en')
3
+    head
4
+        title Client test
5
+        script(src="https://unpkg.com/htmx.org@1.8.0" integrity="sha384-cZuAZ+ZbwkNRnrKi05G/fjBX+azI9DNOkNYysZ0I/X5ZFgsmMiBXgDZof30F5ofc" crossorigin="anonymous")
6
+
7
+    body
8
+        header
9
+            block header
10
+        main
11
+            block content
12
+        footer
13
+            block footer

+ 36
- 0
manifest.js Ver arquivo

1
+const Confidence = require('@hapipal/confidence')
2
+
3
+/** Glue manifest as a confidence store */
4
+module.exports = new Confidence.Store({
5
+    server: {
6
+        host: 'localhost',
7
+        port: {
8
+            $filter: 'NODE_ENV',
9
+            $default: {
10
+                $param: 'API_PORT',
11
+                $coerce: 'number',
12
+                $default: 3001,
13
+            },
14
+            test: { $value: undefined }, // Let the server find an open port
15
+        },
16
+        debug: {
17
+            $filter: 'NODE_ENV',
18
+            $default: {
19
+                log: ['error', 'start'],
20
+                request: ['error'],
21
+            },
22
+            production: {
23
+                request: ['implementation'],
24
+            },
25
+        },
26
+    },
27
+    register: {
28
+        plugins: [
29
+            /** Main app */
30
+            {
31
+                plugin: './lib',
32
+                options: {},
33
+            },
34
+        ],
35
+    },
36
+})

+ 997
- 0
package-lock.json
Diferenças do arquivo suprimidas por serem muito extensas
Ver arquivo


+ 24
- 0
package.json Ver arquivo

1
+{
2
+  "name": "final-countdown",
3
+  "version": "1.0.0",
4
+  "description": "schedule all the things",
5
+  "main": "server.js",
6
+  "scripts": {
7
+    "dev": "node ./server.js",
8
+    "test": "echo \"Error: no test specified\" && exit 1"
9
+  },
10
+  "author": "toj",
11
+  "license": "UNLICENSED",
12
+  "dependencies": {
13
+    "@hapi/glue": "^8.0.0",
14
+    "@hapi/hapi": "^20.2.2",
15
+    "@hapi/vision": "^7.0.0",
16
+    "@hapipal/confidence": "^6.0.2",
17
+    "@hapipal/schmervice": "^2.0.0",
18
+    "bree": "^9.1.1",
19
+    "exiting": "^6.1.0",
20
+    "htmx.org": "^1.8.0",
21
+    "joi": "^17.6.0",
22
+    "pug": "^3.0.2"
23
+  }
24
+}

+ 24
- 0
plugins/client.js Ver arquivo

1
+const Schmervice = require('@hapipal/schmervice')
2
+
3
+const all = require('../routes/client')
4
+// const UserService = require('./services/user')
5
+
6
+module.exports = {
7
+    name: 'client-plugin',
8
+    version: '1.0.0',
9
+    opts: {}, // No need to prefix the gui
10
+    register: async (server, options) => {
11
+
12
+        // Bind to global context
13
+        // So we can use Objection transactions
14
+        server.bind({
15
+            transaction: fn => ({ foo: 'bar' }),
16
+        })
17
+
18
+        await server.register(Schmervice)
19
+        // server.registerService(UserService)
20
+        for(let route of all) {
21
+            await server.route(route)
22
+        }
23
+    },
24
+}

+ 6
- 0
plugins/index.js Ver arquivo

1
+module.exports = {
2
+    all: [
3
+        require('../plugins/client'),
4
+        require('../plugins/scheduler')
5
+    ]
6
+}

+ 24
- 0
plugins/scheduler.js Ver arquivo

1
+const Schmervice = require('@hapipal/schmervice')
2
+
3
+// const UserCurrentRoute = require('./routes/user/current')
4
+const Timeline = require('../services/timeline.service')
5
+
6
+module.exports = {
7
+    name: 'scheduler-plugin',
8
+    version: '1.0.0',
9
+    opts: { 
10
+        routes: { prefix: '/scheduler' }
11
+    },
12
+    register: async (server, options) => {
13
+
14
+        // Bind to global context
15
+        // So we can use Objection transactions
16
+        server.bind({
17
+            transaction: fn => ({ foo: 'bar' }),
18
+        })
19
+
20
+        await server.register(Schmervice)
21
+        server.registerService(Timeline)
22
+        // await server.route(UserCurrentRoute)
23
+    },
24
+}

+ 22
- 0
routes/client/client.clicked.js Ver arquivo

1
+const template = 'index/partials/on_click'
2
+const action = 'client/clicked'
3
+
4
+const state = {
5
+    msg: 'wowow',
6
+    h: 'registered jobs'
7
+}
8
+
9
+const handler = (request, h) => {
10
+    const { timeline } = request.server.services()
11
+    const jobs = timeline.bree.config.jobs
12
+    return h.view(template, { ...state, jobs })
13
+}
14
+
15
+/**
16
+ * Corresponds with templates/index/partials/clicked.pug
17
+ */
18
+module.exports = {
19
+    method: 'POST',
20
+    path: `/${action}`,
21
+    options: { handler }
22
+}

+ 18
- 0
routes/client/client.js Ver arquivo

1
+const template = 'index/index'
2
+const action = 'client'
3
+
4
+const state = {
5
+    title: 'Custom Title',
6
+    message: 'hallo world'
7
+}
8
+
9
+/**
10
+ * Corresponds with templates/index/index.pug
11
+ */
12
+module.exports = {
13
+    method: 'GET',
14
+    path: `/${action}`,
15
+    options: {
16
+        handler: (request, h) => h.view(template, state)
17
+    }
18
+}

+ 7
- 0
routes/client/index.js Ver arquivo

1
+const client = require('./client')
2
+const clientClicked = require('./client.clicked')
3
+
4
+module.exports = [
5
+    client,
6
+    clientClicked
7
+]

+ 0
- 0
routes/current.js Ver arquivo


+ 30
- 0
server.js Ver arquivo

1
+const Glue = require('@hapi/glue')
2
+const Exiting = require('exiting')
3
+const Manifest = require('./manifest')
4
+/**
5
+ * Our main app server
6
+ * @param {boolean} start
7
+ * @returns {Server}
8
+ */
9
+exports.deployment = async ({ start } = {}) => {
10
+    const manifest = Manifest.get('/', process.env)
11
+    const server = await Glue.compose(manifest, { relativeTo: __dirname })
12
+
13
+    if (start) {
14
+        await Exiting.createManager(server).start()
15
+        server.log(['start'], `Server started at ${server.info.uri}`)
16
+        return server
17
+    }
18
+
19
+    // await server.initialize()
20
+
21
+    // return server
22
+}
23
+
24
+if (require.main === module) {
25
+    exports.deployment({ start: true })
26
+
27
+    process.on('unhandledRejection', (err) => {
28
+        throw err
29
+    })
30
+}

+ 36
- 0
services/timeline.service.js Ver arquivo

1
+
2
+const Schmervice = require('@hapipal/schmervice')
3
+const Bree = require('bree')
4
+
5
+const all = require('../jobs')
6
+
7
+module.exports = class Timeline extends Schmervice.Service {
8
+    constructor(...args) {
9
+        super(...args)
10
+        this.bree = new Bree({ jobs: all.jobs })
11
+        this.bree.start()
12
+    }
13
+    async start(jobName) {
14
+        if (!jobName) {
15
+            await this.bree.start()
16
+        } else {
17
+            await this.bree.start(jobName)
18
+        }
19
+        return this.bree
20
+    }
21
+    stop(jobName) {
22
+        if (!jobName) {
23
+            this.bree.stop()
24
+        } else {
25
+            this.bree.stop(jobName)
26
+        }
27
+    }
28
+    async add(jobName) {
29
+        if (!jobName) return
30
+        await this.bree.add(jobName)
31
+    }
32
+    remove(jobName) {
33
+        if (!jobName) return
34
+        this.bree.remove(jobName)
35
+    }
36
+}

Carregando…
Cancelar
Salvar