(set, get)
| 89 | } |
| 90 | |
| 91 | export const createProjectSlice: AppSliceCreator<ProjectSlice> = (set, get) => { |
| 92 | // Immutable bulk upsert into the by-name cache. |
| 93 | const upsertProjects = (projects: Project[]): void => { |
| 94 | set((state) => { |
| 95 | const next = { ...state.projectsByName }; |
| 96 | for (const project of projects) { |
| 97 | next[project.name] = project; |
| 98 | } |
| 99 | return { projectsByName: next }; |
| 100 | }); |
| 101 | }; |
| 102 | |
| 103 | const slice: ProjectSlice = { |
| 104 | projectsByName: {}, |
| 105 | projectRequests: {}, |
| 106 | projectErrorsByName: {}, |
| 107 | |
| 108 | resetProjects: () => { |
| 109 | set({ projectsByName: {}, projectRequests: {}, projectErrorsByName: {} }); |
| 110 | }, |
| 111 | |
| 112 | // Mirrors the Pinia `useProjectV1Store().getProjectByName`: always |
| 113 | // returns a non-null Project, synthesizing the default-project or |
| 114 | // unknown-project placeholder when the name is not in the cache. |
| 115 | getProjectByName: (name) => { |
| 116 | if (name === UNKNOWN_PROJECT_NAME) return unknownProject; |
| 117 | const defaultProject = defaultProjectName(get); |
| 118 | if (name && name === defaultProject) { |
| 119 | return get().projectsByName[name] ?? getDefaultProject(name); |
| 120 | } |
| 121 | return get().projectsByName[name] ?? unknownProject; |
| 122 | }, |
| 123 | |
| 124 | fetchProject: async (name, silent = false) => { |
| 125 | const defaultProject = defaultProjectName(get); |
| 126 | if (name && name === defaultProject) { |
| 127 | const project = createDefaultProject(name); |
| 128 | set((state) => ({ |
| 129 | projectsByName: { |
| 130 | ...state.projectsByName, |
| 131 | [name]: state.projectsByName[name] ?? project, |
| 132 | }, |
| 133 | projectErrorsByName: { |
| 134 | ...state.projectErrorsByName, |
| 135 | [name]: undefined, |
| 136 | }, |
| 137 | })); |
| 138 | return project; |
| 139 | } |
| 140 | if (!isValidProjectName(name) || name === UNKNOWN_PROJECT_NAME) { |
| 141 | return undefined; |
| 142 | } |
| 143 | const existing = get().projectsByName[name]; |
| 144 | if (existing) return existing; |
| 145 | const pending = get().projectRequests[name]; |
| 146 | if (pending) return pending; |
| 147 | |
| 148 | const request = projectServiceClientConnect |
no test coverage detected