openvibers/openvibe.shared Commits

Shared: the product at openre.stream is OpenRestream (owner, 2026-10-09) (#43)

OP OpenVibers committed 9 Oct 2026 · 90c3385f8e · 8 files, +38 −16

Every name people read says OpenRestream instead of OpenRe or OpenRe.Stream, and repository paths say
OpenVibers/OpenRestream (renamed on GitHub the same day). Ids are unchanged (openre, openre.*, ov_openre).

Shared 2.20.0: the navbar brand on openre.stream reads as one word, "OpenRe" + "stream" with no dot between, in
the brand's two colours, both linking to openre.stream (brand().joined, brand().site; ingest. is "Ingest.OpenRestream").
The footer, shipped.js and the showcase say OpenRestream. test/navbar-brand.test.js covers the bare domain.

Changes

ddiff --git a/CHANGELOG.md b/CHANGELOG.md
iindex f21106d..79c0a73 100644
---- a/CHANGELOG.md
++++ b/CHANGELOG.md
@@@ -4,6 +4,13 @@ All notable changes to `openvibe-shared`. Versions follow [semver](https://semve
breaking change to any exported module, browser global or served file name is a new major.
A release is the git tag `vX.Y.Z`; consumers pin the tag's tarball (see README).
++## 2.20.0 — 2026-10-09
++
++- The product at openre.stream is **OpenRestream** (owner, 2026-10-09), not "OpenRe.Stream". The navbar brand there
++ reads as one word: "OpenRe" + "stream" with no dot between, in the brand's two colours, both linking to
++ openre.stream (`brand().joined`, `brand().site`; ingest.openre.stream is "Ingest.OpenRestream"). The footer,
++ `shipped.js` and the showcase name it OpenRestream too.
++
## 2.19.0 — 2026-10-09
- `items.js` draws **community badges** (`network.badge.image@1`, OpenVibe.Inventory's Workshop): the badge's
ddiff --git a/footer.js b/footer.js
iindex c113bc0..0f4114a 100644
---- a/footer.js
++++ b/footer.js
@@@ -143,7 +143,7 @@
const cap = (w) => w ? w.charAt(0).toUpperCase() + w.slice(1) : '';
let m = h.match(/^(?:(.+)\.)?openvibe\.([a-z]+)$/);
if (m) { const sub = m[1] && m[1] !== 'www' ? m[1] : null; return [sub ? (sub.length <= 4 ? sub.toUpperCase() : cap(sub)) : null, 'OpenVibe', TLD_LABELS[m[2]] || cap(m[2])].filter(Boolean).join('.'); }
-- if ((m = h.match(/^(?:(.+)\.)?openre\.stream$/))) return 'OpenRe.Stream';
++ if ((m = h.match(/^(?:(.+)\.)?openre\.stream$/))) return 'OpenRestream';
const found = NETWORK.find(n => n.id === service);
if (service && TLD_LABELS[service]) return `OpenVibe.${TLD_LABELS[service]}`;
if (found && found.name !== 'Account & themes' && found.name !== 'The whole network →') return `${cap(service)}.OpenVibe.Tools`;
ddiff --git a/navbar.js b/navbar.js
iindex 698a957..9af4953 100644
---- a/navbar.js
++++ b/navbar.js
@@@ -478,10 +478,12 @@
function resolveBrand() {
const b = Object.assign({}, _config.brand || {});
const host = currentHost().toLowerCase();
-- let sub = null, tld = null, core = 'OpenVibe';
++ // OpenRestream lives at openre.stream: its brand is one word, "OpenRe" + "stream" with no dot between, so it
++ // reads as OpenRestream while the two colours still show the domain.
++ let sub = null, tld = null, core = 'OpenVibe', joined = false;
let m = host.match(/^(?:(.+)\.)?openvibe\.([a-z]+)$/);
if (m) { sub = m[1] && m[1] !== 'www' ? m[1] : null; tld = m[2]; }
-- else if ((m = host.match(/^(?:(.+)\.)?openre\.stream$/))) { sub = m[1] && m[1] !== 'www' ? m[1] : null; core = 'OpenRe'; tld = 'stream'; }
++ else if ((m = host.match(/^(?:(.+)\.)?openre\.stream$/))) { sub = m[1] && m[1] !== 'www' ? m[1] : null; core = 'OpenRe'; tld = 'stream'; joined = true; }
// Off-network hosts (localhost, previews): fall back to the service id.
if (!tld) { tld = SERVICE_TLD[_config.service] || (SERVICE_SUB[_config.service] ? 'tools' : 'network'); sub = SERVICE_SUB[_config.service] || null; }
// Legacy brandName ("Paste.OpenVibe", "OpenVibe.Live") still steers the segments.
@@@ -494,27 +496,29 @@
if (b.sub !== undefined) sub = b.sub ? String(b.sub).toLowerCase() : null;
if (b.tld) tld = String(b.tld).toLowerCase();
const subText = b.subLabel || (sub ? subLabel(sub) : null);
-- const tldText = b.tldLabel || TLD_LABELS[tld] || titleCase(tld);
-- const name = b.name || [subText, core, tldText].filter(Boolean).join('.');
++ const tldText = b.tldLabel || (joined ? tld : TLD_LABELS[tld] || titleCase(tld));
++ const site = joined ? `${core}${tldText}` : `${core}.${tldText}`;
++ const name = b.name || [subText, site].filter(Boolean).join('.');
const icon = b.icon || _config.brandIcon || null;
-- const variant = b.variant || (core === 'OpenRe' ? 'stream' : tld);
-- return { sub, subText, core, tld, tldText, name, short: subText || `${core}.${tldText}`, icon, variant, tag: b.tag || null, href: b.href || '/' };
++ const variant = b.variant || (joined ? 'stream' : tld);
++ return { sub, subText, core, tld, tldText, joined, site, name, short: subText || site, icon, variant, tag: b.tag || null, href: b.href || '/' };
}
/** Where each brand segment goes: sub → this tool, OpenVibe → the network, TLD → the site's apex. */
function brandLinks(brand) {
-- const apex = brand.core === 'OpenRe' ? 'https://openre.stream/' : `https://openvibe.${brand.tld}/`;
++ const apex = brand.joined ? 'https://openre.stream/' : `https://openvibe.${brand.tld}/`;
if (!brand.subText) return { sub: brand.href, core: brand.href, tld: brand.href, apex };
-- return { sub: brand.href, core: 'https://openvibe.network/', tld: apex, apex };
++ return { sub: brand.href, core: brand.joined ? apex : 'https://openvibe.network/', tld: apex, apex };
}
function brandHTML(brand) {
const to = brandLinks(brand);
const seg = (cls, text, href, title) => `<a href="${escapeAttr(href)}"${title ? ` title="${escapeAttr(title)}"` : ''} class="${cls}">${escapeAttr(text)}</a>`;
const dot = '<span class="b-dot">.</span>';
++ const join = brand.joined ? '' : dot;
const text = brand.subText
-- ? seg('b-sub', brand.subText, to.sub, brand.name) + dot + seg('b-core', brand.core, to.core, 'OpenVibe Network') + dot + seg('b-tld', brand.tldText, to.tld, `All of ${brand.core}.${brand.tldText}`)
-- : seg('b-core', brand.core, to.core, brand.name) + dot + seg('b-tld', brand.tldText, to.tld, brand.name);
++ ? seg('b-sub', brand.subText, to.sub, brand.name) + dot + seg('b-core', brand.core, to.core, brand.joined ? brand.site : 'OpenVibe Network') + join + seg('b-tld', brand.tldText, to.tld, `All of ${brand.site}`)
++ : seg('b-core', brand.core, to.core, brand.name) + join + seg('b-tld', brand.tldText, to.tld, brand.name);
const mark = brand.icon
? `<i class="fa-solid ${escapeAttr(brand.icon)}"></i>`
: `<span class="ov-mark" data-size="28" data-variant="${escapeAttr(brand.variant)}"></span>`;
ddiff --git a/package.json b/package.json
iindex bca147f..48bc5ad 100644
---- a/package.json
++++ b/package.json
@@@ -1,6 +1,6 @@
{
"name": "openvibe-shared",
-- "version": "2.19.0",
++ "version": "2.20.0",
"description": "Shared navbar, footer, themes, icons, legal pages, SEO, auth and analytics for every OpenVibe site",
"main": "index.js",
"bin": {
ddiff --git a/shipped.js b/shipped.js
iindex 0793619..2f6cae0 100644
---- a/shipped.js
++++ b/shipped.js
@@@ -40,7 +40,7 @@
live: 'Live', network: 'Network', tools: 'Tools', media: 'Media', community: 'Community', chat: 'Chat', games: 'Games',
blog: 'Blog', wiki: 'Wiki', news: 'News', reviews: 'Reviews', deals: 'Deals', coupons: 'Coupons', trade: 'Trade',
codes: 'Codes', host: 'Host', ai: 'AI', search: 'Search', sources: 'Sources', events: 'Events', billing: 'Billing',
-- tips: 'Tips', vip: 'VIP', openre: 'OpenRe', bot: 'Bot', sites: 'Sites', realtime: 'Realtime', space: 'Space',
++ tips: 'Tips', vip: 'VIP', openre: 'OpenRestream', bot: 'Bot', sites: 'Sites', realtime: 'Realtime', space: 'Space',
services: 'Services', actor: 'Actor', run: 'Run', watch: 'Watch', node: 'Node', zone: 'Zone', download: 'Download',
video: 'Video', pics: 'Pics', rent: 'Rent', homes: 'Homes', work: 'Work', food: 'Food', help: 'Help', quest: 'Quest',
website: 'Website', fund: 'Fund', 'media-hub': 'Media Hub', extensions: 'Extensions', contracts: 'Contracts', sdk: 'SDK',
ddiff --git a/showcase.js b/showcase.js
iindex 8479028..f3f40b8 100644
---- a/showcase.js
++++ b/showcase.js
@@@ -123,7 +123,7 @@ function stories({ id: sid, title, lede, items } = {}) {
const SERVICE_NAME = (to) => {
const t = String(to || '').toLowerCase();
if (!/^[a-z][a-z0-9-]{0,31}$/.test(t)) return '';
-- if (t === 'openre') return 'OpenRe.Stream';
++ if (t === 'openre') return 'OpenRestream';
return `OpenVibe.${t.split('-').map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join('')}`;
};
// Only links a person can follow safely: https anywhere, or a path on this site. A path may hold no backslash and no
ddiff --git a/test/navbar-brand.test.js b/test/navbar-brand.test.js
iindex f0cfbff..4b71fa2 100644
---- a/test/navbar-brand.test.js
++++ b/test/navbar-brand.test.js
@@@ -89,7 +89,18 @@ function load(hostname, opts = {}) {
const { navbar } = load('ingest.openre.stream');
navbar.init({ service: 'live' });
const b = navbar.brand();
-- assert.strictEqual(b.name, 'Ingest.OpenRe.Stream');
++ assert.strictEqual(b.name, 'Ingest.OpenRestream');
++ assert.strictEqual(b.variant, 'stream');
++}
++{
++ // openre.stream is OpenRestream: "OpenRe" + "stream" as one word (no dot), both linking to openre.stream.
++ const { navbar } = load('openre.stream');
++ navbar.init({ service: 'openre' });
++ const b = navbar.brand();
++ assert.strictEqual(b.name, 'OpenRestream');
++ assert.strictEqual(b.short, 'OpenRestream');
++ assert.strictEqual(b.core, 'OpenRe');
++ assert.strictEqual(b.tldText, 'stream');
assert.strictEqual(b.variant, 'stream');
}
{
ddiff --git a/test/shipped.test.js b/test/shipped.test.js
iindex dc290b3..8fe55a2 100644
---- a/test/shipped.test.js
++++ b/test/shipped.test.js
@@@ -27,7 +27,7 @@ const data = {
assert.ok(items[0].textContent.includes('<img src=x'));
assert.strictEqual(items[0].querySelector('.ov-shipped-site').textContent, 'Live', 'network-wide: each line names its site');
// Every site reads as its name, never as a lowercase id next to capitalised ones (the owner saw "space", "actor").
-- for (const [id, name] of [['space', 'Space'], ['services', 'Services'], ['actor', 'Actor'], ['vip', 'VIP'], ['openre', 'OpenRe'], ['media-hub', 'Media Hub'], ['brand-new', 'Brand New']]) {
++ for (const [id, name] of [['space', 'Space'], ['services', 'Services'], ['actor', 'Actor'], ['vip', 'VIP'], ['openre', 'OpenRestream'], ['media-hub', 'Media Hub'], ['brand-new', 'Brand New']]) {
assert.strictEqual(shipped.siteName(id), name, id);
}
assert.strictEqual(items[1].querySelector('a'), null, 'a non-https link is not a link');