openvibers/openvibe.search Commits
openvibe-shared v1.5.0 (Track R release manifest), openvibe-contracts v0.32.0
Changes
@@@ -200,7 +200,7 @@ the `search.document.removed` event it records:| `search.document.write` | `PUT/DELETE /api/v1/documents/:owner/:type/:id`, `/api/v1/owners/:owner/...` including the removal feed (own owner only) || `search.query.delegate` | the query and saved-search routes, acting for `X-OV-Subject` |--Released in `openvibe-contracts` v0.12.0 with the service manifest (this repo pins v0.13.0);++Released in `openvibe-contracts` v0.12.0 with the service manifest (this repo pins v0.32.0);[server/auth.js](server/auth.js) decides them with the contracts grant rule, and CI runs`openvibe-contracts-check --service search`.@@@ -7,7 +7,7 @@"runtime": "node 22, express, better-sqlite3 (FTS5)","port": 4710,"domain": "search.openvibe.network (vhost in deploy/nginx, not installed: until it is, the name falls through to the admin.openvibe.network placeholder; README \"Public host\")",-- "contracts": "openvibe-contracts v0.13.0",++ "contracts": "openvibe-contracts v0.32.0","capabilities": ["search.document.write", "search.query.delegate"],"capabilitiesRegistered": true,"contractsProposed": ["search.index-document@1 (released in openvibe-contracts v0.12.0)"],@@@ -14,8 +14,8 @@"better-sqlite3": "^11.10.0","dotenv": "^16.4.7","express": "^4.21.2",-- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.13.0",-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.3.0"++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.32.0",++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.5.0"},"engines": {"node": ">=22.0.0"@@@ -969,9 +969,9 @@}},"node_modules/openvibe-contracts": {-- "version": "0.13.0",-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.13.0",-- "integrity": "sha512-MeIGJYHQsbr6ISeEErduUw/PD52X5IBclH2ht/G/t4lSX5X4o2AwcZYLEzOZrcbaXQyplgC7r86RCGFvi1ifUA==",++ "version": "0.32.0",++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.32.0",++ "integrity": "sha512-ntN58SIG03YDxbhsiIzOM5GRH19jRMHZUYWI3xU2VwovExagF5DdwApLVfezsu84UTJ+V2Jfn+LWDc+Oz8ab+g==","license": "AGPL-3.0-only","dependencies": {"ajv": "^8.17.1",@@@ -985,9 +985,9 @@}},"node_modules/openvibe-shared": {-- "version": "1.3.0",-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.3.0",-- "integrity": "sha512-w8yl/5+9eend8I2O/DzAJnEAL2N3GTUY7c7pzK+MLJuLAGD8FmJJQ9gwbgyrq70Snjt3ebrg3TlpORhRAp2kgA==",++ "version": "1.5.0",++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.5.0",++ "integrity": "sha512-cehnscuYMkJwuCYGcI6wPSswbUn0bhTyGAaD5feNCoO//2e9gyC7cgjkEcIOtM8DQF3yTuUNyXnOwckIeM4fUg==","license": "MIT","dependencies": {"jsonwebtoken": "^9.0.0"@@@ -20,8 +20,8 @@"better-sqlite3": "^11.10.0","dotenv": "^16.4.7","express": "^4.21.2",-- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.13.0",-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.3.0"++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.32.0",++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.5.0"},"engines": {"node": ">=22.0.0"@@@ -42,7 +42,8 @@ function createApp({ config, db, store, engine, auth, keys, outbox, relay, purge// fails; the Network key and index consistency are optional and degrade it (see observability.js).const readiness = createSearchReadiness({ db, keys, config, engine, store, outbox, relay, purges, purger, saved, release: release.release });app.get('/api/ready', readiness.handler);-- app.get('/release.json', release.handler);++ // GET /release.json (ADR-016) and POST /release-metrics (open tabs' update reports into /metrics).++ release.mount(app, { registry: metrics.registry });const searcher = createSearcher({ config, store, engine, now });app.use(documentsRouter({ store, auth, db, relay, purges }));@@@ -71,6 +71,14 @@ t('/metrics: 404 through a proxy; route templates and Search gauges direct', asyassert.ok(/\nsearch_outbox_pending \d+\n/.test(text));});++t('/release.json: a registry.release-manifest@1 that names where tabs report updates', async () => {++ const r = await request(svc.base, 'GET', '/release.json');++ assert.strictEqual(r.status, 200, r.text);++ assert.strictEqual(r.body.service, 'search');++ assert.deepStrictEqual(require('openvibe-contracts').validate('registry.release-manifest@1', r.body).errors, []);++ assert.strictEqual(r.body.metrics_url, '/release-metrics');++});++t('a full-text index out of step with the documents degrades /api/ready (still 200)', async () => {await svc.stop();svc = await boot(); // fresh: the index check has no cached result
@@ -200,7 +200,7 @@ the `search.document.removed` event it records:
@@ -200,7 +200,7 @@ the `search.document.removed` event it records:
| `search.document.write` | `PUT/DELETE /api/v1/documents/:owner/:type/:id`, `/api/v1/owners/:owner/...` including the removal feed (own owner only) |
| `search.document.write` | `PUT/DELETE /api/v1/documents/:owner/:type/:id`, `/api/v1/owners/:owner/...` including the removal feed (own owner only) |
| `search.query.delegate` | the query and saved-search routes, acting for `X-OV-Subject` |
| `search.query.delegate` | the query and saved-search routes, acting for `X-OV-Subject` |
-Released in `openvibe-contracts` v0.12.0 with the service manifest (this repo pins v0.13.0);
+Released in `openvibe-contracts` v0.12.0 with the service manifest (this repo pins v0.32.0);
[server/auth.js](server/auth.js) decides them with the contracts grant rule, and CI runs
[server/auth.js](server/auth.js) decides them with the contracts grant rule, and CI runs
`openvibe-contracts-check --service search`.
`openvibe-contracts-check --service search`.
@@ -7,7 +7,7 @@
@@ -7,7 +7,7 @@
"runtime": "node 22, express, better-sqlite3 (FTS5)",
"runtime": "node 22, express, better-sqlite3 (FTS5)",
"port": 4710,
"port": 4710,
"domain": "search.openvibe.network (vhost in deploy/nginx, not installed: until it is, the name falls through to the admin.openvibe.network placeholder; README \"Public host\")",
"domain": "search.openvibe.network (vhost in deploy/nginx, not installed: until it is, the name falls through to the admin.openvibe.network placeholder; README \"Public host\")",
- "contracts": "openvibe-contracts v0.13.0",
+ "contracts": "openvibe-contracts v0.32.0",
"capabilities": ["search.document.write", "search.query.delegate"],
"capabilities": ["search.document.write", "search.query.delegate"],
"capabilitiesRegistered": true,
"capabilitiesRegistered": true,
"contractsProposed": ["search.index-document@1 (released in openvibe-contracts v0.12.0)"],
"contractsProposed": ["search.index-document@1 (released in openvibe-contracts v0.12.0)"],
@@ -14,8 +14,8 @@
@@ -14,8 +14,8 @@
"better-sqlite3": "^11.10.0",
"better-sqlite3": "^11.10.0",
"dotenv": "^16.4.7",
"dotenv": "^16.4.7",
"express": "^4.21.2",
"express": "^4.21.2",
- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.13.0",
- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.3.0"
+ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.32.0",
+ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.5.0"
},
},
"engines": {
"engines": {
"node": ">=22.0.0"
"node": ">=22.0.0"
@@ -969,9 +969,9 @@
@@ -969,9 +969,9 @@
}
}
},
},
"node_modules/openvibe-contracts": {
"node_modules/openvibe-contracts": {
- "version": "0.13.0",
- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.13.0",
- "integrity": "sha512-MeIGJYHQsbr6ISeEErduUw/PD52X5IBclH2ht/G/t4lSX5X4o2AwcZYLEzOZrcbaXQyplgC7r86RCGFvi1ifUA==",
+ "version": "0.32.0",
+ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.32.0",
+ "integrity": "sha512-ntN58SIG03YDxbhsiIzOM5GRH19jRMHZUYWI3xU2VwovExagF5DdwApLVfezsu84UTJ+V2Jfn+LWDc+Oz8ab+g==",
"license": "AGPL-3.0-only",
"license": "AGPL-3.0-only",
"dependencies": {
"dependencies": {
"ajv": "^8.17.1",
"ajv": "^8.17.1",
@@ -985,9 +985,9 @@
@@ -985,9 +985,9 @@
}
}
},
},
"node_modules/openvibe-shared": {
"node_modules/openvibe-shared": {
- "version": "1.3.0",
- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.3.0",
- "integrity": "sha512-w8yl/5+9eend8I2O/DzAJnEAL2N3GTUY7c7pzK+MLJuLAGD8FmJJQ9gwbgyrq70Snjt3ebrg3TlpORhRAp2kgA==",
+ "version": "1.5.0",
+ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.5.0",
+ "integrity": "sha512-cehnscuYMkJwuCYGcI6wPSswbUn0bhTyGAaD5feNCoO//2e9gyC7cgjkEcIOtM8DQF3yTuUNyXnOwckIeM4fUg==",
"license": "MIT",
"license": "MIT",
"dependencies": {
"dependencies": {
"jsonwebtoken": "^9.0.0"
"jsonwebtoken": "^9.0.0"
@@ -20,8 +20,8 @@
@@ -20,8 +20,8 @@
"better-sqlite3": "^11.10.0",
"better-sqlite3": "^11.10.0",
"dotenv": "^16.4.7",
"dotenv": "^16.4.7",
"express": "^4.21.2",
"express": "^4.21.2",
- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.13.0",
- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.3.0"
+ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.32.0",
+ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.5.0"
},
},
"engines": {
"engines": {
"node": ">=22.0.0"
"node": ">=22.0.0"
@@ -42,7 +42,8 @@ function createApp({ config, db, store, engine, auth, keys, outbox, relay, purge
@@ -42,7 +42,8 @@ function createApp({ config, db, store, engine, auth, keys, outbox, relay, purge
// fails; the Network key and index consistency are optional and degrade it (see observability.js).
// fails; the Network key and index consistency are optional and degrade it (see observability.js).
const readiness = createSearchReadiness({ db, keys, config, engine, store, outbox, relay, purges, purger, saved, release: release.release });
const readiness = createSearchReadiness({ db, keys, config, engine, store, outbox, relay, purges, purger, saved, release: release.release });
app.get('/api/ready', readiness.handler);
app.get('/api/ready', readiness.handler);
- app.get('/release.json', release.handler);
+ // GET /release.json (ADR-016) and POST /release-metrics (open tabs' update reports into /metrics).
+ release.mount(app, { registry: metrics.registry });
const searcher = createSearcher({ config, store, engine, now });
const searcher = createSearcher({ config, store, engine, now });
app.use(documentsRouter({ store, auth, db, relay, purges }));
app.use(documentsRouter({ store, auth, db, relay, purges }));
@@ -71,6 +71,14 @@ t('/metrics: 404 through a proxy; route templates and Search gauges direct', asy
@@ -71,6 +71,14 @@ t('/metrics: 404 through a proxy; route templates and Search gauges direct', asy
assert.ok(/\nsearch_outbox_pending \d+\n/.test(text));
assert.ok(/\nsearch_outbox_pending \d+\n/.test(text));
});
});
+t('/release.json: a registry.release-manifest@1 that names where tabs report updates', async () => {
+ const r = await request(svc.base, 'GET', '/release.json');
+ assert.strictEqual(r.status, 200, r.text);
+ assert.strictEqual(r.body.service, 'search');
+ assert.deepStrictEqual(require('openvibe-contracts').validate('registry.release-manifest@1', r.body).errors, []);
+ assert.strictEqual(r.body.metrics_url, '/release-metrics');
+});
+
t('a full-text index out of step with the documents degrades /api/ready (still 200)', async () => {
t('a full-text index out of step with the documents degrades /api/ready (still 200)', async () => {
await svc.stop();
await svc.stop();
svc = await boot(); // fresh: the index check has no cached result
svc = await boot(); // fresh: the index check has no cached result