idz: Temporarily delete fs backend

This commit is contained in:
Tau 2019-04-28 21:42:59 -04:00
parent f0f2ab138d
commit 84541e245c
9 changed files with 0 additions and 413 deletions

View File

@ -1,20 +0,0 @@
import { loadJson, saveJson } from "./_util";
import { FacetRepository } from "../repo";
import { Id } from "../model/base";
import { Profile } from "../model/profile";
export class FacetRepositoryImpl<T> implements FacetRepository<T> {
private _path: string;
constructor(root: string, name: string) {
this._path = `${root}/${name}.json`;
}
load(id: Id<Profile>): Promise<T> {
return loadJson(this._path);
}
save(id: Id<Profile>, obj: T) {
return saveJson(this._path, obj);
}
}

View File

@ -1,21 +0,0 @@
import { loadNumberList, saveNumberList } from "./_util";
import { FlagRepository } from "../repo";
import { Id } from "../model/base";
import { Profile } from "../model/profile";
export class FlagRepositoryImpl<T extends number>
implements FlagRepository<T> {
private _path: string;
constructor(root: string, name: string) {
this._path = `${root}/${name}.txt`;
}
loadAll(profileId: Id<Profile>): Promise<T[]> {
return loadNumberList(this._path);
}
saveAll(profileId: Id<Profile>, codes: T[]): Promise<void> {
return saveNumberList(this._path, codes);
}
}

View File

@ -1,48 +0,0 @@
import * as fs from "fs";
import { promisify } from "util";
const readFile = promisify(fs.readFile);
const writeFile = promisify(fs.writeFile);
export async function loadJson<T>(path: string): Promise<T> {
console.log("Idz: Repository: Loading ", path);
const json = await readFile(path, { encoding: "utf8" });
return JSON.parse(json);
}
export async function saveJson<T>(path: string, obj: T): Promise<void> {
console.log("Idz: Repository: Saving ", path);
const json = JSON.stringify(obj, undefined, 2);
return writeFile(path, json, { encoding: "utf8" });
}
export async function loadNumberList<T extends number[]>(
path: string
): Promise<T> {
console.log("Idz: Repository: Loading ", path);
if (!fs.existsSync(path)) {
return new Array() as T;
}
const text = await readFile(path, { encoding: "ascii" });
const lines = text.split("\n").filter(x => x !== "");
const codes = lines.map(Number); // parseInt fails due to radix arg from map
return codes as T;
}
export async function saveNumberList<T extends number[]>(
path: string,
codes: T
): Promise<void> {
console.log("Idz: Repository: Saving ", path);
const text = codes.map(code => code.toString()).join("\n") + "\n";
return writeFile(path, text, { encoding: "ascii" });
}

View File

@ -1,76 +0,0 @@
import { existsSync } from "fs";
import { loadJson, saveJson } from "./_util";
import { CarRepository } from "../repo";
import { Id } from "../model/base";
import { Car, CarSelector } from "../model/car";
import { Profile } from "../model/profile";
interface GarageJson {
selected?: CarSelector;
cars: Car[];
}
export class CarRepositoryImpl implements CarRepository {
private readonly _path: string;
constructor(root: string) {
this._path = root + "/garage.json";
}
private async _loadJson(): Promise<GarageJson> {
if (existsSync(this._path)) {
return loadJson(this._path);
} else {
return { cars: [] };
}
}
async countCars(profileId: Id<Profile>): Promise<number> {
const garage: GarageJson = await this._loadJson();
return garage.cars.length;
}
async loadAllCars(profileId: Id<Profile>): Promise<Car[]> {
const garage: GarageJson = await this._loadJson();
return garage.cars;
}
async loadSelectedCar(profileId: Id<Profile>): Promise<Car> {
const garage: GarageJson = await this._loadJson();
const sel = garage.cars.find(item => item.selector === garage.selected);
if (sel === undefined) {
throw new Error("No car in garage matching current selector");
}
return sel;
}
async saveCar(profileId: Id<Profile>, car: Car): Promise<void> {
const garage: GarageJson = await this._loadJson();
const rest = garage.cars.filter(item => item.selector != car.selector);
const updated = { ...garage, cars: [...rest, car] };
return saveJson(this._path, updated);
}
async saveSelection(
profileId: Id<Profile>,
selection: CarSelector
): Promise<void> {
const garage: GarageJson = await this._loadJson();
const match = garage.cars.find(item => item.selector === selection);
if (!match) {
throw new Error(`No match for selector ${selection} in garage`);
}
garage.selected = selection;
return saveJson(this._path, garage);
}
}

View File

@ -1,43 +0,0 @@
import { loadNumberList, saveNumberList } from "./_util";
import { CoursePlaysRepository } from "../repo";
import { Id } from "../model/base";
import { Profile } from "../model/profile";
export class CoursePlaysRepositoryImpl implements CoursePlaysRepository {
private readonly _path;
constructor(root) {
this._path = root + "/coursePlays.txt";
}
async loadAll(profileId: Id<Profile>): Promise<Map<number, number>> {
const lines = await loadNumberList(this._path);
const map = new Map<number, number>();
for (let i = 0; i < lines.length; i++) {
map.set(i, lines[i]);
}
return map;
}
saveAll(profileId: Id<Profile>, counts: Map<number, number>): Promise<void> {
let max = 0;
for (const key of counts.keys()) {
if (max < key) {
max = key;
}
}
const array = new Array(max + 1);
array.fill(0);
for (const [k, v] of counts) {
array[k] = v;
}
return saveNumberList(this._path, array);
}
}

