@glossarist/concept-browser 0.7.55 → 0.7.56
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 +112 -20
- package/package.json +1 -1
- package/src/utils/color-theme.ts +4 -6
package/README.md
CHANGED
|
@@ -14,8 +14,13 @@ A statically deployable single-page application for browsing terminology dataset
|
|
|
14
14
|
- **Multi-dataset browsing** — Concepts from multiple terminology registers in one place
|
|
15
15
|
- **Full multilingual support** — Definitions, notes, and examples in all available languages with i18n UI
|
|
16
16
|
- **Concept history timeline** — Review dates, decisions, and change notes per language
|
|
17
|
+
- **Relation sphere** — 3D sphere visualization of a concept's neighborhood with d3 force simulation, per-relation-type colors, and degree filtering
|
|
18
|
+
- **Edition series** — Sidebar timeline for vocabulary edition groups (e.g. VIML 1968/2000/2013/2022) with current-edition markers and supersession chain navigation
|
|
17
19
|
- **Cross-reference graph** — D3 force-directed graph showing concept relationships with dataset filtering
|
|
18
|
-
- **
|
|
20
|
+
- **Dataset groups** — Organize datasets into lineage series, topic bundles, publication families, or curated collections. Each group kind has distinct sidebar rendering
|
|
21
|
+
- **Light/dark mode colors** — Per-dataset `{ light, dark }` color pairs. Per-relation-type colors configurable via site-config
|
|
22
|
+
- **RDF / SHACL outputs** — Every concept emits SHACL-conformant Turtle + JSON-LD. Dataset-level `dcat:Dataset`, group-level `dcat:DatasetSeries`/`dcat:Catalog`, vocabulary SKOS ConceptSchemes, bibliography `dcterms:BibliographicResource`, build provenance `prov:Activity`
|
|
23
|
+
- **Rich sidebar provenance** — Publication reference, owner, status, concept/language counts, sections tree from manifest data
|
|
19
24
|
- **Math rendering** — KaTeX rendering for AsciiMath notation in definitions (`stem:[...]`)
|
|
20
25
|
- **Responsive design** — Mobile-first layout with light/dark mode
|
|
21
26
|
- **Static deployment** — No server required. Deploy to any static host
|
|
@@ -56,10 +61,12 @@ concept-browser <command> [options]
|
|
|
56
61
|
|
|
57
62
|
Commands:
|
|
58
63
|
fetch Fetch/update datasets (from GCR packages, local paths, or source repos)
|
|
59
|
-
generate Convert harmonized YAML concepts to JSON-LD static files
|
|
64
|
+
generate Convert harmonized YAML concepts to JSON-LD static files + RDF artifacts
|
|
60
65
|
edges Build cross-reference edges from generated concept data
|
|
61
66
|
build Full pipeline: fetch + generate + edges + vite build
|
|
62
67
|
site Same as build (alias)
|
|
68
|
+
doctor Run diagnostic checks (node version, deps, shapes, data integrity)
|
|
69
|
+
normalize NFC-normalize YAML concept files in-place
|
|
63
70
|
|
|
64
71
|
Options:
|
|
65
72
|
--site <id> Site config ID (looks for site-config.yml in CWD)
|
|
@@ -78,13 +85,19 @@ Environment:
|
|
|
78
85
|
site-config.yml
|
|
79
86
|
└─> scripts/fetch-datasets.mjs (fetch from GCR, localPath, or sourceRepo)
|
|
80
87
|
└─> .datasets/{id}/concepts/*.yaml
|
|
81
|
-
└─> scripts/generate-data.mjs (YAML → JSON-LD)
|
|
88
|
+
└─> scripts/generate-data.mjs (YAML → JSON-LD + RDF artifacts)
|
|
82
89
|
└─> public/data/{id}/
|
|
83
90
|
├── manifest.json Dataset metadata (ref, owner, stats)
|
|
84
91
|
├── index.json Concept listing (chunked for large sets)
|
|
85
92
|
├── edges.json Pre-computed cross-reference + domain edges
|
|
86
93
|
├── domain-nodes.json Domain classification nodes
|
|
94
|
+
├── {register}.ttl Dataset-level RDF (dcat:Dataset + skos:ConceptScheme + sections)
|
|
95
|
+
├── bib.ttl Bibliography graph (dcterms:BibliographicResource)
|
|
87
96
|
└── concepts/*.json Individual concept documents
|
|
97
|
+
└─> public/data/_vocab.ttl Vocabulary graph (SKOS ConceptSchemes)
|
|
98
|
+
└─> public/data/activity/ Build provenance (prov:Activity per build)
|
|
99
|
+
└─> public/data/agents.ttl Contributor records (foaf:Person)
|
|
100
|
+
└─> public/data/versions.ttl Version chain (prov:Entity)
|
|
88
101
|
└─> scripts/build-edges.js (extract graph + domain edges)
|
|
89
102
|
```
|
|
90
103
|
|
|
@@ -151,7 +164,7 @@ datasets:
|
|
|
151
164
|
| `description` | no | Shown on home page and about page |
|
|
152
165
|
| `owner` | no | Organization name shown in sidebar provenance |
|
|
153
166
|
| `ref` | no | Publication reference shown in sidebar provenance (e.g., "OIML V 1:2022") |
|
|
154
|
-
| `color` | no |
|
|
167
|
+
| `color` | no | Accent color — single hex (`"#004996"`) or `{ light, dark }` pair |
|
|
155
168
|
| `tags` | no | Array of labels shown on dataset card |
|
|
156
169
|
| `languageOrder` | no | Array of ISO 639-2 codes controlling display order |
|
|
157
170
|
| `translations` | no | Localized title and description per language |
|
|
@@ -233,13 +246,17 @@ pages:
|
|
|
233
246
|
|
|
234
247
|
### Dataset groups
|
|
235
248
|
|
|
236
|
-
When a site has many datasets, you can group them in the sidebar navigation.
|
|
249
|
+
When a site has many datasets, you can group them in the sidebar navigation. Each group has a `kind` that determines its visual treatment and semantic assumptions.
|
|
237
250
|
|
|
238
251
|
```yaml
|
|
239
252
|
datasetGroups:
|
|
240
253
|
- id: viml
|
|
241
254
|
label: "VIML — International Vocabulary of Legal Metrology"
|
|
242
|
-
|
|
255
|
+
kind: lineage # edition series (same vocabulary, different years)
|
|
256
|
+
current: viml-2022 # current edition for the series
|
|
257
|
+
color:
|
|
258
|
+
light: "#004996"
|
|
259
|
+
dark: "#3B82F6"
|
|
243
260
|
datasets: [viml-2022, viml-2013, viml-2000, viml-1968]
|
|
244
261
|
translations:
|
|
245
262
|
fra:
|
|
@@ -247,22 +264,44 @@ datasetGroups:
|
|
|
247
264
|
|
|
248
265
|
- id: vim
|
|
249
266
|
label: "VIM — International Vocabulary of Metrology"
|
|
250
|
-
|
|
267
|
+
kind: lineage
|
|
268
|
+
current: vim-2012
|
|
269
|
+
color:
|
|
270
|
+
light: "#005A9C"
|
|
271
|
+
dark: "#2196F3"
|
|
251
272
|
datasets: [vim-2012, vim-2010, vim-2007, vim-1993]
|
|
252
273
|
```
|
|
253
274
|
|
|
254
|
-
####
|
|
275
|
+
#### Group kinds
|
|
276
|
+
|
|
277
|
+
| Kind | Glyph | Description | Sidebar rendering |
|
|
278
|
+
|------|-------|-------------|-------------------|
|
|
279
|
+
| `lineage` | ⏳ | Editions of the same vocabulary over time | Compact timeline with year badges + current-edition star (✦) |
|
|
280
|
+
| `topic` | ◆ | Different vocabularies on the same subject | Standard list entries |
|
|
281
|
+
| `family` | ✦ | Related vocabularies from the same publisher | Standard list entries |
|
|
282
|
+
| `collection` | ❖ | Curated bundle of datasets | Standard list entries |
|
|
283
|
+
| `default` | ▸ | No special semantics (backward compat) | Standard list entries |
|
|
284
|
+
|
|
285
|
+
For `lineage` groups:
|
|
286
|
+
- The `current` field identifies the newest valid edition. If omitted, the newest member by year is auto-detected.
|
|
287
|
+
- Members are displayed as a timeline with year + reference + status badges.
|
|
288
|
+
- When an edition is active, the full expansion (sub-pages, sections tree, provenance) appears below the timeline entry — same as non-series datasets.
|
|
289
|
+
- A supersession chain card (`ConceptEditionRail`) appears in the concept detail sidebar, showing how the concept evolved across editions.
|
|
290
|
+
|
|
291
|
+
#### Group field reference
|
|
255
292
|
|
|
256
293
|
| Field | Required | Description |
|
|
257
294
|
|-------|----------|-------------|
|
|
258
295
|
| `id` | yes | Unique identifier for the group |
|
|
259
296
|
| `label` | yes | Display name shown as the collapsible group header |
|
|
297
|
+
| `kind` | no | Group kind: `lineage`, `topic`, `family`, `collection`, `default`. Defaults to `default` |
|
|
298
|
+
| `current` | no | For `lineage`: dataset id of the current (newest valid) edition |
|
|
260
299
|
| `description` | no | Short description of the group |
|
|
261
|
-
| `color` | no |
|
|
300
|
+
| `color` | no | Accent color — single hex or `{ light, dark }` pair |
|
|
262
301
|
| `datasets` | yes | Ordered array of dataset IDs belonging to this group |
|
|
263
302
|
| `translations` | no | Localized label and description per language |
|
|
264
303
|
|
|
265
|
-
Datasets not assigned to any group appear at the bottom of the dataset list.
|
|
304
|
+
Datasets not assigned to any group appear at the bottom of the dataset list.
|
|
266
305
|
|
|
267
306
|
### Internationalization
|
|
268
307
|
|
|
@@ -288,6 +327,41 @@ datasetGroups:
|
|
|
288
327
|
|
|
289
328
|
This pattern applies everywhere localized text appears: site-level translations, dataset translations, group translations, and page translations. Do not use language suffixes like `_fra` — use nested language maps instead.
|
|
290
329
|
|
|
330
|
+
### Color system
|
|
331
|
+
|
|
332
|
+
Dataset and group colors accept either a single hex string (backward compat) or a `{ light, dark }` pair:
|
|
333
|
+
|
|
334
|
+
```yaml
|
|
335
|
+
# Single hex (applied to both modes)
|
|
336
|
+
color: "#004996"
|
|
337
|
+
|
|
338
|
+
# Explicit light/dark pair
|
|
339
|
+
color:
|
|
340
|
+
light: "#004996"
|
|
341
|
+
dark: "#3B82F6"
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
Relationship-type colors default from `data/colors.json` but can be overridden per deployment:
|
|
345
|
+
|
|
346
|
+
```yaml
|
|
347
|
+
colors:
|
|
348
|
+
relationshipType:
|
|
349
|
+
supersedes:
|
|
350
|
+
light: "#FF0000"
|
|
351
|
+
dark: "#FF5555"
|
|
352
|
+
dataset:
|
|
353
|
+
viml-2022:
|
|
354
|
+
light: "#004996"
|
|
355
|
+
dark: "#3B82F6"
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
CSS variables are emitted on document root by `useColorTheme()`:
|
|
359
|
+
- `--rel-{category}-{light|dark}` per relationship category
|
|
360
|
+
- `--rel-type-{type}-{light|dark}` per relationship type
|
|
361
|
+
- `--concept-status-{status}-{light|dark}` per concept status
|
|
362
|
+
- `--group-kind-{kind}-{light|dark}` per group kind
|
|
363
|
+
- `--ds-{light|dark}` per dataset (scoped via `[data-ds]`)
|
|
364
|
+
|
|
291
365
|
### Cross-reference mapping
|
|
292
366
|
|
|
293
367
|
```yaml
|
|
@@ -375,30 +449,39 @@ To add a new deployment here, open a PR against this README.
|
|
|
375
449
|
- **Pinia** (state management)
|
|
376
450
|
- **Vue Router** (SPA navigation)
|
|
377
451
|
- **Tailwind CSS 3** (utility-first styling)
|
|
378
|
-
- **D3.js** (force-directed graph)
|
|
452
|
+
- **D3.js** (force-directed graph + relation sphere)
|
|
379
453
|
- **KaTeX** (math rendering)
|
|
454
|
+
- **n3** + **rdf-validate-shacl** (RDF parsing + SHACL validation)
|
|
455
|
+
- **fast-check** (property-based fuzz testing)
|
|
456
|
+
- **Vitest** with happy-dom
|
|
380
457
|
|
|
381
458
|
### Project structure
|
|
382
459
|
|
|
383
460
|
```
|
|
384
461
|
src/
|
|
385
462
|
├── adapters/ Data access layer (DatasetAdapter, AdapterFactory, UriRouter)
|
|
386
|
-
├── components/ Vue components (AppSidebar,
|
|
463
|
+
├── components/ Vue components (AppSidebar, ConceptDetail, RelationSphere, etc.)
|
|
464
|
+
│ ├── concept-rdf/ RDF graph IR + emitters + writers (concept, dataset, group, vocab, etc.)
|
|
465
|
+
│ └── groups/ OCP group renderer dispatcher + per-kind sidebar components
|
|
466
|
+
├── composables/ Vue composables (useDatasetSeries, useColorTheme, useSphereProjection)
|
|
467
|
+
├── config/ Site config types, group-types registry, group-renderers registry
|
|
468
|
+
├── data/ Static data (taxonomies.json, colors.json, concept-model shapes)
|
|
387
469
|
├── graph/ Graph engine for concept relationships
|
|
388
470
|
├── stores/ Pinia stores (vocabulary, ui)
|
|
389
|
-
├── views/ Page-level components (HomeView, DatasetView, ConceptView,
|
|
471
|
+
├── views/ Page-level components (HomeView, DatasetView, ConceptView, GroupView)
|
|
390
472
|
├── i18n/ Internationalization (YAML locale files, auto-discovered)
|
|
391
|
-
|
|
392
|
-
└── style.css Global styles and Tailwind layers
|
|
473
|
+
└── utils/ Utilities (color-theme, dataset-style, relationship-categories, content-renderer)
|
|
393
474
|
|
|
394
475
|
cli/
|
|
395
|
-
└── index.mjs CLI entry point (fetch, generate, edges, build
|
|
476
|
+
└── index.mjs CLI entry point (fetch, generate, edges, build, doctor, normalize)
|
|
396
477
|
|
|
397
478
|
scripts/
|
|
398
|
-
├── fetch-datasets.mjs
|
|
399
|
-
├── generate-data.mjs
|
|
400
|
-
├── build-edges.js
|
|
401
|
-
|
|
479
|
+
├── fetch-datasets.mjs Clone + harmonize source repos
|
|
480
|
+
├── generate-data.mjs Convert YAML → JSON-LD + RDF artifacts
|
|
481
|
+
├── build-edges.js Extract cross-reference edges
|
|
482
|
+
├── process-about-pages.mjs Compile markdown/AsciiDoc about pages
|
|
483
|
+
├── validate-shacl.mjs SHACL validation gate
|
|
484
|
+
└── lib/ Build-time emitters (vocab, dataset, group, agents, version, etc.)
|
|
402
485
|
```
|
|
403
486
|
|
|
404
487
|
---
|
|
@@ -418,8 +501,17 @@ UI translations are YAML files in `src/i18n/locales/`, auto-discovered via `impo
|
|
|
418
501
|
```bash
|
|
419
502
|
npm test # Run all tests (Vitest with happy-dom)
|
|
420
503
|
npm run test:watch # Watch mode
|
|
504
|
+
npm run mutation:test # Stryker mutation testing (scoped to RDF emitters, ~3-5 min)
|
|
421
505
|
```
|
|
422
506
|
|
|
507
|
+
Test coverage includes:
|
|
508
|
+
- 1357+ tests across unit, round-trip, SHACL conformance, property-based fuzz, and build-integration layers
|
|
509
|
+
- 7-fixture concept corpus (minimal, multilingual, full-relationships, with-sources, with-non-verbal, with-dates, withdrawn)
|
|
510
|
+
- SHACL conformance gate: all fixtures validated against canonical shapes
|
|
511
|
+
- Property-based fuzz: 200 iterations × 4 invariants via fast-check
|
|
512
|
+
- 10,000-concept scale stress test (< 100ms)
|
|
513
|
+
- Stryker mutation testing scoped to concept/dataset/bibliography emitters
|
|
514
|
+
|
|
423
515
|
---
|
|
424
516
|
|
|
425
517
|
## License
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glossarist/concept-browser",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.56",
|
|
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": {
|
package/src/utils/color-theme.ts
CHANGED
|
@@ -5,13 +5,10 @@
|
|
|
5
5
|
* Pure data + pure accessors — no Vue reactivity. Reactive consumption
|
|
6
6
|
* is via the `useColorTheme()` composable.
|
|
7
7
|
*/
|
|
8
|
-
import
|
|
9
|
-
import { join, dirname } from 'node:path';
|
|
10
|
-
import { fileURLToPath } from 'node:url';
|
|
8
|
+
import colorsJson from '../../data/colors.json';
|
|
11
9
|
import type { DatasetColorSpec, SiteColors } from '../config/types';
|
|
12
10
|
|
|
13
|
-
const
|
|
14
|
-
const COLORS_PATH = join(__dirname, '..', '..', 'data', 'colors.json');
|
|
11
|
+
const COLORS_PATH_RESOLVED = true; /* marker so the import isn't tree-shaken */
|
|
15
12
|
|
|
16
13
|
export interface ColorPair {
|
|
17
14
|
readonly light: string;
|
|
@@ -29,7 +26,8 @@ let cachedDefaults: ColorDefaults | undefined;
|
|
|
29
26
|
|
|
30
27
|
function loadDefaults(): ColorDefaults {
|
|
31
28
|
if (cachedDefaults) return cachedDefaults;
|
|
32
|
-
const raw =
|
|
29
|
+
const raw = colorsJson as any;
|
|
30
|
+
void COLORS_PATH_RESOLVED; /* keep the import meaningful for reviewers */
|
|
33
31
|
cachedDefaults = {
|
|
34
32
|
relationshipCategory: raw.relationshipCategory,
|
|
35
33
|
relationshipType: raw.relationshipType,
|