@eightyfourthousand/data-access 2026.4.0 → 2026.4.2
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/index.js +18 -0
- package/index.js.map +1 -0
- package/lib/auth.d.ts +59 -0
- package/lib/auth.js +134 -0
- package/lib/auth.js.map +1 -0
- package/lib/bibliography.d.ts +9 -0
- package/lib/bibliography.js +30 -0
- package/lib/bibliography.js.map +1 -0
- package/lib/client-browser.d.ts +1 -0
- package/lib/client-browser.js +10 -0
- package/lib/client-browser.js.map +1 -0
- package/lib/client-server.d.ts +4 -0
- package/lib/client-server.js +19 -0
- package/lib/client-server.js.map +1 -0
- package/lib/client-ssr.d.ts +1 -0
- package/lib/client-ssr.js +23 -0
- package/lib/client-ssr.js.map +1 -0
- package/lib/client-token.d.ts +7 -0
- package/lib/client-token.js +21 -0
- package/lib/client-token.js.map +1 -0
- package/lib/feedback.d.ts +6 -0
- package/lib/feedback.js +45 -0
- package/lib/feedback.js.map +1 -0
- package/lib/folio.d.ts +11 -0
- package/lib/folio.js +31 -0
- package/lib/folio.js.map +1 -0
- package/lib/glossary/batch.d.ts +5 -0
- package/lib/glossary/batch.js +22 -0
- package/lib/glossary/batch.js.map +1 -0
- package/lib/glossary/index.js +5 -0
- package/lib/glossary/index.js.map +1 -0
- package/lib/glossary/instance.d.ts +10 -0
- package/lib/glossary/instance.js +28 -0
- package/lib/glossary/instance.js.map +1 -0
- package/lib/glossary/landing.d.ts +5 -0
- package/lib/glossary/landing.js +32 -0
- package/lib/glossary/landing.js.map +1 -0
- package/lib/glossary/pagination.d.ts +55 -0
- package/lib/glossary/pagination.js +254 -0
- package/lib/glossary/pagination.js.map +1 -0
- package/lib/imprint.d.ts +10 -0
- package/lib/imprint.js +23 -0
- package/lib/imprint.js.map +1 -0
- package/lib/library.d.ts +58 -0
- package/lib/library.js +118 -0
- package/lib/library.js.map +1 -0
- package/lib/local-storage.d.ts +10 -0
- package/lib/local-storage.js +25 -0
- package/lib/local-storage.js.map +1 -0
- package/lib/lookup-entity.d.ts +7 -0
- package/lib/lookup-entity.js +93 -0
- package/lib/lookup-entity.js.map +1 -0
- package/lib/panel-url.d.ts +10 -0
- package/lib/panel-url.js +23 -0
- package/lib/panel-url.js.map +1 -0
- package/lib/passage/batch.d.ts +17 -0
- package/lib/passage/batch.js +155 -0
- package/lib/passage/batch.js.map +1 -0
- package/lib/passage/index.js +6 -0
- package/lib/passage/index.js.map +1 -0
- package/lib/passage/pagination.d.ts +43 -0
- package/lib/passage/pagination.js +167 -0
- package/lib/passage/pagination.js.map +1 -0
- package/lib/passage/read.d.ts +15 -0
- package/lib/passage/read.js +59 -0
- package/lib/passage/read.js.map +1 -0
- package/lib/passage/replace-persistence.d.ts +46 -0
- package/lib/passage/replace-persistence.js +93 -0
- package/lib/passage/replace-persistence.js.map +1 -0
- package/lib/passage/save.d.ts +16 -0
- package/lib/passage/save.js +227 -0
- package/lib/passage/save.js.map +1 -0
- package/lib/proxy.d.ts +7 -0
- package/lib/proxy.js +45 -0
- package/lib/proxy.js.map +1 -0
- package/lib/publications.d.ts +86 -0
- package/lib/publications.js +223 -0
- package/lib/publications.js.map +1 -0
- package/lib/replace.d.ts +31 -0
- package/lib/replace.js +151 -0
- package/lib/replace.js.map +1 -0
- package/lib/storage.d.ts +7 -0
- package/lib/storage.js +10 -0
- package/lib/storage.js.map +1 -0
- package/lib/types/alignment.d.ts +18 -0
- package/lib/types/alignment.js +13 -0
- package/lib/types/alignment.js.map +1 -0
- package/lib/types/annotation/abbreviation.d.ts +3 -0
- package/lib/types/annotation/abbreviation.js +20 -0
- package/lib/types/annotation/abbreviation.js.map +1 -0
- package/lib/types/annotation/annotation-type.d.ts +31 -0
- package/lib/types/annotation/annotation-type.js +81 -0
- package/lib/types/annotation/annotation-type.js.map +1 -0
- package/lib/types/annotation/annotation.d.ts +142 -0
- package/lib/types/annotation/annotation.js +23 -0
- package/lib/types/annotation/annotation.js.map +1 -0
- package/lib/types/annotation/audio.d.ts +3 -0
- package/lib/types/annotation/audio.js +24 -0
- package/lib/types/annotation/audio.js.map +1 -0
- package/lib/types/annotation/blockquote.d.ts +3 -0
- package/lib/types/annotation/blockquote.js +8 -0
- package/lib/types/annotation/blockquote.js.map +1 -0
- package/lib/types/annotation/code.d.ts +3 -0
- package/lib/types/annotation/code.js +8 -0
- package/lib/types/annotation/code.js.map +1 -0
- package/lib/types/annotation/deprecated.d.ts +3 -0
- package/lib/types/annotation/deprecated.js +8 -0
- package/lib/types/annotation/deprecated.js.map +1 -0
- package/lib/types/annotation/end-note-link.d.ts +3 -0
- package/lib/types/annotation/end-note-link.js +23 -0
- package/lib/types/annotation/end-note-link.js.map +1 -0
- package/lib/types/annotation/export.d.ts +3 -0
- package/{src/lib/types/annotation/export.ts → lib/types/annotation/export.js} +34 -36
- package/lib/types/annotation/export.js.map +1 -0
- package/lib/types/annotation/glossary-instance.d.ts +3 -0
- package/lib/types/annotation/glossary-instance.js +23 -0
- package/lib/types/annotation/glossary-instance.js.map +1 -0
- package/lib/types/annotation/has-abbreviation.d.ts +3 -0
- package/lib/types/annotation/has-abbreviation.js +20 -0
- package/lib/types/annotation/has-abbreviation.js.map +1 -0
- package/lib/types/annotation/heading.d.ts +3 -0
- package/lib/types/annotation/heading.js +26 -0
- package/lib/types/annotation/heading.js.map +1 -0
- package/lib/types/annotation/image.d.ts +3 -0
- package/lib/types/annotation/image.js +20 -0
- package/lib/types/annotation/image.js.map +1 -0
- package/lib/types/annotation/indent.d.ts +3 -0
- package/lib/types/annotation/indent.js +8 -0
- package/lib/types/annotation/indent.js.map +1 -0
- package/lib/types/annotation/index.js +5 -0
- package/lib/types/annotation/index.js.map +1 -0
- package/lib/types/annotation/inline-title.d.ts +3 -0
- package/lib/types/annotation/inline-title.js +21 -0
- package/lib/types/annotation/inline-title.js.map +1 -0
- package/lib/types/annotation/internal-link.d.ts +3 -0
- package/lib/types/annotation/internal-link.js +62 -0
- package/lib/types/annotation/internal-link.js.map +1 -0
- package/lib/types/annotation/leading-space.d.ts +3 -0
- package/lib/types/annotation/leading-space.js +8 -0
- package/lib/types/annotation/leading-space.js.map +1 -0
- package/lib/types/annotation/line-group.d.ts +3 -0
- package/lib/types/annotation/line-group.js +8 -0
- package/lib/types/annotation/line-group.js.map +1 -0
- package/lib/types/annotation/line.d.ts +3 -0
- package/lib/types/annotation/line.js +8 -0
- package/lib/types/annotation/line.js.map +1 -0
- package/lib/types/annotation/link.d.ts +3 -0
- package/lib/types/annotation/link.js +27 -0
- package/lib/types/annotation/link.js.map +1 -0
- package/lib/types/annotation/list-item.d.ts +3 -0
- package/lib/types/annotation/list-item.js +8 -0
- package/lib/types/annotation/list-item.js.map +1 -0
- package/lib/types/annotation/list.d.ts +3 -0
- package/lib/types/annotation/list.js +31 -0
- package/lib/types/annotation/list.js.map +1 -0
- package/lib/types/annotation/mantra.d.ts +3 -0
- package/lib/types/annotation/mantra.js +21 -0
- package/lib/types/annotation/mantra.js.map +1 -0
- package/lib/types/annotation/mention.d.ts +3 -0
- package/lib/types/annotation/mention.js +50 -0
- package/lib/types/annotation/mention.js.map +1 -0
- package/lib/types/annotation/paragraph.d.ts +3 -0
- package/lib/types/annotation/paragraph.js +8 -0
- package/lib/types/annotation/paragraph.js.map +1 -0
- package/lib/types/annotation/quote.d.ts +3 -0
- package/lib/types/annotation/quote.js +21 -0
- package/lib/types/annotation/quote.js.map +1 -0
- package/lib/types/annotation/quoted.d.ts +3 -0
- package/lib/types/annotation/quoted.js +21 -0
- package/lib/types/annotation/quoted.js.map +1 -0
- package/lib/types/annotation/reference.d.ts +3 -0
- package/lib/types/annotation/reference.js +8 -0
- package/lib/types/annotation/reference.js.map +1 -0
- package/lib/types/annotation/span.d.ts +3 -0
- package/lib/types/annotation/span.js +29 -0
- package/lib/types/annotation/span.js.map +1 -0
- package/lib/types/annotation/table-body-data.d.ts +3 -0
- package/lib/types/annotation/table-body-data.js +8 -0
- package/lib/types/annotation/table-body-data.js.map +1 -0
- package/lib/types/annotation/table-body-header.d.ts +3 -0
- package/lib/types/annotation/table-body-header.js +8 -0
- package/lib/types/annotation/table-body-header.js.map +1 -0
- package/lib/types/annotation/table-body-row.d.ts +3 -0
- package/lib/types/annotation/table-body-row.js +8 -0
- package/lib/types/annotation/table-body-row.js.map +1 -0
- package/lib/types/annotation/table.d.ts +3 -0
- package/lib/types/annotation/table.js +8 -0
- package/lib/types/annotation/table.js.map +1 -0
- package/lib/types/annotation/trailer.d.ts +3 -0
- package/lib/types/annotation/trailer.js +8 -0
- package/lib/types/annotation/trailer.js.map +1 -0
- package/lib/types/annotation/transform.d.ts +6 -0
- package/lib/types/annotation/transform.js +109 -0
- package/lib/types/annotation/transform.js.map +1 -0
- package/lib/types/annotation/unknown.d.ts +3 -0
- package/lib/types/annotation/unknown.js +8 -0
- package/lib/types/annotation/unknown.js.map +1 -0
- package/lib/types/bibliography.d.ts +41 -0
- package/lib/types/bibliography.js +29 -0
- package/lib/types/bibliography.js.map +1 -0
- package/{src/lib/types/client.ts → lib/types/client.d.ts} +0 -1
- package/lib/types/client.js +2 -0
- package/lib/types/client.js.map +1 -0
- package/{src/lib/types/editor-content.ts → lib/types/editor-content.d.ts} +7 -11
- package/lib/types/editor-content.js +2 -0
- package/lib/types/editor-content.js.map +1 -0
- package/lib/types/folio.d.ts +17 -0
- package/lib/types/folio.js +11 -0
- package/lib/types/folio.js.map +1 -0
- package/lib/types/glossary-page.d.ts +48 -0
- package/lib/types/glossary-page.js +21 -0
- package/lib/types/glossary-page.js.map +1 -0
- package/lib/types/glossary.d.ts +76 -0
- package/lib/types/glossary.js +32 -0
- package/lib/types/glossary.js.map +1 -0
- package/lib/types/imprint.d.ts +78 -0
- package/lib/types/imprint.js +78 -0
- package/lib/types/imprint.js.map +1 -0
- package/lib/types/index.js +20 -0
- package/lib/types/index.js.map +1 -0
- package/lib/types/language.d.ts +9 -0
- package/lib/types/language.js +41 -0
- package/lib/types/language.js.map +1 -0
- package/lib/types/layout.d.ts +5 -0
- package/lib/types/layout.js +23 -0
- package/lib/types/layout.js.map +1 -0
- package/lib/types/library.d.ts +19 -0
- package/lib/types/library.js +8 -0
- package/lib/types/library.js.map +1 -0
- package/lib/types/passage.d.ts +73 -0
- package/lib/types/passage.js +123 -0
- package/lib/types/passage.js.map +1 -0
- package/lib/types/semver.js +2 -0
- package/lib/types/semver.js.map +1 -0
- package/lib/types/title.d.ts +21 -0
- package/lib/types/title.js +21 -0
- package/lib/types/title.js.map +1 -0
- package/lib/types/toh.js +2 -0
- package/lib/types/toh.js.map +1 -0
- package/{src/lib/types/translation.ts → lib/types/translation.d.ts} +5 -7
- package/lib/types/translation.js +2 -0
- package/lib/types/translation.js.map +1 -0
- package/{src/lib/types/user.ts → lib/types/user.d.ts} +2 -11
- package/lib/types/user.js +9 -0
- package/lib/types/user.js.map +1 -0
- package/lib/types/work.d.ts +37 -0
- package/lib/types/work.js +12 -0
- package/lib/types/work.js.map +1 -0
- package/lib/use-bookmark.d.ts +10 -0
- package/lib/use-bookmark.js +30 -0
- package/lib/use-bookmark.js.map +1 -0
- package/package.json +25 -3
- package/ssr.js +6 -0
- package/ssr.js.map +1 -0
- package/.babelrc +0 -12
- package/.eslintrc.json +0 -18
- package/README.md +0 -9
- package/jest.config.ts +0 -10
- package/project.json +0 -21
- package/src/lib/auth.ts +0 -203
- package/src/lib/bibliography.ts +0 -57
- package/src/lib/client-browser.ts +0 -12
- package/src/lib/client-server.ts +0 -30
- package/src/lib/client-ssr.ts +0 -24
- package/src/lib/client-token.ts +0 -24
- package/src/lib/feedback.ts +0 -71
- package/src/lib/folio.ts +0 -57
- package/src/lib/glossary/batch.ts +0 -35
- package/src/lib/glossary/instance.ts +0 -54
- package/src/lib/glossary/landing.ts +0 -50
- package/src/lib/glossary/pagination.ts +0 -471
- package/src/lib/imprint.ts +0 -42
- package/src/lib/library.ts +0 -209
- package/src/lib/local-storage.ts +0 -33
- package/src/lib/lookup-entity.ts +0 -122
- package/src/lib/panel-url.ts +0 -43
- package/src/lib/passage/batch.ts +0 -229
- package/src/lib/passage/pagination.ts +0 -277
- package/src/lib/passage/read.ts +0 -100
- package/src/lib/passage/replace-persistence.ts +0 -153
- package/src/lib/passage/save.ts +0 -324
- package/src/lib/proxy.ts +0 -68
- package/src/lib/publications.ts +0 -381
- package/src/lib/replace.spec.ts +0 -154
- package/src/lib/replace.ts +0 -244
- package/src/lib/storage.ts +0 -23
- package/src/lib/types/alignment.ts +0 -32
- package/src/lib/types/annotation/abbreviation.ts +0 -30
- package/src/lib/types/annotation/annotation-type.ts +0 -219
- package/src/lib/types/annotation/annotation.ts +0 -244
- package/src/lib/types/annotation/audio.ts +0 -33
- package/src/lib/types/annotation/blockquote.ts +0 -18
- package/src/lib/types/annotation/code.ts +0 -16
- package/src/lib/types/annotation/deprecated.ts +0 -18
- package/src/lib/types/annotation/end-note-link.ts +0 -35
- package/src/lib/types/annotation/glossary-instance.ts +0 -34
- package/src/lib/types/annotation/has-abbreviation.ts +0 -30
- package/src/lib/types/annotation/heading.ts +0 -37
- package/src/lib/types/annotation/image.ts +0 -29
- package/src/lib/types/annotation/indent.ts +0 -16
- package/src/lib/types/annotation/inline-title.ts +0 -34
- package/src/lib/types/annotation/internal-link.ts +0 -86
- package/src/lib/types/annotation/leading-space.ts +0 -18
- package/src/lib/types/annotation/line-group.ts +0 -18
- package/src/lib/types/annotation/line.ts +0 -16
- package/src/lib/types/annotation/link.ts +0 -38
- package/src/lib/types/annotation/list-item.ts +0 -16
- package/src/lib/types/annotation/list.ts +0 -43
- package/src/lib/types/annotation/mantra.ts +0 -31
- package/src/lib/types/annotation/mention.ts +0 -64
- package/src/lib/types/annotation/paragraph.ts +0 -18
- package/src/lib/types/annotation/quote.ts +0 -30
- package/src/lib/types/annotation/quoted.ts +0 -30
- package/src/lib/types/annotation/reference.ts +0 -18
- package/src/lib/types/annotation/span.ts +0 -39
- package/src/lib/types/annotation/table-body-data.ts +0 -18
- package/src/lib/types/annotation/table-body-header.ts +0 -18
- package/src/lib/types/annotation/table-body-row.ts +0 -18
- package/src/lib/types/annotation/table.ts +0 -16
- package/src/lib/types/annotation/trailer.ts +0 -16
- package/src/lib/types/annotation/transform.ts +0 -140
- package/src/lib/types/annotation/unknown.ts +0 -16
- package/src/lib/types/bibliography.ts +0 -86
- package/src/lib/types/folio.ts +0 -28
- package/src/lib/types/glossary-page.ts +0 -86
- package/src/lib/types/glossary.ts +0 -115
- package/src/lib/types/imprint.ts +0 -159
- package/src/lib/types/language.ts +0 -64
- package/src/lib/types/layout.ts +0 -37
- package/src/lib/types/library.ts +0 -29
- package/src/lib/types/passage.ts +0 -220
- package/src/lib/types/title.ts +0 -47
- package/src/lib/types/work.ts +0 -38
- package/src/lib/use-bookmark.ts +0 -45
- package/tsconfig.json +0 -20
- package/tsconfig.lib.json +0 -26
- package/tsconfig.spec.json +0 -22
- /package/{src/index.ts → index.d.ts} +0 -0
- /package/{src/lib/glossary/index.ts → lib/glossary/index.d.ts} +0 -0
- /package/{src/lib/passage/index.ts → lib/passage/index.d.ts} +0 -0
- /package/{src/lib/types/annotation/index.ts → lib/types/annotation/index.d.ts} +0 -0
- /package/{src/lib/types/index.ts → lib/types/index.d.ts} +0 -0
- /package/{src/lib/types/semver.ts → lib/types/semver.d.ts} +0 -0
- /package/{src/lib/types/toh.ts → lib/types/toh.d.ts} +0 -0
- /package/{src/ssr.ts → ssr.d.ts} +0 -0
package/src/lib/local-storage.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
export type BookmarkItem = {
|
|
2
|
-
type: string;
|
|
3
|
-
subType?: string;
|
|
4
|
-
tab: string;
|
|
5
|
-
uuid: string;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
const LIBRARY_KEY = 'library';
|
|
9
|
-
|
|
10
|
-
export function getBookmarks(): BookmarkItem[] {
|
|
11
|
-
try {
|
|
12
|
-
const raw = localStorage.getItem(LIBRARY_KEY);
|
|
13
|
-
if (!raw) return [];
|
|
14
|
-
return JSON.parse(raw) as BookmarkItem[];
|
|
15
|
-
} catch {
|
|
16
|
-
return [];
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function addBookmark(item: BookmarkItem): void {
|
|
21
|
-
const bookmarks = getBookmarks().filter((b) => b.uuid !== item.uuid);
|
|
22
|
-
bookmarks.push(item);
|
|
23
|
-
localStorage.setItem(LIBRARY_KEY, JSON.stringify(bookmarks));
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function removeBookmark(uuid: string): void {
|
|
27
|
-
const bookmarks = getBookmarks().filter((b) => b.uuid !== uuid);
|
|
28
|
-
localStorage.setItem(LIBRARY_KEY, JSON.stringify(bookmarks));
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function isBookmarked(uuid: string): boolean {
|
|
32
|
-
return getBookmarks().some((b) => b.uuid === uuid);
|
|
33
|
-
}
|
package/src/lib/lookup-entity.ts
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { createServerClient } from './client-ssr';
|
|
2
|
-
import { getBibliographyEntry } from './bibliography';
|
|
3
|
-
import { getPassage, getPassageUuidByXmlId } from './passage';
|
|
4
|
-
import {
|
|
5
|
-
getTranslationMetadataByToh,
|
|
6
|
-
getTranslationMetadataByUuid,
|
|
7
|
-
} from './publications';
|
|
8
|
-
import { panelAndTabForContentType } from './panel-url';
|
|
9
|
-
import { getGlossaryInstance } from './glossary';
|
|
10
|
-
|
|
11
|
-
const ALLOWED_TYPES = ['bibliography', 'glossary', 'passage', 'translation', 'work'];
|
|
12
|
-
|
|
13
|
-
export const lookupEntity = async ({
|
|
14
|
-
type,
|
|
15
|
-
entity,
|
|
16
|
-
prefix = '',
|
|
17
|
-
xmlId,
|
|
18
|
-
searchParams,
|
|
19
|
-
}: {
|
|
20
|
-
type: string;
|
|
21
|
-
entity: string;
|
|
22
|
-
prefix?: string;
|
|
23
|
-
xmlId?: string;
|
|
24
|
-
searchParams?: URLSearchParams;
|
|
25
|
-
}) => {
|
|
26
|
-
if (!ALLOWED_TYPES.includes(type)) {
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
const client = await createServerClient();
|
|
30
|
-
let path = '';
|
|
31
|
-
const query = searchParams || new URLSearchParams();
|
|
32
|
-
|
|
33
|
-
switch (type) {
|
|
34
|
-
case 'bibliography':
|
|
35
|
-
{
|
|
36
|
-
const item = await getBibliographyEntry({ client, uuid: entity });
|
|
37
|
-
if (!item?.workUuid || !item.uuid) {
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
query.set('right', `open:bibliography:${item.uuid}`);
|
|
42
|
-
path = `${prefix}/${item.workUuid}?${query.toString()}`;
|
|
43
|
-
}
|
|
44
|
-
break;
|
|
45
|
-
case 'glossary':
|
|
46
|
-
{
|
|
47
|
-
const item = await getGlossaryInstance({ client, uuid: entity });
|
|
48
|
-
if (!item?.workUuid || !item.authority) {
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
query.set('right', `open:glossary:${item.authority}`);
|
|
53
|
-
path = `${prefix}/${item.workUuid}?${query.toString()}`;
|
|
54
|
-
}
|
|
55
|
-
break;
|
|
56
|
-
case 'passage':
|
|
57
|
-
{
|
|
58
|
-
const item = await getPassage({ client, uuid: entity });
|
|
59
|
-
if (!item?.workUuid || !item.uuid) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const queryTab = query.get('tab') || undefined;
|
|
64
|
-
const { panel, tab } = panelAndTabForContentType(item.type, queryTab);
|
|
65
|
-
|
|
66
|
-
query.delete('tab');
|
|
67
|
-
query.set(panel, `open:${tab}:${item.uuid}`);
|
|
68
|
-
if (item.toh) {
|
|
69
|
-
query.set('toh', item.toh);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
path = `${prefix}/${item.workUuid}?${query.toString()}`;
|
|
73
|
-
}
|
|
74
|
-
break;
|
|
75
|
-
case 'translation':
|
|
76
|
-
{
|
|
77
|
-
const toh = entity.replace('.html', '');
|
|
78
|
-
query.set('toh', toh);
|
|
79
|
-
|
|
80
|
-
if (xmlId) {
|
|
81
|
-
const item = await getPassageUuidByXmlId({ client, xmlId });
|
|
82
|
-
const queryTab = query.get('tab') || undefined;
|
|
83
|
-
const { panel, tab } = panelAndTabForContentType(item.type, queryTab);
|
|
84
|
-
|
|
85
|
-
if (item?.uuid && item?.workUuid) {
|
|
86
|
-
const { uuid, workUuid } = item;
|
|
87
|
-
query.delete('tab');
|
|
88
|
-
query.set(panel, `open:${tab}:${uuid}`);
|
|
89
|
-
|
|
90
|
-
path = `${prefix}/${workUuid}?${query.toString()}`;
|
|
91
|
-
return path;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const item = await getTranslationMetadataByToh({ client, toh });
|
|
96
|
-
if (!item?.uuid) {
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
path = `${prefix}/${item.uuid}?${query.toString()}`;
|
|
101
|
-
}
|
|
102
|
-
break;
|
|
103
|
-
case 'work':
|
|
104
|
-
{
|
|
105
|
-
const item = await getTranslationMetadataByUuid({
|
|
106
|
-
client,
|
|
107
|
-
uuid: entity,
|
|
108
|
-
});
|
|
109
|
-
if (!item?.uuid) {
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
path = `${prefix}/${item.uuid}?${query.toString()}`;
|
|
114
|
-
}
|
|
115
|
-
break;
|
|
116
|
-
default: {
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return path;
|
|
122
|
-
};
|
package/src/lib/panel-url.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
PANEL_FOR_CONTENT_SECTION,
|
|
3
|
-
PanelContentType,
|
|
4
|
-
TAB_FOR_CONTENT_SECTION,
|
|
5
|
-
VARIANT_TABS_FOR_TAB,
|
|
6
|
-
} from './types';
|
|
7
|
-
|
|
8
|
-
export const panelAndTabForContentType = (
|
|
9
|
-
contentType: PanelContentType,
|
|
10
|
-
desiredTab?: string,
|
|
11
|
-
): { panel: string; tab: string } => {
|
|
12
|
-
const section = contentType.replace('Header', '');
|
|
13
|
-
const panel = PANEL_FOR_CONTENT_SECTION[section] || 'main';
|
|
14
|
-
const defaultTab = TAB_FOR_CONTENT_SECTION[section] || 'translation';
|
|
15
|
-
const variantTabs = VARIANT_TABS_FOR_TAB[section] || [];
|
|
16
|
-
const tab =
|
|
17
|
-
desiredTab && variantTabs.includes(desiredTab) ? desiredTab : defaultTab;
|
|
18
|
-
|
|
19
|
-
return { panel, tab };
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export const urlForPanelContent = ({
|
|
23
|
-
location,
|
|
24
|
-
hash,
|
|
25
|
-
contentType,
|
|
26
|
-
}: {
|
|
27
|
-
location: Location;
|
|
28
|
-
hash: string;
|
|
29
|
-
contentType?: PanelContentType;
|
|
30
|
-
}): string => {
|
|
31
|
-
const { href, search } = location;
|
|
32
|
-
const baseUrl = new URL(href);
|
|
33
|
-
const searchParams = new URLSearchParams(search);
|
|
34
|
-
|
|
35
|
-
if (!contentType) {
|
|
36
|
-
baseUrl.hash = `#${hash}`;
|
|
37
|
-
return baseUrl.toString();
|
|
38
|
-
}
|
|
39
|
-
const { panel, tab } = panelAndTabForContentType(contentType);
|
|
40
|
-
searchParams.set(panel, `open:${tab}:${hash}`);
|
|
41
|
-
baseUrl.search = searchParams.toString();
|
|
42
|
-
return baseUrl.toString();
|
|
43
|
-
};
|
package/src/lib/passage/batch.ts
DELETED
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AlignmentDTO,
|
|
3
|
-
AnnotationDTO,
|
|
4
|
-
DataClient,
|
|
5
|
-
Passage,
|
|
6
|
-
PassageDTO,
|
|
7
|
-
Passages,
|
|
8
|
-
passageFromDTO,
|
|
9
|
-
} from '../types';
|
|
10
|
-
|
|
11
|
-
export const getAnnotationsByPassageUuids = async ({
|
|
12
|
-
client,
|
|
13
|
-
passageUuids,
|
|
14
|
-
}: {
|
|
15
|
-
client: DataClient;
|
|
16
|
-
passageUuids: readonly string[];
|
|
17
|
-
}): Promise<Map<string, AnnotationDTO[]>> => {
|
|
18
|
-
const annotationsByPassage = new Map<string, AnnotationDTO[]>();
|
|
19
|
-
|
|
20
|
-
if (passageUuids.length === 0) {
|
|
21
|
-
return annotationsByPassage;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const pageSize = 1000;
|
|
25
|
-
let allData: AnnotationDTO[] = [];
|
|
26
|
-
let offset = 0;
|
|
27
|
-
let hasMore = true;
|
|
28
|
-
|
|
29
|
-
while (hasMore) {
|
|
30
|
-
const { data, error } = await client
|
|
31
|
-
.from('passage_annotations')
|
|
32
|
-
.select('uuid, passage_uuid, type, start, end, content, toh')
|
|
33
|
-
.in('passage_uuid', passageUuids as string[])
|
|
34
|
-
.not('type', 'like', 'deprecated%')
|
|
35
|
-
.range(offset, offset + pageSize - 1);
|
|
36
|
-
|
|
37
|
-
if (error) {
|
|
38
|
-
console.error('Error batch loading annotations:', error);
|
|
39
|
-
return new Map();
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
allData = allData.concat((data ?? []) as AnnotationDTO[]);
|
|
43
|
-
hasMore = (data?.length ?? 0) === pageSize;
|
|
44
|
-
offset += pageSize;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
for (const annotation of allData) {
|
|
48
|
-
const passageUuid = annotation.passage_uuid;
|
|
49
|
-
if (!passageUuid) continue;
|
|
50
|
-
const existing = annotationsByPassage.get(passageUuid);
|
|
51
|
-
if (existing) {
|
|
52
|
-
existing.push(annotation);
|
|
53
|
-
} else {
|
|
54
|
-
annotationsByPassage.set(passageUuid, [annotation]);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
for (const annotations of annotationsByPassage.values()) {
|
|
59
|
-
annotations.sort((a, b) => {
|
|
60
|
-
if (a.start !== b.start) return a.start - b.start;
|
|
61
|
-
return b.end - a.end;
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return annotationsByPassage;
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
export const getAlignmentsByPassageUuids = async ({
|
|
69
|
-
client,
|
|
70
|
-
passageUuids,
|
|
71
|
-
}: {
|
|
72
|
-
client: DataClient;
|
|
73
|
-
passageUuids: readonly string[];
|
|
74
|
-
}): Promise<Map<string, AlignmentDTO[]>> => {
|
|
75
|
-
const alignmentsByPassage = new Map<string, AlignmentDTO[]>();
|
|
76
|
-
|
|
77
|
-
if (passageUuids.length === 0) {
|
|
78
|
-
return alignmentsByPassage;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const pageSize = 1000;
|
|
82
|
-
let allData: (AlignmentDTO & { passage_uuid: string })[] = [];
|
|
83
|
-
let offset = 0;
|
|
84
|
-
let hasMore = true;
|
|
85
|
-
|
|
86
|
-
while (hasMore) {
|
|
87
|
-
const { data, error } = await client
|
|
88
|
-
.from('passage_alignments')
|
|
89
|
-
.select(
|
|
90
|
-
'passage_uuid, folio_uuid, toh, tibetan, folio_number, volume_number',
|
|
91
|
-
)
|
|
92
|
-
.in('passage_uuid', passageUuids as string[])
|
|
93
|
-
.range(offset, offset + pageSize - 1);
|
|
94
|
-
|
|
95
|
-
if (error) {
|
|
96
|
-
console.error('Error batch loading alignments:', error);
|
|
97
|
-
return new Map();
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
allData = allData.concat((data ?? []) as AlignmentDTO[]);
|
|
101
|
-
hasMore = (data?.length ?? 0) === pageSize;
|
|
102
|
-
offset += pageSize;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
for (const row of allData) {
|
|
106
|
-
const existing = alignmentsByPassage.get(row.passage_uuid);
|
|
107
|
-
if (existing) {
|
|
108
|
-
existing.push(row);
|
|
109
|
-
} else {
|
|
110
|
-
alignmentsByPassage.set(row.passage_uuid, [row]);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return alignmentsByPassage;
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
export const getPassageLabelsByUuids = async ({
|
|
118
|
-
client,
|
|
119
|
-
passageUuids,
|
|
120
|
-
}: {
|
|
121
|
-
client: DataClient;
|
|
122
|
-
passageUuids: readonly string[];
|
|
123
|
-
}): Promise<Map<string, string>> => {
|
|
124
|
-
const labelsByUuid = new Map<string, string>();
|
|
125
|
-
|
|
126
|
-
if (passageUuids.length === 0) {
|
|
127
|
-
return labelsByUuid;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const { data, error } = await client
|
|
131
|
-
.from('passages')
|
|
132
|
-
.select('uuid, label')
|
|
133
|
-
.in('uuid', passageUuids as string[]);
|
|
134
|
-
|
|
135
|
-
if (error) {
|
|
136
|
-
console.error('Error batch loading passage labels:', error);
|
|
137
|
-
return labelsByUuid;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
for (const passage of data ?? []) {
|
|
141
|
-
if (passage.label) {
|
|
142
|
-
labelsByUuid.set(passage.uuid, passage.label);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
return labelsByUuid;
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
export const getPassageReferencesByTargetUuids = async ({
|
|
150
|
-
client,
|
|
151
|
-
passageUuids,
|
|
152
|
-
}: {
|
|
153
|
-
client: DataClient;
|
|
154
|
-
passageUuids: readonly string[];
|
|
155
|
-
}): Promise<Map<string, Passages>> => {
|
|
156
|
-
const referencesByTargetUuid = new Map<string, Passages>();
|
|
157
|
-
|
|
158
|
-
if (passageUuids.length === 0) {
|
|
159
|
-
return referencesByTargetUuid;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
const { data: annotations, error: annotationsError } = await client.rpc(
|
|
163
|
-
'get_passage_annotations_by_content_uuids',
|
|
164
|
-
{
|
|
165
|
-
annotation_type: 'end-note-link',
|
|
166
|
-
target_uuids: passageUuids as string[],
|
|
167
|
-
},
|
|
168
|
-
);
|
|
169
|
-
|
|
170
|
-
if (annotationsError) {
|
|
171
|
-
console.error(
|
|
172
|
-
'Error batch loading passage reference annotations:',
|
|
173
|
-
annotationsError,
|
|
174
|
-
);
|
|
175
|
-
return referencesByTargetUuid;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
const targetToSourceUuids = new Map<string, Set<string>>();
|
|
179
|
-
const allSourceUuids = new Set<string>();
|
|
180
|
-
|
|
181
|
-
for (const row of (annotations ?? []) as Array<{
|
|
182
|
-
passage_uuid: string;
|
|
183
|
-
target_uuid: string;
|
|
184
|
-
}>) {
|
|
185
|
-
if (!row.target_uuid || !row.passage_uuid) continue;
|
|
186
|
-
allSourceUuids.add(row.passage_uuid);
|
|
187
|
-
const sourceSet =
|
|
188
|
-
targetToSourceUuids.get(row.target_uuid) ?? new Set<string>();
|
|
189
|
-
sourceSet.add(row.passage_uuid);
|
|
190
|
-
targetToSourceUuids.set(row.target_uuid, sourceSet);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
const sourceUuidArray = Array.from(allSourceUuids);
|
|
194
|
-
const passageMap = new Map<string, Passage>();
|
|
195
|
-
const inBatchSize = 300;
|
|
196
|
-
|
|
197
|
-
for (let i = 0; i < sourceUuidArray.length; i += inBatchSize) {
|
|
198
|
-
const batch = sourceUuidArray.slice(i, i + inBatchSize);
|
|
199
|
-
const { data, error } = await client
|
|
200
|
-
.from('passages')
|
|
201
|
-
.select('uuid, content, label, sort, type, toh, xmlId, work_uuid')
|
|
202
|
-
.in('uuid', batch);
|
|
203
|
-
|
|
204
|
-
if (error) {
|
|
205
|
-
console.error('Error batch loading passage reference data:', error);
|
|
206
|
-
return new Map();
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
for (const row of (data ?? []) as PassageDTO[]) {
|
|
210
|
-
passageMap.set(row.uuid, passageFromDTO(row));
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
for (const targetUuid of passageUuids) {
|
|
215
|
-
const sourceUuids = targetToSourceUuids.get(targetUuid);
|
|
216
|
-
if (!sourceUuids) continue;
|
|
217
|
-
const references: Passages = [];
|
|
218
|
-
for (const sourceUuid of sourceUuids) {
|
|
219
|
-
const passage = passageMap.get(sourceUuid);
|
|
220
|
-
if (passage) references.push(passage);
|
|
221
|
-
}
|
|
222
|
-
referencesByTargetUuid.set(
|
|
223
|
-
targetUuid,
|
|
224
|
-
references.sort((a, b) => a.sort - b.sort),
|
|
225
|
-
);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
return referencesByTargetUuid;
|
|
229
|
-
};
|
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
import { DataClient, PassageRowDTO } from '../types';
|
|
2
|
-
|
|
3
|
-
type ApiPaginationDirection = 'FORWARD' | 'BACKWARD' | 'AROUND';
|
|
4
|
-
|
|
5
|
-
export type PassageConnectionNode = {
|
|
6
|
-
uuid: string;
|
|
7
|
-
workUuid: string;
|
|
8
|
-
content: string;
|
|
9
|
-
label: string | null;
|
|
10
|
-
sort: number;
|
|
11
|
-
type: string;
|
|
12
|
-
toh: string | null;
|
|
13
|
-
xmlId: string | null;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export type PassageConnectionPage = {
|
|
17
|
-
nodes: PassageConnectionNode[];
|
|
18
|
-
nextCursor: string | null;
|
|
19
|
-
prevCursor: string | null;
|
|
20
|
-
hasMoreAfter: boolean;
|
|
21
|
-
hasMoreBefore: boolean;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
const EMPTY_PASSAGE_CONNECTION: PassageConnectionPage = {
|
|
25
|
-
nodes: [],
|
|
26
|
-
nextCursor: null,
|
|
27
|
-
prevCursor: null,
|
|
28
|
-
hasMoreAfter: false,
|
|
29
|
-
hasMoreBefore: false,
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
const DEFAULT_PASSAGE_CONNECTION_LIMIT = 20;
|
|
33
|
-
const MAX_PASSAGE_CONNECTION_LIMIT = 100;
|
|
34
|
-
|
|
35
|
-
function buildPassageConnection(
|
|
36
|
-
nodes: PassageConnectionNode[],
|
|
37
|
-
nextCursor: string | null,
|
|
38
|
-
prevCursor: string | null,
|
|
39
|
-
hasMoreAfter: boolean,
|
|
40
|
-
hasMoreBefore: boolean,
|
|
41
|
-
): PassageConnectionPage {
|
|
42
|
-
return {
|
|
43
|
-
nodes,
|
|
44
|
-
nextCursor,
|
|
45
|
-
prevCursor,
|
|
46
|
-
hasMoreAfter,
|
|
47
|
-
hasMoreBefore,
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function rowToPassageConnectionNode(
|
|
52
|
-
row: PassageRowDTO,
|
|
53
|
-
workUuid: string,
|
|
54
|
-
): PassageConnectionNode {
|
|
55
|
-
return {
|
|
56
|
-
uuid: row.uuid,
|
|
57
|
-
workUuid,
|
|
58
|
-
content: row.content,
|
|
59
|
-
label: row.label,
|
|
60
|
-
sort: row.sort,
|
|
61
|
-
type: row.type,
|
|
62
|
-
toh: row.toh ?? null,
|
|
63
|
-
xmlId: row.xmlId ?? null,
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export const getWorkPassagesConnection = async ({
|
|
68
|
-
client,
|
|
69
|
-
workUuid,
|
|
70
|
-
cursor,
|
|
71
|
-
limit = DEFAULT_PASSAGE_CONNECTION_LIMIT,
|
|
72
|
-
filter,
|
|
73
|
-
direction = 'FORWARD',
|
|
74
|
-
}: {
|
|
75
|
-
client: DataClient;
|
|
76
|
-
workUuid: string;
|
|
77
|
-
cursor?: string;
|
|
78
|
-
limit?: number;
|
|
79
|
-
filter?: { type?: string; types?: string[]; label?: string };
|
|
80
|
-
direction?: ApiPaginationDirection;
|
|
81
|
-
}): Promise<PassageConnectionPage> => {
|
|
82
|
-
const clampedLimit = Math.min(
|
|
83
|
-
Math.max(limit, 1),
|
|
84
|
-
MAX_PASSAGE_CONNECTION_LIMIT,
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
if (direction === 'AROUND') {
|
|
88
|
-
return getWorkPassagesAround({
|
|
89
|
-
client,
|
|
90
|
-
workUuid,
|
|
91
|
-
cursor,
|
|
92
|
-
limit: clampedLimit,
|
|
93
|
-
filter,
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const isForward = direction === 'FORWARD';
|
|
98
|
-
let cursorSort: number | null = null;
|
|
99
|
-
if (cursor) {
|
|
100
|
-
const { data: cursorPassage } = await client
|
|
101
|
-
.from('passages')
|
|
102
|
-
.select('sort')
|
|
103
|
-
.eq('uuid', cursor)
|
|
104
|
-
.single();
|
|
105
|
-
|
|
106
|
-
if (cursorPassage) {
|
|
107
|
-
cursorSort = cursorPassage.sort;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
let query = client
|
|
112
|
-
.from('passages')
|
|
113
|
-
.select('uuid, content, label, sort, type, toh, xmlId, work_uuid')
|
|
114
|
-
.eq('work_uuid', workUuid)
|
|
115
|
-
.order('sort', { ascending: isForward })
|
|
116
|
-
.limit(clampedLimit + 1);
|
|
117
|
-
|
|
118
|
-
if (cursorSort !== null) {
|
|
119
|
-
query = isForward
|
|
120
|
-
? query.gt('sort', cursorSort)
|
|
121
|
-
: query.lt('sort', cursorSort);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (filter?.types && filter.types.length > 0) {
|
|
125
|
-
query = query.in('type', filter.types);
|
|
126
|
-
} else if (filter?.type) {
|
|
127
|
-
query = query.filter('type', 'match', `${filter.type}.*`);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (filter?.label) {
|
|
131
|
-
query = query.ilike('label', filter.label);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const { data, error } = await query;
|
|
135
|
-
|
|
136
|
-
if (error) {
|
|
137
|
-
console.error('Error fetching passages:', error);
|
|
138
|
-
return EMPTY_PASSAGE_CONNECTION;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
const passages = (data ?? []) as PassageRowDTO[];
|
|
142
|
-
const hasMore = passages.length > clampedLimit;
|
|
143
|
-
let resultPassages = hasMore ? passages.slice(0, clampedLimit) : passages;
|
|
144
|
-
|
|
145
|
-
if (!isForward) {
|
|
146
|
-
resultPassages = resultPassages.reverse();
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
const hasMoreAfter = isForward ? hasMore : cursorSort !== null;
|
|
150
|
-
const hasMoreBefore = isForward ? cursorSort !== null : hasMore;
|
|
151
|
-
|
|
152
|
-
if (resultPassages.length === 0) {
|
|
153
|
-
return buildPassageConnection([], null, null, false, hasMoreBefore);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const nodes = resultPassages.map((row) =>
|
|
157
|
-
rowToPassageConnectionNode(row, workUuid),
|
|
158
|
-
);
|
|
159
|
-
const firstPassage = resultPassages[0];
|
|
160
|
-
const lastPassage = resultPassages[resultPassages.length - 1];
|
|
161
|
-
|
|
162
|
-
return buildPassageConnection(
|
|
163
|
-
nodes,
|
|
164
|
-
hasMoreAfter ? lastPassage.uuid : null,
|
|
165
|
-
hasMoreBefore ? firstPassage.uuid : null,
|
|
166
|
-
hasMoreAfter,
|
|
167
|
-
hasMoreBefore,
|
|
168
|
-
);
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
export const getWorkPassagesAround = async ({
|
|
172
|
-
client,
|
|
173
|
-
workUuid,
|
|
174
|
-
cursor,
|
|
175
|
-
limit,
|
|
176
|
-
filter,
|
|
177
|
-
}: {
|
|
178
|
-
client: DataClient;
|
|
179
|
-
workUuid: string;
|
|
180
|
-
cursor?: string;
|
|
181
|
-
limit: number;
|
|
182
|
-
filter?: { type?: string; types?: string[]; label?: string };
|
|
183
|
-
}): Promise<PassageConnectionPage> => {
|
|
184
|
-
if (!cursor) {
|
|
185
|
-
console.error('AROUND direction requires a cursor');
|
|
186
|
-
return EMPTY_PASSAGE_CONNECTION;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
const { data: cursorPassage } = await client
|
|
190
|
-
.from('passages')
|
|
191
|
-
.select('sort')
|
|
192
|
-
.eq('uuid', cursor)
|
|
193
|
-
.single();
|
|
194
|
-
|
|
195
|
-
if (!cursorPassage) {
|
|
196
|
-
console.error('Cursor passage not found');
|
|
197
|
-
return EMPTY_PASSAGE_CONNECTION;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
const cursorSort = cursorPassage.sort;
|
|
201
|
-
const limitBefore = Math.floor(limit / 2);
|
|
202
|
-
const limitAfter = limit - limitBefore;
|
|
203
|
-
const baseSelect = 'uuid, content, label, sort, type, toh, xmlId, work_uuid';
|
|
204
|
-
|
|
205
|
-
let beforeQuery = client
|
|
206
|
-
.from('passages')
|
|
207
|
-
.select(baseSelect)
|
|
208
|
-
.eq('work_uuid', workUuid)
|
|
209
|
-
.lt('sort', cursorSort)
|
|
210
|
-
.order('sort', { ascending: false })
|
|
211
|
-
.limit(limitBefore + 1);
|
|
212
|
-
|
|
213
|
-
let afterQuery = client
|
|
214
|
-
.from('passages')
|
|
215
|
-
.select(baseSelect)
|
|
216
|
-
.eq('work_uuid', workUuid)
|
|
217
|
-
.gte('sort', cursorSort)
|
|
218
|
-
.order('sort', { ascending: true })
|
|
219
|
-
.limit(limitAfter + 1);
|
|
220
|
-
|
|
221
|
-
if (filter?.types && filter.types.length > 0) {
|
|
222
|
-
beforeQuery = beforeQuery.in('type', filter.types);
|
|
223
|
-
afterQuery = afterQuery.in('type', filter.types);
|
|
224
|
-
} else if (filter?.type) {
|
|
225
|
-
const pattern = `${filter.type}.*`;
|
|
226
|
-
beforeQuery = beforeQuery.filter('type', 'match', pattern);
|
|
227
|
-
afterQuery = afterQuery.filter('type', 'match', pattern);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
if (filter?.label) {
|
|
231
|
-
beforeQuery = beforeQuery.ilike('label', filter.label);
|
|
232
|
-
afterQuery = afterQuery.ilike('label', filter.label);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
const [beforeResult, afterResult] = await Promise.all([
|
|
236
|
-
beforeQuery,
|
|
237
|
-
afterQuery,
|
|
238
|
-
]);
|
|
239
|
-
|
|
240
|
-
if (beforeResult.error || afterResult.error) {
|
|
241
|
-
console.error(
|
|
242
|
-
'Error fetching passages around:',
|
|
243
|
-
beforeResult.error || afterResult.error,
|
|
244
|
-
);
|
|
245
|
-
return EMPTY_PASSAGE_CONNECTION;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const passagesBefore = (beforeResult.data ?? []) as PassageRowDTO[];
|
|
249
|
-
const passagesAfter = (afterResult.data ?? []) as PassageRowDTO[];
|
|
250
|
-
const hasMoreBefore = passagesBefore.length > limitBefore;
|
|
251
|
-
const hasMoreAfter = passagesAfter.length > limitAfter;
|
|
252
|
-
const trimmedBefore = hasMoreBefore
|
|
253
|
-
? passagesBefore.slice(0, limitBefore)
|
|
254
|
-
: passagesBefore;
|
|
255
|
-
const trimmedAfter = hasMoreAfter
|
|
256
|
-
? passagesAfter.slice(0, limitAfter)
|
|
257
|
-
: passagesAfter;
|
|
258
|
-
const resultPassages = [...trimmedBefore.reverse(), ...trimmedAfter];
|
|
259
|
-
|
|
260
|
-
if (resultPassages.length === 0) {
|
|
261
|
-
return EMPTY_PASSAGE_CONNECTION;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
const nodes = resultPassages.map((row) =>
|
|
265
|
-
rowToPassageConnectionNode(row, workUuid),
|
|
266
|
-
);
|
|
267
|
-
const firstPassage = resultPassages[0];
|
|
268
|
-
const lastPassage = resultPassages[resultPassages.length - 1];
|
|
269
|
-
|
|
270
|
-
return buildPassageConnection(
|
|
271
|
-
nodes,
|
|
272
|
-
hasMoreAfter ? lastPassage.uuid : null,
|
|
273
|
-
hasMoreBefore ? firstPassage.uuid : null,
|
|
274
|
-
hasMoreAfter,
|
|
275
|
-
hasMoreBefore,
|
|
276
|
-
);
|
|
277
|
-
};
|