openvibers/openvibe.blog Commits

The OpenVibe Frame from this site's own pinned copy: /shared/* is served by openvibe-shared/serve (1.12.0) and every page references it by content hash (/shared/<file>?v=<hash>), so this site's pin decides what its pages run and its navbar and footer keep working while openvibe.network is down; openvibe-publishing 0.4.0 (openvibe-shared as a peer: one copy, no lockstep releases)

OP OpenVibers committed 24 Sept 2026 · 7d9d197db2 · 6 files, +23 −21


Changes

ddiff --git a/package-lock.json b/package-lock.json
iindex 67b886d..90fe4bc 100644
---- a/package-lock.json
++++ b/package-lock.json
@@@ -16,9 +16,9 @@
"express-rate-limit": "^7.5.0",
"helmet": "^8.1.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.33.0",
-- "openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v0.3.2",
++ "openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v0.4.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.7.0",
-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.11.0"
++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.12.0"
},
"devDependencies": {
"jsonwebtoken": "^9.0.2"
@@@ -1031,21 +1031,19 @@
}
},
"node_modules/openvibe-publishing": {
-- "version": "0.3.2",
-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v0.3.2",
-- "integrity": "sha512-XNpM7JJHCWlk2SZRzRqpu2kmWF9kMj6+tS3433hRKdyAB3jubi7Xzeav0OGX1wtqlKk4k00R186XiFmx1igTDg==",
++ "version": "0.4.0",
++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v0.4.0",
++ "integrity": "sha512-zipRyxNSb39fTk6ZtXfCygWgxSRVj/fOVGc31hynBANM5JCwErX/dYKsE/XmdYGlId29E5O3MyZLohgfocBP4w==",
"license": "MIT",
-- "dependencies": {
-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.11.0"
-- },
"engines": {
"node": ">=20"
},
"peerDependencies": {
-- "better-sqlite3": ">=11"
++ "better-sqlite3": ">=11",
++ "openvibe-shared": ">=1.5.0"
},
"peerDependenciesMeta": {
-- "better-sqlite3": {
++ "openvibe-shared": {
"optional": true
}
}
@@@ -1060,9 +1058,9 @@
}
},
"node_modules/openvibe-shared": {
-- "version": "1.11.0",
-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.11.0",
-- "integrity": "sha512-edMW0I25HNFReLcfZ9ak+4q5sy2t7qq7EPG52tOerTBV2fU994C5we/02AD/9i2Vuq0+ayNBBisW0cg60L6DLQ==",
++ "version": "1.12.0",
++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.12.0",
++ "integrity": "sha512-Qpy4YVoPMs1q/0/08/5ZODI0+7ev+Krk75nsRPsTjNCm7Eu91tt1LPnUNLt4kYfRj6duS+N9icm02gksnlMiyA==",
"license": "MIT",
"dependencies": {
"jsonwebtoken": "^9.0.0"
ddiff --git a/package.json b/package.json
iindex 2b245c2..83bf931 100644
---- a/package.json
++++ b/package.json
@@@ -22,9 +22,9 @@
"express-rate-limit": "^7.5.0",
"helmet": "^8.1.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.33.0",
-- "openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v0.3.2",
++ "openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v0.4.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.7.0",
-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.11.0"
++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.12.0"
},
"devDependencies": {
"jsonwebtoken": "^9.0.2"
ddiff --git a/server/app.js b/server/app.js
iindex 4b05cfb..a971c91 100644
---- a/server/app.js
++++ b/server/app.js
@@@ -118,6 +118,8 @@ function createApp(opts = {}) {
{ const legal = require('openvibe-shared/legal'); app.get(legal.PATHS, legal.handler({ id: 'blog', service: 'blog', host: 'openvibe.blog', name: 'OpenVibe.Blog', profile: 'ugc' })); }
// ── Static assets (content-hashed ?v= → immutable) ──────
++ // This site's own pinned copy of the OpenVibe Frame's browser files (openvibe-shared/serve).
++ app.use('/shared', require('openvibe-shared/serve').handler());
app.use(express.static(PUBLIC_DIR, {
index: false, redirect: false,
setHeaders(res, filePath) {
ddiff --git a/server/http/public.js b/server/http/public.js
iindex c862403..9e7296b 100644
---- a/server/http/public.js
++++ b/server/http/public.js
@@@ -17,6 +17,7 @@
* members/VIP and private posts, refusals, 404/410 — is `private, no-store` + X-Robots-Tag.
*/
const express = require('express');
++const ovServe = require('openvibe-shared/serve');
const frame = require('openvibe-shared/frame');
const seo = require('openvibe-publishing/seo');
const ssr = require('openvibe-publishing/ssr');
@@@ -123,7 +124,7 @@ function createPublicRoutes(ctx) {
description: 'Every change deployed to OpenVibe.Blog, newest first, with the Patch notes that gather them.',
decision: pageDecision('/updates'),
canonical: seo.canonicalUrl(config.baseUrl, '/updates'),
-- body: frame.updatesBody({ service: 'blog', siteName: 'OpenVibe.Blog' }) + frame.shippedScript(),
++ body: frame.updatesBody({ service: 'blog', siteName: 'OpenVibe.Blog' }) + `<script src="${ovServe.url('shipped.js')}" defer></script>`,
}, { cacheable: true })));
router.get('/@:handle', wrap(async (req, res) => {
ddiff --git a/server/render/layout.js b/server/render/layout.js
iindex 2647777..178f31e 100644
---- a/server/render/layout.js
++++ b/server/render/layout.js
@@@ -10,6 +10,7 @@
* - a blog's theme preset applied to its content surface only (openvibe-shared tokens)
*/
const crypto = require('crypto');
++const ovServe = require('openvibe-shared/serve');
const fs = require('fs');
const path = require('path');
const seo = require('openvibe-publishing/seo');
@@@ -90,9 +91,9 @@ ${o.modified ? `<meta property="article:modified_time" content="${esc(o.modified
${seo.feedLinks(o.feeds || [])}
${appIcon.headTags({ site: 'blog' })}
<link rel="stylesheet" href="${asset('css/blog.css')}">
--<script src="${NETWORK_URL}/shared/theme-loader.js" defer></script>
--<script src="${NETWORK_URL}/shared/navbar.js" defer></script>
--<script src="${NETWORK_URL}/shared/footer.js" defer></script>
++<script src="${ovServe.url('theme-loader.js')}" defer></script>
++<script src="${ovServe.url('navbar.js')}" defer></script>
++<script src="${ovServe.url('footer.js')}" defer></script>
</head>
<body class="${esc(o.bodyClass || '')}">
<a class="skip" href="#main">Skip to content</a>
ddiff --git a/test/shipped-pages.test.js b/test/shipped-pages.test.js
iindex db19ffc..2a10bf4 100644
---- a/test/shipped-pages.test.js
++++ b/test/shipped-pages.test.js
@@@ -17,14 +17,14 @@ const { boot, check, done } = require('./helpers/boot');
const up = await t.get('/updates');
assert.strictEqual(up.status, 200);
assert.ok(up.text.includes('What shipped on OpenVibe.Blog') && up.text.includes('data-ov-shipped="log" data-service="blog"'));
-- assert.ok(up.text.includes('https://openvibe.network/shared/shipped.js'));
++ assert.ok(/\/shared\/shipped\.js\?v=[0-9a-f]{12}/.test(up.text), 'this site\'s own pinned shipped.js');
assert.ok(up.text.includes('https://openvibe.network/updates?site=blog'), 'no-JavaScript fallback');
});
await check('one account UI: the shared navbar signs out through this site; the old bar is only for no-JS', async () => {
const home = await t.get('/');
assert.ok(home.text.includes('"logoutUrl":"/auth/logout?next={path}"'));
assert.ok(/<noscript><div class="account-bar"/.test(home.text), 'the site account bar only without JavaScript');
-- assert.ok(home.text.includes('https://openvibe.network/shared/footer.js') && home.text.includes('"updates":"/updates"'));
++ assert.ok(/\/shared\/footer\.js\?v=[0-9a-f]{12}/.test(home.text) && home.text.includes('"updates":"/updates"'));
assert.ok(home.text.includes('href="/updates"'), 'the footer links the update log');
});
await t.close();