defineRepository()
The defineRepository() method is used to create a composable that serves as a repository for given model.
Create repository
Creating a model repository is similar to creating a Pinia store.
const useModelRepository = defineRepository(Model);For example:
import { Model, defineRepository } from '@kovalson/prevue';
class User extends Model {
// ...
}
const useUserRepository = defineRepository(User);
export {
User,
useUserRepository,
};Setup
You may pass a setup object as a second parameter to configure the composable.
import { Model, defineRepository } from '@kovalson/prevue';
class User extends Model {
public active: boolean = false;
// ...
}
const useUserRepository = defineRepository(User, {
local: true,
methods: {
active() {
return this
.all()
.filter((user: User) => user.active);
},
},
});
export {
User,
useUserRepository,
};Setup Object
interface ISetupObject {
/**
* Whether the repository is local or global.
*
* Local repository uses a ref to store data. The data is therefore cleared whenever the component using it is
* destroyed.
* Global repository uses a Pinia store, so the data persists when navigating through the app, even when the component
* using it is destroyed. There can only be one global repository for a model.
*
* @default false
* By default, all repositories are global.
*/
local?: boolean;
/**
* Custom methods that enhance the repository functionality.
*
* @default undefined
*/
methods?: Record<string, TCustomMethod>;
}Custom Methods
Custom methods are functions that are automatically bound a special context. This context provides them with all other methods (including other custom created methods).
You may, or may not make use of custom method context. Your method can return anything you like, but bear in mind that the repository should serve as a single source of truth in terms of the local model BREAD management and ideally should reflect the server's state of given model.
For example:
const useUserRepository = defineRepository(User, {
local: true,
methods: {
active(): User[] {
return this
.all()
.filter((user: User) => user.active);
},
activate(id: string, active: boolean): void {
this.update(id, {
active: active,
});
}
},
});Items Map
The custom method context also provides the items property. This property stores a map of all items in that repository. The keys are models' ids, and the values are models' objects:
const useUserRepository = defineRepository(User, {
local: true,
methods: {
active(): User[] {
return this.items
.values()
.filter((user: User) => user.active);
},
},
});Default Methods
The created repository composable has several BREAD methods out-of-the-box.
interface IBaseMethods<M extends Model> {
isEmpty(): boolean;
isNotEmpty(): boolean;
count(): number;
clear(): void;
set(items: M[]): void;
add(items: M[] | M): void;
all(): M[];
find(id: string): M | null;
first(): M | null;
last(): M | null;
update(item: M, data?: Partial<M>): void;
update(item: string, data: Partial<M>): void;
remove(items: (M | string)[] | M | string): void;
toArray(): M[];
getWatchable(): Readonly<Ref<ReadonlyMap<string, DeepReadonly<M>>>>;
}