Implement v2 API for stateful sessions and add engagement metrics support

This commit is contained in:
ImBenji
2026-01-02 12:08:48 +00:00
parent 48e6c7e3c1
commit 469eea4e2f
5 changed files with 48 additions and 2 deletions

1
.gitignore vendored
View File

@@ -1,5 +1,6 @@
node_modules/ node_modules/
cache/ cache/
data/
*.png *.png
.env .env
.DS_Store .DS_Store

12
.idea/dataSources.xml generated Normal file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="sessions" uuid="e68c3313-f9e3-4252-beee-e5a95c69ca2f">
<driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/data/sessions.db</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>

9
api.js
View File

@@ -1,4 +1,5 @@
const express = require('express'); const express = require('express');
const cors = require('cors');
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const crypto = require('crypto'); const crypto = require('crypto');
@@ -18,6 +19,14 @@ if (!fs.existsSync(CACHE_DIR)) {
app.use(express.json({ limit: '1gb' })); app.use(express.json({ limit: '1gb' }));
app.use(express.urlencoded({ limit: '1gb', extended: true })); app.use(express.urlencoded({ limit: '1gb', extended: true }));
// enable CORS for all routes
app.use(cors({
origin: '*',
methods: ['GET', 'POST', 'PATCH', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: false
}));
// Request logging middleware // Request logging middleware
app.use((req, res, next) => { app.use((req, res, next) => {
// skip logging health checks // skip logging health checks

23
package-lock.json generated
View File

@@ -10,6 +10,7 @@
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"better-sqlite3": "^11.0.0", "better-sqlite3": "^11.0.0",
"cors": "^2.8.5",
"express": "^4.18.2", "express": "^4.18.2",
"puppeteer": "^23.0.0" "puppeteer": "^23.0.0"
} }
@@ -527,6 +528,19 @@
"integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/cors": {
"version": "2.8.5",
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
"license": "MIT",
"dependencies": {
"object-assign": "^4",
"vary": "^1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/cosmiconfig": { "node_modules/cosmiconfig": {
"version": "9.0.0", "version": "9.0.0",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz",
@@ -1445,6 +1459,15 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/object-inspect": { "node_modules/object-inspect": {
"version": "1.13.4", "version": "1.13.4",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",

View File

@@ -13,8 +13,9 @@
"license": "ISC", "license": "ISC",
"type": "commonjs", "type": "commonjs",
"dependencies": { "dependencies": {
"puppeteer": "^23.0.0", "better-sqlite3": "^11.0.0",
"cors": "^2.8.5",
"express": "^4.18.2", "express": "^4.18.2",
"better-sqlite3": "^11.0.0" "puppeteer": "^23.0.0"
} }
} }