Add very primitive migration engine
This commit is contained in:
parent
253b206a39
commit
b06a89350f
@ -17,6 +17,8 @@ import PortalVue from 'portal-vue';
|
||||
import VueDragscroll from 'vue-dragscroll';
|
||||
import { Workbox } from "workbox-window";
|
||||
|
||||
import { migrate } from "./store/migrations";
|
||||
|
||||
Vue.use(Vuex);
|
||||
Vue.use(PortalVue);
|
||||
Vue.use(VueDragscroll);
|
||||
@ -25,6 +27,8 @@ Vue.prototype.$isTouch = 'ontouchstart' in window || navigator.msMaxTouchPoints
|
||||
|
||||
// async dependencies
|
||||
(async function () {
|
||||
await migrate("vuex");
|
||||
|
||||
const [ components, { default: store } ] = await Promise.all([
|
||||
import('./components'),
|
||||
import('./store'),
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Vue from 'vue'
|
||||
import { Component, Prop } from 'vue-property-decorator'
|
||||
import { namespace, State } from "vuex-class";
|
||||
import { namespace, State, Mutation } from "vuex-class";
|
||||
import { Favourite } from "../store/favourites";
|
||||
import { SavedState } from "../store/root";
|
||||
import { Stop } from "../model";
|
||||
@ -12,9 +12,10 @@ import { Favourites } from "../store";
|
||||
export class FavouritesComponent extends Vue {
|
||||
@Favourites.State favourites: Favourite[];
|
||||
@Favourites.Mutation remove: (fav: Favourite) => void;
|
||||
@Mutation('replace') setStops: (stops: Stop[]) => void;
|
||||
|
||||
choose(favourite: Favourite) {
|
||||
this.$store.dispatch('load', favourite.state);
|
||||
this.setStops(favourite.stops);
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,11 +23,7 @@ function createFavouriteEntry(name: string, stops: Stop[]): Favourite {
|
||||
return {
|
||||
id: uuid.v4(),
|
||||
name,
|
||||
stops,
|
||||
state: {
|
||||
version: 1,
|
||||
stops: stops.map(stop => stop.id),
|
||||
},
|
||||
stops
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,6 @@ export interface Favourite {
|
||||
id: string;
|
||||
name: string;
|
||||
stops: Stop[];
|
||||
state: SavedState;
|
||||
}
|
||||
|
||||
export interface FavouritesState {
|
||||
|
56
resources/ts/store/migrations.ts
Normal file
56
resources/ts/store/migrations.ts
Normal file
@ -0,0 +1,56 @@
|
||||
import { distinct } from "../utils";
|
||||
import urls from "../urls";
|
||||
import * as uuid from "uuid";
|
||||
|
||||
type Migration = {
|
||||
name: string,
|
||||
key: string,
|
||||
up: (state: any) => Promise<any>;
|
||||
}
|
||||
|
||||
const migrations: Migration[] = [
|
||||
{
|
||||
name: "202001261540_full_stop_in_state",
|
||||
key: "vuex",
|
||||
up: async state => {
|
||||
const current = state.favourites.favourites;
|
||||
|
||||
const ids = current
|
||||
.map(favourite => favourite.state.stops)
|
||||
.reduce((cur, acc) => [ ...cur, ...acc ])
|
||||
.filter(distinct)
|
||||
;
|
||||
|
||||
const stops = await (await fetch(urls.prepare(urls.stops.all, { id: ids }))).json();
|
||||
const lookup = stops.reduce((lookup, stop) => ({ ...lookup, [stop.id]: stop }), {});
|
||||
|
||||
return {
|
||||
...state,
|
||||
favourites: {
|
||||
...state.favourites,
|
||||
favourites: state.favourites.favourites.map(favourite => ({
|
||||
id: favourite.id || uuid.v4(),
|
||||
name: favourite.name,
|
||||
stops: favourite.stops || favourite.state.stops.map(id => lookup[id]).filter(distinct),
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
export async function migrate(key: string) {
|
||||
const current = JSON.parse(window.localStorage.getItem('migrations')) || [];
|
||||
const state = JSON.parse(window.localStorage.getItem(key)) || {};
|
||||
|
||||
const result = await migrations
|
||||
.filter(migration => migration.key == key)
|
||||
.filter(migration => !current.includes(migration.name))
|
||||
.reduce(async (state, migration) => {
|
||||
current.push(migration.name);
|
||||
return await migration.up(state)
|
||||
}, state);
|
||||
|
||||
window.localStorage.setItem('migrations', JSON.stringify(current));
|
||||
window.localStorage.setItem(key, JSON.stringify(result));
|
||||
}
|
@ -63,3 +63,7 @@ export function get(object: any, path: string): any {
|
||||
|
||||
return object[segments.shift()];
|
||||
}
|
||||
|
||||
export function distinct<T>(value: T, index: number, array: T[]) {
|
||||
return array.indexOf(value) === index;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user