Class: OKF::Server::Hub
- Inherits:
-
Object
- Object
- OKF::Server::Hub
- Defined in:
- lib/okf/server/hub.rb
Overview
Multiplexes N bundles behind one server. Each bundle is mounted at
/b// redirects to the
default bundle (explicitly chosen, or the first), or shows an empty-state
page when none are registered. The graph page is already mount-relative (its fetch endpoints
are relative), so hosting under a prefix needs only a clean PATH_INFO strip
here plus a trailing-slash redirect. Part of the shell — it is a Rack app.
GET / 302 -> /b/<default>/ (empty-state page when no bundles)
GET /b/ the bundle index — every hosted bundle, default marked
GET /b/<slug> 301 -> /b/<slug>/ (query string preserved)
GET /b/<slug>/... delegated to that bundle's App (the prefix stripped)
GET (unknown slug) 404 as a page listing the hosted bundles — a stale
bookmark after a rename gets a way home, not bare text
bundles is an ordered array of Hub::Bundle (slug, folder, title). Apps are
built up front, each carrying the other bundles as siblings so the in-page
switcher can jump between them; static okf render files get no siblings and
so cannot switch.
Defined Under Namespace
Classes: Bundle
Constant Summary collapse
- MOUNT =
"/b"- STYLE =
Shared style for the hub's own pages (empty landing, /b/ index, 404) — self-contained and theme-aware, no external requests, in keeping with the graph page's own no-CDN-at-rest rule.
<<~CSS body{margin:0;min-height:100vh;display:grid;place-items:center;background:#f4f5f7;color:#1f2328;font:15px/1.5 system-ui,-apple-system,Segoe UI,Roboto,sans-serif} main{max-width:34rem;width:calc(100% - 4rem);padding:2rem}h1{font-size:1.3rem;margin:0 0 .5rem} code{background:#e6e8eb;padding:.15rem .4rem;border-radius:.35rem} ul.bundles{list-style:none;margin:1rem 0 0;padding:0} ul.bundles li{padding:.45rem 0;border-top:1px solid #e6e8eb;display:flex;justify-content:space-between;gap:1rem;align-items:baseline} ul.bundles a{color:inherit;font-weight:600;text-decoration:none}ul.bundles a:hover{text-decoration:underline} .meta{color:#63697a;font-size:.85rem;white-space:nowrap} .def{margin-left:.5rem;padding:.05rem .45rem;border-radius:99px;background:#e6e8eb;font-size:.75rem} @media(prefers-color-scheme:dark){body{background:#111318;color:#eceef1}code,.def{background:#232833} ul.bundles li{border-color:#2a2e36}.meta{color:#9aa0aa}} CSS
Instance Attribute Summary collapse
-
#bundles ⇒ Object
readonly
The hosted bundles in mount order, and the one
/redirects to — so a caller printing the mount table asks the hub instead of re-deriving the rule and drifting from it. -
#default ⇒ Object
readonly
The hosted bundles in mount order, and the one
/redirects to — so a caller printing the mount table asks the hub instead of re-deriving the rule and drifting from it.
Instance Method Summary collapse
- #call(env) ⇒ Object
-
#initialize(bundles, layout: "cose") ⇒ Hub
constructor
The first bundle is the one
/redirects to — the registry hands them over in its own order, where first is the default (okf registry defaultmoves an entry to the front), and an ephemeral run takes the dirs as typed.
Constructor Details
#initialize(bundles, layout: "cose") ⇒ Hub
The first bundle is the one / redirects to — the registry hands them over
in its own order, where first is the default (okf registry default
moves an entry to the front), and an ephemeral run takes the dirs as typed.
58 59 60 61 62 |
# File 'lib/okf/server/hub.rb', line 58 def initialize(bundles, layout: "cose") @bundles = bundles @default = bundles.first @apps = build_apps(layout) end |
Instance Attribute Details
#bundles ⇒ Object (readonly)
The hosted bundles in mount order, and the one / redirects to — so a
caller printing the mount table asks the hub instead of re-deriving the
rule and drifting from it.
53 54 55 |
# File 'lib/okf/server/hub.rb', line 53 def bundles @bundles end |
#default ⇒ Object (readonly)
The hosted bundles in mount order, and the one / redirects to — so a
caller printing the mount table asks the hub instead of re-deriving the
rule and drifting from it.
53 54 55 |
# File 'lib/okf/server/hub.rb', line 53 def default @default end |
Instance Method Details
#call(env) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/okf/server/hub.rb', line 64 def call(env) request = Rack::Request.new(env) return not_found unless request.get? path = request.path_info query = request.query_string.to_s # Everything this class *emits* must carry the prefix a host mounted it # under; PATH_INFO is already relative to it. base = env["SCRIPT_NAME"].to_s return landing(base, query) if [ "", "/" ].include?(path) return html(200, index_page(base)) if [ MOUNT, "#{MOUNT}/" ].include?(path) slug, rest = split(path) app = slug && @apps[slug] return html(404, missing_page(base, path)) unless app return redirect("#{base}#{MOUNT}/#{slug}/", 301, query) if rest.empty? app.call(mounted(env, slug, rest)) end |