Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Versioning, Mapping, Repositories #56

Closed
mlhaufe opened this issue Dec 20, 2023 · 0 comments · Fixed by #66
Closed

Refactor Versioning, Mapping, Repositories #56

mlhaufe opened this issue Dec 20, 2023 · 0 comments · Fixed by #66
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@mlhaufe
Copy link
Contributor

mlhaufe commented Dec 20, 2023

Currently all the mappers have the following form:

export interface FooJson extends BaseJson {
    ...props
}

export default class FooToJsonMapper extends BaseToJsonMapper {
    override mapFrom(target: FooJson): Foo {
        const version = target.serializationVersion ?? '{undefined}';

        if (version.startsWith('0.3.'))
            return new Foo(target);
        //... additional versions

        throw new Error(`Unsupported serialization version: ${version}`);
    }

    override mapTo(source: Foo): FooJson {
        return {
            ...super.mapTo(source),
            // ..additionalProps
        };
    }
}

Most repositories are of the form:

export default class FooRepository extends BaseRepository<Foo> {
    constructor() { super('foo', new FooToJsonMapper(pkg.version)); }
}

There is also a LocalStorageRepository specialized for the storage type:

export class LocalStorageRepository<E extends Entity> extends Repository<E> {
    constructor(readonly storageKey: string, mapper: Mapper<E, EntityJson>) {
        super(mapper);
    }

    get storage(): Storage {
        return localStorage;
    }

    get(id: E['id']): Promise<E | undefined> { ... }

    getAll(filter: (entity: E) => boolean = _ => true): Promise<E[]> { ... }

    add(item: E): Promise<void> { ... }

    clear(): Promise<void> { ... }

    update(item: E): Promise<void> { ... }

    delete(id: E['id']): Promise<void> { ... }
}

Note the storage member which was defined to support unit testing:

const fakeStorage: Storage = new DomStorage(null, { strict: true });

class TestLocalStorageRepository<F extends Foo> extends LocalStorageRepository<F> {
    override get storage() {
        return fakeStorage;
    }
}

This smells and has significant duplication. This needs to be done better

@mlhaufe mlhaufe added the enhancement New feature or request label Dec 20, 2023
@mlhaufe mlhaufe added this to the v0.4.0 milestone Dec 20, 2023
@mlhaufe mlhaufe self-assigned this Dec 20, 2023
@mlhaufe mlhaufe changed the title Investigate Declarative data versioning and mapping Refactor Versioning, Mapping, Repositories Dec 22, 2023
@mlhaufe mlhaufe linked a pull request Dec 23, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant