11import { create } from "zustand" ;
22import { subscribeWithSelector } from "zustand/middleware" ;
33import { get as lodashGet , set as lodashSet } from "lodash-es" ;
4- import { PackingInputs } from "../types" ;
4+ import { PackingResults , RecipeManifest } from "../types" ;
55import { getFirebaseRecipe , jsonToString } from "../utils/recipeLoader" ;
66import { getPackingInputsDict } from "../utils/firebase" ;
7+ import { EMPTY_PACKING_RESULTS } from "./constants" ;
78
89export interface RecipeData {
910 id : string ;
@@ -14,8 +15,9 @@ export interface RecipeData {
1415
1516export interface RecipeState {
1617 selectedRecipeId : string ;
17- inputOptions : Record < string , PackingInputs > ;
18+ inputOptions : Record < string , RecipeManifest > ;
1819 recipes : Record < string , RecipeData > ;
20+ packingResults : PackingResults ;
1921}
2022
2123export interface UIState {
@@ -43,7 +45,9 @@ type Actions = {
4345 recipeString : string
4446 ) => Promise < void >
4547 ) => Promise < void > ;
46- setResultUrl : ( url : string ) => void ;
48+ setPackingResults : ( results : PackingResults ) => void ;
49+ setJobLogs : ( logs : string ) => void ;
50+ setJobId : ( jobId : string ) => void ;
4751} ;
4852
4953export type RecipeStore = RecipeState & UIState & Actions ;
@@ -56,6 +60,7 @@ const initialState: RecipeState & UIState = {
5660 recipes : { } ,
5761 isLoading : false ,
5862 isPacking : false ,
63+ packingResults : { ...EMPTY_PACKING_RESULTS } ,
5964} ;
6065
6166export const useRecipeStore = create < RecipeStore > ( ) (
@@ -115,6 +120,8 @@ export const useRecipeStore = create<RecipeStore>()(
115120 } ,
116121
117122 selectRecipe : async ( recipeId ) => {
123+ get ( ) . setPackingResults ( { ...EMPTY_PACKING_RESULTS } ) ;
124+
118125 const sel = get ( ) . inputOptions [ recipeId ] ;
119126 if ( ! sel ) return ;
120127
@@ -127,22 +134,27 @@ export const useRecipeStore = create<RecipeStore>()(
127134 }
128135 } ,
129136
137+ setPackingResults : ( results : PackingResults ) => {
138+ set ( { packingResults : results } ) ;
139+ } ,
130140
131- setResultUrl : ( url : string ) => {
132- const { inputOptions, selectedRecipeId } = get ( ) ;
133- const sel = inputOptions [ selectedRecipeId ] ;
134- if ( ! sel ) return ;
141+ setJobLogs : ( logs : string ) => {
135142 set ( {
136- inputOptions : {
137- ...get ( ) . inputOptions ,
138- [ selectedRecipeId ] : {
139- ...sel ,
140- result_path : url ,
141- } ,
143+ packingResults : {
144+ ...get ( ) . packingResults ,
145+ jobLogs : logs ,
142146 } ,
143147 } ) ;
144148 } ,
145149
150+ setJobId : ( jobId : string ) => {
151+ set ( {
152+ packingResults : {
153+ ...get ( ) . packingResults ,
154+ jobId : jobId ,
155+ } ,
156+ } ) ;
157+ } ,
146158
147159 updateRecipeString : ( recipeId , newString ) => {
148160 set ( ( s ) => {
@@ -234,12 +246,13 @@ export const useRecipeStore = create<RecipeStore>()(
234246 } ) )
235247) ;
236248
237- // tiny helpers/ selectors (all derived — not stored)
249+ // simple selectors
238250export const useSelectedRecipeId = ( ) =>
239251 useRecipeStore ( ( s ) => s . selectedRecipeId ) ;
240252export const useCurrentRecipeString = ( ) =>
241253 useRecipeStore ( ( s ) => s . recipes [ s . selectedRecipeId ] ?. currentString ?? "" ) ;
242254export const useInputOptions = ( ) => useRecipeStore ( ( s ) => s . inputOptions ) ;
255+
243256export const useIsLoading = ( ) => useRecipeStore ( ( s ) => s . isLoading ) ;
244257export const useIsPacking = ( ) => useRecipeStore ( ( s ) => s . isPacking ) ;
245258export const useFieldsToDisplay = ( ) =>
@@ -248,8 +261,53 @@ export const useIsCurrentRecipeModified = () =>
248261 useRecipeStore ( ( s ) => s . recipes [ s . selectedRecipeId ] ?. isModified ?? false ) ;
249262export const useGetOriginalValue = ( ) =>
250263 useRecipeStore ( ( s ) => s . getOriginalValue ) ;
251- export const useResultUrl = ( ) =>
252- useRecipeStore ( ( s ) => s . inputOptions [ s . selectedRecipeId ] ?. result_path ) ;
264+ const usePackingResults = ( ) => useRecipeStore ( ( s ) => s . packingResults ) ;
265+
266+ // compound selectors
267+
268+ const useCurrentRecipeManifest = ( ) => {
269+ const selectedRecipeId = useSelectedRecipeId ( ) ;
270+ const inputOptions = useInputOptions ( ) ;
271+ if ( ! selectedRecipeId ) return undefined ;
272+ return inputOptions [ selectedRecipeId ] ;
273+ } ;
274+ const useDefaultResultPath = ( ) => {
275+ const manifest = useCurrentRecipeManifest ( ) ;
276+ return manifest ?. defaultResultPath || "" ;
277+ } ;
278+
279+ export const useRunTime = ( ) => {
280+ const results = usePackingResults ( ) ;
281+ return results . runTime ;
282+ } ;
283+
284+ export const useJobLogs = ( ) => {
285+ const results = usePackingResults ( ) ;
286+ return results . jobLogs ;
287+ } ;
288+
289+ export const useJobId = ( ) => {
290+ const results = usePackingResults ( ) ;
291+ return results . jobId ;
292+ } ;
293+
294+ export const useOutputsDirectory = ( ) => {
295+ const results = usePackingResults ( ) ;
296+ return results . outputDir ;
297+ } ;
298+
299+ export const useResultUrl = ( ) => {
300+ const results = usePackingResults ( ) ;
301+ const currentRecipeId = useSelectedRecipeId ( ) ;
302+ const defaultResultPath = useDefaultResultPath ( ) ;
303+ let path = "" ;
304+ if ( results . resultUrl ) {
305+ path = results . resultUrl ;
306+ } else if ( currentRecipeId ) {
307+ path = defaultResultPath ;
308+ }
309+ return path ;
310+ } ;
253311
254312// action selectors (stable identities)
255313export const useLoadInputOptions = ( ) =>
@@ -265,4 +323,7 @@ export const useRestoreRecipeDefault = () =>
265323export const useStartPacking = ( ) => useRecipeStore ( ( s ) => s . startPacking ) ;
266324export const useGetCurrentValue = ( ) =>
267325 useRecipeStore ( ( s ) => s . getCurrentValue ) ;
268- export const useSetResultUrl = ( ) => useRecipeStore ( ( s ) => s . setResultUrl ) ;
326+ export const useSetPackingResults = ( ) =>
327+ useRecipeStore ( ( s ) => s . setPackingResults ) ;
328+ export const useSetJobLogs = ( ) => useRecipeStore ( ( s ) => s . setJobLogs ) ;
329+ export const useSetJobId = ( ) => useRecipeStore ( ( s ) => s . setJobId ) ;
0 commit comments