@terrafirmagreg-team/guide 0.1.0 → 1.2.1
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 +18 -19
- package/src/components/book-switcher.tsx +12 -6
- package/src/components/mdx/guide-entry.tsx +48 -0
- package/src/components/mdx/multiblock.tsx +86 -0
- package/src/{lib/tree/children.ts → components/tree/children.tsx} +13 -8
- package/src/{lib/tree/index.ts → components/tree/index.tsx} +25 -15
- package/src/components/views/browser.tsx +26 -17
- package/src/components/views/entry/pages.tsx +4 -2
- package/src/components/views/entry/view.tsx +3 -1
- package/src/components/views/kind/links.tsx +3 -2
- package/src/components/views/kind/media.tsx +6 -5
- package/src/components/views/kind/recipe.tsx +6 -51
- package/src/components/views/kind/table.tsx +4 -2
- package/src/components/views/kind/unknown.tsx +1 -0
- package/src/components/views/page/category-body.tsx +3 -1
- package/src/components/views/page/entry-body.tsx +3 -1
- package/src/components/views/page/overview-body.tsx +4 -2
- package/src/components/views/page/text.tsx +1 -0
- package/src/components/views/page/view.tsx +6 -6
- package/src/components/views/text.tsx +4 -2
- package/src/hooks/use-left-sidebar-tree.ts +15 -6
- package/src/hooks/use-tree.ts +5 -3
- package/src/lib/book/convert.ts +2 -1
- package/src/lib/book/index-rows.ts +3 -1
- package/src/lib/book/index.ts +1 -0
- package/src/lib/book/localize.ts +3 -2
- package/src/lib/book/raw.ts +5 -4
- package/src/lib/books.ts +4 -2
- package/src/lib/breadcrumb.ts +3 -1
- package/src/lib/client/guides.ts +86 -13
- package/src/lib/client-payload/extras.ts +10 -8
- package/src/lib/client-payload/index.ts +9 -8
- package/src/lib/client-payload/links.ts +10 -8
- package/src/lib/config.ts +1 -0
- package/src/lib/data/dto.ts +5 -4
- package/src/lib/data/parse.ts +4 -3
- package/src/lib/dump.ts +4 -3
- package/src/lib/embeds.ts +12 -0
- package/src/lib/format.ts +3 -2
- package/src/lib/links.ts +1 -1
- package/src/lib/markdown/book.ts +1 -0
- package/src/lib/markdown/ctx.ts +3 -1
- package/src/lib/markdown/index.ts +1 -0
- package/src/lib/markdown/page.ts +7 -8
- package/src/lib/markdown/table.ts +1 -0
- package/src/lib/markdown/text.ts +1 -0
- package/src/lib/markdown-page.ts +6 -4
- package/src/lib/messages.ts +1 -0
- package/src/lib/meta.ts +1 -0
- package/src/lib/multiblock/index.ts +1 -0
- package/src/lib/multiblock/url.ts +24 -10
- package/src/lib/names.ts +5 -3
- package/src/lib/page-kind.ts +2 -1
- package/src/lib/paths.ts +4 -2
- package/src/lib/preview.ts +8 -4
- package/src/lib/query.ts +1 -0
- package/src/lib/recipe.ts +3 -2
- package/src/lib/reference/index.ts +1 -0
- package/src/lib/reference/resolver.ts +4 -4
- package/src/lib/search/filter.ts +2 -1
- package/src/lib/search/index.ts +41 -14
- package/src/lib/sprites.ts +1 -0
- package/src/lib/table.ts +1 -0
- package/src/lib/toc.ts +3 -2
- package/src/locales/en_us.json +12 -20
- package/src/locales/ru_ru.json +12 -20
- package/src/locales.ts +1 -0
- package/src/types/index.ts +12 -10
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GuideText } from '@terrafirmagreg-team/guide/components/views/text';
|
|
2
2
|
import { Card } from '@terrafirmagreg-team/ui/components/ui/card';
|
|
3
|
-
import {
|
|
3
|
+
import { Entry } from '@terrafirmagreg-team/game/components/entry/entry';
|
|
4
4
|
import {
|
|
5
5
|
Table,
|
|
6
6
|
TableBody,
|
|
@@ -91,7 +91,8 @@ export function TablePage(props: PageRendererProps) {
|
|
|
91
91
|
>
|
|
92
92
|
<span className="inline-flex flex-wrap items-center gap-1">
|
|
93
93
|
{items.map((id) => (
|
|
94
|
-
<
|
|
94
|
+
<Entry
|
|
95
|
+
kind="item"
|
|
95
96
|
key={id}
|
|
96
97
|
id={id}
|
|
97
98
|
name={id}
|
|
@@ -136,3 +137,4 @@ export function TablePage(props: PageRendererProps) {
|
|
|
136
137
|
</>
|
|
137
138
|
);
|
|
138
139
|
}
|
|
140
|
+
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
1
2
|
import { Entry } from '@terrafirmagreg-team/game/components/entry/entry';
|
|
2
3
|
import { ItemRow } from '@terrafirmagreg-team/ui/components/blocks/list/row';
|
|
3
4
|
import { guideBookHref } from '@terrafirmagreg-team/guide/lib/paths';
|
|
@@ -5,7 +6,7 @@ import { guideMessage } from '@terrafirmagreg-team/guide/lib/messages';
|
|
|
5
6
|
import type { GuideIndex, GuideMessages } from '@terrafirmagreg-team/guide/types';
|
|
6
7
|
|
|
7
8
|
type GuideCategoryBodyProps = {
|
|
8
|
-
dataset:
|
|
9
|
+
dataset: DatasetRef;
|
|
9
10
|
lang: string;
|
|
10
11
|
modId?: string;
|
|
11
12
|
bookPath?: string;
|
|
@@ -54,3 +55,4 @@ export function GuideCategoryBody({
|
|
|
54
55
|
</div>
|
|
55
56
|
);
|
|
56
57
|
}
|
|
58
|
+
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
1
2
|
import { EmptyState } from '@terrafirmagreg-team/ui/components/blocks/page/empty-state';
|
|
2
3
|
import { EntryView } from '@terrafirmagreg-team/guide/components/views/entry/view';
|
|
3
4
|
import { guideMessage } from '@terrafirmagreg-team/guide/lib/messages';
|
|
@@ -11,7 +12,7 @@ import type {
|
|
|
11
12
|
} from '@terrafirmagreg-team/guide/types';
|
|
12
13
|
|
|
13
14
|
type GuideEntryBodyProps = {
|
|
14
|
-
dataset:
|
|
15
|
+
dataset: DatasetRef;
|
|
15
16
|
lang: Lang;
|
|
16
17
|
bookPath?: string;
|
|
17
18
|
overview: GuideIndex;
|
|
@@ -77,3 +78,4 @@ export function GuideEntryBody({
|
|
|
77
78
|
/>
|
|
78
79
|
);
|
|
79
80
|
}
|
|
81
|
+
|
|
@@ -6,15 +6,16 @@ import {
|
|
|
6
6
|
guideCategoryHref,
|
|
7
7
|
isRootCategory,
|
|
8
8
|
} from '@terrafirmagreg-team/guide/lib/paths';
|
|
9
|
-
import { texturePublicUrl } from '@terrafirmagreg-team/
|
|
9
|
+
import { texturePublicUrl } from '@terrafirmagreg-team/dump/lib/dump/assets/urls';
|
|
10
10
|
import { useDumpLocation } from '@terrafirmagreg-team/game/hooks/use-dump-location';
|
|
11
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
11
12
|
import { guideMessage } from '@terrafirmagreg-team/guide/lib/messages';
|
|
12
13
|
import type { PagePreviewData } from '@terrafirmagreg-team/ui/types/preview';
|
|
13
14
|
import type { Lang } from '@terrafirmagreg-team/translate/types/locale';
|
|
14
15
|
import type { GuideIndex, GuideMessages } from '@terrafirmagreg-team/guide/types';
|
|
15
16
|
|
|
16
17
|
type GuideOverviewBodyProps = {
|
|
17
|
-
dataset:
|
|
18
|
+
dataset: DatasetRef;
|
|
18
19
|
lang: Lang;
|
|
19
20
|
modId?: string;
|
|
20
21
|
bookPath?: string;
|
|
@@ -95,3 +96,4 @@ export function GuideOverviewBody({
|
|
|
95
96
|
</div>
|
|
96
97
|
);
|
|
97
98
|
}
|
|
99
|
+
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
import { guideConfig } from '@terrafirmagreg-team/guide/lib/config';
|
|
10
10
|
import { GithubInfo } from '@terrafirmagreg-team/ui/components/blocks/git/github-info';
|
|
11
11
|
import { sectionConfig } from '@terrafirmagreg-team/kit/lib/config';
|
|
12
|
-
import { parseDatasetRef } from '@terrafirmagreg-team/kit/lib/location';
|
|
13
12
|
import { categoryMap, guideBreadcrumbItems } from '@terrafirmagreg-team/guide/lib/breadcrumb';
|
|
14
13
|
import { guideToc } from '@terrafirmagreg-team/guide/lib/toc';
|
|
15
14
|
import { GuideText } from '@terrafirmagreg-team/guide/components/views/text';
|
|
@@ -17,7 +16,7 @@ import { GuideOverviewBody } from '@terrafirmagreg-team/guide/components/views/p
|
|
|
17
16
|
import { GuideCategoryBody } from '@terrafirmagreg-team/guide/components/views/page/category-body';
|
|
18
17
|
import { GuideEntryBody } from '@terrafirmagreg-team/guide/components/views/page/entry-body';
|
|
19
18
|
import { guideMessage } from '@terrafirmagreg-team/guide/lib/messages';
|
|
20
|
-
import {
|
|
19
|
+
import { CommentsSlot } from '@terrafirmagreg-team/discussions/components/comments';
|
|
21
20
|
import {
|
|
22
21
|
guideBookHref,
|
|
23
22
|
guideCategoryHref,
|
|
@@ -184,7 +183,7 @@ export function GuidePageView({
|
|
|
184
183
|
});
|
|
185
184
|
|
|
186
185
|
const datasetConf =
|
|
187
|
-
sectionConfig().datasetConfig[
|
|
186
|
+
sectionConfig().datasetConfig[dataset.id];
|
|
188
187
|
const repoSlug = datasetConf?.repo?.split('/');
|
|
189
188
|
const mdQuery = new URLSearchParams();
|
|
190
189
|
if (payload.modId && payload.bookPath) {
|
|
@@ -196,7 +195,7 @@ export function GuidePageView({
|
|
|
196
195
|
mdQuery.set('cat', payload.categoryId);
|
|
197
196
|
}
|
|
198
197
|
mdQuery.set('lang', lang);
|
|
199
|
-
const mdUrl = `/guide/${dataset}.md?${mdQuery}`;
|
|
198
|
+
const mdUrl = `/guide/${dataset.id}.md?${mdQuery}`;
|
|
200
199
|
|
|
201
200
|
const nav = guideNavItems(payload, overview);
|
|
202
201
|
const {
|
|
@@ -270,10 +269,11 @@ export function GuidePageView({
|
|
|
270
269
|
{body}
|
|
271
270
|
</div>
|
|
272
271
|
</WorkspaceBody>
|
|
273
|
-
<
|
|
274
|
-
page={`guide:${dataset}:${payload.modId}:${payload.bookPath}:${payload.entry?.id ?? payload.categoryId ?? 'book'}#${lang}`}
|
|
272
|
+
<CommentsSlot
|
|
273
|
+
page={`guide:${dataset.id}:${payload.modId}:${payload.bookPath}:${payload.entry?.id ?? payload.categoryId ?? 'book'}#${lang}`}
|
|
275
274
|
/>
|
|
276
275
|
</Workspace>
|
|
277
276
|
</EntryProvider>
|
|
278
277
|
);
|
|
279
278
|
}
|
|
279
|
+
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
1
2
|
import { Fragment, type ReactNode } from 'react';
|
|
2
3
|
import { LinkPreview } from '@terrafirmagreg-team/ui/components/blocks/link/link-preview';
|
|
3
4
|
import { guideLink } from '@terrafirmagreg-team/guide/lib/reference';
|
|
@@ -29,7 +30,7 @@ export function GuideText({
|
|
|
29
30
|
previews,
|
|
30
31
|
}: {
|
|
31
32
|
text: string;
|
|
32
|
-
dataset?:
|
|
33
|
+
dataset?: DatasetRef;
|
|
33
34
|
lang?: Lang;
|
|
34
35
|
modId?: string;
|
|
35
36
|
bookPath?: string;
|
|
@@ -89,7 +90,7 @@ export function GuideText({
|
|
|
89
90
|
}
|
|
90
91
|
if (node.type === 'text' && node.link) {
|
|
91
92
|
const { href, external } = guideLink(node, {
|
|
92
|
-
dataset: dataset ?? '',
|
|
93
|
+
dataset: dataset ?? { id: '' },
|
|
93
94
|
lang: lang ?? 'en_us',
|
|
94
95
|
modId: modId ?? '',
|
|
95
96
|
bookPath: bookPath ?? '',
|
|
@@ -128,3 +129,4 @@ export function GuideText({
|
|
|
128
129
|
}
|
|
129
130
|
return <>{children}</>;
|
|
130
131
|
}
|
|
132
|
+
|
|
@@ -1,19 +1,28 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { usePathname } from 'next/navigation';
|
|
3
|
+
import { useMemo } from 'react';
|
|
3
4
|
import type * as PageTree from 'fumadocs-core/page-tree';
|
|
4
|
-
import {
|
|
5
|
+
import { useLocationSearchParams } from '@terrafirmagreg-team/ui/hooks/page/use-location-search';
|
|
5
6
|
import { useResolvedLang } from '@terrafirmagreg-team/translate/hooks/use-resolved-lang';
|
|
6
7
|
import { useLastValue } from '@terrafirmagreg-team/ui/hooks/use-last-value';
|
|
7
8
|
import { useGuideTree } from '@terrafirmagreg-team/guide/hooks/use-tree';
|
|
8
9
|
import { guideQueryFromParams } from '@terrafirmagreg-team/guide/lib/query';
|
|
9
|
-
import { parseSectionLocation } from '@terrafirmagreg-team/
|
|
10
|
+
import { parseSectionLocation } from '@terrafirmagreg-team/sites/location';
|
|
10
11
|
|
|
11
12
|
export function useGuideLeftSidebarTree(tree: PageTree.Root): PageTree.Root {
|
|
12
|
-
const { dataset } = parseSectionLocation(usePathname());
|
|
13
|
+
const { dataset: datasetId } = parseSectionLocation(usePathname());
|
|
13
14
|
const lang = useResolvedLang();
|
|
14
|
-
const
|
|
15
|
-
|
|
15
|
+
const params = useLocationSearchParams();
|
|
16
|
+
const { bookId } = guideQueryFromParams(params);
|
|
17
|
+
const version = params.get('version') ?? undefined;
|
|
18
|
+
const dataset = useMemo(
|
|
19
|
+
() => (datasetId ? { id: datasetId, version } : undefined),
|
|
20
|
+
[datasetId, version],
|
|
21
|
+
);
|
|
22
|
+
const runtime = useLastValue(
|
|
23
|
+
useGuideTree(dataset, lang, bookId),
|
|
24
|
+
dataset?.id ?? '',
|
|
16
25
|
);
|
|
17
|
-
const runtime = useLastValue(useGuideTree(dataset, lang, bookId), dataset);
|
|
18
26
|
return runtime ?? tree;
|
|
19
27
|
}
|
|
28
|
+
|
package/src/hooks/use-tree.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
'use client';
|
|
2
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
2
3
|
|
|
3
4
|
import type * as PageTree from 'fumadocs-core/page-tree';
|
|
4
5
|
import { useAsyncValue } from '@terrafirmagreg-team/ui/hooks/use-async-value';
|
|
5
6
|
import { loadClientGuideBook } from '@terrafirmagreg-team/guide/lib/client/guides';
|
|
6
7
|
import { listGuideBooks } from '@terrafirmagreg-team/guide/lib/books';
|
|
7
|
-
import { guideTreeChildren } from '@terrafirmagreg-team/guide/
|
|
8
|
+
import { guideTreeChildren } from '@terrafirmagreg-team/guide/components/tree/children';
|
|
8
9
|
import type { Lang } from '@terrafirmagreg-team/translate/types/locale';
|
|
9
10
|
|
|
10
11
|
export function useGuideTree(
|
|
11
|
-
dataset:
|
|
12
|
+
dataset: DatasetRef | undefined,
|
|
12
13
|
lang: Lang,
|
|
13
14
|
bookId: string | undefined,
|
|
14
15
|
): PageTree.Root | undefined {
|
|
@@ -24,10 +25,11 @@ export function useGuideTree(
|
|
|
24
25
|
return {
|
|
25
26
|
name: 'guide',
|
|
26
27
|
children: index ? guideTreeChildren(dataset, index) : [],
|
|
27
|
-
$id: `guide/${dataset}/${resolvedId ?? 'none'}/${lang}`,
|
|
28
|
+
$id: `guide/${dataset.id}/${dataset.version ?? ''}/${resolvedId ?? 'none'}/${lang}`,
|
|
28
29
|
} satisfies PageTree.Root;
|
|
29
30
|
}
|
|
30
31
|
: undefined,
|
|
31
32
|
[dataset, lang, bookId],
|
|
32
33
|
);
|
|
33
34
|
}
|
|
35
|
+
|
package/src/lib/book/convert.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { dumpTextLines } from '@terrafirmagreg-team/
|
|
1
|
+
import { dumpTextLines } from '@terrafirmagreg-team/dump/lib/dump/assets/lang/names';
|
|
2
2
|
import type {
|
|
3
3
|
GuideBookJson,
|
|
4
4
|
GuideBookRef,
|
|
@@ -72,3 +72,4 @@ export function bookSlug(
|
|
|
72
72
|
if (explicit) return urlSafeSlug(explicit);
|
|
73
73
|
return urlSafeSlug(ref.bookPath);
|
|
74
74
|
}
|
|
75
|
+
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
1
2
|
import { parseGuideIcon } from '@terrafirmagreg-team/guide/lib/data/parse';
|
|
2
3
|
import type {
|
|
3
4
|
GuideBookJson,
|
|
@@ -99,7 +100,7 @@ export type BookRows = {
|
|
|
99
100
|
|
|
100
101
|
export function indexBookRows(
|
|
101
102
|
rows: BookRows,
|
|
102
|
-
dataset:
|
|
103
|
+
dataset: DatasetRef,
|
|
103
104
|
lang: Lang,
|
|
104
105
|
langMap: Record<string, string>,
|
|
105
106
|
rawLang?: Record<string, string>,
|
|
@@ -132,3 +133,4 @@ export function indexBookRows(
|
|
|
132
133
|
isFallback: rows.isFallback,
|
|
133
134
|
};
|
|
134
135
|
}
|
|
136
|
+
|
package/src/lib/book/index.ts
CHANGED
package/src/lib/book/localize.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { langString } from '@terrafirmagreg-team/
|
|
2
|
-
import type { DumpText } from '@terrafirmagreg-team/
|
|
1
|
+
import { langString } from '@terrafirmagreg-team/dump/lib/dump/assets/lang/names';
|
|
2
|
+
import type { DumpText } from '@terrafirmagreg-team/dump/lib/dump/contract/text';
|
|
3
3
|
|
|
4
4
|
export type FallbackTracker = {
|
|
5
5
|
mark(key: string | undefined): void;
|
|
@@ -74,3 +74,4 @@ export function localizeGuideValue(
|
|
|
74
74
|
}
|
|
75
75
|
return value;
|
|
76
76
|
}
|
|
77
|
+
|
package/src/lib/book/raw.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { asTaggedReference } from '@terrafirmagreg-team/
|
|
2
|
-
import { asDumpTextList } from '@terrafirmagreg-team/
|
|
3
|
-
import type { DumpText } from '@terrafirmagreg-team/
|
|
4
|
-
import type { TaggedReference } from '@terrafirmagreg-team/
|
|
1
|
+
import { asTaggedReference } from '@terrafirmagreg-team/dump/lib/dump/contract/ref';
|
|
2
|
+
import { asDumpTextList } from '@terrafirmagreg-team/dump/lib/dump/contract/text';
|
|
3
|
+
import type { DumpText } from '@terrafirmagreg-team/dump/lib/dump/contract/text';
|
|
4
|
+
import type { TaggedReference } from '@terrafirmagreg-team/dump/lib/dump/contract/ref';
|
|
5
5
|
import { bareId } from '@terrafirmagreg-team/guide/lib/paths';
|
|
6
6
|
|
|
7
7
|
export type RawRecord = Record<string, unknown>;
|
|
@@ -78,3 +78,4 @@ export function categoryMatches(
|
|
|
78
78
|
if (!entryCategory) return false;
|
|
79
79
|
return bareId(entryCategory) === bareId(categoryId);
|
|
80
80
|
}
|
|
81
|
+
|
package/src/lib/books.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
1
2
|
import { sectionConfig } from '@terrafirmagreg-team/kit/lib/config';
|
|
2
3
|
import { listClientGuideBookSummaries } from '@terrafirmagreg-team/guide/lib/client/guides';
|
|
3
4
|
import type { Lang } from '@terrafirmagreg-team/translate/types/locale';
|
|
@@ -20,10 +21,11 @@ function orderGuideBooks<T extends { bookId: string }>(
|
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
export function listGuideBooks(
|
|
23
|
-
dataset:
|
|
24
|
+
dataset: DatasetRef,
|
|
24
25
|
lang: Lang,
|
|
25
26
|
): Promise<GuideBookSummary[]> {
|
|
26
27
|
return listClientGuideBookSummaries(dataset, lang).then((books) =>
|
|
27
|
-
orderGuideBooks(books, sectionConfig().datasetConfig[dataset]?.guide?.bookOrder),
|
|
28
|
+
orderGuideBooks(books, sectionConfig().datasetConfig[dataset.id]?.guide?.bookOrder),
|
|
28
29
|
);
|
|
29
30
|
}
|
|
31
|
+
|
package/src/lib/breadcrumb.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
1
2
|
import { guideBookHref, guideCategoryHref } from '@terrafirmagreg-team/guide/lib/paths';
|
|
2
3
|
import type { GuideCategory, GuideIndex, GuidePageKind } from '@terrafirmagreg-team/guide/types';
|
|
3
4
|
|
|
@@ -24,7 +25,7 @@ export function guideBreadcrumbItems({
|
|
|
24
25
|
}: {
|
|
25
26
|
kind: GuidePageKind;
|
|
26
27
|
title: string;
|
|
27
|
-
dataset:
|
|
28
|
+
dataset: DatasetRef;
|
|
28
29
|
modId?: string;
|
|
29
30
|
bookPath?: string;
|
|
30
31
|
overview: GuideIndex | undefined;
|
|
@@ -52,3 +53,4 @@ export function guideBreadcrumbItems({
|
|
|
52
53
|
items.push({ name: title });
|
|
53
54
|
return items;
|
|
54
55
|
}
|
|
56
|
+
|
package/src/lib/client/guides.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
2
|
+
import { asRecord, asString } from '@terrafirmagreg-team/dump/lib/dump/contract/read';
|
|
3
|
+
import { joinDumpRel } from '@terrafirmagreg-team/dump/lib/dump/paths';
|
|
4
|
+
import { bareId } from '@terrafirmagreg-team/guide/lib/paths';
|
|
5
|
+
import type { GuideEntry } from '@terrafirmagreg-team/guide/types';
|
|
6
|
+
import type { GuideMultiblock } from '@terrafirmagreg-team/guide/lib/data/dto';
|
|
3
7
|
import type {
|
|
4
8
|
GuideBookJson,
|
|
5
9
|
GuideBookRef,
|
|
@@ -16,9 +20,9 @@ import {
|
|
|
16
20
|
clientDumpJson,
|
|
17
21
|
clientDumpLang,
|
|
18
22
|
clientDumpLangRaw,
|
|
19
|
-
|
|
20
|
-
} from '@terrafirmagreg-team/
|
|
21
|
-
import {
|
|
23
|
+
} from '@terrafirmagreg-team/dump/lib/dump/client/dump';
|
|
24
|
+
import { loadDatasetDump } from '@terrafirmagreg-team/dump/lib/dump/mods/load';
|
|
25
|
+
import { createDatasetCache } from '@terrafirmagreg-team/dump/lib/dump/reader';
|
|
22
26
|
|
|
23
27
|
type BookRow = {
|
|
24
28
|
ref: GuideBookRef;
|
|
@@ -26,9 +30,9 @@ type BookRow = {
|
|
|
26
30
|
raw?: GuideBookJson;
|
|
27
31
|
};
|
|
28
32
|
|
|
29
|
-
const listedBookRows =
|
|
30
|
-
async (dataset:
|
|
31
|
-
const dump = await
|
|
33
|
+
const listedBookRows = createDatasetCache(
|
|
34
|
+
async (dataset: DatasetRef): Promise<BookRow[]> => {
|
|
35
|
+
const dump = await loadDatasetDump(dataset);
|
|
32
36
|
if (!dump) return [];
|
|
33
37
|
const raws = await Promise.all(
|
|
34
38
|
dump.mods.flatMap((mod) =>
|
|
@@ -78,7 +82,7 @@ function listedBodies(
|
|
|
78
82
|
}
|
|
79
83
|
|
|
80
84
|
async function bookRows(
|
|
81
|
-
dataset:
|
|
85
|
+
dataset: DatasetRef,
|
|
82
86
|
row: BookRow,
|
|
83
87
|
lang: Lang,
|
|
84
88
|
): Promise<BookRows | null> {
|
|
@@ -138,9 +142,9 @@ async function bookRows(
|
|
|
138
142
|
};
|
|
139
143
|
}
|
|
140
144
|
|
|
141
|
-
export const loadClientGuideBook =
|
|
145
|
+
export const loadClientGuideBook = createDatasetCache(
|
|
142
146
|
async (
|
|
143
|
-
dataset:
|
|
147
|
+
dataset: DatasetRef,
|
|
144
148
|
lang: Lang,
|
|
145
149
|
bookSlugValue: string,
|
|
146
150
|
): Promise<GuideIndex | null> => {
|
|
@@ -157,11 +161,79 @@ export const loadClientGuideBook = createAsyncCache(
|
|
|
157
161
|
if (!rows) return null;
|
|
158
162
|
return indexBookRows(rows, dataset, lang, langMap, rawLang);
|
|
159
163
|
},
|
|
160
|
-
(dataset, lang, bookSlugValue) => `${dataset}${lang}${bookSlugValue}`,
|
|
164
|
+
(dataset, lang, bookSlugValue) => `${dataset.id}/${dataset.version ?? ''}${lang}${bookSlugValue}`,
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
export type ClientGuideEntryHit = {
|
|
168
|
+
entry: GuideEntry;
|
|
169
|
+
modId?: string;
|
|
170
|
+
bookPath?: string;
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
export async function findClientGuideEntry(
|
|
174
|
+
dataset: DatasetRef,
|
|
175
|
+
lang: Lang,
|
|
176
|
+
entryId: string,
|
|
177
|
+
): Promise<ClientGuideEntryHit | undefined> {
|
|
178
|
+
const needle = bareId(entryId);
|
|
179
|
+
const nameNeedle = entryId.trim().toLowerCase();
|
|
180
|
+
for (const row of await listedBookRows(dataset)) {
|
|
181
|
+
const entries = (row.raw as Record<string, unknown> | undefined)?.entries;
|
|
182
|
+
const overview = await loadClientGuideBook(dataset, lang, row.slug);
|
|
183
|
+
const match =
|
|
184
|
+
entries && typeof entries === 'object'
|
|
185
|
+
? Object.keys(entries).find(
|
|
186
|
+
(key) => bareId(key) === needle || key === entryId,
|
|
187
|
+
)
|
|
188
|
+
: undefined;
|
|
189
|
+
const entry = overview?.entries.find(
|
|
190
|
+
(item) =>
|
|
191
|
+
item.id === match ||
|
|
192
|
+
bareId(item.id) === needle ||
|
|
193
|
+
item.name?.trim().toLowerCase() === nameNeedle,
|
|
194
|
+
);
|
|
195
|
+
if (entry) {
|
|
196
|
+
return {
|
|
197
|
+
entry,
|
|
198
|
+
modId: overview?.modId,
|
|
199
|
+
bookPath: overview?.bookPath,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return undefined;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export const loadMultiblockNameIndex = createDatasetCache(
|
|
207
|
+
async (
|
|
208
|
+
dataset: DatasetRef,
|
|
209
|
+
lang: Lang,
|
|
210
|
+
): Promise<Record<string, GuideMultiblock>> => {
|
|
211
|
+
const index: Record<string, GuideMultiblock> = {};
|
|
212
|
+
const put = (key: string | undefined, spec: GuideMultiblock) => {
|
|
213
|
+
const normalized = key?.trim().toLowerCase();
|
|
214
|
+
if (normalized) index[normalized] ??= spec;
|
|
215
|
+
};
|
|
216
|
+
for (const row of await listedBookRows(dataset)) {
|
|
217
|
+
const overview = await loadClientGuideBook(dataset, lang, row.slug);
|
|
218
|
+
for (const entry of overview?.entries ?? []) {
|
|
219
|
+
for (const page of entry.pages ?? []) {
|
|
220
|
+
const spec = page?.multiblock;
|
|
221
|
+
if (!spec) continue;
|
|
222
|
+
const display = asRecord(
|
|
223
|
+
(page as Record<string, unknown>).display,
|
|
224
|
+
);
|
|
225
|
+
put(asString(display?.name) ?? page.name ?? page.title, spec);
|
|
226
|
+
put(entry.id, spec);
|
|
227
|
+
put(entry.name, spec);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return index;
|
|
232
|
+
},
|
|
161
233
|
);
|
|
162
234
|
|
|
163
235
|
export async function listClientGuideBookSummaries(
|
|
164
|
-
dataset:
|
|
236
|
+
dataset: DatasetRef,
|
|
165
237
|
lang: Lang,
|
|
166
238
|
): Promise<
|
|
167
239
|
Array<{
|
|
@@ -187,3 +259,4 @@ export async function listClientGuideBookSummaries(
|
|
|
187
259
|
})
|
|
188
260
|
.sort((a, b) => a.bookId.localeCompare(b.bookId));
|
|
189
261
|
}
|
|
262
|
+
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
1
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
2
|
+
import { stackDisplayName } from '@terrafirmagreg-team/dump/lib/dump/assets/lang/names';
|
|
3
|
+
import { loadClientModAtlases } from '@terrafirmagreg-team/dump/lib/dump/client/atlases';
|
|
4
|
+
import { loadClientKeybinds } from '@terrafirmagreg-team/dump/lib/dump/client/keybinds';
|
|
5
|
+
import { guideEmbeds } from '@terrafirmagreg-team/guide/lib/embeds';
|
|
6
|
+
import { loadClientRegistry } from '@terrafirmagreg-team/dump/lib/dump/client/registry';
|
|
7
|
+
import { parseStackId } from '@terrafirmagreg-team/dump/lib/dump/contract/ref';
|
|
7
8
|
import { spriteIdsFromEntry } from '@terrafirmagreg-team/guide/lib/sprites';
|
|
8
9
|
import { recipeIds } from '@terrafirmagreg-team/guide/lib/recipe';
|
|
9
10
|
import { asMultiblock } from '@terrafirmagreg-team/guide/lib/meta';
|
|
@@ -14,7 +15,7 @@ import type { GuideEntry, GuideEntryExtras } from '@terrafirmagreg-team/guide/ty
|
|
|
14
15
|
import { type QuestLinks, collectPageLinks } from './links';
|
|
15
16
|
|
|
16
17
|
export async function entryExtras(
|
|
17
|
-
dataset:
|
|
18
|
+
dataset: DatasetRef,
|
|
18
19
|
lang: Lang,
|
|
19
20
|
langMap: Record<string, string>,
|
|
20
21
|
bookModId: string,
|
|
@@ -35,7 +36,7 @@ export async function entryExtras(
|
|
|
35
36
|
pages.map(async (page) => {
|
|
36
37
|
await Promise.all(
|
|
37
38
|
recipeIds(page).map(async (id) => {
|
|
38
|
-
const recipe = await
|
|
39
|
+
const recipe = await guideEmbeds().recipe?.load(dataset, id);
|
|
39
40
|
if (recipe) recipes[id] = recipe;
|
|
40
41
|
}),
|
|
41
42
|
);
|
|
@@ -99,3 +100,4 @@ export async function entryExtras(
|
|
|
99
100
|
glbs,
|
|
100
101
|
};
|
|
101
102
|
}
|
|
103
|
+
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
1
2
|
import { loadClientGuideBook } from '@terrafirmagreg-team/guide/lib/client/guides';
|
|
2
3
|
import { uiConfig } from '@terrafirmagreg-team/ui/lib/config';
|
|
3
4
|
import { categoryMap } from '@terrafirmagreg-team/guide/lib/breadcrumb';
|
|
4
5
|
import { bareId, guideBookHref } from '@terrafirmagreg-team/guide/lib/paths';
|
|
5
|
-
import {
|
|
6
|
+
import { guideEmbeds } from '@terrafirmagreg-team/guide/lib/embeds';
|
|
6
7
|
import type { Lang } from '@terrafirmagreg-team/translate/types/locale';
|
|
7
8
|
import type {
|
|
8
9
|
GuideMessages,
|
|
@@ -12,7 +13,7 @@ import { entryExtras } from './extras';
|
|
|
12
13
|
import { type QuestLinks, collectTextLinks } from './links';
|
|
13
14
|
|
|
14
15
|
export async function loadClientGuidePayload(
|
|
15
|
-
dataset:
|
|
16
|
+
dataset: DatasetRef,
|
|
16
17
|
lang: Lang,
|
|
17
18
|
bookId: string | undefined,
|
|
18
19
|
entryId: string | undefined,
|
|
@@ -75,12 +76,11 @@ export async function loadClientGuidePayload(
|
|
|
75
76
|
)
|
|
76
77
|
: undefined;
|
|
77
78
|
for (const hit of Object.values(questLinks)) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
);
|
|
79
|
+
const url = guideEmbeds().quest?.href(dataset, undefined, {
|
|
80
|
+
category: hit.filename,
|
|
81
|
+
id: hit.questId,
|
|
82
|
+
});
|
|
83
|
+
if (url) hrefs.add(url);
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
const previews = await uiConfig().loadPagePreviews?.(lang, langMap, hrefs) ?? {};
|
|
@@ -110,3 +110,4 @@ export async function loadClientGuidePayload(
|
|
|
110
110
|
messages,
|
|
111
111
|
};
|
|
112
112
|
}
|
|
113
|
+
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
1
2
|
import {
|
|
2
|
-
|
|
3
|
-
type
|
|
4
|
-
} from '@terrafirmagreg-team/
|
|
3
|
+
guideEmbeds,
|
|
4
|
+
type EmbedQuestLocation,
|
|
5
|
+
} from '@terrafirmagreg-team/guide/lib/embeds';
|
|
5
6
|
import { classify, pageTexts } from '@terrafirmagreg-team/guide/lib/page-kind';
|
|
6
7
|
import { formatGuide } from '@terrafirmagreg-team/guide/lib/format';
|
|
7
8
|
import {
|
|
@@ -11,10 +12,10 @@ import {
|
|
|
11
12
|
import type { Lang } from '@terrafirmagreg-team/translate/types/locale';
|
|
12
13
|
import type { GuidePage } from '@terrafirmagreg-team/guide/types';
|
|
13
14
|
|
|
14
|
-
export type QuestLinks = Record<string,
|
|
15
|
+
export type QuestLinks = Record<string, EmbedQuestLocation>;
|
|
15
16
|
|
|
16
17
|
async function collectQuestLink(
|
|
17
|
-
dataset:
|
|
18
|
+
dataset: DatasetRef,
|
|
18
19
|
questLinks: QuestLinks,
|
|
19
20
|
target: string | undefined,
|
|
20
21
|
force = false,
|
|
@@ -23,12 +24,12 @@ async function collectQuestLink(
|
|
|
23
24
|
const ref = parseGuideReference(target);
|
|
24
25
|
if (!force && ref.kind !== 'quest') return;
|
|
25
26
|
if (questLinks[ref.id]) return;
|
|
26
|
-
const hit = await
|
|
27
|
+
const hit = await guideEmbeds().quest?.findLocation(dataset, ref.id);
|
|
27
28
|
if (hit) questLinks[ref.id] = hit;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
export async function collectTextLinks(
|
|
31
|
-
dataset:
|
|
32
|
+
dataset: DatasetRef,
|
|
32
33
|
questLinks: QuestLinks,
|
|
33
34
|
hrefs: Set<string>,
|
|
34
35
|
ctx: {
|
|
@@ -58,7 +59,7 @@ export async function collectTextLinks(
|
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
export async function collectPageLinks(
|
|
61
|
-
dataset:
|
|
62
|
+
dataset: DatasetRef,
|
|
62
63
|
lang: Lang,
|
|
63
64
|
bookModId: string,
|
|
64
65
|
bookPath: string,
|
|
@@ -99,3 +100,4 @@ export async function collectPageLinks(
|
|
|
99
100
|
if (resolved.href) hrefs.add(resolved.href);
|
|
100
101
|
}
|
|
101
102
|
}
|
|
103
|
+
|
package/src/lib/config.ts
CHANGED
package/src/lib/data/dto.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { TaggedReference } from '@terrafirmagreg-team/
|
|
2
|
-
import type { DumpText } from '@terrafirmagreg-team/
|
|
3
|
-
import type { GuideBookRef } from '@terrafirmagreg-team/
|
|
4
|
-
import type { DataGuidesBook } from '@terrafirmagreg-team/
|
|
1
|
+
import type { TaggedReference } from '@terrafirmagreg-team/dump/lib/dump/contract/ref';
|
|
2
|
+
import type { DumpText } from '@terrafirmagreg-team/dump/lib/dump/contract/text';
|
|
3
|
+
import type { GuideBookRef } from '@terrafirmagreg-team/dump/lib/dump/mods/dto';
|
|
4
|
+
import type { DataGuidesBook } from '@terrafirmagreg-team/dump/lib/dump/gen';
|
|
5
5
|
|
|
6
6
|
export type { GuideBookRef };
|
|
7
7
|
|
|
@@ -75,3 +75,4 @@ export type GuidePage = {
|
|
|
75
75
|
rotate?: boolean;
|
|
76
76
|
[key: string]: unknown;
|
|
77
77
|
};
|
|
78
|
+
|