@lincyaw/workspace 1.0.0-rc.11 → 1.0.0-rc.12

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.
Files changed (2) hide show
  1. package/package.json +5 -5
  2. package/src/node/build.ts +26 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lincyaw/workspace",
3
- "version": "1.0.0-rc.11",
3
+ "version": "1.0.0-rc.12",
4
4
  "description": "Presmium's workspace service (presmium serve): documents, their history, reviews and the workspace site",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -33,12 +33,12 @@
33
33
  "image-size": "2.0.4",
34
34
  "mime-types": "3.0.2",
35
35
  "yaml": "^2.9.1",
36
- "@lincyaw/kernel": "1.0.0-rc.11",
37
- "@lincyaw/compiler": "1.0.0-rc.11",
38
- "@lincyaw/server": "1.0.0-rc.11"
36
+ "@lincyaw/kernel": "1.0.0-rc.12",
37
+ "@lincyaw/compiler": "1.0.0-rc.12",
38
+ "@lincyaw/server": "1.0.0-rc.12"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@types/mime-types": "^3.0.1",
42
- "@lincyaw/mcp": "1.0.0-rc.11"
42
+ "@lincyaw/mcp": "1.0.0-rc.12"
43
43
  }
44
44
  }
package/src/node/build.ts CHANGED
@@ -3,7 +3,7 @@ import { isAbsolute, join, resolve } from 'node:path'
3
3
  import { build, Compiler } from '@lincyaw/compiler'
4
4
  import type { Compilation, RunStats } from '@lincyaw/compiler'
5
5
  import { errorMessage, isRecord } from '@lincyaw/kernel'
6
- import type { Finding } from '@lincyaw/kernel'
6
+ import type { Finding, IRDocument, SiteSpec } from '@lincyaw/kernel'
7
7
  import { listDocuments, readWorkspaceConfig } from './config.ts'
8
8
  import { siteContext, siteDocument, siteIR, siteSpec, siteTranslations, webRenderer } from './site.ts'
9
9
 
@@ -21,8 +21,10 @@ export async function buildWorkspace(root: string, options: { outDir?: string, b
21
21
  const site = siteSpec(config, [])
22
22
  const base = siteBase(config.site.base)
23
23
  const forms: { dir: string, compilation: Compilation, to: string[] }[] = []
24
+ const compilations: Compilation[] = []
24
25
  for (const document of found) {
25
26
  const compilation = await new Compiler(join(config.root, document.entry), { bundled: options.bundled, settings: config.settings }).compile({ pruneCache: true })
27
+ compilations.push(compilation)
26
28
  const to = presentations(compilation, `${base}${urlPath(document.dir)}/`, siteLook(config.site, config.root))
27
29
  if (to.length > 0) forms.push({ dir: document.dir, compilation, to })
28
30
  const translated = await siteTranslations(compilation)
@@ -33,6 +35,7 @@ export async function buildWorkspace(root: string, options: { outDir?: string, b
33
35
  const outDir = join(resolve(options.outDir ?? join(config.root, 'dist')), 'web')
34
36
  const renderer = await webRenderer(config.root, options.bundled)
35
37
  const ctx = siteContext({ root: config.root, outDir, workDir: join(config.root, '.presmium', 'site'), base, findings })
38
+ ctx.pluginDirs = pluginsByName(site, compilations)
36
39
  try {
37
40
  await renderer.buildSite!(site, ctx)
38
41
  } catch (error) {
@@ -55,6 +58,28 @@ export async function buildWorkspace(root: string, options: { outDir?: string, b
55
58
  return { outDir, documents, findings }
56
59
  }
57
60
 
61
+ /**
62
+ * The site's documents name their plugins by package, as a presentation built alone does, so the pages and the
63
+ * presentations share one viewer app (its key follows the plugin names); the site resolves each name to the directory
64
+ * it was loaded from. A name that two documents load from different directories stays a directory, to tell them apart.
65
+ */
66
+ function pluginsByName(site: SiteSpec, compilations: readonly Compilation[]): Record<string, string> {
67
+ const dirs = new Map<string, Set<string>>(), names = new Map<string, string>()
68
+ for (const { plugins } of compilations) for (const { name, dir } of plugins) {
69
+ let own = dirs.get(name)
70
+ if (!own) dirs.set(name, own = new Set())
71
+ own.add(dir)
72
+ names.set(dir, name)
73
+ }
74
+ const unique = new Map([...dirs].filter(([, own]) => own.size === 1).map(([name, own]) => [name, [...own][0]!]))
75
+ const byName = (doc: IRDocument): IRDocument => ({ ...doc, config: { ...doc.config, plugins: doc.config.plugins.map(dir => names.has(dir) && unique.has(names.get(dir)!) ? names.get(dir)! : dir) } })
76
+ for (const entry of site.documents) {
77
+ if (entry.doc) entry.doc = byName(entry.doc)
78
+ for (const translation of entry.translations ?? []) translation.doc = byName(translation.doc)
79
+ }
80
+ return Object.fromEntries(unique)
81
+ }
82
+
58
83
  const PRESENTATIONS = ['slides', 'lecture']
59
84
 
60
85
  /** The site's theme and its parameters, for its presentations to look like its pages; a theme directory made absolute. */