From c1e94b28a370bdfe40e8e767b82535e248318aa7 Mon Sep 17 00:00:00 2001 From: Loris Cro Date: Sun, 17 Sep 2023 18:21:31 +0200 Subject: [PATCH] autodoc: split json payload per field this will make s3 re-enable compression for the stdlib's autodoc and improve loading times (and data usage) for users alongside this commit the deploy script for the official website is also being updated --- lib/docs/index.html | 12 ++++++- lib/docs/main.js | 46 ++++++++++++++++----------- src/Autodoc.zig | 76 ++++++++++++++++++++------------------------- 3 files changed, 73 insertions(+), 61 deletions(-) diff --git a/lib/docs/index.html b/lib/docs/index.html index bed0210c8f..877c1456c4 100644 --- a/lib/docs/index.html +++ b/lib/docs/index.html @@ -1226,7 +1226,17 @@ - + + + + + + + + + + + diff --git a/lib/docs/main.js b/lib/docs/main.js index a3cad3f17b..87f3f381a1 100644 --- a/lib/docs/main.js +++ b/lib/docs/main.js @@ -1,6 +1,19 @@ "use strict"; -var zigAnalysis; +var zigAnalysis = { + typeKinds, + rootMod, + modules, + astNodes, + calls, + files, + decls, + exprs, + types, + comptimeExprs, + guideSections +}; + let skipNextHashChange = null; const NAV_MODES = { @@ -200,11 +213,8 @@ var scrollHistory = {}; window.addEventListener("keydown", onWindowKeyDown, false); onHashChange(); - let langRefVersion = zigAnalysis.params.zigVersion; - if (!/^\d+\.\d+\.\d+$/.test(langRefVersion)) { - // the version is probably not released yet - langRefVersion = "master"; - } + // TODO: fix this once langref becomes part of autodoc + let langRefVersion = "master"; domLangRefLink.href = `https://ziglang.org/documentation/${langRefVersion}/`; function renderTitle() { @@ -528,8 +538,8 @@ var scrollHistory = {}; } let activeGuide = undefined; - outer: for (let i = 0; i < zigAnalysis.guide_sections.length; i += 1) { - const section = zigAnalysis.guide_sections[i]; + outer: for (let i = 0; i < zigAnalysis.guideSections.length; i += 1) { + const section = zigAnalysis.guideSections[i]; for (let j = 0; j < section.guides.length; j += 1) { const guide = section.guides[j]; if (guide.name == curNav.activeGuide) { @@ -595,7 +605,7 @@ var scrollHistory = {}; domGuideTocList.classList.add("hidden"); domGuideTocListEmtpy.classList.remove("hidden"); - if (zigAnalysis.guide_sections.length > 1 || (zigAnalysis.guide_sections[0].guides.length > 0)) { + if (zigAnalysis.guideSections.length > 1 || (zigAnalysis.guideSections[0].guides.length > 0)) { renderGuidesIndex(); } else { noGuidesAtAll(); @@ -609,8 +619,8 @@ var scrollHistory = {}; // TODO: ensure unique hashes // TODO: hash also guides and their headings function computeGuideHashes() { - for (let i = 1; i < zigAnalysis.guide_sections.length; i += 1) { - const section = zigAnalysis.guide_sections[i]; + for (let i = 1; i < zigAnalysis.guideSections.length; i += 1) { + const section = zigAnalysis.guideSections[i]; section.hash = "section-" + slugify(section.name || i); } } @@ -619,8 +629,8 @@ var scrollHistory = {}; // main content { let html = ""; - for (let i = 0; i < zigAnalysis.guide_sections.length; i += 1) { - const section = zigAnalysis.guide_sections[i]; + for (let i = 0; i < zigAnalysis.guideSections.length; i += 1) { + const section = zigAnalysis.guideSections[i]; if (i != 0) { // first section is the default section html += "

" + section.name + "

