@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
+ }