@terrafirmagreg-team/recipe 0.1.0 → 1.2.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/package.json +16 -16
- package/src/components/button-copy.tsx +1 -0
- package/src/components/cards/card/index.tsx +5 -3
- package/src/components/cards/card/scene.tsx +4 -2
- package/src/components/cards/card/strip.tsx +4 -2
- package/src/components/cards/card/text.tsx +2 -1
- package/src/components/cards/card/tips.tsx +1 -0
- package/src/components/cards/default-item.tsx +6 -2
- package/src/components/cards/glare-filter.tsx +1 -0
- package/src/components/cards/paged-card.tsx +1 -0
- package/src/components/cards/slot-hitbox.tsx +4 -2
- package/src/components/cards/strip-card/buttons.tsx +7 -2
- package/src/components/cards/strip-card/index.tsx +3 -1
- package/src/components/cards/strip-card/member-cell.tsx +4 -2
- package/src/components/cards/strip-card/sprite.tsx +1 -0
- package/src/components/embed-card.tsx +44 -0
- package/src/components/mdx/recipe.tsx +34 -16
- package/src/components/tool-list.tsx +1 -0
- package/src/{lib/tree.ts → components/tree.tsx} +20 -12
- package/src/components/views/alloy/index.tsx +14 -7
- package/src/components/views/alloy/list.tsx +3 -2
- package/src/components/views/alloy/mix/index.tsx +1 -0
- package/src/components/views/alloy/mix/ratio.tsx +7 -6
- package/src/components/views/alloy/mix/rows.tsx +6 -7
- package/src/components/views/alloy/mix/status.tsx +8 -7
- package/src/components/views/alloy/mix/total.tsx +13 -12
- package/src/components/views/alloy/range-bar.tsx +2 -1
- package/src/components/views/alloy/stack-bar.tsx +4 -2
- package/src/components/views/browser/axis-switcher.tsx +13 -12
- package/src/components/views/browser/card-grid.tsx +2 -1
- package/src/components/views/browser/favorite-button.tsx +2 -1
- package/src/components/views/browser/frame.tsx +3 -2
- package/src/components/views/browser/index.tsx +20 -2
- package/src/components/views/browser/item-panel/index.tsx +11 -9
- package/src/components/views/browser/item-panel/skeleton.tsx +1 -0
- package/src/components/views/browser/item-panel-grid/cell.tsx +5 -3
- package/src/components/views/browser/item-panel-grid/favorite-cell.tsx +4 -2
- package/src/components/views/browser/item-panel-grid/index.tsx +4 -2
- package/src/components/views/browser/item-view/index.tsx +7 -12
- package/src/components/views/browser/item-view/tags.tsx +7 -5
- package/src/components/views/browser/item-view-header.tsx +10 -9
- package/src/components/views/browser/pane-tabs.tsx +1 -0
- package/src/components/views/browser/place-header.tsx +4 -3
- package/src/components/views/browser/query-controls.tsx +3 -1
- package/src/components/views/browser/recipe-item-header.tsx +5 -4
- package/src/components/views/browser/settings.tsx +4 -3
- package/src/components/views/browser/toolbar.tsx +3 -2
- package/src/components/views/browser/type-tabs.tsx +5 -3
- package/src/components/views/browser/type-view.tsx +7 -12
- package/src/components/views/browser/workstation-rail.tsx +4 -3
- package/src/components/views/calc/calculator/actions.tsx +4 -14
- package/src/components/views/calc/calculator/help.tsx +69 -28
- package/src/components/views/calc/calculator/index.tsx +34 -82
- package/src/components/views/calc/dot-overlay.tsx +1 -0
- package/src/components/views/calc/edge.tsx +134 -32
- package/src/components/views/calc/flow/index.tsx +92 -54
- package/src/components/views/calc/flow/picker-dialogs.tsx +84 -6
- package/src/components/views/calc/flow/toolbar.tsx +9 -21
- package/src/components/views/calc/flow/view-menu.tsx +16 -120
- package/src/components/views/calc/member-picker.tsx +8 -6
- package/src/components/views/calc/node-card/actions.tsx +28 -106
- package/src/components/views/calc/node-card/badges.tsx +10 -28
- package/src/components/views/calc/node-card/chips.tsx +8 -40
- package/src/components/views/calc/node-card/far.tsx +13 -65
- package/src/components/views/calc/node-card/full.tsx +133 -83
- package/src/components/views/calc/node-card/index.tsx +1 -0
- package/src/components/views/calc/node-card/menu.tsx +93 -22
- package/src/components/views/calc/node-card/port-cells.tsx +186 -0
- package/src/components/views/calc/node-card/port-rails.tsx +251 -0
- package/src/components/views/calc/node-card/ports.tsx +86 -0
- package/src/components/views/calc/recipe-picker/body.tsx +17 -14
- package/src/components/views/calc/recipe-picker/footer.tsx +5 -3
- package/src/components/views/calc/recipe-picker/index.tsx +5 -0
- package/src/components/views/calc/sidebar.tsx +19 -10
- package/src/components/views/calc/trees/icon-picker.tsx +3 -2
- package/src/components/views/calc/trees/index.tsx +5 -4
- package/src/components/views/calc/trees/label.tsx +6 -4
- package/src/components/views/calc/trees/rows.tsx +6 -5
- package/src/components/views/forge/gui.tsx +2 -1
- package/src/components/views/forge/index.tsx +14 -7
- package/src/components/views/forge/list.tsx +3 -2
- package/src/components/views/forge/workbench/controls.tsx +13 -6
- package/src/components/views/forge/workbench/index.tsx +3 -2
- package/src/components/views/forge/workbench/panel.tsx +1 -0
- package/src/components/views/forge/workbench/ruler.tsx +5 -4
- package/src/components/views/forge/workbench/status.tsx +6 -5
- package/src/components/views/forge/workbench/tape.tsx +5 -4
- package/src/hooks/alloy/use-fluid-colors.ts +12 -9
- package/src/hooks/alloy/use-mix-state.ts +3 -2
- package/src/hooks/calc/flow/use-engage.ts +129 -0
- package/src/hooks/calc/flow/use-handlers.ts +192 -0
- package/src/hooks/calc/flow/use-layout.ts +105 -0
- package/src/hooks/calc/flow/{mount.ts → use-mount.ts} +1 -0
- package/src/hooks/calc/flow/{nodes.ts → use-nodes.ts} +46 -37
- package/src/hooks/calc/flow/use-pickers.ts +57 -0
- package/src/hooks/calc/flow/{viewport.ts → use-viewport.ts} +13 -26
- package/src/hooks/calc/flow/{window.ts → use-window.ts} +1 -0
- package/src/hooks/calc/use-actions.ts +208 -229
- package/src/hooks/calc/use-amounts.ts +23 -60
- package/src/hooks/calc/use-data.ts +106 -192
- package/src/hooks/calc/use-defaults.ts +4 -2
- package/src/hooks/calc/use-far-mode.ts +1 -0
- package/src/hooks/calc/use-focus.ts +8 -7
- package/src/hooks/calc/use-maps.ts +1 -0
- package/src/hooks/calc/use-reset.ts +1 -0
- package/src/hooks/calc/use-resolver.ts +32 -196
- package/src/hooks/calc/use-session.ts +1 -0
- package/src/hooks/calc/use-share.ts +5 -2
- package/src/hooks/calc/use-storage.ts +5 -4
- package/src/hooks/calc/use-tier.ts +1 -0
- package/src/hooks/calc/use-view-mode.ts +1 -0
- package/src/hooks/calc/use-worker.ts +56 -121
- package/src/hooks/forge/use-anvil-gui.ts +4 -2
- package/src/hooks/forge/use-forge-state.ts +1 -0
- package/src/hooks/forge/use-ruler.ts +1 -0
- package/src/hooks/use-add-to-calc.ts +23 -19
- package/src/hooks/use-categories-by-id.ts +18 -0
- package/src/hooks/use-favorite-hotkey.ts +1 -0
- package/src/hooks/use-favorites.ts +1 -0
- package/src/hooks/use-group-outlines.ts +1 -0
- package/src/hooks/use-hide-unused.ts +2 -1
- package/src/hooks/use-index.ts +6 -2
- package/src/hooks/use-item-feeds.ts +3 -1
- package/src/hooks/use-item-pane.ts +6 -4
- package/src/hooks/use-item-press.ts +27 -23
- package/src/hooks/use-item-tag-groups.ts +4 -2
- package/src/hooks/use-item-tooltips.ts +3 -1
- package/src/hooks/use-left-sidebar-tree.ts +11 -3
- package/src/hooks/use-mod-names.ts +4 -2
- package/src/hooks/use-mount-limit.ts +1 -0
- package/src/hooks/use-panel-cells.ts +3 -1
- package/src/hooks/use-panel-page.ts +9 -6
- package/src/hooks/use-panel-tabs.ts +2 -1
- package/src/hooks/use-query.ts +8 -6
- package/src/hooks/use-session.ts +6 -2
- package/src/hooks/use-sidebar-group.ts +3 -7
- package/src/hooks/use-tag-members.ts +3 -1
- package/src/hooks/use-tool-recipes.ts +1 -0
- package/src/hooks/use-type-filter.ts +1 -0
- package/src/lib/alloy/mix.ts +1 -0
- package/src/lib/alloy/parse.ts +1 -0
- package/src/lib/calc/defaults.ts +6 -4
- package/src/lib/calc/flow.ts +143 -107
- package/src/lib/calc/focus.ts +1 -0
- package/src/lib/calc/meta.ts +3 -1
- package/src/lib/calc/pack.ts +47 -154
- package/src/lib/calc/ports.ts +43 -0
- package/src/lib/calc/resolve.ts +6 -38
- package/src/lib/calc/route/buckets.ts +1 -0
- package/src/lib/calc/route/geometry.ts +13 -24
- package/src/lib/calc/route/index.ts +1 -0
- package/src/lib/calc/route/polyline.ts +3 -3
- package/src/lib/calc/route/router.ts +181 -57
- package/src/lib/calc/scheme.ts +226 -0
- package/src/lib/calc/storage/entry.ts +27 -19
- package/src/lib/calc/storage/index.ts +2 -0
- package/src/lib/calc/storage/keys.ts +4 -8
- package/src/lib/calc/storage/store.ts +11 -36
- package/src/lib/calc/tree/index.ts +2 -16
- package/src/lib/calc/tree/materials.ts +1 -0
- package/src/lib/calc/tree/recipe.ts +1 -0
- package/src/lib/calc/tree/share.ts +86 -149
- package/src/lib/calc/worker/api.ts +3 -11
- package/src/lib/calc/worker/fetch.ts +1 -0
- package/src/lib/calc/worker/flush.ts +7 -20
- package/src/lib/calc/worker/index.ts +1 -1
- package/src/lib/calc/worker/protocol.ts +16 -13
- package/src/lib/calc/worker/resolve.ts +32 -84
- package/src/lib/calc/worker/state.ts +5 -6
- package/src/{components/cards/card/model.ts → lib/card-model.ts} +1 -0
- package/src/lib/client/recipe-categories.ts +11 -93
- package/src/lib/client/recipe.ts +13 -11
- package/src/lib/client-index/catalog.ts +33 -27
- package/src/lib/client-index/chrome.ts +30 -30
- package/src/lib/client-index/index.ts +1 -0
- package/src/lib/client-index/registry.ts +70 -59
- package/src/lib/client-index/rows.ts +63 -57
- package/src/lib/client-index/tooltips.ts +28 -34
- package/src/lib/config.ts +2 -1
- package/src/lib/data/category/dto.ts +4 -3
- package/src/lib/data/category/load.ts +9 -8
- package/src/lib/data/category/parse.ts +4 -3
- package/src/lib/data/dto.ts +4 -3
- package/src/lib/data/grid.ts +2 -1
- package/src/lib/data/parse/entry.ts +3 -2
- package/src/lib/data/parse/index.ts +1 -0
- package/src/lib/data/parse/layout.ts +5 -2
- package/src/lib/data/parse/slots.ts +3 -2
- package/src/lib/data/parse/widgets.ts +3 -2
- package/src/lib/data/scene.ts +1 -1
- package/src/lib/data/slot-io.ts +1 -0
- package/src/lib/dump.ts +4 -3
- package/src/lib/embed.ts +22 -0
- package/src/lib/favorite-hover.ts +1 -0
- package/src/lib/fluid-outputs.ts +10 -12
- package/src/lib/forge/actions.ts +2 -1
- package/src/lib/forge/data.ts +2 -1
- package/src/lib/forge/solve.ts +1 -0
- package/src/lib/group.ts +1 -0
- package/src/lib/index-store.ts +15 -9
- package/src/lib/links.ts +15 -9
- package/src/lib/lookup.ts +10 -8
- package/src/lib/panel-outline.ts +1 -0
- package/src/lib/panel.ts +3 -2
- package/src/lib/preview.ts +12 -8
- package/src/lib/recipe-slots.ts +1 -0
- package/src/lib/search.ts +1 -0
- package/src/lib/sidebar.ts +1 -0
- package/src/lib/used-items.ts +1 -0
- package/src/locales/en_us.json +170 -226
- package/src/locales/ru_ru.json +170 -226
- package/src/locales.ts +1 -0
- package/src/types/alloy.ts +1 -0
- package/src/{hooks/calc/flow/props.ts → types/calc-flow-props.ts} +18 -14
- package/src/types/calc.ts +41 -44
- package/src/types/forge.ts +1 -0
- package/src/types/index.ts +4 -2
- package/styles/calc.css +308 -47
- package/src/components/cards/fit-card.tsx +0 -26
- package/src/components/views/calc/target.tsx +0 -271
- package/src/hooks/calc/flow/engage.ts +0 -89
- package/src/hooks/calc/flow/handlers.ts +0 -115
- package/src/hooks/calc/flow/layout.ts +0 -149
- package/src/hooks/calc/flow/pickers.ts +0 -50
- package/src/hooks/calc/use-calc-fill.ts +0 -91
- package/src/hooks/calc/use-density.ts +0 -28
- package/src/hooks/calc/use-derived.ts +0 -258
- package/src/hooks/calc/use-direction.ts +0 -23
- package/src/hooks/calc/use-edge-style.ts +0 -40
- package/src/hooks/calc/use-fill.ts +0 -213
- package/src/lib/alloy/alloy.test.ts +0 -186
- package/src/lib/calc/tree/build.ts +0 -196
- package/src/lib/calc/tree/context.ts +0 -42
- package/src/lib/calc/tree/goal.ts +0 -64
- package/src/lib/calc/tree/ideal.ts +0 -36
- package/src/lib/calc/tree/pick.ts +0 -68
- package/src/lib/calc/tree/tree.test.ts +0 -169
- package/src/lib/calc/worker/fill.ts +0 -123
- package/src/lib/client-index/cache.ts +0 -13
- package/src/lib/forge/forge.test.ts +0 -123
|
@@ -1,96 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
import { createAsyncCache } from '@terrafirmagreg-team/ui/lib/utils/async-cache';
|
|
13
|
-
|
|
14
|
-
const clientCategoryFile = createAsyncCache(
|
|
15
|
-
async (dataset: string, ns: string) => {
|
|
16
|
-
const manifest = await loadClientManifest(dataset);
|
|
17
|
-
const listed = manifest?.namespaces[ns];
|
|
18
|
-
if (!listed || !listed.registry.includes('recipe_categories')) {
|
|
19
|
-
return undefined;
|
|
20
|
-
}
|
|
21
|
-
return asRecord(
|
|
22
|
-
await clientDumpJson(
|
|
23
|
-
dataset,
|
|
24
|
-
'registry/recipe_categories.json',
|
|
25
|
-
'high',
|
|
26
|
-
),
|
|
27
|
-
);
|
|
28
|
-
},
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
function categoryFromRaw(
|
|
32
|
-
catalogKey: string,
|
|
33
|
-
raw: unknown,
|
|
34
|
-
): DumpRecipeCategory | undefined {
|
|
35
|
-
return asCategory(
|
|
36
|
-
raw && typeof raw === 'object' && !Array.isArray(raw) && !('id' in raw)
|
|
37
|
-
? { ...raw, id: catalogKey }
|
|
38
|
-
: raw,
|
|
1
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
2
|
+
import { loadDatasetRecipeCategories } from '@terrafirmagreg-team/recipe/lib/data/category/load';
|
|
3
|
+
import type { DumpRecipeLayout } from '@terrafirmagreg-team/recipe/lib/data/category/dto';
|
|
4
|
+
|
|
5
|
+
export function clientRecipeLayout(
|
|
6
|
+
dataset: DatasetRef,
|
|
7
|
+
categoryId: string,
|
|
8
|
+
): Promise<DumpRecipeLayout | undefined> {
|
|
9
|
+
return loadDatasetRecipeCategories(dataset).then(
|
|
10
|
+
(categories) =>
|
|
11
|
+
categories.find((cat) => cat.id === categoryId)?.layout,
|
|
39
12
|
);
|
|
40
13
|
}
|
|
41
14
|
|
|
42
|
-
export const clientRecipeLayout = createAsyncCache(
|
|
43
|
-
async (
|
|
44
|
-
dataset: string,
|
|
45
|
-
categoryId: string,
|
|
46
|
-
): Promise<DumpRecipeLayout | undefined> => {
|
|
47
|
-
const ns = categoryId.split(':', 1)[0];
|
|
48
|
-
if (!ns) return undefined;
|
|
49
|
-
const entries = await clientCategoryFile(dataset, ns);
|
|
50
|
-
return categoryFromRaw(categoryId, entries?.[categoryId])?.layout;
|
|
51
|
-
},
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
function recipeNamespaces(types: RecipeTypeRow[] | undefined): string[] {
|
|
55
|
-
const out = new Set<string>();
|
|
56
|
-
for (const row of types ?? []) {
|
|
57
|
-
const ns = row.id.split(':', 1)[0];
|
|
58
|
-
if (ns) out.add(ns);
|
|
59
|
-
for (const fileNs of Object.keys(row.files ?? {})) {
|
|
60
|
-
if (fileNs) out.add(fileNs);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return [...out];
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export const loadClientRecipeCategories = createAsyncCache(
|
|
67
|
-
async (dataset: string): Promise<DumpRecipeCategory[]> => {
|
|
68
|
-
const merged = asRecord(
|
|
69
|
-
await clientDumpJson(dataset, 'registry/recipe_categories.json'),
|
|
70
|
-
);
|
|
71
|
-
if (merged) {
|
|
72
|
-
const out: DumpRecipeCategory[] = [];
|
|
73
|
-
for (const [catalogKey, raw] of Object.entries(merged)) {
|
|
74
|
-
const cat = categoryFromRaw(catalogKey, raw);
|
|
75
|
-
if (cat) out.push(cat);
|
|
76
|
-
}
|
|
77
|
-
out.sort((a, b) => a.order - b.order || a.id.localeCompare(b.id));
|
|
78
|
-
return out;
|
|
79
|
-
}
|
|
80
|
-
const manifest = await loadClientManifest(dataset);
|
|
81
|
-
const namespaces = recipeNamespaces(manifest?.indexes.recipes.types);
|
|
82
|
-
const out: DumpRecipeCategory[] = [];
|
|
83
|
-
await Promise.all(
|
|
84
|
-
namespaces.map(async (ns) => {
|
|
85
|
-
const entries = await clientCategoryFile(dataset, ns);
|
|
86
|
-
if (!entries) return;
|
|
87
|
-
for (const [catalogKey, raw] of Object.entries(entries)) {
|
|
88
|
-
const cat = categoryFromRaw(catalogKey, raw);
|
|
89
|
-
if (cat) out.push(cat);
|
|
90
|
-
}
|
|
91
|
-
}),
|
|
92
|
-
);
|
|
93
|
-
out.sort((a, b) => a.order - b.order || a.id.localeCompare(b.id));
|
|
94
|
-
return out;
|
|
95
|
-
},
|
|
96
|
-
);
|
package/src/lib/client/recipe.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
2
|
+
import { asRecord, asString } from '@terrafirmagreg-team/dump/lib/dump/contract/read';
|
|
2
3
|
import { parseRecipe } from '@terrafirmagreg-team/recipe/lib/data/parse';
|
|
3
4
|
import type { Recipe } from '@terrafirmagreg-team/recipe/lib/data/dto';
|
|
4
|
-
import { dumpRelPublicUrl } from '@terrafirmagreg-team/
|
|
5
|
+
import { dumpRelPublicUrl } from '@terrafirmagreg-team/dump/lib/dump/paths';
|
|
5
6
|
import {
|
|
6
7
|
clientDumpJson,
|
|
7
8
|
loadClientManifest,
|
|
8
|
-
} from '@terrafirmagreg-team/
|
|
9
|
+
} from '@terrafirmagreg-team/dump/lib/dump/client/dump';
|
|
9
10
|
import { clientRecipeLayout } from '@terrafirmagreg-team/recipe/lib/client/recipe-categories';
|
|
10
|
-
import {
|
|
11
|
+
import { createDatasetCache } from '@terrafirmagreg-team/dump/lib/dump/reader';
|
|
11
12
|
|
|
12
|
-
const recipeIndex =
|
|
13
|
+
const recipeIndex = createDatasetCache(async (dataset: DatasetRef, ns: string) => {
|
|
13
14
|
const manifest = await loadClientManifest(dataset);
|
|
14
15
|
const listed = manifest?.namespaces[ns];
|
|
15
16
|
if (!listed || !listed.registry.includes('recipes')) return undefined;
|
|
@@ -19,7 +20,7 @@ const recipeIndex = createAsyncCache(async (dataset: string, ns: string) => {
|
|
|
19
20
|
});
|
|
20
21
|
|
|
21
22
|
export async function clientRecipeFileRels(
|
|
22
|
-
dataset:
|
|
23
|
+
dataset: DatasetRef,
|
|
23
24
|
recipeId: string,
|
|
24
25
|
): Promise<string[]> {
|
|
25
26
|
const ns = recipeId.split(':', 1)[0];
|
|
@@ -46,19 +47,19 @@ export async function clientRecipeFileRels(
|
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
async function clientRecipeFileRel(
|
|
49
|
-
dataset:
|
|
50
|
+
dataset: DatasetRef,
|
|
50
51
|
recipeId: string,
|
|
51
52
|
): Promise<string | undefined> {
|
|
52
53
|
return (await clientRecipeFileRels(dataset, recipeId))[0];
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
export const loadClientRecipe: (
|
|
56
|
-
dataset:
|
|
57
|
+
dataset: DatasetRef,
|
|
57
58
|
id: string,
|
|
58
59
|
bucket?: string,
|
|
59
|
-
) => Promise<Recipe | undefined> =
|
|
60
|
+
) => Promise<Recipe | undefined> = createDatasetCache(
|
|
60
61
|
async (
|
|
61
|
-
dataset:
|
|
62
|
+
dataset: DatasetRef,
|
|
62
63
|
id: string,
|
|
63
64
|
bucket?: string,
|
|
64
65
|
): Promise<Recipe | undefined> => {
|
|
@@ -74,10 +75,11 @@ export const loadClientRecipe: (
|
|
|
74
75
|
: undefined;
|
|
75
76
|
return parseRecipe(raw, {
|
|
76
77
|
modId: ns,
|
|
77
|
-
bodyUrl: dumpRelPublicUrl(dataset, rel) ?? `/${dataset}`,
|
|
78
|
+
bodyUrl: dumpRelPublicUrl(dataset, rel) ?? `/${dataset.id}`,
|
|
78
79
|
id,
|
|
79
80
|
...(layout ? { layout } : {}),
|
|
80
81
|
});
|
|
81
82
|
},
|
|
82
83
|
(dataset, id, bucket) => JSON.stringify([dataset, id, bucket ?? '']),
|
|
83
84
|
);
|
|
85
|
+
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
1
2
|
import type { RecipeChrome, RecipeCompactIndex } from '@terrafirmagreg-team/recipe/types';
|
|
2
|
-
import {
|
|
3
|
+
import { loadDatasetRecipeCategories } from '@terrafirmagreg-team/recipe/lib/data/category/load';
|
|
3
4
|
import { stackDisplayName } from '@terrafirmagreg-team/game/lib/entry/display';
|
|
4
|
-
import {
|
|
5
|
+
import { createDatasetCache } from '@terrafirmagreg-team/dump/lib/dump/reader';
|
|
5
6
|
import { recipeTypeRows } from './rows';
|
|
6
7
|
|
|
7
|
-
const indexCache = new Map<string, RecipeCompactIndex>();
|
|
8
|
-
const skeletonCache = new Map<string, Promise<RecipeCompactIndex>>();
|
|
9
|
-
|
|
10
8
|
const emptyRecipeIndex = (): RecipeCompactIndex => ({
|
|
11
9
|
types: [],
|
|
12
10
|
items: [],
|
|
@@ -14,7 +12,7 @@ const emptyRecipeIndex = (): RecipeCompactIndex => ({
|
|
|
14
12
|
});
|
|
15
13
|
|
|
16
14
|
async function loadRecipeStructureFromDump(
|
|
17
|
-
dataset:
|
|
15
|
+
dataset: DatasetRef,
|
|
18
16
|
chrome: RecipeChrome,
|
|
19
17
|
): Promise<RecipeCompactIndex> {
|
|
20
18
|
const rows = await recipeTypeRows(dataset);
|
|
@@ -37,33 +35,40 @@ async function loadRecipeStructureFromDump(
|
|
|
37
35
|
};
|
|
38
36
|
}
|
|
39
37
|
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
const indexCache = createDatasetCache(
|
|
39
|
+
async (
|
|
40
|
+
dataset: DatasetRef,
|
|
41
|
+
chrome?: RecipeChrome,
|
|
42
|
+
): Promise<RecipeCompactIndex> => {
|
|
43
|
+
if (!chrome) return emptyRecipeIndex();
|
|
44
|
+
return loadRecipeStructureFromDump(dataset, chrome);
|
|
45
|
+
},
|
|
46
|
+
(dataset, chrome) =>
|
|
47
|
+
`${dataset.id}/${dataset.version ?? ''} ${chrome ? (Object.keys(chrome.names)[0] ?? '') : ''}`,
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const skeletonCache = createDatasetCache(
|
|
51
|
+
async (dataset: DatasetRef): Promise<RecipeCompactIndex> =>
|
|
52
|
+
loadDatasetRecipeCategories(dataset).then((categories) =>
|
|
53
|
+
loadRecipeStructureFromDump(dataset, {
|
|
54
|
+
items: [],
|
|
55
|
+
names: {},
|
|
56
|
+
...(categories.length ? { categories } : {}),
|
|
57
|
+
}),
|
|
58
|
+
),
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
export function loadRecipeCompactIndex(
|
|
62
|
+
dataset: DatasetRef,
|
|
42
63
|
chrome?: RecipeChrome,
|
|
43
64
|
): Promise<RecipeCompactIndex> {
|
|
44
|
-
|
|
45
|
-
const cacheKey = `${dataset} ${lang}`;
|
|
46
|
-
const cached = indexCache.get(cacheKey);
|
|
47
|
-
if (cached) return cached;
|
|
48
|
-
if (!chrome) return emptyRecipeIndex();
|
|
49
|
-
const index = await loadRecipeStructureFromDump(dataset, chrome);
|
|
50
|
-
indexCache.set(cacheKey, index);
|
|
51
|
-
return index;
|
|
65
|
+
return indexCache(dataset, chrome);
|
|
52
66
|
}
|
|
53
67
|
|
|
54
68
|
export function loadRecipeSkeletonIndex(
|
|
55
|
-
dataset:
|
|
69
|
+
dataset: DatasetRef,
|
|
56
70
|
): Promise<RecipeCompactIndex> {
|
|
57
|
-
|
|
58
|
-
if (cached) return cached;
|
|
59
|
-
const pending = loadClientRecipeCategories(dataset).then((categories) =>
|
|
60
|
-
loadRecipeStructureFromDump(dataset, {
|
|
61
|
-
items: [],
|
|
62
|
-
names: {},
|
|
63
|
-
...(categories.length ? { categories } : {}),
|
|
64
|
-
}),
|
|
65
|
-
);
|
|
66
|
-
return memoPending(skeletonCache, dataset, pending);
|
|
71
|
+
return skeletonCache(dataset);
|
|
67
72
|
}
|
|
68
73
|
|
|
69
74
|
export function nonEmptyCategoryIds(
|
|
@@ -83,3 +88,4 @@ export function recipeItemName(
|
|
|
83
88
|
): string {
|
|
84
89
|
return stackDisplayName(names[lang] ?? names.en_us, id);
|
|
85
90
|
}
|
|
91
|
+
|
|
@@ -1,34 +1,33 @@
|
|
|
1
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
1
2
|
import type {
|
|
2
3
|
RecipeCategory,
|
|
3
4
|
RecipeChrome,
|
|
4
5
|
RecipeStackGroup,
|
|
5
6
|
} from '@terrafirmagreg-team/recipe/types';
|
|
6
|
-
import { clientDumpLang, loadClientManifest } from '@terrafirmagreg-team/
|
|
7
|
+
import { clientDumpLang, loadClientManifest } from '@terrafirmagreg-team/dump/lib/dump/client/dump';
|
|
7
8
|
import {
|
|
8
9
|
creativeTabName,
|
|
9
10
|
dumpTextString,
|
|
10
|
-
} from '@terrafirmagreg-team/
|
|
11
|
+
} from '@terrafirmagreg-team/dump/lib/dump/assets/lang/names';
|
|
11
12
|
import { stackDisplayName } from '@terrafirmagreg-team/game/lib/entry/display';
|
|
12
13
|
import {
|
|
13
14
|
loadClientRegistry,
|
|
14
15
|
loadClientRegistryOrder,
|
|
15
16
|
resolveClientStackDisplay,
|
|
16
|
-
} from '@terrafirmagreg-team/
|
|
17
|
-
import { loadClientTagMembers } from '@terrafirmagreg-team/
|
|
18
|
-
import { loadClientTabs } from '@terrafirmagreg-team/
|
|
19
|
-
import {
|
|
20
|
-
import { loadClientRegistryGroups } from '@terrafirmagreg-team/
|
|
21
|
-
import { loadClientModNames } from '@terrafirmagreg-team/
|
|
22
|
-
import { loadClientModAtlases } from '@terrafirmagreg-team/
|
|
23
|
-
import { lookupSpriteInBundle } from '@terrafirmagreg-team/
|
|
24
|
-
import { stackIdBase, stackIdFromRef } from '@terrafirmagreg-team/
|
|
25
|
-
import type { AtlasBundle } from '@terrafirmagreg-team/
|
|
26
|
-
import {
|
|
27
|
-
|
|
28
|
-
const chromeCache = new Map<string, Promise<RecipeChrome>>();
|
|
17
|
+
} from '@terrafirmagreg-team/dump/lib/dump/client/registry';
|
|
18
|
+
import { loadClientTagMembers } from '@terrafirmagreg-team/dump/lib/dump/client/tags';
|
|
19
|
+
import { loadClientTabs } from '@terrafirmagreg-team/dump/lib/dump/client/tabs';
|
|
20
|
+
import { loadDatasetRecipeCategories } from '@terrafirmagreg-team/recipe/lib/data/category/load';
|
|
21
|
+
import { loadClientRegistryGroups } from '@terrafirmagreg-team/dump/lib/dump/client/groups';
|
|
22
|
+
import { loadClientModNames } from '@terrafirmagreg-team/dump/lib/dump/client/mods';
|
|
23
|
+
import { loadClientModAtlases } from '@terrafirmagreg-team/dump/lib/dump/client/atlases';
|
|
24
|
+
import { lookupSpriteInBundle } from '@terrafirmagreg-team/dump/lib/dump/assets/atlas/lookup';
|
|
25
|
+
import { stackIdBase, stackIdFromRef } from '@terrafirmagreg-team/dump/lib/dump/contract/ref';
|
|
26
|
+
import type { AtlasBundle } from '@terrafirmagreg-team/dump/lib/dump/assets/atlas/dto';
|
|
27
|
+
import { createDatasetCache } from '@terrafirmagreg-team/dump/lib/dump/reader';
|
|
29
28
|
|
|
30
29
|
async function clientEntityNames(
|
|
31
|
-
dataset:
|
|
30
|
+
dataset: DatasetRef,
|
|
32
31
|
lang: string,
|
|
33
32
|
ids: Iterable<string>,
|
|
34
33
|
): Promise<Record<string, string>> {
|
|
@@ -78,7 +77,7 @@ async function clientEntityNames(
|
|
|
78
77
|
}
|
|
79
78
|
|
|
80
79
|
async function clientNamedCategories(
|
|
81
|
-
dataset:
|
|
80
|
+
dataset: DatasetRef,
|
|
82
81
|
lang: string,
|
|
83
82
|
types: string[],
|
|
84
83
|
categories: RecipeCategory[],
|
|
@@ -92,13 +91,13 @@ async function clientNamedCategories(
|
|
|
92
91
|
return names;
|
|
93
92
|
}
|
|
94
93
|
|
|
95
|
-
async function clientUsedIds(dataset:
|
|
94
|
+
async function clientUsedIds(dataset: DatasetRef): Promise<string[]> {
|
|
96
95
|
const manifest = await loadClientManifest(dataset);
|
|
97
96
|
return manifest?.indexes.used ?? [];
|
|
98
97
|
}
|
|
99
98
|
|
|
100
99
|
async function clientRecipeGroups(
|
|
101
|
-
dataset:
|
|
100
|
+
dataset: DatasetRef,
|
|
102
101
|
lang: string,
|
|
103
102
|
): Promise<RecipeStackGroup[]> {
|
|
104
103
|
const rows = await loadClientRegistryGroups(dataset);
|
|
@@ -111,20 +110,14 @@ async function clientRecipeGroups(
|
|
|
111
110
|
}));
|
|
112
111
|
}
|
|
113
112
|
|
|
114
|
-
|
|
115
|
-
dataset: string
|
|
116
|
-
lang: string,
|
|
117
|
-
): Promise<RecipeChrome> {
|
|
118
|
-
const key = `${dataset} ${lang}`;
|
|
119
|
-
const cached = chromeCache.get(key);
|
|
120
|
-
if (cached) return cached;
|
|
121
|
-
const pending = (async (): Promise<RecipeChrome> => {
|
|
113
|
+
const loadChrome = createDatasetCache(
|
|
114
|
+
async (dataset: DatasetRef, lang: string): Promise<RecipeChrome> => {
|
|
122
115
|
const [items, fluids, creative, categories, usedIds, itemTags, blockTags] =
|
|
123
116
|
await Promise.all([
|
|
124
117
|
loadClientRegistryOrder(dataset, 'item'),
|
|
125
118
|
loadClientRegistryOrder(dataset, 'fluid'),
|
|
126
119
|
loadClientTabs(dataset),
|
|
127
|
-
|
|
120
|
+
loadDatasetRecipeCategories(dataset),
|
|
128
121
|
clientUsedIds(dataset),
|
|
129
122
|
loadClientTagMembers(dataset, 'item'),
|
|
130
123
|
loadClientTagMembers(dataset, 'block'),
|
|
@@ -175,6 +168,13 @@ export function loadRecipeChromeClient(
|
|
|
175
168
|
[lang]: { ...tabNames, ...categoryNames, ...entityNames },
|
|
176
169
|
},
|
|
177
170
|
};
|
|
178
|
-
}
|
|
179
|
-
|
|
171
|
+
},
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
export function loadRecipeChromeClient(
|
|
175
|
+
dataset: DatasetRef,
|
|
176
|
+
lang: string,
|
|
177
|
+
): Promise<RecipeChrome> {
|
|
178
|
+
return loadChrome(dataset, lang);
|
|
180
179
|
}
|
|
180
|
+
|
|
@@ -1,19 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
2
|
+
import { clientDumpJson } from '@terrafirmagreg-team/dump/lib/dump/client/dump';
|
|
3
|
+
import { loadClientTagMembers } from '@terrafirmagreg-team/dump/lib/dump/client/tags';
|
|
3
4
|
import {
|
|
4
5
|
asRecord,
|
|
5
6
|
asStringList,
|
|
6
7
|
resolveEdgeRows,
|
|
7
|
-
} from '@terrafirmagreg-team/
|
|
8
|
-
import { stackIdBase } from '@terrafirmagreg-team/
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
const registrySliceCache = new Map<
|
|
12
|
-
string,
|
|
13
|
-
Promise<Record<string, Record<string, unknown>>>
|
|
14
|
-
>();
|
|
15
|
-
const tagSliceCache = new Map<string, Promise<Record<string, string[]>>>();
|
|
16
|
-
const tagMembersCache = new Map<string, Promise<Record<string, string[]>>>();
|
|
8
|
+
} from '@terrafirmagreg-team/dump/lib/dump/contract/read';
|
|
9
|
+
import { stackIdBase } from '@terrafirmagreg-team/dump/lib/dump/contract/ref';
|
|
10
|
+
import { createDatasetCache } from '@terrafirmagreg-team/dump/lib/dump/reader';
|
|
17
11
|
|
|
18
12
|
const REGISTRY_FIELD: Record<
|
|
19
13
|
string,
|
|
@@ -29,24 +23,28 @@ function registryField(kind: string) {
|
|
|
29
23
|
return REGISTRY_FIELD[kind] ?? 'items';
|
|
30
24
|
}
|
|
31
25
|
|
|
26
|
+
const registrySliceCache = createDatasetCache(
|
|
27
|
+
async (
|
|
28
|
+
dataset: DatasetRef,
|
|
29
|
+
kind: string,
|
|
30
|
+
): Promise<Record<string, Record<string, unknown>>> => {
|
|
31
|
+
const field = registryField(kind);
|
|
32
|
+
const raw = await clientDumpJson(dataset, `registry/${field}.json`);
|
|
33
|
+
const map = asRecord(raw);
|
|
34
|
+
return map ? resolveEdgeRows(map) : {};
|
|
35
|
+
},
|
|
36
|
+
(dataset, kind) => `${dataset.id}/${dataset.version ?? ''} ${registryField(kind)}`,
|
|
37
|
+
);
|
|
38
|
+
|
|
32
39
|
function loadRegistryFile(
|
|
33
|
-
dataset:
|
|
40
|
+
dataset: DatasetRef,
|
|
34
41
|
kind: string,
|
|
35
42
|
): Promise<Record<string, Record<string, unknown>>> {
|
|
36
|
-
|
|
37
|
-
const key = `${dataset} ${field}`;
|
|
38
|
-
const cached = registrySliceCache.get(key);
|
|
39
|
-
if (cached) return cached;
|
|
40
|
-
const pending = clientDumpJson(dataset, `registry/${field}.json`)
|
|
41
|
-
.then((raw) => {
|
|
42
|
-
const map = asRecord(raw);
|
|
43
|
-
return map ? resolveEdgeRows(map) : {};
|
|
44
|
-
});
|
|
45
|
-
return memoPending(registrySliceCache, key, pending);
|
|
43
|
+
return registrySliceCache(dataset, kind);
|
|
46
44
|
}
|
|
47
45
|
|
|
48
46
|
export async function loadRegistryEntrySlice(
|
|
49
|
-
dataset:
|
|
47
|
+
dataset: DatasetRef,
|
|
50
48
|
kind: string,
|
|
51
49
|
id: string,
|
|
52
50
|
): Promise<Record<string, unknown> | undefined> {
|
|
@@ -55,16 +53,14 @@ export async function loadRegistryEntrySlice(
|
|
|
55
53
|
return map[id] ?? map[base];
|
|
56
54
|
}
|
|
57
55
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const prefix = `${ns}:`;
|
|
67
|
-
const pending = loadRegistryFile(dataset, kind).then((map) => {
|
|
56
|
+
const tagSliceCache = createDatasetCache(
|
|
57
|
+
async (
|
|
58
|
+
dataset: DatasetRef,
|
|
59
|
+
kind: string,
|
|
60
|
+
ns: string,
|
|
61
|
+
): Promise<Record<string, string[]>> => {
|
|
62
|
+
const prefix = `${ns}:`;
|
|
63
|
+
const map = await loadRegistryFile(dataset, kind);
|
|
68
64
|
const out: Record<string, string[]> = {};
|
|
69
65
|
for (const [id, entry] of Object.entries(map)) {
|
|
70
66
|
if (!id.startsWith(prefix)) continue;
|
|
@@ -72,39 +68,54 @@ export function loadTagSlice(
|
|
|
72
68
|
if (tags.length) out[id] = tags;
|
|
73
69
|
}
|
|
74
70
|
return out;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
}
|
|
71
|
+
},
|
|
72
|
+
);
|
|
78
73
|
|
|
79
|
-
function
|
|
80
|
-
dataset:
|
|
74
|
+
export function loadTagSlice(
|
|
75
|
+
dataset: DatasetRef,
|
|
81
76
|
kind: string,
|
|
77
|
+
ns: string,
|
|
82
78
|
): Promise<Record<string, string[]>> {
|
|
83
|
-
|
|
84
|
-
const key = `${dataset} ${memberKind}`;
|
|
85
|
-
const cached = tagMembersCache.get(key);
|
|
86
|
-
if (cached) return cached;
|
|
87
|
-
const pending = loadClientTagMembers(dataset, memberKind).then(
|
|
88
|
-
(raw) => raw ?? {},
|
|
89
|
-
);
|
|
90
|
-
return memoPending(tagMembersCache, key, pending);
|
|
79
|
+
return tagSliceCache(dataset, kind, ns);
|
|
91
80
|
}
|
|
92
81
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
82
|
+
const tagMembersByKindCache = createDatasetCache(
|
|
83
|
+
async (
|
|
84
|
+
dataset: DatasetRef,
|
|
85
|
+
kind: string,
|
|
86
|
+
): Promise<Record<string, string[]>> => {
|
|
87
|
+
const memberKind = registryField(kind) === 'blocks' ? 'block' : 'item';
|
|
88
|
+
return (await loadClientTagMembers(dataset, memberKind)) ?? {};
|
|
89
|
+
},
|
|
90
|
+
(dataset, kind) =>
|
|
91
|
+
`${dataset.id}/${dataset.version ?? ''} ${registryField(kind) === 'blocks' ? 'block' : 'item'}`,
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
const allTagMembersCache = createDatasetCache(
|
|
95
|
+
async (dataset: DatasetRef): Promise<Record<string, string[]>> => {
|
|
96
|
+
const [items, blocks] = await Promise.all([
|
|
97
|
+
loadTagMembersByKind(dataset, 'item'),
|
|
98
|
+
loadTagMembersByKind(dataset, 'block'),
|
|
99
|
+
]);
|
|
103
100
|
const merged: Record<string, string[]> = { ...items };
|
|
104
101
|
for (const [tag, ids] of Object.entries(blocks)) {
|
|
105
102
|
merged[tag] = merged[tag] ? [...merged[tag], ...ids] : ids;
|
|
106
103
|
}
|
|
107
104
|
return merged;
|
|
108
|
-
}
|
|
109
|
-
|
|
105
|
+
},
|
|
106
|
+
(dataset) => `${dataset.id}/${dataset.version ?? ''} all`,
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
function loadTagMembersByKind(
|
|
110
|
+
dataset: DatasetRef,
|
|
111
|
+
kind: string,
|
|
112
|
+
): Promise<Record<string, string[]>> {
|
|
113
|
+
return tagMembersByKindCache(dataset, kind);
|
|
110
114
|
}
|
|
115
|
+
|
|
116
|
+
export function loadAllTagMembers(
|
|
117
|
+
dataset: DatasetRef,
|
|
118
|
+
): Promise<Record<string, string[]>> {
|
|
119
|
+
return allTagMembersCache(dataset);
|
|
120
|
+
}
|
|
121
|
+
|