Skip to content

Commit afdc7cd

Browse files
committed
display a link to latest stable release if viewing non-canonical documentation, and emit a rel=canonical link element and header if applicable
1 parent 6fd87ac commit afdc7cd

34 files changed

+697
-169
lines changed

Assets/css/Main.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/css/Main.css.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Sources/UnidocAnalysis/Volume (ext).swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ extension Volume
1010
func siteMap() -> SiteMap<PackageIdentifier>
1111
{
1212
var lines:[UInt8] = []
13-
for master:Volume.Master in self.masters
13+
for master:Volume.Master in self.vertices
1414
{
1515
switch master
1616
{
@@ -37,7 +37,7 @@ extension Volume
3737
var procs:[Unidoc.Scalar: [Shoot]] = [:]
3838
var types:Types = .init()
3939

40-
for master:Master in self.masters
40+
for master:Master in self.vertices
4141
{
4242
switch master
4343
{

Sources/UnidocDB/Volumes/UnidocDatabase.Masters.swift renamed to Sources/UnidocDB/Volumes/UnidocDatabase.Vertices.swift

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
1+
import MongoDB
12
import MongoQL
23
import Unidoc
34
import UnidocSelectors
45
import UnidocRecords
56

67
extension UnidocDatabase
78
{
8-
public
9-
struct Masters
9+
@frozen public
10+
struct Vertices
1011
{
12+
public
1113
let database:Mongo.Database
1214

15+
@inlinable internal
1316
init(database:Mongo.Database)
1417
{
1518
self.database = database
1619
}
1720
}
1821
}
19-
extension UnidocDatabase.Masters:DatabaseCollection
22+
extension UnidocDatabase.Vertices:DatabaseCollection
2023
{
2124
@inlinable public static
2225
var name:Mongo.Collection { "masters" }
@@ -64,3 +67,13 @@ extension UnidocDatabase.Masters:DatabaseCollection
6467
},
6568
]
6669
}
70+
extension UnidocDatabase.Vertices
71+
{
72+
public
73+
func recode(with session:Mongo.Session) async throws -> (modified:Int, of:Int)
74+
{
75+
try await self.recode(through: Volume.Master.self,
76+
with: session,
77+
by: .now.advanced(by: .seconds(60)))
78+
}
79+
}

Sources/UnidocDB/Volumes/UnidocDatabase.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ extension UnidocDatabase
2626
{
2727
var policies:Policies { .init() }
2828

29-
var masters:Masters { .init(database: self.id) }
29+
@inlinable public
30+
var vertices:Vertices { .init(database: self.id) }
3031
var groups:Groups { .init(database: self.id) }
3132
var search:Search { .init(database: self.id) }
3233
var trees:Trees { .init(database: self.id) }
@@ -47,7 +48,7 @@ extension UnidocDatabase:DatabaseModel
4748
public
4849
func setup(with session:Mongo.Session) async throws
4950
{
50-
try await self.masters.setup(with: session)
51+
try await self.vertices.setup(with: session)
5152
try await self.groups.setup(with: session)
5253
try await self.search.setup(with: session)
5354
try await self.trees.setup(with: session)
@@ -134,7 +135,7 @@ extension UnidocDatabase
134135
{
135136
try await self.search.delete(volume.id, with: session)
136137

137-
try await self.masters.clear(receipt.edition, with: session)
138+
try await self.vertices.clear(receipt.edition, with: session)
138139
try await self.groups.clear(receipt.edition, with: session)
139140
try await self.trees.clear(receipt.edition, with: session)
140141

@@ -152,7 +153,7 @@ extension UnidocDatabase
152153
{
153154
let (index, trees):(SearchIndex<VolumeIdentifier>, [Volume.TypeTree]) = volume.indexes()
154155

155-
try await self.masters.insert(volume.masters, with: session)
156+
try await self.vertices.insert(volume.vertices, with: session)
156157
try await self.names.insert(volume.names, with: session)
157158
try await self.trees.insert(trees, with: session)
158159
try await self.search.insert(index, with: session)
@@ -196,7 +197,7 @@ extension UnidocDatabase
196197
let id:Snapshot.ID = snapshot.id
197198

198199
var volume:Volume = .init(latest: latestRelease?.id,
199-
masters: linker.masters,
200+
vertices: linker.vertices,
200201
groups: linker.groups,
201202
names: .init(id: snapshot.edition,
202203
display: snapshot.metadata.display,

Sources/UnidocLinker/Linker/DynamicLinker.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ struct DynamicLinker
1919
private
2020
var extensions:Extensions
2121

22-
/// Maps masters to groups.
22+
/// Maps vertices to groups.
2323
private
2424
var memberships:[Int32: Unidoc.Scalar]
2525
private
@@ -30,7 +30,7 @@ struct DynamicLinker
3030
)
3131

3232
public private(set)
33-
var masters:[Volume.Master]
33+
var vertices:[Volume.Master]
3434
public private(set)
3535
var groups:[Volume.Group]
3636

@@ -52,7 +52,7 @@ struct DynamicLinker
5252
self.next.autogroup = .init(zone: context.current.edition)
5353
self.next.topic = .init(zone: context.current.edition)
5454

55-
self.masters = []
55+
self.vertices = []
5656
self.groups = []
5757
}
5858
}
@@ -92,10 +92,10 @@ extension DynamicLinker
9292

9393
defer
9494
{
95-
self.masters.append(.meta(meta))
95+
self.vertices.append(.meta(meta))
9696
for culture:Volume.Master.Culture in cultures
9797
{
98-
self.masters.append(.culture(culture))
98+
self.vertices.append(.culture(culture))
9999
}
100100
}
101101

@@ -132,7 +132,7 @@ extension DynamicLinker
132132
context.current.files.indices,
133133
context.current.files)
134134
{
135-
self.masters.append(.file(.init(id: context.current.edition + f, symbol: file)))
135+
self.vertices.append(.file(.init(id: context.current.edition + f, symbol: file)))
136136
}
137137

138138
// Create extension records, and compute weighted stats.
@@ -342,7 +342,7 @@ extension DynamicLinker
342342

343343
(record.overview, record.details) = resolver.link(article: node.body)
344344

345-
self.masters.append(.article(record))
345+
self.vertices.append(.article(record))
346346
}
347347
}
348348

@@ -446,7 +446,7 @@ extension DynamicLinker
446446
(record.overview, record.details) = resolver.link(article: article)
447447
}
448448

449-
self.masters.append(.decl(record))
449+
self.vertices.append(.decl(record))
450450
}
451451
}
452452
}

Sources/UnidocPages/ApplicationPage.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,19 @@ protocol ApplicationPage:FixedPage
88
associatedtype Navigator:HyperTextOutputStreamable
99
associatedtype Sidebar:HyperTextOutputStreamable
1010

11+
var canonical:CanonicalVersion? { get }
1112
var navigator:Navigator { get }
1213
var sidebar:Sidebar? { get }
1314

1415
var volume:VolumeIdentifier { get }
1516

1617
func main(_:inout HTML.ContentEncoder)
1718
}
19+
extension ApplicationPage
20+
{
21+
@inlinable public
22+
var canonical:CanonicalVersion? { nil }
23+
}
1824
extension ApplicationPage where Navigator == HTML.Logo
1925
{
2026
var navigator:HTML.Logo { .init() }
@@ -26,6 +32,9 @@ extension ApplicationPage where Sidebar == Never
2632
}
2733
extension ApplicationPage
2834
{
35+
@inlinable public
36+
var canonicalURI:URI? { self.canonical?.uri }
37+
2938
public
3039
func head(augmenting head:inout HTML.ContentEncoder)
3140
{
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
extension CanonicalVersion
2+
{
3+
@frozen @usableFromInline internal
4+
enum Relationship
5+
{
6+
case earlier
7+
case later
8+
case stable
9+
}
10+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import URI
2+
3+
extension CanonicalVersion
4+
{
5+
@frozen @usableFromInline internal
6+
enum Target
7+
{
8+
case article(URI?)
9+
case culture(URI?)
10+
case decl(URI?)
11+
case meta
12+
}
13+
}
14+
extension CanonicalVersion.Target
15+
{
16+
var indefiniteArticle:String
17+
{
18+
switch self
19+
{
20+
case .article: return "An"
21+
case .culture: return "A"
22+
case .decl: return "A"
23+
case .meta: return "A"
24+
}
25+
}
26+
var demonym:String
27+
{
28+
switch self
29+
{
30+
case .article: return "article"
31+
case .culture: return "module"
32+
case .decl: return "symbol"
33+
case .meta: return "package"
34+
}
35+
}
36+
var identity:String
37+
{
38+
switch self
39+
{
40+
case .article: return "name"
41+
case .culture: return "name"
42+
case .decl: return "signature"
43+
case .meta: return "identity"
44+
}
45+
}
46+
47+
var uri:URI?
48+
{
49+
switch self
50+
{
51+
case .article(let uri): return uri
52+
case .culture(let uri): return uri
53+
case .decl(let uri): return uri
54+
case .meta: return nil
55+
}
56+
}
57+
}

0 commit comments

Comments
 (0)