@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.
Files changed (240) hide show
  1. package/package.json +16 -16
  2. package/src/components/button-copy.tsx +1 -0
  3. package/src/components/cards/card/index.tsx +5 -3
  4. package/src/components/cards/card/scene.tsx +4 -2
  5. package/src/components/cards/card/strip.tsx +4 -2
  6. package/src/components/cards/card/text.tsx +2 -1
  7. package/src/components/cards/card/tips.tsx +1 -0
  8. package/src/components/cards/default-item.tsx +6 -2
  9. package/src/components/cards/glare-filter.tsx +1 -0
  10. package/src/components/cards/paged-card.tsx +1 -0
  11. package/src/components/cards/slot-hitbox.tsx +4 -2
  12. package/src/components/cards/strip-card/buttons.tsx +7 -2
  13. package/src/components/cards/strip-card/index.tsx +3 -1
  14. package/src/components/cards/strip-card/member-cell.tsx +4 -2
  15. package/src/components/cards/strip-card/sprite.tsx +1 -0
  16. package/src/components/embed-card.tsx +44 -0
  17. package/src/components/mdx/recipe.tsx +34 -16
  18. package/src/components/tool-list.tsx +1 -0
  19. package/src/{lib/tree.ts → components/tree.tsx} +20 -12
  20. package/src/components/views/alloy/index.tsx +14 -7
  21. package/src/components/views/alloy/list.tsx +3 -2
  22. package/src/components/views/alloy/mix/index.tsx +1 -0
  23. package/src/components/views/alloy/mix/ratio.tsx +7 -6
  24. package/src/components/views/alloy/mix/rows.tsx +6 -7
  25. package/src/components/views/alloy/mix/status.tsx +8 -7
  26. package/src/components/views/alloy/mix/total.tsx +13 -12
  27. package/src/components/views/alloy/range-bar.tsx +2 -1
  28. package/src/components/views/alloy/stack-bar.tsx +4 -2
  29. package/src/components/views/browser/axis-switcher.tsx +13 -12
  30. package/src/components/views/browser/card-grid.tsx +2 -1
  31. package/src/components/views/browser/favorite-button.tsx +2 -1
  32. package/src/components/views/browser/frame.tsx +3 -2
  33. package/src/components/views/browser/index.tsx +20 -2
  34. package/src/components/views/browser/item-panel/index.tsx +11 -9
  35. package/src/components/views/browser/item-panel/skeleton.tsx +1 -0
  36. package/src/components/views/browser/item-panel-grid/cell.tsx +5 -3
  37. package/src/components/views/browser/item-panel-grid/favorite-cell.tsx +4 -2
  38. package/src/components/views/browser/item-panel-grid/index.tsx +4 -2
  39. package/src/components/views/browser/item-view/index.tsx +7 -12
  40. package/src/components/views/browser/item-view/tags.tsx +7 -5
  41. package/src/components/views/browser/item-view-header.tsx +10 -9
  42. package/src/components/views/browser/pane-tabs.tsx +1 -0
  43. package/src/components/views/browser/place-header.tsx +4 -3
  44. package/src/components/views/browser/query-controls.tsx +3 -1
  45. package/src/components/views/browser/recipe-item-header.tsx +5 -4
  46. package/src/components/views/browser/settings.tsx +4 -3
  47. package/src/components/views/browser/toolbar.tsx +3 -2
  48. package/src/components/views/browser/type-tabs.tsx +5 -3
  49. package/src/components/views/browser/type-view.tsx +7 -12
  50. package/src/components/views/browser/workstation-rail.tsx +4 -3
  51. package/src/components/views/calc/calculator/actions.tsx +4 -14
  52. package/src/components/views/calc/calculator/help.tsx +69 -28
  53. package/src/components/views/calc/calculator/index.tsx +34 -82
  54. package/src/components/views/calc/dot-overlay.tsx +1 -0
  55. package/src/components/views/calc/edge.tsx +134 -32
  56. package/src/components/views/calc/flow/index.tsx +92 -54
  57. package/src/components/views/calc/flow/picker-dialogs.tsx +84 -6
  58. package/src/components/views/calc/flow/toolbar.tsx +9 -21
  59. package/src/components/views/calc/flow/view-menu.tsx +16 -120
  60. package/src/components/views/calc/member-picker.tsx +8 -6
  61. package/src/components/views/calc/node-card/actions.tsx +28 -106
  62. package/src/components/views/calc/node-card/badges.tsx +10 -28
  63. package/src/components/views/calc/node-card/chips.tsx +8 -40
  64. package/src/components/views/calc/node-card/far.tsx +13 -65
  65. package/src/components/views/calc/node-card/full.tsx +133 -83
  66. package/src/components/views/calc/node-card/index.tsx +1 -0
  67. package/src/components/views/calc/node-card/menu.tsx +93 -22
  68. package/src/components/views/calc/node-card/port-cells.tsx +186 -0
  69. package/src/components/views/calc/node-card/port-rails.tsx +251 -0
  70. package/src/components/views/calc/node-card/ports.tsx +86 -0
  71. package/src/components/views/calc/recipe-picker/body.tsx +17 -14
  72. package/src/components/views/calc/recipe-picker/footer.tsx +5 -3
  73. package/src/components/views/calc/recipe-picker/index.tsx +5 -0
  74. package/src/components/views/calc/sidebar.tsx +19 -10
  75. package/src/components/views/calc/trees/icon-picker.tsx +3 -2
  76. package/src/components/views/calc/trees/index.tsx +5 -4
  77. package/src/components/views/calc/trees/label.tsx +6 -4
  78. package/src/components/views/calc/trees/rows.tsx +6 -5
  79. package/src/components/views/forge/gui.tsx +2 -1
  80. package/src/components/views/forge/index.tsx +14 -7
  81. package/src/components/views/forge/list.tsx +3 -2
  82. package/src/components/views/forge/workbench/controls.tsx +13 -6
  83. package/src/components/views/forge/workbench/index.tsx +3 -2
  84. package/src/components/views/forge/workbench/panel.tsx +1 -0
  85. package/src/components/views/forge/workbench/ruler.tsx +5 -4
  86. package/src/components/views/forge/workbench/status.tsx +6 -5
  87. package/src/components/views/forge/workbench/tape.tsx +5 -4
  88. package/src/hooks/alloy/use-fluid-colors.ts +12 -9
  89. package/src/hooks/alloy/use-mix-state.ts +3 -2
  90. package/src/hooks/calc/flow/use-engage.ts +129 -0
  91. package/src/hooks/calc/flow/use-handlers.ts +192 -0
  92. package/src/hooks/calc/flow/use-layout.ts +105 -0
  93. package/src/hooks/calc/flow/{mount.ts → use-mount.ts} +1 -0
  94. package/src/hooks/calc/flow/{nodes.ts → use-nodes.ts} +46 -37
  95. package/src/hooks/calc/flow/use-pickers.ts +57 -0
  96. package/src/hooks/calc/flow/{viewport.ts → use-viewport.ts} +13 -26
  97. package/src/hooks/calc/flow/{window.ts → use-window.ts} +1 -0
  98. package/src/hooks/calc/use-actions.ts +208 -229
  99. package/src/hooks/calc/use-amounts.ts +23 -60
  100. package/src/hooks/calc/use-data.ts +106 -192
  101. package/src/hooks/calc/use-defaults.ts +4 -2
  102. package/src/hooks/calc/use-far-mode.ts +1 -0
  103. package/src/hooks/calc/use-focus.ts +8 -7
  104. package/src/hooks/calc/use-maps.ts +1 -0
  105. package/src/hooks/calc/use-reset.ts +1 -0
  106. package/src/hooks/calc/use-resolver.ts +32 -196
  107. package/src/hooks/calc/use-session.ts +1 -0
  108. package/src/hooks/calc/use-share.ts +5 -2
  109. package/src/hooks/calc/use-storage.ts +5 -4
  110. package/src/hooks/calc/use-tier.ts +1 -0
  111. package/src/hooks/calc/use-view-mode.ts +1 -0
  112. package/src/hooks/calc/use-worker.ts +56 -121
  113. package/src/hooks/forge/use-anvil-gui.ts +4 -2
  114. package/src/hooks/forge/use-forge-state.ts +1 -0
  115. package/src/hooks/forge/use-ruler.ts +1 -0
  116. package/src/hooks/use-add-to-calc.ts +23 -19
  117. package/src/hooks/use-categories-by-id.ts +18 -0
  118. package/src/hooks/use-favorite-hotkey.ts +1 -0
  119. package/src/hooks/use-favorites.ts +1 -0
  120. package/src/hooks/use-group-outlines.ts +1 -0
  121. package/src/hooks/use-hide-unused.ts +2 -1
  122. package/src/hooks/use-index.ts +6 -2
  123. package/src/hooks/use-item-feeds.ts +3 -1
  124. package/src/hooks/use-item-pane.ts +6 -4
  125. package/src/hooks/use-item-press.ts +27 -23
  126. package/src/hooks/use-item-tag-groups.ts +4 -2
  127. package/src/hooks/use-item-tooltips.ts +3 -1
  128. package/src/hooks/use-left-sidebar-tree.ts +11 -3
  129. package/src/hooks/use-mod-names.ts +4 -2
  130. package/src/hooks/use-mount-limit.ts +1 -0
  131. package/src/hooks/use-panel-cells.ts +3 -1
  132. package/src/hooks/use-panel-page.ts +9 -6
  133. package/src/hooks/use-panel-tabs.ts +2 -1
  134. package/src/hooks/use-query.ts +8 -6
  135. package/src/hooks/use-session.ts +6 -2
  136. package/src/hooks/use-sidebar-group.ts +3 -7
  137. package/src/hooks/use-tag-members.ts +3 -1
  138. package/src/hooks/use-tool-recipes.ts +1 -0
  139. package/src/hooks/use-type-filter.ts +1 -0
  140. package/src/lib/alloy/mix.ts +1 -0
  141. package/src/lib/alloy/parse.ts +1 -0
  142. package/src/lib/calc/defaults.ts +6 -4
  143. package/src/lib/calc/flow.ts +143 -107
  144. package/src/lib/calc/focus.ts +1 -0
  145. package/src/lib/calc/meta.ts +3 -1
  146. package/src/lib/calc/pack.ts +47 -154
  147. package/src/lib/calc/ports.ts +43 -0
  148. package/src/lib/calc/resolve.ts +6 -38
  149. package/src/lib/calc/route/buckets.ts +1 -0
  150. package/src/lib/calc/route/geometry.ts +13 -24
  151. package/src/lib/calc/route/index.ts +1 -0
  152. package/src/lib/calc/route/polyline.ts +3 -3
  153. package/src/lib/calc/route/router.ts +181 -57
  154. package/src/lib/calc/scheme.ts +226 -0
  155. package/src/lib/calc/storage/entry.ts +27 -19
  156. package/src/lib/calc/storage/index.ts +2 -0
  157. package/src/lib/calc/storage/keys.ts +4 -8
  158. package/src/lib/calc/storage/store.ts +11 -36
  159. package/src/lib/calc/tree/index.ts +2 -16
  160. package/src/lib/calc/tree/materials.ts +1 -0
  161. package/src/lib/calc/tree/recipe.ts +1 -0
  162. package/src/lib/calc/tree/share.ts +86 -149
  163. package/src/lib/calc/worker/api.ts +3 -11
  164. package/src/lib/calc/worker/fetch.ts +1 -0
  165. package/src/lib/calc/worker/flush.ts +7 -20
  166. package/src/lib/calc/worker/index.ts +1 -1
  167. package/src/lib/calc/worker/protocol.ts +16 -13
  168. package/src/lib/calc/worker/resolve.ts +32 -84
  169. package/src/lib/calc/worker/state.ts +5 -6
  170. package/src/{components/cards/card/model.ts → lib/card-model.ts} +1 -0
  171. package/src/lib/client/recipe-categories.ts +11 -93
  172. package/src/lib/client/recipe.ts +13 -11
  173. package/src/lib/client-index/catalog.ts +33 -27
  174. package/src/lib/client-index/chrome.ts +30 -30
  175. package/src/lib/client-index/index.ts +1 -0
  176. package/src/lib/client-index/registry.ts +70 -59
  177. package/src/lib/client-index/rows.ts +63 -57
  178. package/src/lib/client-index/tooltips.ts +28 -34
  179. package/src/lib/config.ts +2 -1
  180. package/src/lib/data/category/dto.ts +4 -3
  181. package/src/lib/data/category/load.ts +9 -8
  182. package/src/lib/data/category/parse.ts +4 -3
  183. package/src/lib/data/dto.ts +4 -3
  184. package/src/lib/data/grid.ts +2 -1
  185. package/src/lib/data/parse/entry.ts +3 -2
  186. package/src/lib/data/parse/index.ts +1 -0
  187. package/src/lib/data/parse/layout.ts +5 -2
  188. package/src/lib/data/parse/slots.ts +3 -2
  189. package/src/lib/data/parse/widgets.ts +3 -2
  190. package/src/lib/data/scene.ts +1 -1
  191. package/src/lib/data/slot-io.ts +1 -0
  192. package/src/lib/dump.ts +4 -3
  193. package/src/lib/embed.ts +22 -0
  194. package/src/lib/favorite-hover.ts +1 -0
  195. package/src/lib/fluid-outputs.ts +10 -12
  196. package/src/lib/forge/actions.ts +2 -1
  197. package/src/lib/forge/data.ts +2 -1
  198. package/src/lib/forge/solve.ts +1 -0
  199. package/src/lib/group.ts +1 -0
  200. package/src/lib/index-store.ts +15 -9
  201. package/src/lib/links.ts +15 -9
  202. package/src/lib/lookup.ts +10 -8
  203. package/src/lib/panel-outline.ts +1 -0
  204. package/src/lib/panel.ts +3 -2
  205. package/src/lib/preview.ts +12 -8
  206. package/src/lib/recipe-slots.ts +1 -0
  207. package/src/lib/search.ts +1 -0
  208. package/src/lib/sidebar.ts +1 -0
  209. package/src/lib/used-items.ts +1 -0
  210. package/src/locales/en_us.json +170 -226
  211. package/src/locales/ru_ru.json +170 -226
  212. package/src/locales.ts +1 -0
  213. package/src/types/alloy.ts +1 -0
  214. package/src/{hooks/calc/flow/props.ts → types/calc-flow-props.ts} +18 -14
  215. package/src/types/calc.ts +41 -44
  216. package/src/types/forge.ts +1 -0
  217. package/src/types/index.ts +4 -2
  218. package/styles/calc.css +308 -47
  219. package/src/components/cards/fit-card.tsx +0 -26
  220. package/src/components/views/calc/target.tsx +0 -271
  221. package/src/hooks/calc/flow/engage.ts +0 -89
  222. package/src/hooks/calc/flow/handlers.ts +0 -115
  223. package/src/hooks/calc/flow/layout.ts +0 -149
  224. package/src/hooks/calc/flow/pickers.ts +0 -50
  225. package/src/hooks/calc/use-calc-fill.ts +0 -91
  226. package/src/hooks/calc/use-density.ts +0 -28
  227. package/src/hooks/calc/use-derived.ts +0 -258
  228. package/src/hooks/calc/use-direction.ts +0 -23
  229. package/src/hooks/calc/use-edge-style.ts +0 -40
  230. package/src/hooks/calc/use-fill.ts +0 -213
  231. package/src/lib/alloy/alloy.test.ts +0 -186
  232. package/src/lib/calc/tree/build.ts +0 -196
  233. package/src/lib/calc/tree/context.ts +0 -42
  234. package/src/lib/calc/tree/goal.ts +0 -64
  235. package/src/lib/calc/tree/ideal.ts +0 -36
  236. package/src/lib/calc/tree/pick.ts +0 -68
  237. package/src/lib/calc/tree/tree.test.ts +0 -169
  238. package/src/lib/calc/worker/fill.ts +0 -123
  239. package/src/lib/client-index/cache.ts +0 -13
  240. package/src/lib/forge/forge.test.ts +0 -123
