@brillout/docpress 0.15.2 → 0.15.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/+config.ts CHANGED
@@ -4,7 +4,7 @@ import type { Config } from 'vike/types'
4
4
  import { viteConfig } from './vite.config.js'
5
5
  import type { Config as DocpressConfig } from './types/Config'
6
6
  import type { PageSection } from './parsePageSections'
7
- import type { Conf } from './resolveConf.js'
7
+ import type { Resolved } from './resolvePageContext.js'
8
8
 
9
9
  const config = {
10
10
  name: '@brillout/docpress',
@@ -33,7 +33,7 @@ declare global {
33
33
  namespace Vike {
34
34
  interface PageContext {
35
35
  Page: ReactComponent
36
- conf: Conf
36
+ resolved: Resolved
37
37
  }
38
38
  interface Config {
39
39
  docpress?: DocpressConfig
package/Layout.tsx CHANGED
@@ -46,7 +46,7 @@ const whitespaceBuster2: React.CSSProperties = {
46
46
 
47
47
  function Layout({ children }: { children: React.ReactNode }) {
48
48
  const pageContext = usePageContext()
49
- const { isLandingPage } = pageContext.conf
49
+ const { isLandingPage } = pageContext.resolved
50
50
 
51
51
  let content: React.JSX.Element
52
52
  if (isLandingPage) {
@@ -85,8 +85,8 @@ function Layout({ children }: { children: React.ReactNode }) {
85
85
  function LayoutDocsPage({ children }: { children: React.ReactNode }) {
86
86
  const pageContext = usePageContext()
87
87
  const hideNavLeftAlways =
88
- pageContext.conf.pageDesign?.hideMenuLeft ||
89
- (pageContext.conf.navItemsDetached && pageContext.conf.navItemsDetached.length <= 1)
88
+ pageContext.resolved.pageDesign?.hideMenuLeft ||
89
+ (pageContext.resolved.navItemsDetached && pageContext.resolved.navItemsDetached.length <= 1)
90
90
  return (
91
91
  <>
92
92
  <Style>{getStyle()}</Style>
@@ -155,13 +155,13 @@ function LayoutLandingPage({ children }: { children: React.ReactNode }) {
155
155
 
156
156
  function PageContent({ children }: { children: React.ReactNode }) {
157
157
  const pageContext = usePageContext()
158
- const { isLandingPage, pageTitle } = pageContext.conf
158
+ const { isLandingPage, pageTitle } = pageContext.resolved
159
159
  const pageTitleParsed = pageTitle && parseMarkdownMini(pageTitle)
160
160
  /*
161
161
  const { globalNote } = pageContext.globalContext.config.docpress
162
162
  */
163
163
  const ifDocPage = (style: React.CSSProperties) => (isLandingPage ? {} : style)
164
- const contentMaxWidth = pageContext.conf.pageDesign?.contentMaxWidth ?? mainViewWidthMax
164
+ const contentMaxWidth = pageContext.resolved.pageDesign?.contentMaxWidth ?? mainViewWidthMax
165
165
  return (
166
166
  <div
167
167
  className="page-wrapper low-prio-grow"
@@ -187,7 +187,7 @@ function PageContent({ children }: { children: React.ReactNode }) {
187
187
  }}
188
188
  >
189
189
  {/* globalNote */}
190
- {pageTitleParsed && !pageContext.conf.pageDesign?.hideTitle && (
190
+ {pageTitleParsed && !pageContext.resolved.pageDesign?.hideTitle && (
191
191
  <div>
192
192
  <EditLink className="show-only-on-desktop" style={{ float: 'right', marginTop: 6, padding: 10 }} />
193
193
  <h1 id={`${pageContext.urlPathname.replace('/', '')}`}>{pageTitleParsed}</h1>
@@ -201,7 +201,7 @@ function PageContent({ children }: { children: React.ReactNode }) {
201
201
 
202
202
  function NavLeft() {
203
203
  const pageContext = usePageContext()
204
- const { navItemsAll, navItemsDetached } = pageContext.conf
204
+ const { navItemsAll, navItemsDetached } = pageContext.resolved
205
205
  return (
206
206
  <>
207
207
  <div
@@ -280,7 +280,7 @@ const menuLinkStyle: React.CSSProperties = {
280
280
 
281
281
  function NavHead({ isNavLeft }: { isNavLeft?: true }) {
282
282
  const pageContext = usePageContext()
283
- const { isLandingPage } = pageContext.conf
283
+ const { isLandingPage } = pageContext.resolved
284
284
  const { navMaxWidth, name, algolia } = pageContext.globalContext.config.docpress
285
285
 
286
286
  const navSecondaryContent = (
package/MenuModal.tsx CHANGED
@@ -73,7 +73,7 @@ function BorderBottom() {
73
73
  }
74
74
  function Nav() {
75
75
  const pageContext = usePageContext()
76
- const navItems = pageContext.conf.navItemsAll
76
+ const navItems = pageContext.resolved.navItemsAll
77
77
  return <NavigationWithColumnLayout navItems={navItems} />
78
78
  }
79
79
 
@@ -141,7 +141,7 @@ function findLinkData(
141
141
  { pageContext, noWarning }: { pageContext: PageContext; noWarning?: boolean },
142
142
  ): LinkData | null {
143
143
  assert(href.startsWith('/') || href.startsWith('#'))
144
- const { linksAll } = pageContext.conf
144
+ const { linksAll } = pageContext.resolved
145
145
  const linkData = linksAll.find(({ url }) => href === url)
146
146
  if (href.startsWith('#')) {
147
147
  if (!noWarning) {
package/dist/+config.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { config as default };
2
2
  import type { Config as DocpressConfig } from './types/Config';
3
3
  import type { PageSection } from './parsePageSections';
4
- import type { Conf } from './resolveConf.js';
4
+ import type { Resolved } from './resolvePageContext.js';
5
5
  declare const config: {
6
6
  name: string;
7
7
  require: {
@@ -35,7 +35,7 @@ declare global {
35
35
  namespace Vike {
36
36
  interface PageContext {
37
37
  Page: ReactComponent;
38
- conf: Conf;
38
+ resolved: Resolved;
39
39
  }
40
40
  interface Config {
41
41
  docpress?: DocpressConfig;
@@ -91,7 +91,7 @@ function getLinkTextData(_a) {
91
91
  function findLinkData(href, _a) {
92
92
  var pageContext = _a.pageContext, noWarning = _a.noWarning;
93
93
  assert(href.startsWith('/') || href.startsWith('#'));
94
- var linksAll = pageContext.conf.linksAll;
94
+ var linksAll = pageContext.resolved.linksAll;
95
95
  var linkData = linksAll.find(function (_a) {
96
96
  var url = _a.url;
97
97
  return href === url;
@@ -9,7 +9,7 @@ var globalObject = getGlobalObject('usePageContext.ts', {
9
9
  function usePageContextLegacy() {
10
10
  var Ctx = globalObject.Ctx;
11
11
  var pageContext = useContext(Ctx);
12
- return pageContext.conf;
12
+ return pageContext.resolved;
13
13
  }
14
14
  function usePageContext() {
15
15
  var pageContext = useContext(globalObject.Ctx);
@@ -1,9 +1,9 @@
1
- export { resolveConf };
2
- export type Conf = ReturnType<typeof resolveConf>;
1
+ export { resolvePageContext };
2
+ export type Resolved = ReturnType<typeof resolvePageContext>;
3
3
  import type { NavItem } from './NavItemComponent';
4
4
  import type { LinkData } from './components';
5
5
  import type { PageContextServer } from 'vike/types';
6
- declare function resolveConf(pageContext: PageContextServer): {
6
+ declare function resolvePageContext(pageContext: PageContextServer): {
7
7
  navItemsAll: NavItem[];
8
8
  navItemsDetached: NavItem[] | undefined;
9
9
  pageDesign: {
@@ -18,13 +18,13 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
18
18
  }
19
19
  return to.concat(ar || Array.prototype.slice.call(from));
20
20
  };
21
- export { resolveConf };
21
+ export { resolvePageContext };
22
22
  import { assert } from './utils/assert';
23
23
  import { jsxToTextContent } from './utils/jsxToTextContent';
24
24
  import pc from '@brillout/picocolors';
25
25
  import { parseMarkdownMini } from './parseMarkdownMini';
26
26
  import { determineNavItemsColumnLayout } from './determineNavItemsColumnLayout';
27
- function resolveConf(pageContext) {
27
+ function resolvePageContext(pageContext) {
28
28
  var _a;
29
29
  var config = pageContext.globalContext.config.docpress;
30
30
  var urlPathname = pageContext.urlPathname;
@@ -33,9 +33,9 @@ function resolveConf(pageContext) {
33
33
  var headings = config.headings, headingsDetached = config.headingsDetached;
34
34
  assertHeadingsDefinition(__spreadArray(__spreadArray([], headings, true), headingsDetached, true));
35
35
  }
36
- var resolved = getHeadingsResolved(config);
37
- var headingsDetachedResolved = resolved.headingsDetachedResolved;
38
- var headingsResolved = resolved.headingsResolved;
36
+ var ret = getHeadingsResolved(config);
37
+ var headingsDetachedResolved = ret.headingsDetachedResolved;
38
+ var headingsResolved = ret.headingsResolved;
39
39
  var _b = getActiveHeading(headingsResolved, headingsDetachedResolved, urlPathname), activeHeading = _b.activeHeading, isDetachedPage = _b.isDetachedPage, activeCategoryName = _b.activeCategoryName;
40
40
  var _c = getTitles(activeHeading, urlPathname, config), documentTitle = _c.documentTitle, isLandingPage = _c.isLandingPage, pageTitle = _c.pageTitle;
41
41
  var pageSectionsResolved = getPageSectionsResolved(pageSections, activeHeading);
@@ -61,7 +61,7 @@ function resolveConf(pageContext) {
61
61
  });
62
62
  }
63
63
  }
64
- var conf = {
64
+ var resolved = {
65
65
  navItemsAll: navItemsAll,
66
66
  navItemsDetached: navItemsDetached,
67
67
  pageDesign: activeHeading.pageDesign,
@@ -71,7 +71,7 @@ function resolveConf(pageContext) {
71
71
  documentTitle: documentTitle,
72
72
  activeCategoryName: activeCategoryName,
73
73
  };
74
- return conf;
74
+ return resolved;
75
75
  }
76
76
  function headingToNavItem(heading) {
77
77
  return {
@@ -21,6 +21,7 @@ type Config = {
21
21
  apiKey: string;
22
22
  indexName: string;
23
23
  };
24
+ googleAnalytics?: string;
24
25
  i18n?: true;
25
26
  pressKit?: true;
26
27
  docsDir?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brillout/docpress",
3
- "version": "0.15.2",
3
+ "version": "0.15.3",
4
4
  "type": "module",
5
5
  "dependencies": {
6
6
  "@brillout/picocolors": "^1.0.10",
@@ -1,8 +1,8 @@
1
1
  export { onCreatePageContext }
2
2
 
3
3
  import type { PageContextServer } from 'vike/types'
4
- import { resolveConf } from '../resolveConf'
4
+ import { resolvePageContext } from '../resolvePageContext'
5
5
 
6
6
  function onCreatePageContext(pageContext: PageContextServer) {
7
- pageContext.conf = resolveConf(pageContext)
7
+ pageContext.resolved = resolvePageContext(pageContext)
8
8
  }
@@ -12,9 +12,11 @@ import { getGlobalObject } from '../utils/client'
12
12
  import { initKeyBindings } from '../initKeyBindings'
13
13
  import { initOnNavigation } from './initOnNavigation'
14
14
  import { setHydrationIsFinished } from './getHydrationPromise'
15
+ import { addScript } from '../utils/addScript'
15
16
 
16
17
  const globalObject = getGlobalObject<{
17
18
  root?: ReactDOM.Root
19
+ isNotFirstRender?: true
18
20
  }>('onRenderClient.ts', {})
19
21
 
20
22
  addEcosystemStamp()
@@ -30,6 +32,7 @@ async function onRenderClient(pageContext: PageContextClient) {
30
32
  })
31
33
  let page = getPageElement(pageContext)
32
34
  page = <OnRenderDoneHook renderPromiseResolve={renderPromiseResolve}>{page}</OnRenderDoneHook>
35
+
33
36
  const container = document.getElementById('page-view')!
34
37
  if (pageContext.isHydration) {
35
38
  globalObject.root = ReactDOM.hydrateRoot(container, page)
@@ -42,11 +45,19 @@ async function onRenderClient(pageContext: PageContextClient) {
42
45
  if (!pageContext.isHydration) {
43
46
  applyHead(pageContext)
44
47
  }
48
+
45
49
  await renderPromise
50
+
51
+ autoScrollNav()
52
+ installSectionUrlHashs()
53
+ setHydrationIsFinished()
54
+ initGoogleAnalytics(pageContext)
55
+
56
+ globalObject.isNotFirstRender = true
46
57
  }
47
58
 
48
59
  function applyHead(pageContext: PageContextClient) {
49
- document.title = pageContext.conf.documentTitle
60
+ document.title = pageContext.resolved.documentTitle
50
61
  }
51
62
 
52
63
  function onRenderStart() {
@@ -54,18 +65,13 @@ function onRenderStart() {
54
65
  closeMenuModal()
55
66
  }
56
67
 
57
- function onRenderDone(renderPromiseResolve: () => void) {
58
- autoScrollNav()
59
- installSectionUrlHashs()
60
- setHydrationIsFinished()
61
- renderPromiseResolve()
62
- }
63
-
64
68
  function OnRenderDoneHook({
65
69
  renderPromiseResolve,
66
70
  children,
67
71
  }: { renderPromiseResolve: () => void; children: React.ReactNode }) {
68
- useEffect(() => onRenderDone(renderPromiseResolve))
72
+ useEffect(() => {
73
+ renderPromiseResolve()
74
+ })
69
75
  return children
70
76
  }
71
77
 
@@ -74,3 +80,27 @@ function OnRenderDoneHook({
74
80
  function addEcosystemStamp() {
75
81
  ;(window as any)._isBrilloutDocpress = true
76
82
  }
83
+
84
+ async function initGoogleAnalytics(pageContext: PageContextClient) {
85
+ const isFirstRender = !globalObject.isNotFirstRender
86
+ const id = pageContext.config.docpress.googleAnalytics
87
+
88
+ if (!id) return
89
+ if (isFirstRender) await installGoogleAnalytics(id)
90
+ }
91
+ async function installGoogleAnalytics(id: string) {
92
+ window.dataLayer = window.dataLayer || []
93
+ window.gtag = function gtag() {
94
+ window.dataLayer.push(arguments)
95
+ }
96
+ window.gtag('js', new Date())
97
+ window.gtag('config', id)
98
+
99
+ await addScript(`https://www.googletagmanager.com/gtag/js?id=${id}`)
100
+ }
101
+ declare global {
102
+ interface Window {
103
+ dataLayer: any[]
104
+ gtag: (...args: any[]) => void
105
+ }
106
+ }
@@ -10,7 +10,7 @@ import type { Config } from '../types/Config'
10
10
  async function onRenderHtml(pageContext: PageContextServer): Promise<any> {
11
11
  const page = getPageElement(pageContext)
12
12
 
13
- const { isLandingPage } = pageContext.conf
13
+ const { isLandingPage } = pageContext.resolved
14
14
  assert(typeof isLandingPage === 'boolean')
15
15
  const { tagline } = pageContext.globalContext.config.docpress
16
16
  assert(tagline)
@@ -21,7 +21,7 @@ async function onRenderHtml(pageContext: PageContextServer): Promise<any> {
21
21
  const faviconUrl = pageContext.globalContext.config.docpress.favicon ?? pageContext.globalContext.config.docpress.logo
22
22
  assert(faviconUrl)
23
23
 
24
- const { documentTitle } = pageContext.conf
24
+ const { documentTitle } = pageContext.resolved
25
25
  assert(documentTitle)
26
26
  return escapeInject`<!DOCTYPE html>
27
27
  <html>
@@ -56,7 +56,7 @@ type ActiveCategory = {
56
56
  }
57
57
  function getActiveCategory(pageContext: PageContextServer) {
58
58
  const config = pageContext.globalContext.config.docpress
59
- const { activeCategoryName } = pageContext.conf
59
+ const { activeCategoryName } = pageContext.resolved
60
60
 
61
61
  const activeCategory: ActiveCategory = config.categories
62
62
  // normalize
@@ -13,7 +13,7 @@ const globalObject = getGlobalObject('usePageContext.ts', {
13
13
  function usePageContextLegacy() {
14
14
  const { Ctx } = globalObject
15
15
  const pageContext = useContext(Ctx)
16
- return pageContext.conf
16
+ return pageContext.resolved
17
17
  }
18
18
 
19
19
  function usePageContext(): PageContext {
@@ -1,5 +1,5 @@
1
- export { resolveConf }
2
- export type Conf = ReturnType<typeof resolveConf>
1
+ export { resolvePageContext }
2
+ export type Resolved = ReturnType<typeof resolvePageContext>
3
3
 
4
4
  import type { Config } from './types/Config'
5
5
  import type { NavItem } from './NavItemComponent'
@@ -26,7 +26,7 @@ type PageSectionResolved = {
26
26
  pageSectionLevel: number
27
27
  }
28
28
 
29
- function resolveConf(pageContext: PageContextServer) {
29
+ function resolvePageContext(pageContext: PageContextServer) {
30
30
  const config = pageContext.globalContext.config.docpress
31
31
  const { urlPathname } = pageContext
32
32
  const pageSections = pageContext.config.pageSectionsExport ?? []
@@ -36,9 +36,9 @@ function resolveConf(pageContext: PageContextServer) {
36
36
  assertHeadingsDefinition([...headings, ...headingsDetached])
37
37
  }
38
38
 
39
- const resolved = getHeadingsResolved(config)
40
- const { headingsDetachedResolved } = resolved
41
- let { headingsResolved } = resolved
39
+ const ret = getHeadingsResolved(config)
40
+ const { headingsDetachedResolved } = ret
41
+ let { headingsResolved } = ret
42
42
 
43
43
  const { activeHeading, isDetachedPage, activeCategoryName } = getActiveHeading(
44
44
  headingsResolved,
@@ -76,7 +76,7 @@ function resolveConf(pageContext: PageContextServer) {
76
76
  }
77
77
  }
78
78
 
79
- const conf = {
79
+ const resolved = {
80
80
  navItemsAll,
81
81
  navItemsDetached,
82
82
  pageDesign: activeHeading.pageDesign,
@@ -86,7 +86,7 @@ function resolveConf(pageContext: PageContextServer) {
86
86
  documentTitle,
87
87
  activeCategoryName,
88
88
  }
89
- return conf
89
+ return resolved
90
90
  }
91
91
 
92
92
  function headingToNavItem(heading: HeadingResolved | HeadingDetachedResolved): NavItem {
package/types/Config.ts CHANGED
@@ -26,6 +26,7 @@ type Config = {
26
26
  apiKey: string
27
27
  indexName: string
28
28
  }
29
+ googleAnalytics?: string
29
30
 
30
31
  i18n?: true
31
32
  pressKit?: true
@@ -0,0 +1,12 @@
1
+ export { addScript }
2
+
3
+ import { genPromise } from './genPromise'
4
+
5
+ async function addScript(src: string) {
6
+ const { promise, resolve, reject } = genPromise()
7
+ const script = document.createElement('script')
8
+ script.onload = () => resolve()
9
+ script.onerror = () => reject(new Error(`Failed to load script: ${src}`))
10
+ script.src = src
11
+ return promise
12
+ }
@@ -1,5 +1,13 @@
1
- export function genPromise<T = void>(): { promise: Promise<T>; resolve: (val: T) => void } {
1
+ export function genPromise<T = void>(): {
2
+ promise: Promise<T>
3
+ resolve: (val: T) => void
4
+ reject: (err: unknown) => void
5
+ } {
2
6
  let resolve!: (val: T) => void
3
- const promise = new Promise<T>((r) => (resolve = r))
4
- return { promise, resolve }
7
+ let reject!: (err: unknown) => void
8
+ const promise = new Promise<T>((resolve_, reject_) => {
9
+ resolve = resolve_
10
+ reject = reject_
11
+ })
12
+ return { promise, resolve, reject }
5
13
  }