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 VueDragscroll from 'vue-dragscroll';
|
||||||
import { Workbox } from "workbox-window";
|
import { Workbox } from "workbox-window";
|
||||||
|
|
||||||
|
import { migrate } from "./store/migrations";
|
||||||
|
|
||||||
Vue.use(Vuex);
|
Vue.use(Vuex);
|
||||||
Vue.use(PortalVue);
|
Vue.use(PortalVue);
|
||||||
Vue.use(VueDragscroll);
|
Vue.use(VueDragscroll);
|
||||||
@ -25,6 +27,8 @@ Vue.prototype.$isTouch = 'ontouchstart' in window || navigator.msMaxTouchPoints
|
|||||||
|
|
||||||
// async dependencies
|
// async dependencies
|
||||||
(async function () {
|
(async function () {
|
||||||
|
await migrate("vuex");
|
||||||
|
|
||||||
const [ components, { default: store } ] = await Promise.all([
|
const [ components, { default: store } ] = await Promise.all([
|
||||||
import('./components'),
|
import('./components'),
|
||||||
import('./store'),
|
import('./store'),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import { Component, Prop } from 'vue-property-decorator'
|
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 { Favourite } from "../store/favourites";
|
||||||
import { SavedState } from "../store/root";
|
import { SavedState } from "../store/root";
|
||||||
import { Stop } from "../model";
|
import { Stop } from "../model";
|
||||||
@ -12,9 +12,10 @@ import { Favourites } from "../store";
|
|||||||
export class FavouritesComponent extends Vue {
|
export class FavouritesComponent extends Vue {
|
||||||
@Favourites.State favourites: Favourite[];
|
@Favourites.State favourites: Favourite[];
|
||||||
@Favourites.Mutation remove: (fav: Favourite) => void;
|
@Favourites.Mutation remove: (fav: Favourite) => void;
|
||||||
|
@Mutation('replace') setStops: (stops: Stop[]) => void;
|
||||||
|
|
||||||
choose(favourite: Favourite) {
|
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 {
|
return {
|
||||||
id: uuid.v4(),
|
id: uuid.v4(),
|
||||||
name,
|
name,
|
||||||
stops,
|
stops
|
||||||
state: {
|
|
||||||
version: 1,
|
|
||||||
stops: stops.map(stop => stop.id),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@ export interface Favourite {
|
|||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
stops: Stop[];
|
stops: Stop[];
|
||||||
state: SavedState;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FavouritesState {
|
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()];
|
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