@glossarist/concept-browser 0.7.5 → 0.7.7
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/README.md +211 -258
- package/cli/index.mjs +1 -3
- package/package.json +1 -1
- package/scripts/fetch-datasets.mjs +2 -2
- package/src/config/types.ts +2 -0
package/README.md
CHANGED
|
@@ -1,28 +1,45 @@
|
|
|
1
|
-
# Glossarist
|
|
1
|
+
# Glossarist Concept Browser
|
|
2
2
|
|
|
3
|
-
A statically deployable single-page application for browsing
|
|
3
|
+
A statically deployable single-page application for browsing terminology datasets. Built with Vue 3, TypeScript, and Tailwind CSS. Add new datasets with zero code changes — just configure `site-config.yml`.
|
|
4
4
|
|
|
5
|
-
**Live
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
**Live sites:**
|
|
6
|
+
- [GeoLexica](https://www.geolexica.org) — IEC Electropedia + ISO/TC 211 + more
|
|
7
|
+
- [VIML](https://metanorma.github.io/oiml-viml/) — OIML International Vocabulary of Legal Metrology
|
|
8
|
+
- [OIML Terms](https://metanorma.github.io/oiml-terms/) — OIML G 18 terminology
|
|
8
9
|
|
|
9
10
|
---
|
|
10
11
|
|
|
11
12
|
## Features
|
|
12
13
|
|
|
13
14
|
- **Multi-dataset browsing** — Concepts from multiple terminology registers in one place
|
|
14
|
-
- **Full multilingual support** — Definitions, notes, and examples in all available languages
|
|
15
|
+
- **Full multilingual support** — Definitions, notes, and examples in all available languages with i18n UI
|
|
15
16
|
- **Concept history timeline** — Review dates, decisions, and change notes per language
|
|
16
17
|
- **Cross-reference graph** — D3 force-directed graph showing concept relationships with dataset filtering
|
|
18
|
+
- **Rich sidebar provenance** — Publication reference, owner, status, concept/language counts from manifest data
|
|
17
19
|
- **Math rendering** — KaTeX rendering for AsciiMath notation in definitions (`stem:[...]`)
|
|
18
|
-
- **Responsive design** — Mobile-first layout with
|
|
20
|
+
- **Responsive design** — Mobile-first layout with light/dark mode
|
|
19
21
|
- **Static deployment** — No server required. Deploy to any static host
|
|
20
22
|
|
|
21
23
|
---
|
|
22
24
|
|
|
23
|
-
## Quick Start
|
|
25
|
+
## Quick Start (deployment repo)
|
|
26
|
+
|
|
27
|
+
A deployment repo is a separate repository that provides a `site-config.yml`, dataset source files, and content pages. The concept-browser is installed as an npm package.
|
|
24
28
|
|
|
25
29
|
```bash
|
|
30
|
+
# In your deployment repo:
|
|
31
|
+
npm install --ignore-scripts @glossarist/concept-browser
|
|
32
|
+
npm install --prefix node_modules/@glossarist/concept-browser sharp 2>/dev/null || true
|
|
33
|
+
npx concept-browser build
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The CLI reads `site-config.yml` from the working directory, fetches/generates data, and builds the SPA into `dist/`.
|
|
37
|
+
|
|
38
|
+
### Quick Start (development)
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
git clone https://github.com/glossarist/concept-browser.git
|
|
42
|
+
cd concept-browser
|
|
26
43
|
npm install
|
|
27
44
|
npm run dev
|
|
28
45
|
# Open http://localhost:5173
|
|
@@ -32,317 +49,250 @@ The dev server serves pre-built data from `public/data/`. If no data is present
|
|
|
32
49
|
|
|
33
50
|
---
|
|
34
51
|
|
|
35
|
-
##
|
|
52
|
+
## CLI Reference
|
|
36
53
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
54
|
+
```
|
|
55
|
+
concept-browser <command> [options]
|
|
56
|
+
|
|
57
|
+
Commands:
|
|
58
|
+
fetch Fetch/update datasets (from GCR packages, local paths, or source repos)
|
|
59
|
+
generate Convert harmonized YAML concepts to JSON-LD static files
|
|
60
|
+
edges Build cross-reference edges from generated concept data
|
|
61
|
+
build Full pipeline: fetch + generate + edges + vite build
|
|
62
|
+
site Same as build (alias)
|
|
63
|
+
|
|
64
|
+
Options:
|
|
65
|
+
--site <id> Site config ID (looks for site-config.yml in CWD)
|
|
66
|
+
|
|
67
|
+
Environment:
|
|
68
|
+
SITE_CONFIG Site config file path (highest priority)
|
|
69
|
+
SITE_ID Site config ID (same as --site)
|
|
70
|
+
GITHUB_TOKEN GitHub token for private repos
|
|
71
|
+
```
|
|
47
72
|
|
|
48
73
|
---
|
|
49
74
|
|
|
50
75
|
## Data Pipeline
|
|
51
76
|
|
|
52
77
|
```
|
|
53
|
-
|
|
54
|
-
└─> scripts/fetch-datasets.mjs
|
|
78
|
+
site-config.yml
|
|
79
|
+
└─> scripts/fetch-datasets.mjs (fetch from GCR, localPath, or sourceRepo)
|
|
55
80
|
└─> .datasets/{id}/concepts/*.yaml
|
|
56
|
-
└─> scripts/generate-data.mjs
|
|
81
|
+
└─> scripts/generate-data.mjs (YAML → JSON-LD)
|
|
57
82
|
└─> public/data/{id}/
|
|
58
|
-
├── manifest.json Dataset metadata
|
|
83
|
+
├── manifest.json Dataset metadata (ref, owner, stats)
|
|
59
84
|
├── index.json Concept listing (chunked for large sets)
|
|
60
85
|
├── edges.json Pre-computed cross-reference + domain edges
|
|
61
86
|
├── domain-nodes.json Domain classification nodes
|
|
62
87
|
└── concepts/*.json Individual concept documents
|
|
63
|
-
└─> scripts/build-edges.js
|
|
88
|
+
└─> scripts/build-edges.js (extract graph + domain edges)
|
|
64
89
|
```
|
|
65
90
|
|
|
66
|
-
|
|
91
|
+
---
|
|
67
92
|
|
|
68
|
-
|
|
69
|
-
# 1. Fetch source repos and harmonize concepts
|
|
70
|
-
npm run fetch-datasets
|
|
93
|
+
## Configuration: `site-config.yml`
|
|
71
94
|
|
|
72
|
-
|
|
73
|
-
npm run generate-data
|
|
95
|
+
All configuration lives in a single file. The CLI reads it from the current working directory.
|
|
74
96
|
|
|
75
|
-
|
|
76
|
-
node scripts/build-edges.js
|
|
97
|
+
### Top-level fields
|
|
77
98
|
|
|
78
|
-
|
|
79
|
-
|
|
99
|
+
```yaml
|
|
100
|
+
id: viml # Site identifier
|
|
101
|
+
domain: viml.oiml.info # Primary domain
|
|
102
|
+
basePath: /oiml-viml/ # URL subpath for GitHub Pages deployment
|
|
103
|
+
title: VIML # Site title
|
|
104
|
+
subtitle: International Vocabulary... # Short description
|
|
105
|
+
description: Terminology from... # Longer description
|
|
106
|
+
|
|
107
|
+
uiLanguages: # Available UI languages
|
|
108
|
+
- code: eng
|
|
109
|
+
label: English
|
|
110
|
+
- code: fra
|
|
111
|
+
label: Français
|
|
112
|
+
|
|
113
|
+
translations: # Localized title/subtitle/description
|
|
114
|
+
fra:
|
|
115
|
+
subtitle: Vocabulaire international de métrologie légale
|
|
116
|
+
description: Terminologie du Vocabulaire international...
|
|
117
|
+
|
|
118
|
+
defaults:
|
|
119
|
+
language: eng # Default concept language
|
|
120
|
+
|
|
121
|
+
copyright: "OIML" # Footer copyright text
|
|
80
122
|
```
|
|
81
123
|
|
|
82
|
-
|
|
124
|
+
### Dataset configuration
|
|
83
125
|
|
|
84
|
-
```
|
|
85
|
-
|
|
126
|
+
```yaml
|
|
127
|
+
datasets:
|
|
128
|
+
- id: viml
|
|
129
|
+
uri: "urn:oiml:pub:v:1:2022"
|
|
130
|
+
sourceRepo: https://github.com/metanorma/oiml-viml
|
|
131
|
+
localPath: viml-glossarist # Local dataset directory (relative to CWD)
|
|
132
|
+
title: "VIML — International Vocabulary of Legal Metrology"
|
|
133
|
+
description: "Terminology definitions from..."
|
|
134
|
+
owner: OIML
|
|
135
|
+
ref: "OIML V 1:2022" # Publication reference (shown in sidebar provenance)
|
|
136
|
+
color: "#004996"
|
|
137
|
+
tags: [metrology, legal, oiml]
|
|
138
|
+
languageOrder: [eng, fra]
|
|
86
139
|
```
|
|
87
140
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
To use a local checkout instead of cloning from GitHub:
|
|
141
|
+
#### Dataset field reference
|
|
91
142
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
143
|
+
| Field | Required | Description |
|
|
144
|
+
|-------|----------|-------------|
|
|
145
|
+
| `id` | yes | URL-safe identifier used in routes and data paths |
|
|
146
|
+
| `uri` | no | URI pattern for this dataset |
|
|
147
|
+
| `sourceRepo` | no | Git repository URL containing concept YAML files |
|
|
148
|
+
| `gcrPackage` | no | URL to a pre-built `.gcr` ZIP archive (alternative to sourceRepo) |
|
|
149
|
+
| `localPath` | no | Local directory with `concepts/` and `register.yaml` (relative to CWD) |
|
|
150
|
+
| `title` | no | Display name. Falls back to `register.yaml` name field |
|
|
151
|
+
| `description` | no | Shown on home page and about page |
|
|
152
|
+
| `owner` | no | Organization name shown in sidebar provenance |
|
|
153
|
+
| `ref` | no | Publication reference shown in sidebar provenance (e.g., "OIML V 1:2022") |
|
|
154
|
+
| `color` | no | Hex color for UI accent. Auto-assigned if omitted |
|
|
155
|
+
| `tags` | no | Array of labels shown on dataset card |
|
|
156
|
+
| `languageOrder` | no | Array of ISO 639-2 codes controlling display order |
|
|
157
|
+
| `translations` | no | Localized title and description per language |
|
|
97
158
|
|
|
98
|
-
|
|
159
|
+
#### Dataset source resolution
|
|
99
160
|
|
|
100
|
-
|
|
161
|
+
The CLI resolves dataset sources in this priority order:
|
|
101
162
|
|
|
102
|
-
|
|
163
|
+
1. **`.gcr/{id}.gcr`** on disk — extract to `.datasets/{id}/`
|
|
164
|
+
2. **`gcrPackage`** URL — download and extract
|
|
165
|
+
3. **`localPath`** — copy `concepts/` and `register.yaml` from a local directory
|
|
166
|
+
4. **`sourceRepo`** — git clone to `.datasets/{id}/`
|
|
103
167
|
|
|
104
|
-
###
|
|
168
|
+
### Base path for subpath deployment
|
|
105
169
|
|
|
106
|
-
|
|
170
|
+
Set `basePath` in `site-config.yml` to deploy to a subdirectory (e.g., GitHub Pages at `metanorma.github.io/my-site/`):
|
|
107
171
|
|
|
108
172
|
```yaml
|
|
109
|
-
|
|
110
|
-
primaryColor: "#d97706"
|
|
111
|
-
darkColor: "#1a1a2e"
|
|
112
|
-
logo:
|
|
113
|
-
path: /logos/my-logo.svg # URL path served to browsers
|
|
114
|
-
alt: "My Org"
|
|
115
|
-
localPath: logos/my-logo.svg # Local file used as favicon source
|
|
116
|
-
favicon: logos/my-favicon.svg # Optional — overrides logo.localPath for favicon generation
|
|
173
|
+
basePath: /my-site/
|
|
117
174
|
```
|
|
118
175
|
|
|
119
|
-
|
|
176
|
+
This configures Vite's `base` so all asset paths, router paths, and data fetches use the correct prefix. The `BASE_PATH` environment variable can override this if needed.
|
|
120
177
|
|
|
121
|
-
|
|
122
|
-
2. `branding.logo.localPath` — falls back to the site logo
|
|
123
|
-
3. Package default `public/favicon.svg`
|
|
124
|
-
|
|
125
|
-
The build produces: `favicon.ico`, `favicon.svg`, `favicon-{16,32,48}x{16,32,48}.png`, `apple-touch-icon-*.png` (all standard iOS sizes), and injects the corresponding `<link>` and `<meta>` tags into `index.html` via a Vite plugin.
|
|
126
|
-
|
|
127
|
-
### Full reference
|
|
178
|
+
### Branding and favicon
|
|
128
179
|
|
|
129
180
|
```yaml
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
181
|
+
branding:
|
|
182
|
+
primaryColor: "#004996"
|
|
183
|
+
darkColor: "#003366"
|
|
184
|
+
fonts:
|
|
185
|
+
header:
|
|
186
|
+
family: "Source Serif 4"
|
|
187
|
+
source: "google"
|
|
188
|
+
weights: [400, 600]
|
|
189
|
+
body:
|
|
190
|
+
family: "Source Sans 3"
|
|
191
|
+
source: "google"
|
|
192
|
+
weights: [400, 500, 700]
|
|
193
|
+
logo:
|
|
194
|
+
path: /logos/oiml-logo.svg # URL path served to browsers
|
|
195
|
+
alt: OIML
|
|
196
|
+
localPath: logos/oiml-logo.svg # Local file for favicon generation
|
|
197
|
+
localLight: logos/oiml-logo-icon-light.svg # Light variant (dark mode)
|
|
198
|
+
localDark: logos/oiml-logo-icon-dark.svg # Dark variant (light mode)
|
|
199
|
+
ownerName: OIML
|
|
200
|
+
ownerUrl: "https://www.oiml.org"
|
|
144
201
|
```
|
|
145
202
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
| Field | Required | Description |
|
|
149
|
-
|-------|----------|-------------|
|
|
150
|
-
| `id` | yes | URL-safe identifier used in routes (`/dataset/{id}/concept/...`) and data paths (`public/data/{id}/`) |
|
|
151
|
-
| `sourceRepo` | yes* | Git repository URL containing concept YAML files in `concepts/` directory. `gcrPackage` is an alternative. |
|
|
152
|
-
| `gcrPackage` | no | URL to a pre-built `.gcr` ZIP archive. Used instead of `sourceRepo` when available. See `docs/gcr-spec.md`. |
|
|
153
|
-
| `title` | no | Display name. Falls back to `name` field in the repo's `register.yaml`. |
|
|
154
|
-
| `description` | no | Shown on the home page dataset card and the about page. |
|
|
155
|
-
| `owner` | no | Organization name shown in concept badges and the about page. |
|
|
156
|
-
| `color` | no | Hex color (`#RRGGBB`) for dataset accent. Used for graph nodes, sidebar highlights, and card borders. Auto-assigned if omitted. |
|
|
157
|
-
| `tags` | no | Array of short labels shown on the dataset card. |
|
|
158
|
-
| `existingSiteUrl` | no | Link to the dataset's existing website, shown as a badge on the dataset page. |
|
|
159
|
-
| `externalConceptUrlTemplate` | no | URL template for linking to the official source of each concept. `{conceptId}` is replaced with the concept ID. |
|
|
160
|
-
| `languageOrder` | no | Array of ISO 639-2 language codes controlling the display order on concept pages. Without this, languages default to English-first then alphabetical. |
|
|
203
|
+
Favicons are auto-generated from the logo SVG using the `favicons` package. Resolution order: `branding.favicon` → `branding.logo.localPath` → package default `public/favicon.svg`.
|
|
161
204
|
|
|
162
205
|
### Site features
|
|
163
206
|
|
|
164
|
-
The `features` section in `site-config.yml` toggles functionality and customizes branding:
|
|
165
|
-
|
|
166
207
|
```yaml
|
|
167
208
|
features:
|
|
168
|
-
news:
|
|
209
|
+
news: false # enable news posts
|
|
169
210
|
stats: true # show statistics dashboard
|
|
170
211
|
graph: true # enable concept graph visualization
|
|
171
212
|
about: true # enable about page
|
|
172
213
|
search: true # enable full-text search
|
|
173
|
-
poweredBy:
|
|
174
|
-
|
|
175
|
-
url: "https://
|
|
214
|
+
poweredBy:
|
|
215
|
+
title: "Glossarist"
|
|
216
|
+
url: "https://glossarist.org"
|
|
176
217
|
```
|
|
177
218
|
|
|
178
|
-
|
|
179
|
-
|-------|---------|-------------|
|
|
180
|
-
| `poweredBy.message` | `Built with the Glossarist Concept Browser` | Link text shown in sidebar and footer |
|
|
181
|
-
| `poweredBy.url` | `https://github.com/glossarist/concept-browser` | Link href |
|
|
219
|
+
### Content pages
|
|
182
220
|
|
|
183
|
-
|
|
221
|
+
```yaml
|
|
222
|
+
pages:
|
|
223
|
+
- type: about
|
|
224
|
+
route: about
|
|
225
|
+
title: About
|
|
226
|
+
icon: info
|
|
227
|
+
source: about.md
|
|
228
|
+
translations:
|
|
229
|
+
fra:
|
|
230
|
+
title: À propos
|
|
231
|
+
source: about-fra.md
|
|
232
|
+
```
|
|
184
233
|
|
|
185
234
|
### Cross-reference mapping
|
|
186
235
|
|
|
187
|
-
The top-level `crossReferences` section maps inline references to dataset IDs:
|
|
188
|
-
|
|
189
236
|
```yaml
|
|
190
237
|
crossReferences:
|
|
191
238
|
refPrefixMap:
|
|
192
|
-
IEV: iev
|
|
239
|
+
IEV: iev
|
|
193
240
|
urnStandardMap:
|
|
194
|
-
"14812": isotc204
|
|
241
|
+
"14812": isotc204
|
|
195
242
|
```
|
|
196
243
|
|
|
197
244
|
---
|
|
198
245
|
|
|
199
|
-
## Adding a New Dataset
|
|
200
|
-
|
|
201
|
-
1. Add an entry to `datasets.yml` (see configuration above)
|
|
202
|
-
2. Run `npm run fetch-datasets && npm run generate-data && node scripts/build-edges.js`
|
|
203
|
-
3. Verify with `npm run dev`
|
|
204
|
-
4. Commit and push
|
|
205
|
-
|
|
206
|
-
For the full guide, see [Adding a Dataset](docs/adding-a-dataset.md).
|
|
207
|
-
|
|
208
|
-
### Source repository requirements
|
|
209
|
-
|
|
210
|
-
The source repository must contain:
|
|
211
|
-
|
|
212
|
-
- `concepts/` directory with YAML concept files (one per concept)
|
|
213
|
-
- Optionally `register.yaml` with dataset metadata
|
|
214
|
-
|
|
215
|
-
Concepts must conform to the [canonical format](docs/dataset-schema.md). The harmonization step in `fetch-datasets` normalizes common variants automatically.
|
|
216
|
-
|
|
217
|
-
---
|
|
218
|
-
|
|
219
|
-
## Included Datasets
|
|
220
|
-
|
|
221
|
-
| Dataset | Concepts | Languages | Description |
|
|
222
|
-
|---------|----------|-----------|-------------|
|
|
223
|
-
| IEC Electropedia (IEV) | 22,228 | 17 | World's most comprehensive electrotechnical terminology database |
|
|
224
|
-
| ISO/TC 211 Multi-Lingual Glossary | 1,302 | 5+ | Geographic information terminology |
|
|
225
|
-
| ISO/TC 204 ITS Vocabulary | 312 | 1 | Intelligent transport systems terminology |
|
|
226
|
-
| OSGeo Lexicon | 444 | 1 | Open Source Geospatial Foundation glossary |
|
|
227
|
-
|
|
228
|
-
---
|
|
229
|
-
|
|
230
246
|
## Deployment
|
|
231
247
|
|
|
232
|
-
###
|
|
233
|
-
|
|
234
|
-
```
|
|
235
|
-
glossarist/vocabulary-browser geolexica/geolexica.org
|
|
236
|
-
(Glossarist software) (Deployment target)
|
|
237
|
-
───────────────────── ──────────────────────
|
|
238
|
-
Push to main Push to main / repository_dispatch
|
|
239
|
-
│ │
|
|
240
|
-
├─ .github/workflows/deploy.yml │
|
|
241
|
-
│ fetch + generate + build │
|
|
242
|
-
│ → deploys to GitHub Pages (preview)│
|
|
243
|
-
│ → triggers geolexica.org dispatch │
|
|
244
|
-
│ │
|
|
245
|
-
└──── repository_dispatch ─────────> build_deploy.yml
|
|
246
|
-
checkout vocabulary-browser
|
|
247
|
-
fetch + generate + build
|
|
248
|
-
→ GitHub Pages → www.geolexica.org
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
The vocabulary-browser repository is the **Glossarist software**. The [geolexica.org](https://github.com/geolexica/geolexica.org) repository is the **deployment target** — its workflow checks out vocabulary-browser, builds it, and deploys to GitHub Pages at `www.geolexica.org`.
|
|
248
|
+
### GitHub Pages (recommended)
|
|
252
249
|
|
|
253
|
-
|
|
250
|
+
1. Create a deployment repo with `site-config.yml`, dataset source, and content pages
|
|
251
|
+
2. Add a GitHub Actions workflow:
|
|
254
252
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
9. Triggers `geolexica.org` deployment via `repository_dispatch`
|
|
283
|
-
|
|
284
|
-
### Custom base path
|
|
285
|
-
|
|
286
|
-
By default the app deploys to the root (`/`). To deploy to a subdirectory (e.g., `/vocab/`):
|
|
287
|
-
|
|
288
|
-
```bash
|
|
289
|
-
BASE_PATH=/vocab/ npm run build
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
This sets the Vite `base` config so all asset paths are prefixed correctly.
|
|
293
|
-
|
|
294
|
-
**How it works:**
|
|
295
|
-
|
|
296
|
-
The `BASE_PATH` environment variable controls subpath deployment through two mechanisms:
|
|
297
|
-
|
|
298
|
-
1. **Build time (Node.js scripts):** `generate-data.mjs` uses `BASE_PATH` to prefix logo paths in the generated `site-config.json`. The favicon generation in `cli/index.mjs` also prefixes favicon link hrefs. These are build-time rewrites because they produce static JSON/HTML that can't use Vite's runtime resolution.
|
|
299
|
-
|
|
300
|
-
2. **Runtime (browser):** The Vue app uses `import.meta.env.BASE_URL` (a Vite compile-time constant derived from `base`) to prefix all `fetch()` paths. This includes:
|
|
301
|
-
- `datasets.json` (dataset registry)
|
|
302
|
-
- `site-config.json` (branding, features)
|
|
303
|
-
- `data/{id}/...` (concept data via `DatasetAdapter`)
|
|
304
|
-
- `pages/*.json` (content pages)
|
|
305
|
-
- `news.json` (news feed)
|
|
306
|
-
- `data/{id}/bibliography.json` and `data/{id}/images/*` (render-time resources)
|
|
307
|
-
|
|
308
|
-
The Vite `base` config normalizes trailing slashes automatically, so `BASE_PATH=/vocab` and `BASE_PATH=/vocab/` both work. The value is passed through to `import.meta.env.BASE_URL` which always ends with `/`.
|
|
309
|
-
|
|
310
|
-
**CLI usage:**
|
|
311
|
-
|
|
312
|
-
When using the `concept-browser` CLI from a deployment repo (not the package source):
|
|
313
|
-
|
|
314
|
-
```bash
|
|
315
|
-
git clone --branch fix/subpath-base-url --depth 1 https://github.com/glossarist/concept-browser.git /tmp/cb
|
|
316
|
-
cd /tmp/cb && npm install --ignore-scripts
|
|
317
|
-
npm install --prefix /tmp/cb sharp 2>/dev/null || true
|
|
318
|
-
|
|
319
|
-
# Build from the deployment repo's working directory
|
|
320
|
-
cd /path/to/deployment-repo
|
|
321
|
-
node /tmp/cb/cli/index.mjs build
|
|
253
|
+
```yaml
|
|
254
|
+
jobs:
|
|
255
|
+
build:
|
|
256
|
+
runs-on: ubuntu-latest
|
|
257
|
+
steps:
|
|
258
|
+
- uses: actions/checkout@v4
|
|
259
|
+
- uses: actions/setup-node@v4
|
|
260
|
+
with:
|
|
261
|
+
node-version: 20
|
|
262
|
+
- name: Install concept-browser
|
|
263
|
+
run: |
|
|
264
|
+
npm install --ignore-scripts @glossarist/concept-browser
|
|
265
|
+
npm install --prefix node_modules/@glossarist/concept-browser sharp 2>/dev/null || true
|
|
266
|
+
- name: Build site
|
|
267
|
+
run: npx concept-browser build
|
|
268
|
+
env:
|
|
269
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
270
|
+
- name: Upload artifact
|
|
271
|
+
uses: actions/upload-pages-artifact@v3
|
|
272
|
+
with:
|
|
273
|
+
path: dist
|
|
274
|
+
deploy:
|
|
275
|
+
needs: build
|
|
276
|
+
runs-on: ubuntu-latest
|
|
277
|
+
if: ${{ github.ref == 'refs/heads/main' }}
|
|
278
|
+
steps:
|
|
279
|
+
- uses: actions/deploy-pages@v4
|
|
322
280
|
```
|
|
323
281
|
|
|
324
|
-
|
|
282
|
+
All configuration (base path, dataset sources, branding) comes from `site-config.yml` — no dataset-specific environment variables needed.
|
|
325
283
|
|
|
326
284
|
### Other hosting platforms
|
|
327
285
|
|
|
328
|
-
The build produces static files in `dist/` with an SPA `404.html` fallback
|
|
286
|
+
The build produces static files in `dist/` with an SPA `404.html` fallback:
|
|
329
287
|
|
|
330
|
-
- **Netlify:**
|
|
331
|
-
- **Vercel:**
|
|
332
|
-
- **AWS S3 + CloudFront:** Upload `dist
|
|
333
|
-
- **GitHub Pages:** Set **Settings → Pages → Source** to "GitHub Actions", then push to `main`
|
|
334
|
-
- **Any static host:** Upload `dist/` and configure all 404s to serve `index.html`
|
|
288
|
+
- **Netlify:** Build command `npx concept-browser build`, publish directory `dist`, add `_redirects` with `/* /index.html 200`
|
|
289
|
+
- **Vercel:** Framework Vite, build command `npx concept-browser build`, output directory `dist`
|
|
290
|
+
- **AWS S3 + CloudFront:** Upload `dist/`, error document `index.html`, configure CloudFront for SPA routing
|
|
335
291
|
|
|
336
292
|
---
|
|
337
293
|
|
|
338
294
|
## Architecture
|
|
339
295
|
|
|
340
|
-
See [Architecture Documentation](docs/architecture.md) for:
|
|
341
|
-
- System architecture diagrams
|
|
342
|
-
- Component hierarchy
|
|
343
|
-
- Data pipeline details
|
|
344
|
-
- Adapter pattern and graph engine internals
|
|
345
|
-
|
|
346
296
|
### Tech Stack
|
|
347
297
|
|
|
348
298
|
- **Vue 3** + **TypeScript** + **Vite**
|
|
@@ -351,46 +301,49 @@ See [Architecture Documentation](docs/architecture.md) for:
|
|
|
351
301
|
- **Tailwind CSS 3** (utility-first styling)
|
|
352
302
|
- **D3.js** (force-directed graph)
|
|
353
303
|
- **KaTeX** (math rendering)
|
|
354
|
-
- **DM Serif Display** + **DM Sans** + **JetBrains Mono** (typography)
|
|
355
304
|
|
|
356
305
|
### Project structure
|
|
357
306
|
|
|
358
307
|
```
|
|
359
308
|
src/
|
|
360
309
|
├── adapters/ Data access layer (DatasetAdapter, AdapterFactory, UriRouter)
|
|
361
|
-
├── components/
|
|
362
|
-
├── graph/ Graph engine for concept relationships
|
|
310
|
+
├── components/ Vue components (AppSidebar, AppFooter, ConceptDetail, GraphPanel, etc.)
|
|
311
|
+
├── graph/ Graph engine for concept relationships
|
|
363
312
|
├── stores/ Pinia stores (vocabulary, ui)
|
|
364
313
|
├── views/ Page-level components (HomeView, DatasetView, ConceptView, etc.)
|
|
314
|
+
├── i18n/ Internationalization (YAML locale files, auto-discovered)
|
|
365
315
|
├── utils/ Utilities (math rendering, language names, dataset styling)
|
|
366
316
|
└── style.css Global styles and Tailwind layers
|
|
367
317
|
|
|
318
|
+
cli/
|
|
319
|
+
└── index.mjs CLI entry point (fetch, generate, edges, build commands)
|
|
320
|
+
|
|
368
321
|
scripts/
|
|
369
|
-
├── fetch-datasets.mjs Clone + harmonize source repos
|
|
370
|
-
├── generate-data.mjs Convert YAML → JSON-LD
|
|
322
|
+
├── fetch-datasets.mjs Clone + harmonize source repos, resolve localPath/GCR
|
|
323
|
+
├── generate-data.mjs Convert YAML → JSON-LD, generate manifest with provenance data
|
|
371
324
|
├── build-edges.js Extract cross-reference edges
|
|
372
|
-
├── build-gcr.mjs Build GCR packages (optional)
|
|
373
325
|
└── generate-404.js SPA fallback for GitHub Pages
|
|
374
|
-
|
|
375
|
-
docs/
|
|
376
|
-
├── adding-a-dataset.md Step-by-step guide for adding datasets
|
|
377
|
-
├── dataset-schema.md Canonical concept YAML format reference
|
|
378
|
-
├── gcr-spec.md GCR packaging format specification
|
|
379
|
-
└── architecture.md Full architecture documentation
|
|
380
326
|
```
|
|
381
327
|
|
|
382
328
|
---
|
|
383
329
|
|
|
330
|
+
## i18n
|
|
331
|
+
|
|
332
|
+
UI translations are YAML files in `src/i18n/locales/`, auto-discovered via `import.meta.glob`. To add a new language:
|
|
333
|
+
|
|
334
|
+
1. Copy `eng.yml` to `{lang-code}.yml`
|
|
335
|
+
2. Translate all values
|
|
336
|
+
3. Add the language to `uiLanguages` in `site-config.yml`
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
384
340
|
## Testing
|
|
385
341
|
|
|
386
342
|
```bash
|
|
387
|
-
npm test # Run all tests
|
|
343
|
+
npm test # Run all tests (Vitest with happy-dom)
|
|
388
344
|
npm run test:watch # Watch mode
|
|
389
|
-
npx vitest run src/__tests__/graph.test.ts # Single test file
|
|
390
345
|
```
|
|
391
346
|
|
|
392
|
-
Tests use Vitest with happy-dom environment. Vue Test Utils for component tests.
|
|
393
|
-
|
|
394
347
|
---
|
|
395
348
|
|
|
396
349
|
## License
|
package/cli/index.mjs
CHANGED
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
* SITE_CONFIG Path to site config file (overrides --site)
|
|
18
18
|
* SITE_ID Site config ID (overrides --site)
|
|
19
19
|
* GITHUB_TOKEN GitHub token for private repos
|
|
20
|
-
* DATASET_SOURCE_{ID} Override dataset source with local path
|
|
21
20
|
*/
|
|
22
21
|
|
|
23
22
|
import { loadSiteConfig } from '../scripts/load-site-config.mjs';
|
|
@@ -69,8 +68,7 @@ Options:
|
|
|
69
68
|
Environment:
|
|
70
69
|
SITE_CONFIG Site config file path (highest priority)
|
|
71
70
|
SITE_ID Site config ID (same as --site)
|
|
72
|
-
GITHUB_TOKEN GitHub token for private repos
|
|
73
|
-
DATASET_SOURCE_{ID} Override dataset source with local path`);
|
|
71
|
+
GITHUB_TOKEN GitHub token for private repos`);
|
|
74
72
|
process.exit(cmd ? 0 : 1);
|
|
75
73
|
}
|
|
76
74
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glossarist/concept-browser",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.7",
|
|
4
4
|
"description": "Vue SPA for browsing Glossarist terminology datasets with cross-reference resolution, graph visualization, and multi-language support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* After fetching, validates that all GCR dependencies are satisfiable
|
|
11
11
|
* (either provided locally or routed externally).
|
|
12
12
|
*
|
|
13
|
-
* Supports
|
|
13
|
+
* Supports localPath field in dataset config for local paths.
|
|
14
14
|
* Supports GITHUB_TOKEN for private repos.
|
|
15
15
|
*/
|
|
16
16
|
import fs from 'fs';
|
|
@@ -150,7 +150,7 @@ for (const ds of config.datasets) {
|
|
|
150
150
|
}
|
|
151
151
|
extractGcr(gcrPath, targetDir);
|
|
152
152
|
} else {
|
|
153
|
-
const envOverride =
|
|
153
|
+
const envOverride = ds.localPath;
|
|
154
154
|
if (envOverride) {
|
|
155
155
|
console.log(` Using local path: ${envOverride}`);
|
|
156
156
|
if (!fs.existsSync(targetDir)) fs.mkdirSync(targetDir, { recursive: true });
|
package/src/config/types.ts
CHANGED
|
@@ -88,6 +88,7 @@ export interface DatasetConfig {
|
|
|
88
88
|
uriAliases?: string[];
|
|
89
89
|
gcrPackage: string;
|
|
90
90
|
sourceRepo?: string;
|
|
91
|
+
localPath?: string;
|
|
91
92
|
title: string;
|
|
92
93
|
description?: string;
|
|
93
94
|
owner?: string;
|
|
@@ -144,6 +145,7 @@ export interface SiteConfig {
|
|
|
144
145
|
id: string;
|
|
145
146
|
domain: string;
|
|
146
147
|
uriBase?: string;
|
|
148
|
+
basePath?: string;
|
|
147
149
|
title: string;
|
|
148
150
|
subtitle?: string;
|
|
149
151
|
description?: string;
|