-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
10 changed files
with
582 additions
and
1,964 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import type { App } from "vue"; | ||
import AtlasManager from "@/core/manager"; | ||
|
||
export default { | ||
install(app: App) { | ||
app.use(AtlasManager) | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,144 +1,165 @@ | ||
import type { App } from "vue"; | ||
import axios from "axios"; | ||
import * as yaml from "js-yaml"; | ||
import type { VibRecipe, Module } from "@/core/models"; | ||
import AtlasConfig from "@/config"; | ||
import { useAtlasStore } from '@/core/store'; | ||
|
||
class AtlasManager { | ||
private static readonly storageKey = "vibRecipes"; | ||
|
||
private static async fetchRecipeFromRepo( | ||
repo: string | ||
): Promise<string | null> { | ||
const url = `${AtlasConfig.registry}/${repo}/main/recipe.yml`; | ||
try { | ||
const response = await axios.get(url); | ||
return response.data; | ||
} catch (error) { | ||
console.error( | ||
`Error fetching recipe.yml from ${repo}: ${(error as Error).message}` | ||
); | ||
return null; | ||
} | ||
} | ||
import { useAtlasStore } from "@/core/store"; | ||
|
||
|
||
private static async fetchModuleContentFromRepo( | ||
export interface IAtlasManager { | ||
getVibRecipes(force: boolean): Promise<VibRecipe[]>; | ||
getVibRecipe(id: string): Promise<VibRecipe | null>; | ||
getFetchDate(): Promise<Date | null>; | ||
fetchRecipeFromRepo(repo: string): Promise<string | null>; | ||
fetchModuleContentFromRepo( | ||
repo: string, | ||
path: string | ||
): Promise<string | null> { | ||
const url = `${AtlasConfig.registry}/${repo}/main/${path}.yml`; | ||
try { | ||
const response = await axios.get(url); | ||
return response.data; | ||
} catch (error) { | ||
console.error( | ||
`Error fetching module content from ${url}: ${(error as Error).message}` | ||
); | ||
return null; | ||
} | ||
} | ||
): Promise<string | null>; | ||
} | ||
|
||
private static getFromLocalStorage(): VibRecipe[] | null { | ||
export default { | ||
install: (app: App) => { | ||
const store = useAtlasStore(); | ||
return store.getVibRecipes; | ||
} | ||
|
||
private static saveToLocalStorage(recipes: VibRecipe[]): void { | ||
const store = useAtlasStore(); | ||
store.setVibRecipes(recipes); | ||
} | ||
app.config.globalProperties.$atlasManager = { | ||
async getVibRecipes(force: boolean = false): Promise<VibRecipe[]> { | ||
console.log("Fetching VibRecipes..."); | ||
|
||
if (!force) { | ||
console.log("Checking for cached VibRecipes..."); | ||
const cachedRecipes = store.vibRecipes; | ||
const lastFetchDate = store.lastFetchDate; | ||
|
||
if (cachedRecipes.length > 0 && lastFetchDate) { | ||
console.log("Using cached VibRecipes."); | ||
return cachedRecipes; | ||
} | ||
} else { | ||
console.log("Forcing fetch of VibRecipes..."); | ||
} | ||
|
||
public static async getVibRecipes(force: boolean = false): Promise<VibRecipe[]> { | ||
console.log("Fetching VibRecipes..."); | ||
|
||
if (!force) { | ||
const cachedRecipes = this.getFromLocalStorage(); | ||
const lastFetchDate = localStorage.getItem("lastFetchDate"); | ||
|
||
if (cachedRecipes !== null && cachedRecipes.length > 0 && lastFetchDate) { | ||
console.log("Using cached VibRecipes."); | ||
return cachedRecipes; | ||
} | ||
} | ||
|
||
const vibRecipes: VibRecipe[] = []; | ||
|
||
try { | ||
const fetchPromises = AtlasConfig.repos.map(async (repo) => { | ||
console.log(`Fetching recipe.yml from ${repo}`); | ||
const recipeYaml = await this.fetchRecipeFromRepo(repo); | ||
if (recipeYaml !== null) { | ||
console.log(`Parsing recipe.yml from ${repo}`); | ||
const recipeObject = yaml.load(recipeYaml) as VibRecipe; | ||
recipeObject.snippet = recipeYaml; | ||
const modules: Module[] = []; | ||
|
||
if (recipeObject.modules) { | ||
for (const module of recipeObject.modules) { | ||
if (module.includes) { | ||
console.log( | ||
`Fetching and processing included modules for ${repo}` | ||
); | ||
for (const includePath of module.includes) { | ||
const moduleContent = await this.fetchModuleContentFromRepo( | ||
repo, | ||
includePath | ||
); | ||
if (moduleContent) { | ||
try { | ||
const includedModule = yaml.load(moduleContent) as Module; | ||
includedModule.snippet = moduleContent; | ||
modules.push(includedModule); | ||
} catch (error) { | ||
console.error( | ||
`Error parsing included module from ${repo}: ${(error as Error).message | ||
}` | ||
const vibRecipes: VibRecipe[] = []; | ||
|
||
try { | ||
const fetchPromises = AtlasConfig.repos.map(async (repo) => { | ||
console.log(`Fetching recipe.yml from ${repo}`); | ||
const recipeYaml = await this.fetchRecipeFromRepo(repo); | ||
if (recipeYaml !== null) { | ||
console.log(`Parsing recipe.yml from ${repo}`); | ||
const recipeObject = yaml.load(recipeYaml) as VibRecipe; | ||
recipeObject.snippet = recipeYaml; | ||
const modules: Module[] = []; | ||
|
||
if (recipeObject.modules) { | ||
for (const module of recipeObject.modules) { | ||
if (module.includes) { | ||
console.log( | ||
`Fetching and processing included modules for ${repo}` | ||
); | ||
for (const includePath of module.includes) { | ||
const moduleContent = await this.fetchModuleContentFromRepo( | ||
repo, | ||
includePath | ||
); | ||
if (moduleContent) { | ||
try { | ||
const includedModule = yaml.load( | ||
moduleContent | ||
) as Module; | ||
includedModule.snippet = moduleContent; | ||
modules.push(includedModule); | ||
} catch (error) { | ||
console.error( | ||
`Error parsing included module from ${repo}: ${(error as Error).message}` | ||
); | ||
} | ||
} | ||
} | ||
} else { | ||
module.snippet = yaml.dump(module); | ||
modules.push(module); | ||
} | ||
} | ||
} else { | ||
module.snippet = yaml.dump(module); | ||
modules.push(module); | ||
} | ||
|
||
recipeObject.id = repo.replace("/", "-"); | ||
recipeObject.modules = modules; | ||
vibRecipes.push(recipeObject); | ||
} | ||
} | ||
}); | ||
|
||
recipeObject.id = repo.replace("/", "-"); | ||
recipeObject.modules = modules; | ||
vibRecipes.push(recipeObject); | ||
await Promise.all(fetchPromises); | ||
} catch (error) { | ||
console.error( | ||
`Error fetching or parsing recipes: ${(error as Error).message}` | ||
); | ||
} | ||
}); | ||
|
||
await Promise.all(fetchPromises); | ||
} catch (error) { | ||
console.error(`Error fetching or parsing recipes: ${(error as Error).message}`); | ||
} | ||
store.$patch({ vibRecipes: vibRecipes }); | ||
store.$patch({ lastFetchDate: Date.now() }); | ||
|
||
this.saveToLocalStorage(vibRecipes); | ||
console.log("Finished fetching VibRecipes"); | ||
return vibRecipes; | ||
}, | ||
|
||
console.log("Finished fetching VibRecipes"); | ||
return vibRecipes; | ||
} | ||
async getVibRecipe(id: string): Promise<VibRecipe | null> { | ||
const vibRecipes = await this.getVibRecipes(false); | ||
for (const recipe of vibRecipes) { | ||
if (recipe.id === id) { | ||
return recipe; | ||
} | ||
} | ||
return null; | ||
}, | ||
|
||
public static async getVibRecipe(id: string): Promise<VibRecipe | null> { | ||
const vibRecipes = await this.getVibRecipes(); | ||
for (const recipe of vibRecipes) { | ||
if (recipe.id === id) { | ||
return recipe; | ||
} | ||
} | ||
return null; | ||
} | ||
async getFetchDate(): Promise<Date | null> { | ||
const lastFetchDate = store.lastFetchDate; | ||
if (lastFetchDate) { | ||
return new Date(lastFetchDate); | ||
} | ||
return null; | ||
}, | ||
|
||
async fetchRecipeFromRepo(repo: string): Promise<string | null> { | ||
const url = `${AtlasConfig.registry}/${repo}/main/recipe.yml`; | ||
try { | ||
const response = await axios.get(url); | ||
return response.data; | ||
} catch (error) { | ||
console.error( | ||
`Error fetching recipe.yml from ${repo}: ${(error as Error).message}` | ||
); | ||
return null; | ||
} | ||
}, | ||
|
||
async fetchModuleContentFromRepo( | ||
repo: string, | ||
path: string | ||
): Promise<string | null> { | ||
const url = `${AtlasConfig.registry}/${repo}/main/${path}.yml`; | ||
try { | ||
const response = await axios.get(url); | ||
return response.data; | ||
} catch (error) { | ||
console.error( | ||
`Error fetching module content from ${url}: ${(error as Error).message}` | ||
); | ||
return null; | ||
} | ||
}, | ||
} as IAtlasManager; | ||
|
||
public static getFetchDate(): Date | null { | ||
const store = useAtlasStore(); | ||
const lastFetchDate = store.getLastFetchDate; | ||
if (lastFetchDate) { | ||
return new Date(lastFetchDate); | ||
} | ||
return null; | ||
console.log("AtlasManager: fetching VibRecipes..."); | ||
app.config.globalProperties.$atlasManager.getVibRecipes(false); | ||
console.log("AtlasManager: done"); | ||
|
||
}, | ||
}; | ||
|
||
declare module "@vue/runtime-core" { | ||
//Bind to `this` keyword | ||
interface IAtlasManager { | ||
$atlasManager: IAtlasManager; | ||
} | ||
} | ||
|
||
export default AtlasManager; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,12 @@ | ||
import { defineStore } from 'pinia'; | ||
import type { VibRecipe } from '@/core/models'; | ||
|
||
export const useAtlasStore = defineStore({ | ||
id: 'atlas', | ||
export const useAtlasStore = defineStore('atlas', { | ||
state: () => ({ | ||
vibRecipes: null as VibRecipe[] | null, | ||
lastFetchDate: null as string | null, | ||
vibRecipes: [] as VibRecipe[], | ||
lastFetchDate: Date.now(), | ||
}), | ||
getters: { | ||
getVibRecipes(): VibRecipe[] { | ||
if (this.vibRecipes) { | ||
return this.vibRecipes; | ||
} | ||
|
||
const vibRecipes = localStorage.getItem("vibRecipes"); | ||
if (vibRecipes) { | ||
this.vibRecipes = JSON.parse(vibRecipes) as VibRecipe[]; | ||
this.lastFetchDate = localStorage.getItem("lastFetchDate"); | ||
return this.vibRecipes; | ||
} | ||
|
||
return []; | ||
}, | ||
getLastFetchDate(): string | null { | ||
return this.lastFetchDate; | ||
}, | ||
}, | ||
actions: { | ||
setVibRecipes(vibRecipes: VibRecipe[]) { | ||
this.vibRecipes = vibRecipes; | ||
this.lastFetchDate = new Date().toISOString(); | ||
localStorage.setItem("vibRecipes", JSON.stringify(vibRecipes)); | ||
localStorage.setItem("lastFetchDate", this.lastFetchDate); | ||
}, | ||
persist: { | ||
storage: window.localStorage, | ||
}, | ||
}); |
Oops, something went wrong.