@webhandle/initialize-webhandle-component 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# @webhandle/initialize-webhandle-component
|
|
2
|
+
|
|
3
|
+
Webhandle Components are a way to add services, templates, static files, middleware, or other
|
|
4
|
+
code to a webhandle instance. What the component does, how it does it, and how it exposes
|
|
5
|
+
that functionality is totally up to the component.
|
|
6
|
+
|
|
7
|
+
There are only three rules:
|
|
8
|
+
|
|
9
|
+
1. A file will exist at the root of the package, initialize-webhandle-component.mjs, that will
|
|
10
|
+
export a default async function taking a webhandle instance and options as parameters.
|
|
11
|
+
|
|
12
|
+
```js
|
|
13
|
+
export default async function setup(webhandle, options) {
|
|
14
|
+
// something here
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
2. The function is safe to invoke multiple times on the same webhandle instance.
|
|
19
|
+
|
|
20
|
+
3. The function returns an object which exposes any data or functionality that the
|
|
21
|
+
component provides. This can be an empty object if there's no exposed functionality.
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
The code in this package has some ideas about what exposed functionality looks like and
|
|
26
|
+
how to handle multiple invocations of the function. They are only suggestions and the
|
|
27
|
+
code itself in this package only exists to prevent having to copy the same boilerplate
|
|
28
|
+
over and over again.
|
|
29
|
+
|
|
30
|
+
## Install
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install @webhandle/initialize-webhandle-component.mjs
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
## Creating a Component
|
|
38
|
+
|
|
39
|
+
The initialization file can be created for you by running
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npx create-initialize-webhandle-component-file
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
This will create the file `initiailze-webhandle-component.mjs` in the current directory.
|
|
46
|
+
Make sure to go in and change the component name and add the code needed to integrate
|
|
47
|
+
your functionality.
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
## Using a Component
|
|
51
|
+
|
|
52
|
+
1. Install that component via npm like:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npm install @my/component
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
2. Import and run the setup function like:
|
|
59
|
+
|
|
60
|
+
```js
|
|
61
|
+
import setup from "@my/component/initialize-webhandle-component.mjs"
|
|
62
|
+
await setup(myWebhandleInstance, options)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
## Component Documentation
|
|
67
|
+
|
|
68
|
+
There's lots of things you'd want to document about the what your component does, but here
|
|
69
|
+
are the things you probably should mention to help callers access those functions.
|
|
70
|
+
|
|
71
|
+
On the server side:
|
|
72
|
+
|
|
73
|
+
1. The services exposed
|
|
74
|
+
2. The events emitted
|
|
75
|
+
3. The static content made available
|
|
76
|
+
4. The templates made available
|
|
77
|
+
|
|
78
|
+
On the client side:
|
|
79
|
+
|
|
80
|
+
1. The js modules supplied to client code.
|
|
81
|
+
2. The URLs at which exposed functionality is available.
|
|
82
|
+
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import EventEmitter from 'events'
|
|
2
|
+
|
|
3
|
+
export default class ComponentManager {
|
|
4
|
+
|
|
5
|
+
views;
|
|
6
|
+
templateLoaders;
|
|
7
|
+
staticPaths;
|
|
8
|
+
staticServers;
|
|
9
|
+
sinks;
|
|
10
|
+
services;
|
|
11
|
+
routers;
|
|
12
|
+
events;
|
|
13
|
+
|
|
14
|
+
constructor(options) {
|
|
15
|
+
Object.assign(this, options)
|
|
16
|
+
|
|
17
|
+
this.setIfUnset('views', [])
|
|
18
|
+
|
|
19
|
+
/* functions which load templates */
|
|
20
|
+
this.setIfUnset('templateLoaders', [])
|
|
21
|
+
|
|
22
|
+
/* info objects which contain static files to server */
|
|
23
|
+
this.setIfUnset('staticPaths', [])
|
|
24
|
+
|
|
25
|
+
/* the servers of files */
|
|
26
|
+
this.setIfUnset('staticServers', [])
|
|
27
|
+
|
|
28
|
+
/* FileSink objects which allow access to static resources */
|
|
29
|
+
this.setIfUnset('sinks', {})
|
|
30
|
+
|
|
31
|
+
/* services created to access and process data */
|
|
32
|
+
this.setIfUnset('services', {})
|
|
33
|
+
|
|
34
|
+
/* handlers for user requests */
|
|
35
|
+
this.setIfUnset('routers', [])
|
|
36
|
+
|
|
37
|
+
/* event emitters for communications between decoupled components */
|
|
38
|
+
this.setIfUnset('events', {
|
|
39
|
+
component: new EventEmitter()
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
setIfUnset(attr, value) {
|
|
44
|
+
if ((attr in this) === false) {
|
|
45
|
+
this[attr] = value
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#! /usr/local/bin/node
|
|
2
|
+
import fs from "node:fs"
|
|
3
|
+
import path from "node:path"
|
|
4
|
+
|
|
5
|
+
let filename = 'initialize-webhandle-component.mjs'
|
|
6
|
+
|
|
7
|
+
let cwd = process.cwd()
|
|
8
|
+
let packageDir = import.meta.dirname
|
|
9
|
+
let outputPath = path.join(cwd, filename)
|
|
10
|
+
let sourceFile = path.join(packageDir, filename)
|
|
11
|
+
fs.stat(outputPath, (err, stats) => {
|
|
12
|
+
if(err || !stats) {
|
|
13
|
+
fs.readFile(sourceFile, (err, data) => {
|
|
14
|
+
if(!err) {
|
|
15
|
+
data = data.toString()
|
|
16
|
+
|
|
17
|
+
// replaces the component name
|
|
18
|
+
data = data.split('@webhandle/initialize-webhandle-component').join('component' + (new Date().getTime()))
|
|
19
|
+
|
|
20
|
+
// replaces the relative includes at the top
|
|
21
|
+
data = data.split('"./').join('"@webhandle/initialize-webhandle-component/')
|
|
22
|
+
fs.writeFile(outputPath, data, (err) => {
|
|
23
|
+
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
console.error(err)
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
}
|
|
32
|
+
})
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
|
|
2
|
+
export default function createInitializeWebhandleComponent() {
|
|
3
|
+
|
|
4
|
+
const setup = async function initializeWebhandleComponent(webhandle, options) {
|
|
5
|
+
if (webhandle.id in initializeWebhandleComponent.cache) {
|
|
6
|
+
return initializeWebhandleComponent.cache[webhandle.id]
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
let config = Object.assign({}, initializeWebhandleComponent.defaultConfig, webhandle.config[initializeWebhandleComponent.componentName], options)
|
|
10
|
+
webhandle.config[initializeWebhandleComponent.componentName] = config
|
|
11
|
+
let managementObject = await initializeWebhandleComponent.setup(webhandle, config)
|
|
12
|
+
managementObject ||= {}
|
|
13
|
+
initializeWebhandleComponent.cache[webhandle.id] = managementObject
|
|
14
|
+
webhandle.componentManagers[initializeWebhandleComponent.componentName] = managementObject
|
|
15
|
+
|
|
16
|
+
managementObject.webhandle = webhandle
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
return managementObject
|
|
21
|
+
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
setup.cache = {}
|
|
25
|
+
setup.defaultConfig = {}
|
|
26
|
+
return setup
|
|
27
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import createInitializeWebhandleComponent from "./create-initialize-webhandle-component.mjs"
|
|
2
|
+
import ComponentManager from "./component-manager.mjs"
|
|
3
|
+
import path from "node:path"
|
|
4
|
+
|
|
5
|
+
let initializeWebhandleComponent = createInitializeWebhandleComponent()
|
|
6
|
+
|
|
7
|
+
initializeWebhandleComponent.componentName = '@webhandle/initialize-webhandle-component'
|
|
8
|
+
initializeWebhandleComponent.componentDir = import.meta.dirname
|
|
9
|
+
initializeWebhandleComponent.defaultConfig = {}
|
|
10
|
+
initializeWebhandleComponent.staticFilePaths = ['public']
|
|
11
|
+
initializeWebhandleComponent.templatePaths = ['views']
|
|
12
|
+
|
|
13
|
+
initializeWebhandleComponent.setup = async function(webhandle, config) {
|
|
14
|
+
let manager = new ComponentManager()
|
|
15
|
+
|
|
16
|
+
for(let filePath of initializeWebhandleComponent.staticFilePaths) {
|
|
17
|
+
manager.staticPaths.push(webhandle.addStaticDir(path.join(initializeWebhandleComponent.componentDir, filePath)))
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
for(let templatePath of initializeWebhandleComponent.templatePaths) {
|
|
21
|
+
webhandle.addTemplateDir(path.join(initializeWebhandleComponent.componentDir, templatePath))
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return manager
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default initializeWebhandleComponent
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@webhandle/initialize-webhandle-component",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Boilerplate code for a module to add itself to a webhandle instance",
|
|
5
|
+
"main": "create-initialize-webhandle-component.mjs",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"bin": {
|
|
10
|
+
"create-initialize-webhandle-component-file": "create-initialize-webhandle-component-file.mjs"
|
|
11
|
+
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/EmergentIdeas/webhandle-initialize-webhandle-component.git"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [],
|
|
17
|
+
"author": "",
|
|
18
|
+
"license": "ISC",
|
|
19
|
+
"type": "module",
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/EmergentIdeas/webhandle-initialize-webhandle-component/issues"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://github.com/EmergentIdeas/webhandle-initialize-webhandle-component#readme"
|
|
24
|
+
, "files": [
|
|
25
|
+
"README.md"
|
|
26
|
+
, "*.mjs"
|
|
27
|
+
]
|
|
28
|
+
}
|