feat: add MQTT journal server for session persistence
Implement a journal server that uses an Aedes MQTT broker to persist stream messages to JSONL files and manage session metadata via a manifest. - Add `aedes`, `mqtt`, and `zod` dependencies - Implement `createJournalServer` in `src/cli/journal.ts` - Integrate journal server into the `serve` command - Add `--mqtt-port` option to the CLI - Add session lifecycle management (create, update, delete) via retained MQTT topics
This commit is contained in:
parent
08389601ac
commit
21f8fbcd0b
|
|
@ -13,6 +13,7 @@
|
||||||
"@solidjs/router": "^0.15.0",
|
"@solidjs/router": "^0.15.0",
|
||||||
"@thisbeyond/solid-dnd": "^0.7.5",
|
"@thisbeyond/solid-dnd": "^0.7.5",
|
||||||
"@types/three": "^0.183.1",
|
"@types/three": "^0.183.1",
|
||||||
|
"aedes": "^1.1.1",
|
||||||
"chokidar": "^5.0.0",
|
"chokidar": "^5.0.0",
|
||||||
"commander": "^14.0.3",
|
"commander": "^14.0.3",
|
||||||
"csv-parse": "^6.1.0",
|
"csv-parse": "^6.1.0",
|
||||||
|
|
@ -23,11 +24,13 @@
|
||||||
"marked-directive": "^1.0.7",
|
"marked-directive": "^1.0.7",
|
||||||
"marked-gfm-heading-id": "^4.1.3",
|
"marked-gfm-heading-id": "^4.1.3",
|
||||||
"mermaid": "^11.0.0",
|
"mermaid": "^11.0.0",
|
||||||
|
"mqtt": "^5.15.1",
|
||||||
"solid-element": "^1.9.1",
|
"solid-element": "^1.9.1",
|
||||||
"solid-js": "^1.9.3",
|
"solid-js": "^1.9.3",
|
||||||
"three": "^0.183.2",
|
"three": "^0.183.2",
|
||||||
"three-3mf-exporter": "^45.1.0",
|
"three-3mf-exporter": "^45.1.0",
|
||||||
"yarn-spinner-loader": "^0.1.0"
|
"yarn-spinner-loader": "^0.1.0",
|
||||||
|
"zod": "^4.4.3"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"ttrpg": "dist/cli/index.js"
|
"ttrpg": "dist/cli/index.js"
|
||||||
|
|
@ -721,6 +724,15 @@
|
||||||
"@babel/core": "^7.0.0-0"
|
"@babel/core": "^7.0.0-0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@babel/runtime": {
|
||||||
|
"version": "7.29.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz",
|
||||||
|
"integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@babel/template": {
|
"node_modules/@babel/template": {
|
||||||
"version": "7.28.6",
|
"version": "7.28.6",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz",
|
||||||
|
|
@ -1871,6 +1883,15 @@
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@modelcontextprotocol/sdk/node_modules/zod": {
|
||||||
|
"version": "3.25.76",
|
||||||
|
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
|
||||||
|
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/colinhacks"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@module-federation/error-codes": {
|
"node_modules/@module-federation/error-codes": {
|
||||||
"version": "0.22.0",
|
"version": "0.22.0",
|
||||||
"resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.22.0.tgz",
|
"resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.22.0.tgz",
|
||||||
|
|
@ -3310,12 +3331,20 @@
|
||||||
"version": "22.19.17",
|
"version": "22.19.17",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.17.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.17.tgz",
|
||||||
"integrity": "sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==",
|
"integrity": "sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==",
|
||||||
"devOptional": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~6.21.0"
|
"undici-types": "~6.21.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/readable-stream": {
|
||||||
|
"version": "4.0.24",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.24.tgz",
|
||||||
|
"integrity": "sha512-NRvUNC/JFGPJvqdAfEve8oginbM6V08u5NzLWpG8MwA2kTPOLnqk+wpwuPT+mp3aUsxyuT6m2gnrPuHYCruzEg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/stack-utils": {
|
"node_modules/@types/stack-utils": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
|
||||||
|
|
@ -3364,6 +3393,15 @@
|
||||||
"integrity": "sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==",
|
"integrity": "sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/ws": {
|
||||||
|
"version": "8.18.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
|
||||||
|
"integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/yargs": {
|
"node_modules/@types/yargs": {
|
||||||
"version": "17.0.35",
|
"version": "17.0.35",
|
||||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz",
|
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz",
|
||||||
|
|
@ -3405,6 +3443,18 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-3-Clause"
|
"license": "BSD-3-Clause"
|
||||||
},
|
},
|
||||||
|
"node_modules/abort-controller": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"event-target-shim": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.16.0",
|
"version": "8.16.0",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
|
||||||
|
|
@ -3441,6 +3491,138 @@
|
||||||
"node": ">=0.4.0"
|
"node": ">=0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/aedes": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/aedes/-/aedes-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-kmKFRgQrjGyv9HuVqpNGM/aPD2K4bf20aF1UbrxEvh3j8BJ1OD0rHi3E3u3xfrgc3ydj2+9UiPdW0sHiP6d+Sg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"aedes-packet": "^3.0.0",
|
||||||
|
"aedes-persistence": "^10.2.2",
|
||||||
|
"mqemitter": "^7.1.0",
|
||||||
|
"mqtt-packet": "^9.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/aedes"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"aedes-persistence-level": "^9.1.2",
|
||||||
|
"aedes-persistence-mongodb": "^9.3.1",
|
||||||
|
"aedes-persistence-redis": "^11.2.1"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"aedes-persistence-level": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"aedes-persistence-mongodb": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"aedes-persistence-redis": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/aedes-packet": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/aedes-packet/-/aedes-packet-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-swASey0BxGs4/npZGWoiVDmnEyPvVFIRY6l2LVKL4rbiW8IhcIGDLfnb20Qo8U20itXlitAKPQ3MVTEbOGG5ZA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"mqtt-packet": "^7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/aedes-packet/node_modules/bl": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"buffer": "^5.5.0",
|
||||||
|
"inherits": "^2.0.4",
|
||||||
|
"readable-stream": "^3.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/aedes-packet/node_modules/buffer": {
|
||||||
|
"version": "5.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
|
||||||
|
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"base64-js": "^1.3.1",
|
||||||
|
"ieee754": "^1.1.13"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/aedes-packet/node_modules/mqtt-packet": {
|
||||||
|
"version": "7.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-7.1.2.tgz",
|
||||||
|
"integrity": "sha512-FFZbcZ2omsf4c5TxEQfcX9hI+JzDpDKPT46OmeIBpVA7+t32ey25UNqlqNXTmeZOr5BLsSIERpQQLsFWJS94SQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"bl": "^4.0.2",
|
||||||
|
"debug": "^4.1.1",
|
||||||
|
"process-nextick-args": "^2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/aedes-packet/node_modules/readable-stream": {
|
||||||
|
"version": "3.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||||
|
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"string_decoder": "^1.1.1",
|
||||||
|
"util-deprecate": "^1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/aedes-persistence": {
|
||||||
|
"version": "10.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/aedes-persistence/-/aedes-persistence-10.3.1.tgz",
|
||||||
|
"integrity": "sha512-C/z0zLEXY9PkUH+7pz31H5gGzlQZxqhFONK1lt5VON0hiHXQq6tr4cSIAtFUVQ1kyUdd7SsfkeKLAECp3gjjpw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"aedes-packet": "^4.0.1",
|
||||||
|
"qlobber": "^8.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/aedes-persistence/node_modules/aedes-packet": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/aedes-packet/-/aedes-packet-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-PLjKJElXEYB66RzHhJCw0SrRLfSmGRbbg2mtO5t/6FAbFp8vC0cG5ErhvPvfa9iKBrKZwoluWLgn8doBU8sRAw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"mqtt-packet": "^9.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/agent-base": {
|
"node_modules/agent-base": {
|
||||||
"version": "6.0.2",
|
"version": "6.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||||
|
|
@ -3727,6 +3909,26 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/base64-js": {
|
||||||
|
"version": "1.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||||
|
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/baseline-browser-mapping": {
|
"node_modules/baseline-browser-mapping": {
|
||||||
"version": "2.10.15",
|
"version": "2.10.15",
|
||||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.15.tgz",
|
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.15.tgz",
|
||||||
|
|
@ -3740,6 +3942,63 @@
|
||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/bl": {
|
||||||
|
"version": "6.1.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/bl/-/bl-6.1.6.tgz",
|
||||||
|
"integrity": "sha512-jLsPgN/YSvPUg9UX0Kd73CXpm2Psg9FxMeCSXnk3WBO3CMT10JMwijubhGfHCnFu6TPn1ei3b975dxv7K2pWVg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/readable-stream": "^4.0.0",
|
||||||
|
"buffer": "^6.0.3",
|
||||||
|
"inherits": "^2.0.4",
|
||||||
|
"readable-stream": "^4.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/bl/node_modules/readable-stream": {
|
||||||
|
"version": "4.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
|
||||||
|
"integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"abort-controller": "^3.0.0",
|
||||||
|
"buffer": "^6.0.3",
|
||||||
|
"events": "^3.3.0",
|
||||||
|
"process": "^0.11.10",
|
||||||
|
"string_decoder": "^1.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/bl/node_modules/safe-buffer": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/bl/node_modules/string_decoder": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": "~5.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "1.1.13",
|
"version": "1.1.13",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz",
|
||||||
|
|
@ -3763,6 +4022,18 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/broker-factory": {
|
||||||
|
"version": "3.1.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/broker-factory/-/broker-factory-3.1.15.tgz",
|
||||||
|
"integrity": "sha512-ko+aWvgNuP49meGrdjUu7rC+Y+Wai3cCPxP3xWwHsHfehFjOh5ZQM2yC4gEB2UddeZ/YXhm0K1eG/L6fxym2Og==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.29.7",
|
||||||
|
"fast-unique-numbers": "^9.0.27",
|
||||||
|
"tslib": "^2.8.1",
|
||||||
|
"worker-factory": "^7.0.50"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/browserslist": {
|
"node_modules/browserslist": {
|
||||||
"version": "4.28.2",
|
"version": "4.28.2",
|
||||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz",
|
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz",
|
||||||
|
|
@ -3820,11 +4091,34 @@
|
||||||
"node-int64": "^0.4.0"
|
"node-int64": "^0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/buffer": {
|
||||||
|
"version": "6.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
|
||||||
|
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"base64-js": "^1.3.1",
|
||||||
|
"ieee754": "^1.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/buffer-from": {
|
"node_modules/buffer-from": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/bytes": {
|
"node_modules/bytes": {
|
||||||
|
|
@ -4063,6 +4357,12 @@
|
||||||
"node": ">=20"
|
"node": ">=20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/commist": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/commist/-/commist-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/component-register": {
|
"node_modules/component-register": {
|
||||||
"version": "0.8.8",
|
"version": "0.8.8",
|
||||||
"resolved": "https://registry.npmjs.org/component-register/-/component-register-0.8.8.tgz",
|
"resolved": "https://registry.npmjs.org/component-register/-/component-register-0.8.8.tgz",
|
||||||
|
|
@ -4076,6 +4376,35 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/concat-stream": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==",
|
||||||
|
"engines": [
|
||||||
|
"node >= 6.0"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"buffer-from": "^1.0.0",
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"readable-stream": "^3.0.2",
|
||||||
|
"typedarray": "^0.0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/concat-stream/node_modules/readable-stream": {
|
||||||
|
"version": "3.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||||
|
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"string_decoder": "^1.1.1",
|
||||||
|
"util-deprecate": "^1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/confbox": {
|
"node_modules/confbox": {
|
||||||
"version": "0.1.8",
|
"version": "0.1.8",
|
||||||
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
|
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
|
||||||
|
|
@ -4778,7 +5107,6 @@
|
||||||
"version": "4.4.3",
|
"version": "4.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||||
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ms": "^2.1.3"
|
"ms": "^2.1.3"
|
||||||
|
|
@ -5119,6 +5447,24 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/event-target-shim": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/events": {
|
||||||
|
"version": "3.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
|
||||||
|
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/execa": {
|
"node_modules/execa": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
|
||||||
|
|
@ -5199,6 +5545,19 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-unique-numbers": {
|
||||||
|
"version": "9.0.27",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-9.0.27.tgz",
|
||||||
|
"integrity": "sha512-nDA9ADeINN8SA2u2wCtU+siWFTTDqQR37XvgPIDDmboWQeExz7X0mImxuaN+kJddliIqy2FpVRmnvRZ+j8i1/A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.29.2",
|
||||||
|
"tslib": "^2.8.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fast-uri": {
|
"node_modules/fast-uri": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
|
||||||
|
|
@ -5250,6 +5609,16 @@
|
||||||
"fxparser": "src/cli/cli.js"
|
"fxparser": "src/cli/cli.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fastparallel": {
|
||||||
|
"version": "2.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fastparallel/-/fastparallel-2.4.1.tgz",
|
||||||
|
"integrity": "sha512-qUmhxPgNHmvRjZKBFUNI0oZuuH9OlSIOXmJ98lhKPxMZZ7zS/Fi0wRHOihDSz0R1YiIOjxzOY4bq65YTcdBi2Q==",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"reusify": "^1.0.4",
|
||||||
|
"xtend": "^4.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fastq": {
|
"node_modules/fastq": {
|
||||||
"version": "1.20.1",
|
"version": "1.20.1",
|
||||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
|
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
|
||||||
|
|
@ -5571,6 +5940,12 @@
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/help-me": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/html-encoding-sniffer": {
|
"node_modules/html-encoding-sniffer": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
|
||||||
|
|
@ -5685,6 +6060,26 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ieee754": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "BSD-3-Clause"
|
||||||
|
},
|
||||||
"node_modules/immediate": {
|
"node_modules/immediate": {
|
||||||
"version": "3.0.6",
|
"version": "3.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
|
||||||
|
|
@ -5748,6 +6143,15 @@
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ip-address": {
|
||||||
|
"version": "10.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz",
|
||||||
|
"integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-arrayish": {
|
"node_modules/is-arrayish": {
|
||||||
"version": "0.2.1",
|
"version": "0.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
||||||
|
|
@ -7430,6 +7834,16 @@
|
||||||
"jiti": "lib/jiti-cli.mjs"
|
"jiti": "lib/jiti-cli.mjs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/js-sdsl": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/js-sdsl"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/js-tokens": {
|
"node_modules/js-tokens": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
|
|
@ -8167,7 +8581,6 @@
|
||||||
"version": "1.2.8",
|
"version": "1.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
||||||
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
|
@ -8191,11 +8604,117 @@
|
||||||
"integrity": "sha512-m2fmM2dDm7GZQsY7KK2cme8agi+AAljILjQnof7p1ZMDe6dQ4bdnSMx0cPppudoeNv5hEFQirN6u+O4fDE0IWA==",
|
"integrity": "sha512-m2fmM2dDm7GZQsY7KK2cme8agi+AAljILjQnof7p1ZMDe6dQ4bdnSMx0cPppudoeNv5hEFQirN6u+O4fDE0IWA==",
|
||||||
"license": "BSD-3-Clause"
|
"license": "BSD-3-Clause"
|
||||||
},
|
},
|
||||||
|
"node_modules/mqemitter": {
|
||||||
|
"version": "7.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mqemitter/-/mqemitter-7.1.0.tgz",
|
||||||
|
"integrity": "sha512-GnBDNz3lxmllW201ne0mrmdy5tPOTnc79jjVcsfUa2LG2pUGeyGWVeiae6ZysfC/64XrYOqCKRAQYrB7pGyBVQ==",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"fastparallel": "^2.4.1",
|
||||||
|
"qlobber": "^8.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mqtt": {
|
||||||
|
"version": "5.15.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.15.1.tgz",
|
||||||
|
"integrity": "sha512-V1WnkGuJh3ec9QXzy5Iylw8OOBK+Xu1WhxcQ9mMpLThG+/JZIMV1PgLNRgIiqXhZnvnVLsuyxHl5A/3bHHbcAA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/readable-stream": "^4.0.21",
|
||||||
|
"@types/ws": "^8.18.1",
|
||||||
|
"commist": "^3.2.0",
|
||||||
|
"concat-stream": "^2.0.0",
|
||||||
|
"debug": "^4.4.1",
|
||||||
|
"help-me": "^5.0.0",
|
||||||
|
"lru-cache": "^10.4.3",
|
||||||
|
"minimist": "^1.2.8",
|
||||||
|
"mqtt-packet": "^9.0.2",
|
||||||
|
"number-allocator": "^1.0.14",
|
||||||
|
"readable-stream": "^4.7.0",
|
||||||
|
"rfdc": "^1.4.1",
|
||||||
|
"socks": "^2.8.6",
|
||||||
|
"split2": "^4.2.0",
|
||||||
|
"worker-timers": "^8.0.23",
|
||||||
|
"ws": "^8.18.3"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"mqtt": "build/bin/mqtt.js",
|
||||||
|
"mqtt_pub": "build/bin/pub.js",
|
||||||
|
"mqtt_sub": "build/bin/sub.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mqtt-packet": {
|
||||||
|
"version": "9.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-9.0.2.tgz",
|
||||||
|
"integrity": "sha512-MvIY0B8/qjq7bKxdN1eD+nrljoeaai+qjLJgfRn3TiMuz0pamsIWY2bFODPZMSNmabsLANXsLl4EMoWvlaTZWA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"bl": "^6.0.8",
|
||||||
|
"debug": "^4.3.4",
|
||||||
|
"process-nextick-args": "^2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mqtt/node_modules/lru-cache": {
|
||||||
|
"version": "10.4.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
|
||||||
|
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"node_modules/mqtt/node_modules/readable-stream": {
|
||||||
|
"version": "4.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
|
||||||
|
"integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"abort-controller": "^3.0.0",
|
||||||
|
"buffer": "^6.0.3",
|
||||||
|
"events": "^3.3.0",
|
||||||
|
"process": "^0.11.10",
|
||||||
|
"string_decoder": "^1.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mqtt/node_modules/safe-buffer": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/mqtt/node_modules/string_decoder": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": "~5.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ms": {
|
"node_modules/ms": {
|
||||||
"version": "2.1.3",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/nanoid": {
|
"node_modules/nanoid": {
|
||||||
|
|
@ -8268,6 +8787,16 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/number-allocator": {
|
||||||
|
"version": "1.0.14",
|
||||||
|
"resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz",
|
||||||
|
"integrity": "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.3.1",
|
||||||
|
"js-sdsl": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/nwsapi": {
|
"node_modules/nwsapi": {
|
||||||
"version": "2.2.23",
|
"version": "2.2.23",
|
||||||
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.23.tgz",
|
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.23.tgz",
|
||||||
|
|
@ -8624,6 +9153,15 @@
|
||||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/process": {
|
||||||
|
"version": "0.11.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
||||||
|
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/process-nextick-args": {
|
"node_modules/process-nextick-args": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||||
|
|
@ -8684,6 +9222,15 @@
|
||||||
],
|
],
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/qlobber": {
|
||||||
|
"version": "8.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/qlobber/-/qlobber-8.0.1.tgz",
|
||||||
|
"integrity": "sha512-O+Wd1chXj5YE1DwmD+ae0bXiSLehmnS3czlC1R9FL/Nt/3q8uMS1bIHmg2lJfCoiimCxClWM8AAuJrF0EvNiog==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 16"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/querystringify": {
|
"node_modules/querystringify": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
|
||||||
|
|
@ -8874,6 +9421,12 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/rfdc": {
|
||||||
|
"version": "1.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
|
||||||
|
"integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/robust-predicates": {
|
"node_modules/robust-predicates": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.3.tgz",
|
||||||
|
|
@ -9071,6 +9624,30 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/smart-buffer": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6.0.0",
|
||||||
|
"npm": ">= 3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/socks": {
|
||||||
|
"version": "2.8.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/socks/-/socks-2.8.9.tgz",
|
||||||
|
"integrity": "sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ip-address": "^10.1.1",
|
||||||
|
"smart-buffer": "^4.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0",
|
||||||
|
"npm": ">= 3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/solid-element": {
|
"node_modules/solid-element": {
|
||||||
"version": "1.9.1",
|
"version": "1.9.1",
|
||||||
"resolved": "https://registry.npmjs.org/solid-element/-/solid-element-1.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/solid-element/-/solid-element-1.9.1.tgz",
|
||||||
|
|
@ -9139,6 +9716,15 @@
|
||||||
"source-map": "^0.6.0"
|
"source-map": "^0.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/split2": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/sprintf-js": {
|
"node_modules/sprintf-js": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||||
|
|
@ -9611,7 +10197,6 @@
|
||||||
"version": "2.8.1",
|
"version": "2.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||||
"devOptional": true,
|
|
||||||
"license": "0BSD"
|
"license": "0BSD"
|
||||||
},
|
},
|
||||||
"node_modules/type-detect": {
|
"node_modules/type-detect": {
|
||||||
|
|
@ -9637,6 +10222,12 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/typedarray": {
|
||||||
|
"version": "0.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||||
|
"integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "5.9.3",
|
"version": "5.9.3",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||||
|
|
@ -9675,7 +10266,6 @@
|
||||||
"version": "6.21.0",
|
"version": "6.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
||||||
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
|
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
|
||||||
"devOptional": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/universalify": {
|
"node_modules/universalify": {
|
||||||
|
|
@ -10016,6 +10606,53 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/worker-factory": {
|
||||||
|
"version": "7.0.50",
|
||||||
|
"resolved": "https://registry.npmjs.org/worker-factory/-/worker-factory-7.0.50.tgz",
|
||||||
|
"integrity": "sha512-hhwc0G+sFwM4qBuhJIUBn2p1Jf8v/FwmLUANBf/Q+Lt2uI8mfIZQhXaZQACodQD4R7Zp6cn/6702bIvNn2puJQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.29.7",
|
||||||
|
"fast-unique-numbers": "^9.0.27",
|
||||||
|
"tslib": "^2.8.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/worker-timers": {
|
||||||
|
"version": "8.0.33",
|
||||||
|
"resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-8.0.33.tgz",
|
||||||
|
"integrity": "sha512-RQVlKkek80v8M6SHvdMKiywaXFmX3XTpYTXTw0r62PdXB06t74XNxcTuG8wsQwnjorAQymNQyyQ0rzv7PykEMQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.29.7",
|
||||||
|
"tslib": "^2.8.1",
|
||||||
|
"worker-timers-broker": "^8.0.18",
|
||||||
|
"worker-timers-worker": "^9.0.15"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/worker-timers-broker": {
|
||||||
|
"version": "8.0.18",
|
||||||
|
"resolved": "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-8.0.18.tgz",
|
||||||
|
"integrity": "sha512-FrjzDVX1wKfZN0gRbCFqv8VHuTncG4sbI/WGEg4tSSQeIsnwqg4YBYWMAHYLJtUDEYYmiK65UKFrVMVk2irDSg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.29.7",
|
||||||
|
"broker-factory": "^3.1.15",
|
||||||
|
"fast-unique-numbers": "^9.0.27",
|
||||||
|
"tslib": "^2.8.1",
|
||||||
|
"worker-timers-worker": "^9.0.15"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/worker-timers-worker": {
|
||||||
|
"version": "9.0.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-9.0.15.tgz",
|
||||||
|
"integrity": "sha512-KKUe7lZ/Aignr51H6hOUik8LwTnIgojH/1lwhli8A8qIEIyewogZTpNpMW5B6BF7nmwBOkUoTYgf1H3QShcjSA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.29.7",
|
||||||
|
"tslib": "^2.8.1",
|
||||||
|
"worker-factory": "^7.0.50"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/wrap-ansi": {
|
"node_modules/wrap-ansi": {
|
||||||
"version": "7.0.0",
|
"version": "7.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||||
|
|
@ -10059,7 +10696,6 @@
|
||||||
"version": "8.20.0",
|
"version": "8.20.0",
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz",
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz",
|
||||||
"integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==",
|
"integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.0.0"
|
"node": ">=10.0.0"
|
||||||
|
|
@ -10094,6 +10730,15 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/xtend": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/y18n": {
|
"node_modules/y18n": {
|
||||||
"version": "5.0.8",
|
"version": "5.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||||
|
|
@ -10194,9 +10839,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/zod": {
|
"node_modules/zod": {
|
||||||
"version": "3.25.76",
|
"version": "4.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
|
"resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz",
|
||||||
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
|
"integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/colinhacks"
|
"url": "https://github.com/sponsors/colinhacks"
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@
|
||||||
"@solidjs/router": "^0.15.0",
|
"@solidjs/router": "^0.15.0",
|
||||||
"@thisbeyond/solid-dnd": "^0.7.5",
|
"@thisbeyond/solid-dnd": "^0.7.5",
|
||||||
"@types/three": "^0.183.1",
|
"@types/three": "^0.183.1",
|
||||||
|
"aedes": "^1.1.1",
|
||||||
"chokidar": "^5.0.0",
|
"chokidar": "^5.0.0",
|
||||||
"commander": "^14.0.3",
|
"commander": "^14.0.3",
|
||||||
"csv-parse": "^6.1.0",
|
"csv-parse": "^6.1.0",
|
||||||
|
|
@ -46,11 +47,13 @@
|
||||||
"marked-directive": "^1.0.7",
|
"marked-directive": "^1.0.7",
|
||||||
"marked-gfm-heading-id": "^4.1.3",
|
"marked-gfm-heading-id": "^4.1.3",
|
||||||
"mermaid": "^11.0.0",
|
"mermaid": "^11.0.0",
|
||||||
|
"mqtt": "^5.15.1",
|
||||||
"solid-element": "^1.9.1",
|
"solid-element": "^1.9.1",
|
||||||
"solid-js": "^1.9.3",
|
"solid-js": "^1.9.3",
|
||||||
"three": "^0.183.2",
|
"three": "^0.183.2",
|
||||||
"three-3mf-exporter": "^45.1.0",
|
"three-3mf-exporter": "^45.1.0",
|
||||||
"yarn-spinner-loader": "^0.1.0"
|
"yarn-spinner-loader": "^0.1.0",
|
||||||
|
"zod": "^4.4.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@image-tracer-ts/core": "^1.0.2",
|
"@image-tracer-ts/core": "^1.0.2",
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import { createReadStream } from "fs";
|
||||||
import { join, resolve, extname, sep, relative, dirname } from "path";
|
import { join, resolve, extname, sep, relative, dirname } from "path";
|
||||||
import { watch } from "chokidar";
|
import { watch } from "chokidar";
|
||||||
import { fileURLToPath } from "url";
|
import { fileURLToPath } from "url";
|
||||||
|
import { createJournalServer } from "../journal.js";
|
||||||
|
|
||||||
interface ContentIndex {
|
interface ContentIndex {
|
||||||
[path: string]: string;
|
[path: string]: string;
|
||||||
|
|
@ -63,7 +64,11 @@ export function scanDirectory(dir: string): ContentIndex {
|
||||||
const stats = statSync(fullPath);
|
const stats = statSync(fullPath);
|
||||||
if (stats.isDirectory()) {
|
if (stats.isDirectory()) {
|
||||||
scan(fullPath, relPath);
|
scan(fullPath, relPath);
|
||||||
} else if (entry.endsWith(".md") || entry.endsWith(".csv") || entry.endsWith(".yarn")) {
|
} else if (
|
||||||
|
entry.endsWith(".md") ||
|
||||||
|
entry.endsWith(".csv") ||
|
||||||
|
entry.endsWith(".yarn")
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
const content = readFileSync(fullPath, "utf-8");
|
const content = readFileSync(fullPath, "utf-8");
|
||||||
index[normalizedRelPath] = content;
|
index[normalizedRelPath] = content;
|
||||||
|
|
@ -205,6 +210,7 @@ export function createContentServer(
|
||||||
port: number,
|
port: number,
|
||||||
distPath: string = distDir,
|
distPath: string = distDir,
|
||||||
host: string = "0.0.0.0",
|
host: string = "0.0.0.0",
|
||||||
|
mqttPort: number = 1883,
|
||||||
): ContentServer {
|
): ContentServer {
|
||||||
let contentIndex: ContentIndex = {};
|
let contentIndex: ContentIndex = {};
|
||||||
|
|
||||||
|
|
@ -216,14 +222,18 @@ export function createContentServer(
|
||||||
// 监听文件变化
|
// 监听文件变化
|
||||||
console.log("监听文件变化...");
|
console.log("监听文件变化...");
|
||||||
const watcher = watch(contentDir, {
|
const watcher = watch(contentDir, {
|
||||||
ignored: /(^|[\/\\])\../,
|
ignored: /(^|[\/\\])\./,
|
||||||
persistent: true,
|
persistent: true,
|
||||||
ignoreInitial: true,
|
ignoreInitial: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
watcher
|
watcher
|
||||||
.on("add", (path) => {
|
.on("add", (path) => {
|
||||||
if (path.endsWith(".md") || path.endsWith(".csv") || path.endsWith(".yarn")) {
|
if (
|
||||||
|
path.endsWith(".md") ||
|
||||||
|
path.endsWith(".csv") ||
|
||||||
|
path.endsWith(".yarn")
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
const content = readFileSync(path, "utf-8");
|
const content = readFileSync(path, "utf-8");
|
||||||
const relPath = "/" + relative(contentDir, path).split(sep).join("/");
|
const relPath = "/" + relative(contentDir, path).split(sep).join("/");
|
||||||
|
|
@ -235,7 +245,11 @@ export function createContentServer(
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.on("change", (path) => {
|
.on("change", (path) => {
|
||||||
if (path.endsWith(".md") || path.endsWith(".csv") || path.endsWith(".yarn")) {
|
if (
|
||||||
|
path.endsWith(".md") ||
|
||||||
|
path.endsWith(".csv") ||
|
||||||
|
path.endsWith(".yarn")
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
const content = readFileSync(path, "utf-8");
|
const content = readFileSync(path, "utf-8");
|
||||||
const relPath = "/" + relative(contentDir, path).split(sep).join("/");
|
const relPath = "/" + relative(contentDir, path).split(sep).join("/");
|
||||||
|
|
@ -247,13 +261,24 @@ export function createContentServer(
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.on("unlink", (path) => {
|
.on("unlink", (path) => {
|
||||||
if (path.endsWith(".md") || path.endsWith(".csv") || path.endsWith(".yarn")) {
|
if (
|
||||||
|
path.endsWith(".md") ||
|
||||||
|
path.endsWith(".csv") ||
|
||||||
|
path.endsWith(".yarn")
|
||||||
|
) {
|
||||||
const relPath = "/" + relative(contentDir, path).split(sep).join("/");
|
const relPath = "/" + relative(contentDir, path).split(sep).join("/");
|
||||||
delete contentIndex[relPath];
|
delete contentIndex[relPath];
|
||||||
console.log(`[删除] ${relPath}`);
|
console.log(`[删除] ${relPath}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ---- Journal / MQTT broker ----
|
||||||
|
let journal: Awaited<ReturnType<typeof createJournalServer>> | null = null;
|
||||||
|
|
||||||
|
createJournalServer(contentDir, mqttPort).then((j) => {
|
||||||
|
journal = j;
|
||||||
|
});
|
||||||
|
|
||||||
// 创建请求处理器
|
// 创建请求处理器
|
||||||
const handleRequest = createRequestHandler(
|
const handleRequest = createRequestHandler(
|
||||||
contentDir,
|
contentDir,
|
||||||
|
|
@ -269,7 +294,9 @@ export function createContentServer(
|
||||||
console.log(`\n开发服务器已启动:http://${displayHost}:${port}`);
|
console.log(`\n开发服务器已启动:http://${displayHost}:${port}`);
|
||||||
console.log(`内容目录:${contentDir}`);
|
console.log(`内容目录:${contentDir}`);
|
||||||
console.log(`静态资源目录:${distPath}`);
|
console.log(`静态资源目录:${distPath}`);
|
||||||
console.log(`索引文件:http://${displayHost}:${port}/__CONTENT_INDEX.json\n`);
|
console.log(
|
||||||
|
`MQTT 代理端口:${mqttPort} (connect via tcp://${displayHost}:${mqttPort})\n`,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -280,6 +307,7 @@ export function createContentServer(
|
||||||
console.log("关闭内容服务器...");
|
console.log("关闭内容服务器...");
|
||||||
server.close();
|
server.close();
|
||||||
watcher.close();
|
watcher.close();
|
||||||
|
if (journal) journal.close();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -291,6 +319,7 @@ export const serveCommand: ServeCommandHandler = async (dir, options) => {
|
||||||
const contentDir = resolve(dir);
|
const contentDir = resolve(dir);
|
||||||
const port = parseInt(options.port, 10);
|
const port = parseInt(options.port, 10);
|
||||||
const host = options.host || "0.0.0.0";
|
const host = options.host || "0.0.0.0";
|
||||||
|
const mqttPort = parseInt(options.mqttPort || "1883", 10);
|
||||||
|
|
||||||
createContentServer(contentDir, port, distDir, host);
|
createContentServer(contentDir, port, distDir, host, mqttPort);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,33 @@
|
||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
import { Command } from 'commander';
|
import { Command } from "commander";
|
||||||
import { serveCommand } from './commands/serve.js';
|
import { serveCommand } from "./commands/serve.js";
|
||||||
import { compileCommand } from './commands/compile.js';
|
import { compileCommand } from "./commands/compile.js";
|
||||||
import { mcpCommand } from './commands/mcp.js';
|
import { mcpCommand } from "./commands/mcp.js";
|
||||||
import type { ServeOptions, CompileOptions } from './types.js';
|
import type { ServeOptions, CompileOptions } from "./types.js";
|
||||||
|
|
||||||
const program = new Command();
|
const program = new Command();
|
||||||
|
|
||||||
program
|
program
|
||||||
.name('ttrpg')
|
.name("ttrpg")
|
||||||
.description('TTRPG 工具箱 - 用于编译和预览 TTRPG 文档')
|
.description("TTRPG 工具箱 - 用于编译和预览 TTRPG 文档")
|
||||||
.version('0.0.1');
|
.version("0.0.1");
|
||||||
|
|
||||||
program
|
program
|
||||||
.command('serve')
|
.command("serve")
|
||||||
.description('运行一个 web 服务器预览目录中的内容,并实时监听更新')
|
.description("运行一个 web 服务器预览目录中的内容,并实时监听更新")
|
||||||
.argument('[dir]', '要预览的目录', '.')
|
.argument("[dir]", "要预览的目录", ".")
|
||||||
.option('-p, --port <port>', '端口号', '3000')
|
.option("-p, --port <port>", "HTTP 端口号", "3000")
|
||||||
.option('-h, --host <host>', '主机地址', '0.0.0.0')
|
.option("--mqtt-port <port>", "MQTT 代理端口号", "1883")
|
||||||
|
.option("-h, --host <host>", "主机地址", "0.0.0.0")
|
||||||
.action(serveCommand);
|
.action(serveCommand);
|
||||||
|
|
||||||
program
|
program
|
||||||
.command('compile')
|
.command("compile")
|
||||||
.description('将目录中的内容输出为带 hash 路由、单个 html 入口的 web 应用')
|
.description("将目录中的内容输出为带 hash 路由、单个 html 入口的 web 应用")
|
||||||
.argument('[dir]', '要编译的目录', '.')
|
.argument("[dir]", "要编译的目录", ".")
|
||||||
.option('-o, --output <dir>', '输出目录', './dist/output')
|
.option("-o, --output <dir>", "输出目录", "./dist/output")
|
||||||
.action(compileCommand);
|
.action(compileCommand);
|
||||||
|
|
||||||
program
|
program.addCommand(mcpCommand);
|
||||||
.addCommand(mcpCommand);
|
|
||||||
|
|
||||||
program.parse();
|
program.parse();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,227 @@
|
||||||
|
/**
|
||||||
|
* Journal stream persistence — MQTT broker + JSONL append + session manifest
|
||||||
|
*
|
||||||
|
* Starts an aedes MQTT broker and connects to itself to:
|
||||||
|
* 1. Persist all stream messages to .ttrpg/sessions/{id}/stream.jsonl
|
||||||
|
* 2. Manage session lifecycle via retained meta topics
|
||||||
|
*
|
||||||
|
* No HTTP routes — the JSONL files are served by the existing static server.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { join, resolve } from "path";
|
||||||
|
import {
|
||||||
|
appendFileSync,
|
||||||
|
existsSync,
|
||||||
|
mkdirSync,
|
||||||
|
readFileSync,
|
||||||
|
rmdirSync,
|
||||||
|
unlinkSync,
|
||||||
|
writeFileSync,
|
||||||
|
} from "fs";
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Types
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
interface SessionMeta {
|
||||||
|
name: string;
|
||||||
|
created: number;
|
||||||
|
players: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SessionManifest {
|
||||||
|
sessions: Record<string, SessionMeta>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface JournalServer {
|
||||||
|
/** MQTT broker instance */
|
||||||
|
broker: import("aedes").Aedes;
|
||||||
|
/** TCP server the broker is attached to */
|
||||||
|
tcpServer: import("net").Server;
|
||||||
|
/** Persistence client (server subscribes to itself) */
|
||||||
|
persistenceClient: import("mqtt").MqttClient | null;
|
||||||
|
/** Clean shutdown */
|
||||||
|
close(): Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Path helpers
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function dataDir(contentDir: string): string {
|
||||||
|
const d = resolve(contentDir, ".ttrpg");
|
||||||
|
mkdirSync(d, { recursive: true });
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
function manifestPath(dataRoot: string): string {
|
||||||
|
return join(dataRoot, "manifest.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
function sessionDir(dataRoot: string, id: string): string {
|
||||||
|
return join(dataRoot, "sessions", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function streamPath(dataRoot: string, id: string): string {
|
||||||
|
return join(sessionDir(dataRoot, id), "stream.jsonl");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Manifest
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function loadManifest(dataRoot: string): SessionManifest {
|
||||||
|
const p = manifestPath(dataRoot);
|
||||||
|
if (!existsSync(p)) return { sessions: {} };
|
||||||
|
try {
|
||||||
|
return JSON.parse(readFileSync(p, "utf-8"));
|
||||||
|
} catch {
|
||||||
|
return { sessions: {} };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveManifest(dataRoot: string, m: SessionManifest): void {
|
||||||
|
writeFileSync(manifestPath(dataRoot), JSON.stringify(m, null, 2), "utf-8");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// JSONL persistence
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function appendStream(dataRoot: string, id: string, line: string): void {
|
||||||
|
const sd = sessionDir(dataRoot, id);
|
||||||
|
mkdirSync(sd, { recursive: true });
|
||||||
|
appendFileSync(streamPath(dataRoot, id), line + "\n", "utf-8");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Server factory
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export async function createJournalServer(
|
||||||
|
contentDir: string,
|
||||||
|
mqttPort: number,
|
||||||
|
): Promise<JournalServer> {
|
||||||
|
const root = dataDir(contentDir);
|
||||||
|
console.log(`[journal] data dir: ${root}`);
|
||||||
|
|
||||||
|
// ---- MQTT Broker ----
|
||||||
|
const { Aedes: AedesFactory } = await import("aedes");
|
||||||
|
const { createServer } = await import("net");
|
||||||
|
|
||||||
|
const broker = new AedesFactory();
|
||||||
|
const tcpServer = createServer(broker.handle.bind(broker));
|
||||||
|
|
||||||
|
tcpServer.listen(mqttPort, "0.0.0.0", () => {
|
||||||
|
console.log(`[journal] MQTT broker on port ${mqttPort}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// ---- Persistence + Manifest client ----
|
||||||
|
let client: import("mqtt").MqttClient | null = null;
|
||||||
|
|
||||||
|
const { default: mqtt } = await import("mqtt");
|
||||||
|
client = mqtt.connect(`mqtt://127.0.0.1:${mqttPort}`, {
|
||||||
|
clientId: "journal-server",
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on("connect", () => {
|
||||||
|
// 1. Persistence: append every stream message to JSONL
|
||||||
|
client!.subscribe("ttrpg/+/stream", { qos: 1 }, (err) => {
|
||||||
|
if (err) console.error("[journal] stream sub err:", err);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2. Session meta: manage manifest from retained meta topics
|
||||||
|
client!.subscribe("ttrpg/+/meta", { qos: 1 }, (err) => {
|
||||||
|
if (err) console.error("[journal] meta sub err:", err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on("message", (topic, payload) => {
|
||||||
|
const parts = topic.split("/");
|
||||||
|
if (parts.length < 3) return;
|
||||||
|
const sessionId = parts[1];
|
||||||
|
const subtopic = parts[2];
|
||||||
|
|
||||||
|
if (subtopic === "stream") {
|
||||||
|
// Persist every stream message
|
||||||
|
try {
|
||||||
|
appendStream(root, sessionId, payload.toString());
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`[journal] stream append err for ${sessionId}:`, e);
|
||||||
|
}
|
||||||
|
} else if (subtopic === "meta") {
|
||||||
|
// Session lifecycle
|
||||||
|
handleMetaChange(root, sessionId, client!, payload.toString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("[journal] persistence listener active");
|
||||||
|
|
||||||
|
return {
|
||||||
|
broker,
|
||||||
|
tcpServer,
|
||||||
|
persistenceClient: client,
|
||||||
|
async close() {
|
||||||
|
console.log("[journal] shutting down...");
|
||||||
|
client?.end(true);
|
||||||
|
await new Promise<void>((r) => broker.close(() => r()));
|
||||||
|
await new Promise<void>((r) => tcpServer.close(() => r()));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Session lifecycle
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const $SESSIONS = "ttrpg/$SESSIONS";
|
||||||
|
|
||||||
|
function handleMetaChange(
|
||||||
|
root: string,
|
||||||
|
sessionId: string,
|
||||||
|
client: import("mqtt").MqttClient,
|
||||||
|
rawPayload: string,
|
||||||
|
): void {
|
||||||
|
const manifest = loadManifest(root);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const meta = JSON.parse(rawPayload) as SessionMeta | null;
|
||||||
|
|
||||||
|
if (!meta || !meta.name) {
|
||||||
|
// Tombstone: empty or invalid payload → delete session
|
||||||
|
if (manifest.sessions[sessionId]) {
|
||||||
|
delete manifest.sessions[sessionId];
|
||||||
|
|
||||||
|
// Wipe files
|
||||||
|
const sp = streamPath(root, sessionId);
|
||||||
|
if (existsSync(sp)) unlinkSync(sp);
|
||||||
|
const sd = sessionDir(root, sessionId);
|
||||||
|
try {
|
||||||
|
rmdirSync(sd);
|
||||||
|
} catch {
|
||||||
|
/* not empty, fine */
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`[journal] session deleted: ${sessionId}`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Create or update
|
||||||
|
manifest.sessions[sessionId] = {
|
||||||
|
name: meta.name,
|
||||||
|
created: meta.created || Date.now(),
|
||||||
|
players: meta.players || [],
|
||||||
|
};
|
||||||
|
console.log(`[journal] session updated: ${sessionId} (${meta.name})`);
|
||||||
|
}
|
||||||
|
|
||||||
|
saveManifest(root, manifest);
|
||||||
|
|
||||||
|
// Republish full manifest as a retained message
|
||||||
|
client.publish($SESSIONS, JSON.stringify(manifest), {
|
||||||
|
qos: 1,
|
||||||
|
retain: true,
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`[journal] meta parse err for ${sessionId}:`, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,14 +1,21 @@
|
||||||
export interface ServeOptions {
|
export interface ServeOptions {
|
||||||
port: string;
|
port: string;
|
||||||
host?: string;
|
host?: string;
|
||||||
|
mqttPort?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CompileOptions {
|
export interface CompileOptions {
|
||||||
output: string;
|
output: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ServeCommandHandler = (dir: string, options: ServeOptions) => Promise<void>;
|
export type ServeCommandHandler = (
|
||||||
export type CompileCommandHandler = (dir: string, options: CompileOptions) => Promise<void>;
|
dir: string,
|
||||||
|
options: ServeOptions,
|
||||||
|
) => Promise<void>;
|
||||||
|
export type CompileCommandHandler = (
|
||||||
|
dir: string,
|
||||||
|
options: CompileOptions,
|
||||||
|
) => Promise<void>;
|
||||||
|
|
||||||
export interface MarkdownFile {
|
export interface MarkdownFile {
|
||||||
path: string;
|
path: string;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue