Hi all!
I'd like to pitch an enhancement to Swift-DocC in support of the new navigation sidebar that is being developed in Swift-DocC-Render.
You can see more information about the in-development Swift-DocC-Render navigation sidebar in these threads:
This pitch is to enable emitting a JSON representation of Swift-DocC's navigator index (called RenderIndex JSON) by default. This will allow for immediate support of the Swift-DocC-Render navigation sidebar and, moving forward, easier adoption of navigator index information by other clients
Overview
Swift-DocC already supports emitting an index of the navigation hierarchy of a DocC archive during the conversion process. This index is emitted as an LMDB database and only if explicitly requested via the --index
flag to docc convert
.
In practice, the --index
flag is almost always passed, since both Swift-DocC's integration with Xcode and its integration with SwiftPM via the Swift-DocC Plugin include the --index
flag.
The current LMDB representation of the navigator index was designed for Swift-DocC's integration into documentation browsing applications and IDEs. It was also designed to support extremely large DocC archives. However, it is not well suited for consumption on the web and the average sized DocC archive we see in practice doesn't benefit much from the potential performance improvments of an LMDB representation.
The JSON representation will fill in this gap to immediately allow Swift-DocC-Render to display a navigation sidebar and, moving forward, allow for easier adoption of any clients that don't wish to use LMDB.
The change discussed here would mean that while docc convert
continues to only emit the LMDB index if the --index
flag (now --emit-lmdb-index
) is passed, it will now always emit the JSON representation of the index so that clients can rely on it being there.
Links & Technical Details
- The PR for feature enablement is here: Emit RenderIndex JSON by default by ethan-kusters · Pull Request #100 · apple/swift-docc · GitHub
- The OpenAPI spec for the RenderIndex schema is here: swift-docc/RenderIndex.spec.json at bae42d2a84089ee0a780443058d3558d194592d4 · apple/swift-docc · GitHub
- An example of a pretty-printed RenderIndex JSON file for ArgumentParser is here: swift-argument-parser/index.json at gh-pages · ethan-kusters/swift-argument-parser · GitHub
- (The RenderIndex JSON will not be pretty-printed by default.)
In designing the RenderIndex schema, I prioritized readability as, in practice, we found that the prevalence and effectiveness of gzip compression on the web means that we don't need to make the JSON as compact as possible at the cost of readability. This also fits in well with our existing RenderNode schema.
Note that the PR for feature enablement also bumps the minor version of the RenderNode schema to 0.3.0
from 0.2.0
. This will allow clients, including Swift-DocC-Render, to detect if a DocC archive is likely to include RenderIndex JSON to ease in the migration period where we have many existing DocC archives that do not contain the index. Without this, clients like Swift-DocC-Render would have to offer a sub-optimal UX when rendering older DocC archives where the page might flicker while making a request to see if the RenderIndex JSON exists.
Future Directions
Moving forward, I'd like to make the JSON representation of the navigator index fully interchangeable with the LMDB one. With this initial release, the JSON version doesn't hold all of the availability information of the LDMB version so we need to keep both.
But in the future, I think we can teach the SwiftDocC framework to read either a JSON representation of the navigator index or an LMDB one and make this totally transparent to clients of SwiftDocC. This will allow us to migrate the majority of DocC archives over to only having a JSON representation of the navigator index and leave the LMDB representation as opt-in for those with unusually large DocC archives where the speed benefits of the database representation are really worth it.