@glossarist/concept-browser 0.7.7 → 0.7.8
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glossarist/concept-browser",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.8",
|
|
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": {
|
|
@@ -679,10 +679,11 @@ function processDataset(dir, register, opts) {
|
|
|
679
679
|
}));
|
|
680
680
|
|
|
681
681
|
const graphNodeEntries = concepts.map(c => {
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
682
|
+
const cleanDesignations = {};
|
|
683
|
+
for (const [l, t] of Object.entries(c.designations)) {
|
|
684
|
+
if (t) cleanDesignations[l] = t.replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').trim();
|
|
685
|
+
}
|
|
686
|
+
return [c.id, cleanDesignations, c.status];
|
|
686
687
|
});
|
|
687
688
|
fs.mkdirSync(path.join(DATA, register), { recursive: true });
|
|
688
689
|
fs.writeFileSync(
|
|
@@ -61,9 +61,9 @@ describe('DatasetAdapter', () => {
|
|
|
61
61
|
chunkSize: 500,
|
|
62
62
|
chunks: [],
|
|
63
63
|
concepts: [
|
|
64
|
-
{ id: '102-01-01', eng: 'equality', status: 'Standard' },
|
|
65
|
-
{ id: '102-01-02', eng: 'inequality', status: 'Standard' },
|
|
66
|
-
{ id: '103-01-02', eng: 'functional', status: 'Standard' },
|
|
64
|
+
{ id: '102-01-01', designations: { eng: 'equality' }, eng: 'equality', status: 'Standard' },
|
|
65
|
+
{ id: '102-01-02', designations: { eng: 'inequality' }, eng: 'inequality', status: 'Standard' },
|
|
66
|
+
{ id: '103-01-02', designations: { eng: 'functional' }, eng: 'functional', status: 'Standard' },
|
|
67
67
|
],
|
|
68
68
|
};
|
|
69
69
|
mockFetch.mockReturnValue(mockJsonResponse(index));
|
|
@@ -128,9 +128,9 @@ describe('DatasetAdapter', () => {
|
|
|
128
128
|
chunkSize: 500,
|
|
129
129
|
chunks: [],
|
|
130
130
|
concepts: [
|
|
131
|
-
{ id: '102-01-01', eng: 'equality', status: 'Standard' },
|
|
132
|
-
{ id: '102-01-02', eng: 'inequality', status: 'Standard' },
|
|
133
|
-
{ id: '103-01-02', eng: 'functional', status: 'Standard' },
|
|
131
|
+
{ id: '102-01-01', designations: { eng: 'equality' }, eng: 'equality', status: 'Standard' },
|
|
132
|
+
{ id: '102-01-02', designations: { eng: 'inequality' }, eng: 'inequality', status: 'Standard' },
|
|
133
|
+
{ id: '103-01-02', designations: { eng: 'functional' }, eng: 'functional', status: 'Standard' },
|
|
134
134
|
],
|
|
135
135
|
};
|
|
136
136
|
mockFetch.mockReturnValue(mockJsonResponse(index));
|
|
@@ -150,7 +150,7 @@ describe('DatasetAdapter', () => {
|
|
|
150
150
|
chunkSize: 500,
|
|
151
151
|
chunks: [],
|
|
152
152
|
concepts: [
|
|
153
|
-
{ id: '103-01-02', eng: 'functional', status: 'Standard' },
|
|
153
|
+
{ id: '103-01-02', designations: { eng: 'functional' }, eng: 'functional', status: 'Standard' },
|
|
154
154
|
],
|
|
155
155
|
};
|
|
156
156
|
mockFetch.mockReturnValue(mockJsonResponse(index));
|
|
@@ -169,7 +169,7 @@ describe('DatasetAdapter', () => {
|
|
|
169
169
|
chunkSize: 500,
|
|
170
170
|
chunks: [],
|
|
171
171
|
concepts: [
|
|
172
|
-
{ id: '102-01-01', eng: 'Equality', status: 'Standard' },
|
|
172
|
+
{ id: '102-01-01', designations: { eng: 'Equality' }, eng: 'Equality', status: 'Standard' },
|
|
173
173
|
],
|
|
174
174
|
};
|
|
175
175
|
mockFetch.mockReturnValue(mockJsonResponse(index));
|
|
@@ -187,7 +187,7 @@ describe('DatasetAdapter', () => {
|
|
|
187
187
|
chunkSize: 500,
|
|
188
188
|
chunks: [],
|
|
189
189
|
concepts: [
|
|
190
|
-
{ id: '102-01-01', eng: 'equality', status: 'Standard' },
|
|
190
|
+
{ id: '102-01-01', designations: { eng: 'equality' }, eng: 'equality', status: 'Standard' },
|
|
191
191
|
],
|
|
192
192
|
};
|
|
193
193
|
mockFetch.mockReturnValue(mockJsonResponse(index));
|
|
@@ -26,6 +26,9 @@ describe('GraphView', () => {
|
|
|
26
26
|
pinia = createPinia();
|
|
27
27
|
setActivePinia(pinia);
|
|
28
28
|
router = await createTestRouter();
|
|
29
|
+
// Mark store as initialized so loadAllGraphData skips discoverDatasets
|
|
30
|
+
const store = useVocabularyStore();
|
|
31
|
+
store.initialized = true;
|
|
29
32
|
});
|
|
30
33
|
|
|
31
34
|
function mountGraph() {
|
|
@@ -69,23 +69,12 @@ export class DatasetAdapter {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
private normalizeIndex(data: any): ConceptIndex {
|
|
72
|
-
const concepts: ConceptSummary[] = (data.concepts || []).map((c: any) => {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
status: c.status,
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
// Legacy format: c.eng is a string, no designations map
|
|
82
|
-
return {
|
|
83
|
-
id: c.id,
|
|
84
|
-
designations: c.eng ? { eng: c.eng } : {},
|
|
85
|
-
eng: c.eng || '',
|
|
86
|
-
status: c.status,
|
|
87
|
-
};
|
|
88
|
-
});
|
|
72
|
+
const concepts: ConceptSummary[] = (data.concepts || []).map((c: any) => ({
|
|
73
|
+
id: c.id,
|
|
74
|
+
designations: c.designations || {},
|
|
75
|
+
eng: c.eng || c.designations?.eng || Object.values(c.designations || {})[0] || '',
|
|
76
|
+
status: c.status,
|
|
77
|
+
}));
|
|
89
78
|
|
|
90
79
|
return {
|
|
91
80
|
registerId: data.registerId,
|
|
@@ -391,7 +380,7 @@ export class DatasetAdapter {
|
|
|
391
380
|
return data.edges ?? [];
|
|
392
381
|
}
|
|
393
382
|
|
|
394
|
-
async loadGraphNodes(): Promise<{ uriPrefix: string; nodes: [string, string, string
|
|
383
|
+
async loadGraphNodes(): Promise<{ uriPrefix: string; nodes: [string, Record<string, string>, string][] }> {
|
|
395
384
|
const resp = await fetch(`${this.baseUrl}/graph-nodes.json`);
|
|
396
385
|
if (!resp.ok) return { uriPrefix: '', nodes: [] };
|
|
397
386
|
return await resp.json();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { useRouter } from 'vue-router';
|
|
2
|
+
import { useRouter, useRoute } from 'vue-router';
|
|
3
3
|
import { useUiStore } from '../stores/ui';
|
|
4
4
|
import { useVocabularyStore } from '../stores/vocabulary';
|
|
5
5
|
import { ref, watch, onMounted, computed, nextTick } from 'vue';
|
|
@@ -9,6 +9,7 @@ import { useDsStyle } from '../utils/dataset-style';
|
|
|
9
9
|
import { useI18n } from '../i18n';
|
|
10
10
|
|
|
11
11
|
const router = useRouter();
|
|
12
|
+
const route = useRoute();
|
|
12
13
|
const ui = useUiStore();
|
|
13
14
|
const store = useVocabularyStore();
|
|
14
15
|
const { getStyle } = useDsStyle();
|
|
@@ -37,7 +38,9 @@ async function doSearch() {
|
|
|
37
38
|
}
|
|
38
39
|
searched.value = true;
|
|
39
40
|
selectedIdx.value = -1;
|
|
40
|
-
|
|
41
|
+
if (route.query.q !== q) {
|
|
42
|
+
router.replace({ query: { q } });
|
|
43
|
+
}
|
|
41
44
|
}
|
|
42
45
|
|
|
43
46
|
function onInput() {
|
package/src/stores/vocabulary.ts
CHANGED
|
@@ -140,6 +140,10 @@ export const useVocabularyStore = defineStore('vocabulary', () => {
|
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
async function loadAllGraphData() {
|
|
143
|
+
if (!initialized.value) {
|
|
144
|
+
await discoverDatasets();
|
|
145
|
+
}
|
|
146
|
+
|
|
143
147
|
const engine = toRaw(graph.value);
|
|
144
148
|
const adapters = factory.getAdapters();
|
|
145
149
|
|
|
@@ -155,13 +159,13 @@ export const useVocabularyStore = defineStore('vocabulary', () => {
|
|
|
155
159
|
|
|
156
160
|
if (nodeResult.status === 'fulfilled') {
|
|
157
161
|
const { uriPrefix, nodes } = nodeResult.value;
|
|
158
|
-
for (const [id,
|
|
162
|
+
for (const [id, designations, status] of nodes) {
|
|
159
163
|
engine.addNode({
|
|
160
164
|
uri: uriPrefix + id,
|
|
161
165
|
register: adapter.registerId,
|
|
162
166
|
conceptId: id,
|
|
163
|
-
designations:
|
|
164
|
-
status,
|
|
167
|
+
designations: designations || {},
|
|
168
|
+
status: status || 'unknown',
|
|
165
169
|
loaded: false,
|
|
166
170
|
});
|
|
167
171
|
}
|
|
@@ -296,9 +300,16 @@ export const useVocabularyStore = defineStore('vocabulary', () => {
|
|
|
296
300
|
}
|
|
297
301
|
|
|
298
302
|
async function searchAcrossDatasets(query: string): Promise<SearchHit[]> {
|
|
303
|
+
if (!initialized.value) {
|
|
304
|
+
await discoverDatasets();
|
|
305
|
+
}
|
|
306
|
+
|
|
299
307
|
const allHits: SearchHit[] = [];
|
|
300
308
|
for (const adapter of datasets.value.values()) {
|
|
301
|
-
if (adapter.
|
|
309
|
+
if (adapter.manifest) {
|
|
310
|
+
if (!adapter.index) {
|
|
311
|
+
await adapter.loadIndex();
|
|
312
|
+
}
|
|
302
313
|
await adapter.ensureAllChunksLoaded();
|
|
303
314
|
allHits.push(...adapter.search(query));
|
|
304
315
|
}
|