@eightyfourthousand/data-access 2026.3.0 → 2026.4.0
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 +4 -2
- package/package.json +2 -2
- package/src/index.ts +1 -2
- package/src/lib/folio.ts +23 -9
- package/src/lib/glossary/batch.ts +35 -0
- package/src/lib/glossary/index.ts +4 -0
- package/src/lib/glossary/instance.ts +54 -0
- package/src/lib/glossary/landing.ts +50 -0
- package/src/lib/glossary/pagination.ts +471 -0
- package/src/lib/passage/batch.ts +229 -0
- package/src/lib/passage/index.ts +5 -0
- package/src/lib/passage/pagination.ts +277 -0
- package/src/lib/passage/read.ts +100 -0
- package/src/lib/passage/replace-persistence.ts +153 -0
- package/src/lib/passage/save.ts +324 -0
- package/src/lib/publications.ts +168 -0
- package/src/lib/replace.spec.ts +154 -0
- package/src/lib/replace.ts +244 -0
- package/src/lib/types/folio.ts +2 -2
- package/src/lib/types/glossary-page.ts +0 -118
- package/src/lib/types/glossary.ts +3 -2
- package/src/lib/types/index.ts +0 -3
- package/src/lib/canon.ts +0 -111
- package/src/lib/glossary.ts +0 -147
- package/src/lib/passage.ts +0 -122
- package/src/lib/projects.ts +0 -107
- package/src/lib/types/canon.ts +0 -148
- package/src/lib/types/contributor.ts +0 -84
- package/src/lib/types/project.ts +0 -200
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
# data-access
|
|
1
|
+
# @eightyfourthousand/data-access
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Shared data-access clients, DTO mappers, and domain types for 84000 applications.
|
|
4
|
+
|
|
5
|
+
Use this package for typed access to shared application data models and server/client data helpers.
|
|
4
6
|
|
|
5
7
|
## Running unit tests
|
|
6
8
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eightyfourthousand/data-access",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.4.0",
|
|
4
4
|
"description": "Shared data access clients, DTO mappers, and domain types for 84000 applications.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"repository": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"access": "public"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@eightyfourthousand/lib-utils": "^2026.3.
|
|
20
|
+
"@eightyfourthousand/lib-utils": "^2026.3.1"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
23
|
"next": "^16.0.0",
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export * from './lib/auth';
|
|
2
2
|
export * from './lib/bibliography';
|
|
3
|
-
export * from './lib/canon';
|
|
4
3
|
export * from './lib/client-browser';
|
|
5
4
|
export * from './lib/client-server';
|
|
6
5
|
export * from './lib/client-token';
|
|
@@ -10,8 +9,8 @@ export * from './lib/imprint';
|
|
|
10
9
|
export * from './lib/panel-url';
|
|
11
10
|
export * from './lib/library';
|
|
12
11
|
export * from './lib/passage';
|
|
13
|
-
export * from './lib/projects';
|
|
14
12
|
export * from './lib/publications';
|
|
13
|
+
export * from './lib/replace';
|
|
15
14
|
export * from './lib/storage';
|
|
16
15
|
export * from './lib/types';
|
|
17
16
|
export * from './lib/local-storage';
|
package/src/lib/folio.ts
CHANGED
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
'use server';
|
|
2
2
|
|
|
3
3
|
import { createServerClient } from './client-ssr';
|
|
4
|
-
import { TohokuCatalogEntry } from './types';
|
|
4
|
+
import { DataClient, TohokuCatalogEntry } from './types';
|
|
5
5
|
import { FolioDTO, folioFromDTO } from './types/folio';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
toh,
|
|
10
|
-
page = 0,
|
|
11
|
-
size = 10,
|
|
12
|
-
}: {
|
|
7
|
+
type GetWorkFoliosArgs = {
|
|
8
|
+
client: DataClient;
|
|
13
9
|
uuid: string;
|
|
14
10
|
toh: TohokuCatalogEntry;
|
|
15
11
|
page?: number;
|
|
16
12
|
size?: number;
|
|
17
|
-
}
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const getWorkFolios = async ({
|
|
16
|
+
client,
|
|
17
|
+
uuid,
|
|
18
|
+
toh,
|
|
19
|
+
page = 0,
|
|
20
|
+
size = 10,
|
|
21
|
+
}: GetWorkFoliosArgs) => {
|
|
18
22
|
const start = page * size;
|
|
19
23
|
const end = start + size - 1;
|
|
20
|
-
const client = await createServerClient();
|
|
21
24
|
const { data, error } = await client
|
|
22
25
|
.from('tibetan_works_folios')
|
|
23
26
|
.select(
|
|
@@ -30,6 +33,7 @@ export const getFolios = async ({
|
|
|
30
33
|
)
|
|
31
34
|
.eq('work_uuid', uuid)
|
|
32
35
|
.eq('toh', toh)
|
|
36
|
+
.order('volume_number', { ascending: true })
|
|
33
37
|
.order('folio_number', { ascending: true })
|
|
34
38
|
.order('side', { ascending: true })
|
|
35
39
|
.range(start, end);
|
|
@@ -41,3 +45,13 @@ export const getFolios = async ({
|
|
|
41
45
|
|
|
42
46
|
return data.map((dto) => folioFromDTO(dto as FolioDTO));
|
|
43
47
|
};
|
|
48
|
+
|
|
49
|
+
export const getFolios = async ({
|
|
50
|
+
uuid,
|
|
51
|
+
toh,
|
|
52
|
+
page = 0,
|
|
53
|
+
size = 10,
|
|
54
|
+
}: Omit<GetWorkFoliosArgs, 'client'>) => {
|
|
55
|
+
const client = await createServerClient();
|
|
56
|
+
return getWorkFolios({ client, uuid, toh, page, size });
|
|
57
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { DataClient } from '../types';
|
|
2
|
+
|
|
3
|
+
export const getGlossaryDisplayNamesByUuids = async ({
|
|
4
|
+
client,
|
|
5
|
+
glossaryUuids,
|
|
6
|
+
}: {
|
|
7
|
+
client: DataClient;
|
|
8
|
+
glossaryUuids: readonly string[];
|
|
9
|
+
}): Promise<Map<string, string>> => {
|
|
10
|
+
const namesByUuid = new Map<string, string>();
|
|
11
|
+
if (glossaryUuids.length === 0) return namesByUuid;
|
|
12
|
+
|
|
13
|
+
const { data, error } = await client
|
|
14
|
+
.from('glossaries')
|
|
15
|
+
.select('uuid, names:names!name_uuid(content)')
|
|
16
|
+
.in('uuid', glossaryUuids as string[]);
|
|
17
|
+
|
|
18
|
+
if (error) {
|
|
19
|
+
console.error('Error batch loading glossary names:', error);
|
|
20
|
+
return namesByUuid;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
for (const glossary of data ?? []) {
|
|
24
|
+
const names = glossary.names as unknown as
|
|
25
|
+
| { content: string }
|
|
26
|
+
| { content: string }[]
|
|
27
|
+
| null;
|
|
28
|
+
const content = Array.isArray(names) ? names[0]?.content : names?.content;
|
|
29
|
+
if (content) {
|
|
30
|
+
namesByUuid.set(glossary.uuid, content);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return namesByUuid;
|
|
35
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DataClient,
|
|
3
|
+
GlossaryTermInstanceDTO,
|
|
4
|
+
GlossaryTermInstancesDTO,
|
|
5
|
+
glossaryTermInstanceFromDTO,
|
|
6
|
+
} from '../types';
|
|
7
|
+
|
|
8
|
+
export const getGlossaryInstances = async ({
|
|
9
|
+
client,
|
|
10
|
+
uuid,
|
|
11
|
+
withAttestations = false,
|
|
12
|
+
}: {
|
|
13
|
+
client: DataClient;
|
|
14
|
+
uuid: string;
|
|
15
|
+
withAttestations?: boolean;
|
|
16
|
+
}) => {
|
|
17
|
+
const { data, error } = await client.rpc('show_glossary_entries', {
|
|
18
|
+
v_work_uuid: uuid,
|
|
19
|
+
v_with_attestation: withAttestations,
|
|
20
|
+
});
|
|
21
|
+
if (error) {
|
|
22
|
+
console.error(
|
|
23
|
+
`Error fetching glossary instances for work: ${uuid} `,
|
|
24
|
+
error,
|
|
25
|
+
);
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const dto = data as GlossaryTermInstancesDTO;
|
|
30
|
+
return dto.glossary_entries.map(glossaryTermInstanceFromDTO).sort((a, b) => {
|
|
31
|
+
const nameA = a.names.english || '';
|
|
32
|
+
const nameB = b.names.english || '';
|
|
33
|
+
return nameA.localeCompare(nameB);
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const getGlossaryInstance = async ({
|
|
38
|
+
client,
|
|
39
|
+
uuid,
|
|
40
|
+
}: {
|
|
41
|
+
client: DataClient;
|
|
42
|
+
uuid: string;
|
|
43
|
+
}) => {
|
|
44
|
+
const { data, error } = await client.rpc('show_glossary_entry', {
|
|
45
|
+
v_glossary_uuid: uuid,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
if (error) {
|
|
49
|
+
console.error(`Error fetching glossary instance: ${uuid} `, error);
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return glossaryTermInstanceFromDTO(data as GlossaryTermInstanceDTO);
|
|
54
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DataClient,
|
|
3
|
+
GlossaryLandingItem,
|
|
4
|
+
GlossaryLandingItemDTO,
|
|
5
|
+
glossaryLandingItemFromDTO,
|
|
6
|
+
} from '../types';
|
|
7
|
+
|
|
8
|
+
export const getAllGlossaryTerms = async ({
|
|
9
|
+
client,
|
|
10
|
+
uuids,
|
|
11
|
+
}: {
|
|
12
|
+
client: DataClient;
|
|
13
|
+
uuids?: string[];
|
|
14
|
+
}): Promise<GlossaryLandingItem[]> => {
|
|
15
|
+
const pageSize = 1000;
|
|
16
|
+
let start = 0;
|
|
17
|
+
let end = pageSize - 1;
|
|
18
|
+
let count = pageSize;
|
|
19
|
+
const terms: GlossaryLandingItem[] = [];
|
|
20
|
+
|
|
21
|
+
while (count === pageSize) {
|
|
22
|
+
let rpc = client.rpc('scholar_glossary_get_all');
|
|
23
|
+
|
|
24
|
+
if (uuids?.length) {
|
|
25
|
+
rpc = rpc.in('authority_uuid', uuids);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const { data, error } = await rpc.range(start, end);
|
|
29
|
+
|
|
30
|
+
if (error) {
|
|
31
|
+
console.error('Error fetching glossary terms:', error);
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
if (!data || !data.length) {
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const dtos = data as GlossaryLandingItemDTO[];
|
|
39
|
+
const items = dtos
|
|
40
|
+
.map((item) => glossaryLandingItemFromDTO(item as GlossaryLandingItemDTO))
|
|
41
|
+
.flatMap((item) => (item ? [item] : []));
|
|
42
|
+
|
|
43
|
+
terms.push(...items);
|
|
44
|
+
start += pageSize;
|
|
45
|
+
end += pageSize;
|
|
46
|
+
count = data.length;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return terms;
|
|
50
|
+
};
|