@@ -1,258 +0,0 @@
1
- 'use client';
2
-
3
- import { useCallback, useMemo } from 'react';
4
- import {
5
- AUTO_NODE_BUDGET,
6
- buildGoal,
7
- flattenTree,
8
- idealBatchMultiplier,
9
- mergeAmounts,
10
- type BuildContext,
11
- type CalcGoal,
12
- } from '@terrafirmagreg-team/recipe/lib/calc/tree';
13
- import {
14
- pickAutoRecipe,
15
- summaryCacheFor,
16
- summarizeRecipes,
17
- } from '@terrafirmagreg-team/recipe/lib/calc/resolve';
18
- import type { RecipeCompactRow, RecipeCompactIndex } from '@terrafirmagreg-team/recipe/types';
19
- import type {
20
- CalcKind,
21
- CalcMaterial,
22
- CalcNode,
23
- CalcRecipe,
24
- CalcRecipeSummary,
25
- CalculatorTarget,
26
- TagResolution,
27
- } from '@terrafirmagreg-team/recipe/types/calc';
28
-
29
- export type CalcDataMaps = {
30
- outMap: Map<string, RecipeCompactRow[]>;
31
- recipeMap: Map<string, CalcRecipe>;
32
- tagMap: Map<string, TagResolution>;
33
- deadIds: ReadonlySet<string>;
34
- };
35
-
36
- export function useCalcDerived({
37
- catalog,
38
- target,
39
- inventory,
40
- auto,
41
- effectiveSelections,
42
- tagSelections,
43
- collapsedSet,
44
- data,
45
- workerDriven,
46
- workerGoals,
47
- workerSummary,
48
- workerSettled,
49
- }: {
50
- catalog: RecipeCompactIndex | null;
51
- target: CalculatorTarget | null;
52
- inventory: CalcMaterial[];
53
- auto: string[];
54
- effectiveSelections: Record<string, string>;
55
- tagSelections: Record<string, string>;
56
- collapsedSet: Set<string>;
57
- data: CalcDataMaps;
58
- workerDriven: boolean;
59
- workerGoals: CalcGoal[] | null;
60
- workerSummary: { raw: CalcMaterial[]; catalysts: CalcMaterial[] } | null;
61
- workerSettled: boolean;
62
- }) {
63
- const { outMap: dataOutMap, recipeMap: dataRecipeMap } = data;
64
- const { tagMap: dataTagMap, deadIds: dataDeadIds } = data;
65
-
66
- const tagMembers = useCallback(
67
- (tagId: string): TagResolution | undefined => dataTagMap.get(tagId),
68
- [dataTagMap],
69
- );
70
-
71
- const getRecipesForItem = useCallback(
72
- (materialId: string, kind: CalcKind): CalcRecipeSummary[] => {
73
- if (!catalog) return [];
74
- return summarizeRecipes(
75
- dataOutMap,
76
- dataRecipeMap,
77
- catalog.types,
78
- summaryCacheFor(dataOutMap, dataRecipeMap),
79
- materialId,
80
- kind,
81
- );
82
- },
83
- [catalog, dataOutMap, dataRecipeMap],
84
- );
85
-
86
- const buildCtx = useCallback(
87
- (
88
- autoRoots: readonly string[] = [],
89
- extraSelections?: Record<string, string>,
90
- recipePool?: Map<string, CalcRecipe>,
91
- ): Omit<BuildContext, 'pool' | 'used' | 'usedMaterials'> => ({
92
- recipeMap: recipePool ?? dataRecipeMap,
93
- getRecipesForItem,
94
- selections: extraSelections ?? effectiveSelections,
95
- tagSelections,
96
- tagMembers,
97
- collapsed: collapsedSet,
98
- autoRoots,
99
- autoBudget: { left: AUTO_NODE_BUDGET },
100
- recipesResolved: (id) => dataOutMap.has(id),
101
- deadIds: dataDeadIds,
102
- }),
103
- [
104
- dataRecipeMap,
105
- getRecipesForItem,
106
- effectiveSelections,
107
- tagSelections,
108
- tagMembers,
109
- collapsedSet,
110
- dataOutMap,
111
- dataDeadIds,
112
- ],
113
- );
114
-
115
- const goals = useMemo<CalcGoal[]>(() => {
116
-
117
- if (!target) return [];
118
-
119
- if (workerGoals?.length) return workerGoals;
120
- return [buildGoal(target, buildCtx(auto), 'g0', inventory)];
121
- }, [workerGoals, target, inventory, buildCtx, auto]);
122
-
123
- const tagIds = useMemo(() => {
124
- if (workerDriven) return [] as string[];
125
- const ids = new Set<string>();
126
- const walk = (n: CalcNode): void => {
127
- if (n.tagId) ids.add(n.tagId);
128
- if (n.recipe) {
129
- for (const input of n.recipe.inputs) {
130
- if (input.tagId) ids.add(input.tagId);
131
- }
132
- }
133
- n.children.forEach(walk);
134
- };
135
- for (const goal of goals) walk(goal.node);
136
- return [...ids];
137
- }, [goals, workerDriven]);
138
-
139
- const materialIds = useMemo(() => {
140
- if (workerDriven) return [] as string[];
141
- const ids = new Set<string>();
142
- if (target) ids.add(target.id);
143
- const walk = (n: CalcNode): void => {
144
- ids.add(n.materialId);
145
- n.children.forEach(walk);
146
- };
147
- for (const goal of goals) walk(goal.node);
148
- return [...ids];
149
- }, [target, goals, workerDriven]);
150
-
151
- const needed = useMemo(() => {
152
- const empty = { recipes: [] as string[], outs: [] as string[] };
153
- if (workerDriven) return empty;
154
- const recipes = new Set<string>();
155
- const outs = new Set<string>();
156
- const pickCtx = {
157
- recipeMap: dataRecipeMap,
158
- getRecipesForItem,
159
- recipesResolved: (id: string) => dataOutMap.has(id),
160
- deadIds: dataDeadIds,
161
- };
162
- for (const id of Object.values(effectiveSelections)) {
163
- if (id) recipes.add(id);
164
- }
165
- const walk = (n: CalcNode, ancestors: Set<string>): void => {
166
- const next =
167
- n.recipe && n.need > 0
168
- ? new Set(ancestors).add(`${n.kind}:${n.materialId}`)
169
- : ancestors;
170
- if (!n.recipe && n.auto && n.availableRecipes.length) {
171
- const autoPick = pickAutoRecipe(
172
- n,
173
- effectiveSelections,
174
- ancestors,
175
- pickCtx,
176
- );
177
- if (autoPick.pick) recipes.add(autoPick.pick);
178
- for (const id of autoPick.wantRecipes) recipes.add(id);
179
- for (const id of autoPick.wantOut) outs.add(id);
180
- }
181
- for (const child of n.children) walk(child, next);
182
- };
183
- for (const goal of goals) walk(goal.node, new Set());
184
- return { recipes: [...recipes], outs: [...outs] };
185
- }, [
186
- effectiveSelections,
187
- goals,
188
- dataDeadIds,
189
- workerDriven,
190
- dataRecipeMap,
191
- dataOutMap,
192
- getRecipesForItem,
193
- ]);
194
-
195
- const dataSettled = useMemo(
196
- () =>
197
- workerDriven
198
- ? workerSettled
199
- : materialIds.every((id) => dataOutMap.has(id)) &&
200
- tagIds.every((id) => dataTagMap.has(id)) &&
201
- needed.recipes.every(
202
- (id) => dataRecipeMap.has(id) || dataDeadIds.has(id),
203
- ) &&
204
- needed.outs.every((id) => dataOutMap.has(id)),
205
- [
206
- workerDriven,
207
- workerSettled,
208
- materialIds,
209
- dataOutMap,
210
- tagIds,
211
- dataTagMap,
212
- needed,
213
- dataRecipeMap,
214
- dataDeadIds,
215
- ],
216
- );
217
-
218
- const summary = useMemo(() => {
219
- const remainders: CalcMaterial[] = [];
220
- for (const goal of goals) remainders.push(...goal.remainders);
221
- if (workerSummary) {
222
- return {
223
- raw: workerSummary.raw,
224
- remainders: mergeAmounts(remainders),
225
- catalysts: workerSummary.catalysts,
226
- };
227
- }
228
- const raw: CalcMaterial[] = [];
229
- const catalysts: CalcMaterial[] = [];
230
- for (const goal of goals) {
231
- const flat = flattenTree(goal.node);
232
- raw.push(...flat.cost);
233
- catalysts.push(...flat.catalysts);
234
- }
235
- return {
236
- raw: mergeAmounts(raw),
237
- remainders: mergeAmounts(remainders),
238
- catalysts: mergeAmounts(catalysts),
239
- };
240
- }, [goals, workerSummary]);
241
-
242
- const ideal = useMemo(() => {
243
- const root = goals[0]?.node;
244
- if (!root) return 1;
245
- const mult = idealBatchMultiplier(root);
246
- return Number.isFinite(mult) ? mult : Infinity;
247
- }, [goals]);
248
-
249
- return {
250
- tagMembers,
251
- getRecipesForItem,
252
- buildCtx,
253
- goals,
254
- dataSettled,
255
- summary,
256
- ideal,
257
- };
258
- }
@@ -1,23 +0,0 @@
1
- 'use client';
2
-
3
- import { startTransition, useCallback } from 'react';
4
- import {
5
- createStoredValue,
6
- literalCodec,
7
- } from '@terrafirmagreg-team/ui/lib/utils/stored-value';
8
- import type { CalcDirection } from '@terrafirmagreg-team/recipe/lib/calc/flow';
9
-
10
- const DIRS: CalcDirection[] = ['vertical', 'horizontal'];
11
- const useStoredDir = createStoredValue(
12
- 'calc:dir',
13
- literalCodec(DIRS, 'vertical'),
14
- );
15
-
16
- export function useCalcDirection() {
17
- const [dir, setStored] = useStoredDir();
18
- const setDir = useCallback(
19
- (next: CalcDirection) => startTransition(() => setStored(next)),
20
- [setStored],
21
- );
22
- return [dir, setDir] as const;
23
- }
@@ -1,40 +0,0 @@
1
- 'use client';
2
-
3
- import { startTransition, useCallback } from 'react';
4
- import {
5
- createStoredValue,
6
- type StoredCodec,
7
- } from '@terrafirmagreg-team/ui/lib/utils/stored-value';
8
- import type { CalcEdgeStyle } from '@terrafirmagreg-team/recipe/lib/calc/flow';
9
-
10
- const STYLES: CalcEdgeStyle[] = [
11
- 'default',
12
- 'straight',
13
- 'step',
14
- 'smoothstep',
15
- 'circuit',
16
- ];
17
-
18
- const MIGRATED: Record<string, CalcEdgeStyle> = {
19
- corner: 'step',
20
- route: 'circuit',
21
- };
22
- const codec: StoredCodec<CalcEdgeStyle> = {
23
- read: (raw) =>
24
- raw == null
25
- ? 'default'
26
- : STYLES.includes(raw as CalcEdgeStyle)
27
- ? (raw as CalcEdgeStyle)
28
- : (MIGRATED[raw] ?? 'default'),
29
- write: (value) => value,
30
- };
31
- const useStoredStyle = createStoredValue('calc:edge', codec);
32
-
33
- export function useCalcEdgeStyle() {
34
- const [style, setStored] = useStoredStyle();
35
- const setStyle = useCallback((next: CalcEdgeStyle) => {
36
-
37
- startTransition(() => setStored(next));
38
- }, [setStored]);
39
- return [style, setStyle] as const;
40
- }
@@ -1,213 +0,0 @@
1
- 'use client';
2
-
3
- import { useCallback } from 'react';
4
- import {
5
- AUTO_NODE_BUDGET,
6
- buildGoal,
7
- type BuildContext,
8
- type CalcGoal,
9
- } from '@terrafirmagreg-team/recipe/lib/calc/tree';
10
- import {
11
- createFrameBudget,
12
- createSummaries,
13
- fetchSlices,
14
- pickAutoRecipe,
15
- } from '@terrafirmagreg-team/recipe/lib/calc/resolve';
16
- import type { RecipeCompactIndex } from '@terrafirmagreg-team/recipe/types';
17
- import type {
18
- CalcMaterial,
19
- CalcNode,
20
- CalculatorTarget,
21
- } from '@terrafirmagreg-team/recipe/types/calc';
22
- import type { CalcMaps, CalcMapsSlice } from './use-maps';
23
- import type { useCalcWorker } from './use-worker';
24
-
25
- type WorkerSlice = ReturnType<typeof useCalcWorker>;
26
-
27
- export function useFillTree({
28
- catalog,
29
- dataset,
30
- target,
31
- inventory,
32
- effectiveSelections,
33
- tagSelections,
34
- collapsed,
35
- auto,
36
- maps,
37
- applyMaps,
38
- worker,
39
- }: {
40
- catalog: RecipeCompactIndex | null;
41
- dataset: string;
42
- target: CalculatorTarget | null;
43
- inventory: CalcMaterial[];
44
- effectiveSelections: Record<string, string>;
45
- tagSelections: Record<string, string>;
46
- collapsed: string[];
47
- auto: string[];
48
- maps: CalcMaps;
49
- applyMaps: (src: CalcMapsSlice) => void;
50
- worker: Pick<WorkerSlice, 'ref' | 'call'>;
51
- }) {
52
- const { recipeMap, bodyMap, outMap, tagMap, deadIds } = maps;
53
- const { ref: workerRef, call } = worker;
54
- return useCallback(
55
- async (roots: readonly string[]) => {
56
- const picks: Record<string, string> = {};
57
- if (!catalog) return picks;
58
- if (workerRef.current) {
59
- return (
60
- (await call((api) =>
61
- api.fill({
62
- roots: [...roots],
63
- target,
64
- inventory,
65
- selections: effectiveSelections,
66
- tagSelections,
67
- collapsed,
68
- auto,
69
- }),
70
- ).catch(() => null)) ?? picks
71
- );
72
- }
73
- const localRecipes = new Map(recipeMap);
74
- const localOut = new Map(outMap);
75
- const localTag = new Map(tagMap);
76
- const localBodies = new Map(bodyMap);
77
- const openCollapsed = new Set<string>();
78
- const deadLocal = new Set(deadIds);
79
- const summaries = createSummaries(catalog, localOut, localRecipes);
80
- const yieldToInput = createFrameBudget();
81
- let latestGoals: CalcGoal[] = [];
82
- for (let iter = 0; iter < 200 && roots.length; iter += 1) {
83
- await yieldToInput();
84
- const merged = { ...effectiveSelections, ...picks };
85
- const ctxAuto = (
86
- budget: number,
87
- ): Omit<BuildContext, 'pool' | 'used' | 'usedMaterials'> => ({
88
- recipeMap: localRecipes,
89
- getRecipesForItem: summaries.get,
90
- selections: merged,
91
- tagSelections,
92
- tagMembers: (id) => localTag.get(id),
93
- collapsed: openCollapsed,
94
- autoRoots: roots,
95
- autoBudget: { left: budget },
96
- recipesResolved: (id) => localOut.has(id),
97
- deadIds: deadLocal,
98
- });
99
- const wanted = new Set<string>();
100
- const wantedOut = new Set<string>();
101
- const wantedTag = new Set<string>();
102
- const built: CalcGoal[] = [];
103
- if (target) {
104
- const goalCtx = ctxAuto(AUTO_NODE_BUDGET);
105
- const goal = buildGoal(target, goalCtx, 'g0', inventory);
106
- built.push(goal);
107
- const walk = (n: CalcNode, ancestors: Set<string>): void => {
108
- const next =
109
- n.recipe && n.need > 0
110
- ? new Set(ancestors).add(`${n.kind}:${n.materialId}`)
111
- : ancestors;
112
- if (n.path) {
113
- if (n.recipe) picks[n.path] = n.recipe.recipeId;
114
- else if (n.auto && !n.catalyst && n.availableRecipes.length) {
115
- const autoPick = pickAutoRecipe(
116
- n,
117
- merged,
118
- ancestors,
119
- goalCtx,
120
- );
121
- if (
122
- autoPick.pick &&
123
- !localRecipes.has(autoPick.pick) &&
124
- !deadLocal.has(autoPick.pick)
125
- )
126
- wanted.add(autoPick.pick);
127
- for (const id of autoPick.wantRecipes) {
128
- if (!localRecipes.has(id) && !deadLocal.has(id))
129
- wanted.add(id);
130
- }
131
- for (const id of autoPick.wantOut) {
132
- if (!localOut.has(id)) wantedOut.add(id);
133
- }
134
- }
135
- }
136
- if (n.tagId && !localTag.has(n.tagId)) {
137
- wantedTag.add(n.tagId);
138
- } else if (!localOut.has(n.materialId)) {
139
- wantedOut.add(n.materialId);
140
- }
141
- for (const child of n.children) walk(child, next);
142
- };
143
- walk(goal.node, new Set());
144
- }
145
- latestGoals = built;
146
- if (!wanted.size && !wantedOut.size && !wantedTag.size) break;
147
- const slices = await fetchSlices(dataset, catalog, {
148
- recipes: wanted,
149
- outs: wantedOut,
150
- tags: wantedTag,
151
- });
152
- let progressed = false;
153
- for (const [id, entry] of slices.recipes) {
154
- localRecipes.set(id, entry.calc);
155
- localBodies.set(id, entry.body);
156
- progressed = true;
157
- }
158
- for (const id of slices.dead) deadLocal.add(id);
159
- for (const [id, list] of slices.outs) {
160
- localOut.set(id, list);
161
- progressed = true;
162
- }
163
- for (const [id, tag] of slices.tags) {
164
- localTag.set(id, tag);
165
- progressed = true;
166
- }
167
- if (!progressed) break;
168
- summaries.clear();
169
- }
170
- applyMaps({
171
- out: localOut,
172
- tag: localTag,
173
- recipes: localRecipes,
174
- bodies: localBodies,
175
- dead: deadLocal,
176
- });
177
-
178
- const out: Record<string, string> = {};
179
- const collect = (n: CalcNode): void => {
180
- if (
181
- n.path &&
182
- n.recipe &&
183
- roots.some(
184
- (root) => n.path === root || n.path!.startsWith(`${root}/`),
185
- )
186
- ) {
187
- out[n.path] = n.recipe.recipeId;
188
- }
189
- for (const child of n.children) collect(child);
190
- };
191
- for (const goal of latestGoals) collect(goal.node);
192
- return out;
193
- },
194
- [
195
- recipeMap,
196
- bodyMap,
197
- outMap,
198
- tagMap,
199
- deadIds,
200
- effectiveSelections,
201
- tagSelections,
202
- target,
203
- inventory,
204
- dataset,
205
- catalog,
206
- collapsed,
207
- auto,
208
- call,
209
- workerRef,
210
- applyMaps,
211
- ],
212
- );
213
- }