{"id":28964206,"url":"https://github.com/flancer32/teq-web","last_synced_at":"2026-03-11T18:06:05.823Z","repository":{"id":294257690,"uuid":"986396990","full_name":"flancer32/teq-web","owner":"flancer32","description":"Node.js web plugin supporting Express and Fastify integration, with built-in server for standalone operation.","archived":false,"fork":false,"pushed_at":"2025-06-21T08:03:23.000Z","size":120,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-21T08:05:37.900Z","etag":null,"topics":["dispatcher","express","fastify","http","middleware","nodejs","teqfw","web-server"],"latest_commit_sha":null,"homepage":"https://cms.teqfw.com/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flancer32.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-19T14:45:17.000Z","updated_at":"2025-06-21T08:02:04.000Z","dependencies_parsed_at":"2025-05-19T16:35:44.126Z","dependency_job_id":"726f25ec-4777-4c36-bcfd-d001047220c9","html_url":"https://github.com/flancer32/teq-web","commit_stats":null,"previous_names":["flancer32/teq-web"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/flancer32/teq-web","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flancer32%2Fteq-web","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flancer32%2Fteq-web/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flancer32%2Fteq-web/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flancer32%2Fteq-web/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flancer32","download_url":"https://codeload.github.com/flancer32/teq-web/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flancer32%2Fteq-web/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261607954,"owners_count":23184012,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dispatcher","express","fastify","http","middleware","nodejs","teqfw","web-server"],"created_at":"2025-06-24T05:01:19.045Z","updated_at":"2026-03-11T18:06:05.818Z","avatar_url":"https://github.com/flancer32.png","language":"JavaScript","readme":"# @flancer32/teq-web\n\n**@flancer32/teq-web** is a modular request dispatcher and web server for Node.js applications.  \nIt follows the principles of the [TeqFW](https://github.com/flancer32/teqfw) architecture but works independently and\ncan be integrated into any Node.js project.  \nThe plugin offers a flexible, pluggable HTTP/2-capable server with three-stage handler processing and dependency-driven\nexecution order.\n\n---\n\n## Overview\n\nThis package provides:\n\n- A **dispatcher** that processes HTTP requests in three well-defined stages: `pre`, `process`, `post`.\n- A **handler interface** for modular request handling across plugins or components.\n- A **built-in server** based on Node.js libraries (`http`, `http2`), supporting TLS via `http2.createSecureServer()`.\n- Support for **relative handler ordering** using `before` / `after` declarations and topological sorting.\n- Compatibility with **external servers** like Express/Fastify by using the dispatcher as middleware.\n- Minimal dependencies and full support for dependency injection via `@teqfw/di`.\n\n---\n\n## Architecture\n\nThe dispatcher runs HTTP requests through a consistent three-phase pipeline:\n\n1. **Pre-processing (`pre`)** — All handlers are executed in a defined order (e.g., logging, authentication).\n2. **Processing (`process`)** — Handlers are checked sequentially until one returns `true` (request handled).\n3. **Post-processing (`post`)** — All handlers are executed unconditionally, even after errors.\n\nEach handler provides its registration metadata via the `getRegistrationInfo()` method. Execution order is resolved with\na built-in implementation of Kahn's algorithm.\n\nExample handler definition:\n\n```js\nconst My_Handler = {\n    getRegistrationInfo: () =\u003e Object.freeze({\n        name: 'My_Handler',\n        stage: 'process', // can be 'pre', 'process', or 'post'\n        before: [],\n        after: [],\n    }),\n\n    handle: async (req, res) =\u003e {\n        res.writeHead(200, {'Content-Type': 'text/plain'});\n        res.end('Hello from My_Handler!');\n        return true;\n    },\n};\n\nexport default My_Handler;\n````\n\n---\n\n## Usage\n\nThis example shows how to create a minimal application that:\n\n* Registers two handlers: a logger and a static file server\n* Starts a secure HTTPS server using built-in components\n\nThe static handler reads from one or more **sources** described by the\n`Handler_Source` DTO. To expose selected files from `node_modules`, create a\nsource with `root: 'node_modules'` and pass it to `Handler_Static` during\ninitialization.\n\n```js\nimport Container from '@teqfw/di';\nimport {readFileSync} from 'node:fs';\nimport {join, resolve} from 'node:path';\nimport {fileURLToPath} from 'node:url';\n\n// Resolve working directory\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = resolve(__filename, '..');\nconst webRoot = join(__dirname, 'web');\nconst certs = join(__dirname, 'certs');\n\n// DI container setup\nconst container = new Container();\nconst resolver = container.getResolver();\nresolver.addNamespaceRoot('Fl32_Web_', './node_modules/@flancer32/teq-web/src');\n\n// Get and configure built-in handlers\nconst logHandler = await container.get('Fl32_Web_Back_Handler_Pre_Log$');\nconst staticHandler = await container.get('Fl32_Web_Back_Handler_Static$');\nconst SourceCfg = await container.get('Fl32_Web_Back_Dto_Handler_Source$');\nconst srcNpm = SourceCfg.create({\n    root: 'node_modules',\n    prefix: '/node_modules/',\n    allow: {\n        vue: ['dist/vue.global.prod.js'],\n        '@teqfw/di': ['src/Container.mjs'],\n    }\n});\nconst srcWeb = SourceCfg.create({ root: webRoot, prefix: '/' });\nawait staticHandler.init({sources: [srcNpm, srcWeb]});\n\n// Register handlers\nconst dispatcher = await container.get('Fl32_Web_Back_Dispatcher$');\ndispatcher.addHandler(logHandler);\ndispatcher.addHandler(staticHandler);\n\n// Create and start the server\nconst server = await container.get('Fl32_Web_Back_Server$');\nawait server.start({\n    port: 3443,\n    type: 'https',\n    tls: {\n        key: readFileSync(join(certs, 'key.pem'), 'utf8'),\n        cert: readFileSync(join(certs, 'cert.pem'), 'utf8'),\n        ca: readFileSync(join(certs, 'ca.pem'), 'utf8'),\n    }\n});\n```\n\nThis will start an HTTPS server on port `3443` with:\n\n* `Fl32_Web_Back_Handler_Pre_Log` logging each request method and URL;\n* `Fl32_Web_Back_Handler_Static` serving files from `node_modules` and the `/web` folder.\n\n---\n\n### Using with Express or Fastify\n\nThe dispatcher can be connected to external web frameworks instead of the built-in server.\n\n```js\n// Express\nconst app = Express();\napp.use(async (req, res) =\u003e {\n    await dispatcher.onEventRequest(req, res);\n});\napp.listen(3000);\n\n// Fastify\nconst fastify = Fastify();\nfastify.all('*', async (request, reply) =\u003e {\n    const req = request.raw;\n    const res = reply.raw;\n    await dispatcher.onEventRequest(req, res);\n});\nawait fastify.listen({port: 3000});\n```\n\n---\n\n## Installation\n\n```bash\nnpm install @flancer32/teq-web\n```\n\nThis plugin requires a configured `@teqfw/di` container and optionally integrates with TeqFW-based apps.\n\n---\n\n## Status\n\nThis package is under active development and already used in real-world applications. Documentation is built using the\n**3DP** method (Dialog-Driven Development Process) and evolves alongside actual use cases.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflancer32%2Fteq-web","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflancer32%2Fteq-web","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflancer32%2Fteq-web/lists"}