@ministerjs/model
v1.2.2
Published
Pacote de modelagem de dados para Vue.js, fornecendo abstrações de alto nível que integram stores (@ministerjs/store) com recursos de API (@ministerjs/resource).
Readme
@ministerjs/model
Pacote de modelagem de dados para Vue.js, fornecendo abstrações de alto nível que integram stores (@ministerjs/store) com recursos de API (@ministerjs/resource).
📦 Instalação
npm install @ministerjs/model
# ou
pnpm add @ministerjs/model
# ou
yarn add @ministerjs/model🚀 Funcionalidades
- ItemModel: Modelagem para um item único (ex: perfil do usuário, configurações)
- TableModel: Modelagem para coleções de dados (ex: lista de usuários, produtos)
- Cache inteligente: Sistema de cache usando
Mappara evitar instanciações desnecessárias - TypeScript: Totalmente tipado com TypeScript
- Integração automática: Combina automaticamente @ministerjs/store e @ministerjs/resource
- Mapeamento de dados: Suporte a callbacks de transformação de dados
📖 Uso Básico
ItemModel - Gerenciando um item único
import { useModels } from "@ministerjs/model";
interface UserProfile {
id: number;
name: string;
email: string;
avatar?: string;
}
// Criando o model
const { generateItem } = useModels();
const profileModel = generateItem<UserProfile>("profile");
// Carregando dados da API
const response = await profileModel.get();
console.log(response.data); // Dados da API
// Acessando o store reativo
const profileState = profileModel.store.get();
console.log(profileState.value.name); // Estado reativo
// Atualizando dados
await profileModel.update({ name: "João Silva" });TableModel - Gerenciando coleções
import { useModels } from "@ministerjs/model";
interface User {
id: number;
name: string;
email: string;
active: boolean;
}
// Criando o model
const { generateTable } = useModels();
const usersModel = generateTable<User, "id">("users", "id");
// Listando dados da API
const response = await usersModel.list({ page: 1, limit: 10 });
console.log(response.data); // Array de usuários
// Acessando o store reativo
const usersState = usersModel.store.list();
console.log(usersState.length); // Quantidade de usuários no store
// Criando novo usuário
const formData = new FormData();
formData.append("name", "João");
formData.append("email", "[email protected]");
await usersModel.create(formData);
// Atualizando usuário
await usersModel.update(1, { name: "João Silva" });
// Removendo usuário
await usersModel.delete(1);🏗️ Gerenciamento Avançado
Uso com Fetch Customizado
import { useModels } from "@ministerjs/model";
// Fetch customizado com autenticação
const customFetch = (url: string, options?: RequestInit) => {
return fetch(url, {
...options,
headers: {
...options?.headers,
Authorization: `Bearer ${token}`,
},
});
};
const { generateItem, generateTable } = useModels(customFetch);Uso com Models Pré-configurados
import { useModels } from "@ministerjs/model";
// Definindo models pré-configurados
const models = useModels(fetch, {
users: () => generateTable<User, "id">("users", "id"),
profile: () => generateItem<UserProfile>("profile"),
settings: () => generateItem<AppSettings>("settings"),
});
// Usando models pré-configurados (com cache automático)
const userModel = models.get("users");
const profileModel = models.get("profile");
const settingsModel = models.get("settings");
// Chamadas subsequentes retornam do cache
const userModelAgain = models.get("users"); // Cache hit!Mapeamento de Dados
// Com callback de mapeamento para transformar dados da API
const usersModel = generateTable<User, "id">("users", "id", (rawData) => ({
...rawData,
fullName: `${rawData.firstName} ${rawData.lastName}`,
isActive: rawData.status === "active",
}));🔧 API Reference
useModels Interface
interface BaseMethods {
generateItem: <T>(key: string, mapCallback?: Function) => ItemModel<T>;
generateTable: <T, PK>(
key: string,
primaryKey: PK,
mapCallback?: Function,
) => TableModel<T, PK>;
}
interface Methods<MS> extends BaseMethods {
get: <K extends keyof MS>(key: K) => ReturnType<MS[K]>;
}ItemModel Interface
interface ItemModel<T> {
store: ItemStore<T>;
resource: Resource<T>;
mapCallback?: (item: Record<keyof T, any>) => T;
get(): Promise<GettedItemResponse<T>>;
update(
payload: FormData | Record<string, any>,
): Promise<UpdatedItemResponse<T>>;
}TableModel Interface
interface TableModel<T, PK> {
store: TableStore<T, PK>;
resource: Resource<T>;
mapCallback?: (item: Record<keyof T, any>) => T;
list(query?: ListQuery): Promise<ListedItemsResponse<T>>;
get(id: T[PK]): Promise<GettedItemResponse<T>>;
create(
formData: FormData,
options?: CreateOptions,
): Promise<CreatedItemResponse<T>>;
update(id: T[PK], formData: FormData): Promise<UpdatedItemResponse<T>>;
updateMany(
ids: T[PK][],
formData: FormData,
): Promise<UpdatedManyItemsResponse<T>>;
delete(id: T[PK]): Promise<DeletedItemResponse<T>>;
}🏆 Boas Práticas
1. Organização de Models
// models/user.ts
export const useUserModels = () => {
const { generateItem, generateTable } = useModels();
const profile = generateItem<UserProfile>("profile");
const users = generateTable<User, "id">("users", "id");
return { profile, users };
};
// models/index.ts
export const models = useModels(fetch, {
userProfile: () => useUserModels().profile,
users: () => useUserModels().users,
});2. Composables Especializados
// composables/useUserManagement.ts
export const useUserManagement = () => {
const { users, profile } = useUserModels();
const loadUsers = async (filters?: UserFilters) => {
const response = await users.list(filters);
return response.data;
};
const updateProfile = async (data: Partial<UserProfile>) => {
const formData = new FormData();
Object.entries(data).forEach(([key, value]) => {
formData.append(key, value);
});
return await profile.update(formData);
};
return {
loadUsers,
updateProfile,
usersStore: users.store,
profileStore: profile.store,
};
};3. Integração com Componentes Vue
// components/UserList.vue
<script setup lang="ts">
import { onMounted } from 'vue';
import { useUserManagement } from '@/composables/useUserManagement';
const { loadUsers, usersStore } = useUserManagement();
// Estado reativo dos usuários
const users = usersStore.list();
onMounted(async () => {
await loadUsers();
});
</script>
<template>
<div>
<div v-for="user in users" :key="user.id">
{{ user.name }} - {{ user.email }}
</div>
</div>
</template>🔗 Dependências
- @ministerjs/store: Gerenciamento de estado
- @ministerjs/resource: Comunicação com APIs
- Vue 3.5+: Framework reativo
- TypeScript: Tipagem estática
📄 Licença
UNLICENSED - Uso interno do MinisterJS Framework
🤝 Contribuindo
Este pacote faz parte do monorepo MinisterJS. Para contribuir:
- Clone o repositório principal
- Instale as dependências:
pnpm install - Execute os testes:
pnpm test - Faça suas alterações no pacote
packages/model/ - Execute o build:
pnpm build
Para mais informações, consulte o README principal do MinisterJS.