"; } @@ -635,10 +645,10 @@ var scrollHistory = {}; // sidebar / fast navigation { domGuidesMenuTitle.textContent = "Sections"; - if (zigAnalysis.guide_sections.length > 1) { + if (zigAnalysis.guideSections.length > 1) { let html = ""; - for (let i = 1; i < zigAnalysis.guide_sections.length; i += 1) { - const section = zigAnalysis.guide_sections[i]; + for (let i = 1; i < zigAnalysis.guideSections.length; i += 1) { + const section = zigAnalysis.guideSections[i]; html += "
  • " + section.name + "
  • "; } domGuideTocList.innerHTML = ""; @@ -3978,8 +3988,8 @@ Happy writing! } function parseGuides() { - for (let j = 0; j < zigAnalysis.guide_sections.length; j += 1) { - const section = zigAnalysis.guide_sections[j]; + for (let j = 0; j < zigAnalysis.guideSections.length; j += 1) { + const section = zigAnalysis.guideSections[j]; for (let i = 0; i < section.guides.length; i += 1) { let reader = new commonmark.Parser({ smart: true }); const guide = section.guides[i]; diff --git a/src/Autodoc.zig b/src/Autodoc.zig index c4506dc857..abc80e2138 100644 --- a/src/Autodoc.zig +++ b/src/Autodoc.zig @@ -344,7 +344,6 @@ fn generateZirData(self: *Autodoc, output_dir: std.fs.Dir) !void { } var data = DocData{ - .params = .{}, .modules = self.modules, .files = self.files, .calls = self.calls.items, @@ -353,28 +352,41 @@ fn generateZirData(self: *Autodoc, output_dir: std.fs.Dir) !void { .exprs = self.exprs.items, .astNodes = self.ast_nodes.items, .comptimeExprs = self.comptime_exprs.items, - .guide_sections = self.guide_sections, + .guideSections = self.guide_sections, }; - { - const data_js_f = try output_dir.createFile("data.js", .{}); + inline for (comptime std.meta.tags(std.meta.FieldEnum(DocData))) |f| { + const field_name = @tagName(f); + const file_name = "data-" ++ field_name ++ ".js"; + const data_js_f = try output_dir.createFile(file_name, .{}); defer data_js_f.close(); - var buffer = std.io.bufferedWriter(data_js_f.writer()); + var buffer = std.io.bufferedWriter(data_js_f.writer()); const out = buffer.writer(); - try out.print( - \\ /** @type {{DocData}} */ - \\ var zigAnalysis= - , .{}); - try std.json.stringifyArbitraryDepth( - self.arena, - data, - .{ - .whitespace = .minified, - .emit_null_optional_fields = true, - }, - out, - ); + + try out.print("var {s} =", .{field_name}); + + var jsw = std.json.writeStream(out, .{ + .whitespace = .minified, + .emit_null_optional_fields = true, + }); + + switch (f) { + .files => try writeFileTableToJson(data.files, data.modules, &jsw), + .guideSections => try writeGuidesToJson(data.guideSections, &jsw), + .modules => try jsw.write(data.modules.values()), + else => try jsw.write(@field(data, field_name)), + } + + // try std.json.stringifyArbitraryDepth( + // self.arena, + // @field(data, field.name), + // .{ + // .whitespace = .minified, + // .emit_null_optional_fields = true, + // }, + // out, + // ); try out.print(";", .{}); // last thing (that can fail) that we do is flush @@ -476,18 +488,12 @@ const Scope = struct { /// The output of our analysis process. const DocData = struct { + // NOTE: editing fields of DocData requires also updating: + // - the deployment script for ziglang.org + // - imports in index.html typeKinds: []const []const u8 = std.meta.fieldNames(DocTypeKinds), rootMod: u32 = 0, - params: struct { - zigId: []const u8 = "arst", - zigVersion: []const u8 = build_options.version, - target: []const u8 = "arst", - builds: []const struct { target: []const u8 } = &.{ - .{ .target = "arst" }, - }, - }, modules: std.AutoArrayHashMapUnmanaged(*Module, DocModule), - errors: []struct {} = &.{}, // non-hardcoded stuff astNodes: []AstNode, @@ -498,7 +504,7 @@ const DocData = struct { exprs: []Expr, comptimeExprs: []ComptimeExpr, - guide_sections: std.ArrayListUnmanaged(Section), + guideSections: std.ArrayListUnmanaged(Section), const Call = struct { func: Expr, @@ -506,20 +512,6 @@ const DocData = struct { ret: Expr, }; - pub fn jsonStringify(self: DocData, jsw: anytype) !void { - try jsw.beginObject(); - inline for (comptime std.meta.tags(std.meta.FieldEnum(DocData))) |f| { - const f_name = @tagName(f); - try jsw.objectField(f_name); - switch (f) { - .files => try writeFileTableToJson(self.files, self.modules, jsw), - .guide_sections => try writeGuidesToJson(self.guide_sections, jsw), - .modules => try jsw.write(self.modules.values()), - else => try jsw.write(@field(self, f_name)), - } - } - try jsw.endObject(); - } /// All the type "families" as described by `std.builtin.TypeId` /// plus a couple extra that are unique to our use case. ///