View File

@ -1,78 +0,0 @@
import * as fs from "fs";
import { FacetRepositoryImpl } from "./_facet";
import { FlagRepositoryImpl } from "./_flag";
import { CarRepositoryImpl } from "./car";
import { CoursePlaysRepositoryImpl } from "./coursePlays";
import { Repositories } from "../repo";
import { ProfileRepositoryImpl } from "./profile";
import { TicketsRepositoryImpl } from "./tickets";
import { TimeAttackRepositoryImpl } from "./timeAttack";
import * as Model from "../model";
export { Repositories as World };
class WorldImpl implements Repositories {
constructor(private readonly _root: string) {}
backgrounds() {
return new FlagRepositoryImpl<Model.BackgroundCode>(
this._root,
"backgrounds"
);
}
car() {
return new CarRepositoryImpl(this._root);
}
chara() {
return new FacetRepositoryImpl<Model.Chara>(this._root, "chara");
}
coursePlays() {
return new CoursePlaysRepositoryImpl(this._root);
}
missions() {
return new FacetRepositoryImpl<Model.MissionState>(this._root, "missions");
}
profile() {
return new ProfileRepositoryImpl(this._root);
}
settings() {
return new FacetRepositoryImpl<Model.Settings>(this._root, "settings");
}
story() {
return new FacetRepositoryImpl<Model.Story>(this._root, "story");
}
tickets() {
return new TicketsRepositoryImpl(this._root);
}
timeAttack() {
return new TimeAttackRepositoryImpl(this._root);
}
titles() {
return new FlagRepositoryImpl<Model.TitleCode>(this._root, "titles");
}
unlocks() {
return new FacetRepositoryImpl<Model.Unlocks>(this._root, "unlocks");
}
}
export async function beginFilesystemSession(
root: string
): Promise<Repositories> {
if (!fs.existsSync(root)) {
fs.mkdirSync(root);
}
return new WorldImpl(root);
}

View File

@ -1,38 +0,0 @@
import * as fs from "fs";
import { promisify } from "util";
import { loadJson, saveJson } from "./_util";
import { ProfileRepository } from "../repo";
import { Id } from "../model/base";
import { Profile } from "../model/profile";
import { AimeId } from "../../model";
const exists = promisify(fs.exists);
export class ProfileRepositoryImpl implements ProfileRepository {
private readonly _path: string;
constructor(root) {
this._path = root + "/profile.json";
}
async generateId(): Promise<Id<Profile>> {
return 1 as Id<Profile>;
}
discoverByAimeId(id: AimeId): Promise<boolean> {
return exists(this._path);
}
loadByAimeId(id: AimeId): Promise<Profile> {
return loadJson(this._path);
}
load(id: Id<Profile>): Promise<Profile> {
return loadJson(this._path);
}
save(id: Id<Profile>, profile: Profile): Promise<void> {
return saveJson(this._path, profile);
}
}

View File

@ -1,42 +0,0 @@
import { loadJson, saveJson } from "./_util";
import { FacetRepository } from "../repo";
import { Tickets } from "../model/tickets";
import { Id, Profile } from "../model";
interface TicketsJson {
freeCar?: {
validFrom: string;
// Valid To cannot be controlled, it is always 14 days after issue date.
};
freeContinue?: {
validFrom: string;
validTo: string;
};
}
export class TicketsRepositoryImpl implements FacetRepository<Tickets> {
private readonly _path: string;
constructor(root: string) {
this._path = root + "/tickets.json";
}
async load(profileId: Id<Profile>): Promise<Tickets> {
const json: TicketsJson = await loadJson(this._path);
return {
freeCar: json.freeCar && {
validFrom: new Date(json.freeCar.validFrom),
},
freeContinue: json.freeContinue && {
validFrom: new Date(json.freeContinue.validFrom),
validTo: new Date(json.freeContinue.validTo),
},
};
}
save(profileId: Id<Profile>, tickets: Tickets): Promise<void> {
// Date objects stringify to ISO8601 so this does this right thing.
return saveJson(this._path, tickets);
}
}

View File

@ -1,47 +0,0 @@
import * as fs from "fs";
import { loadJson, saveJson } from "./_util";
import { TimeAttackRepository } from "../repo";
import { Id } from "../model/base";
import { Profile } from "../model/profile";
import { TimeAttackScore } from "../model/timeAttack";
interface TimeAttackJson {
scores: TimeAttackScore[];
}
export class TimeAttackRepositoryImpl implements TimeAttackRepository {
private readonly _path: string;
constructor(root) {
this._path = root + "/timeAttack.json";
}
async loadAll(profileId: Id<Profile>): Promise<TimeAttackScore[]> {
if (!fs.existsSync(this._path)) {
return [];
}
const json: TimeAttackJson = await loadJson(this._path);
return json.scores;
}
async load(
profileId: Id<Profile>,
courseId: number
): Promise<TimeAttackScore | undefined> {
const scores = await this.loadAll(profileId);
return scores.find(item => item.courseId === courseId);
}
async save(profileId: Id<Profile>, score: TimeAttackScore): Promise<void> {
const scores = await this.loadAll(profileId);
const rest = scores.filter(item => item.courseId !== score.courseId);
const updated: TimeAttackJson = { scores: [...rest, score] };
return saveJson(this._path, updated);
}
}