@hf-chimera/vue
v0.2.5
Published
Cross-end reactivity API - Vue adapter
Maintainers
Readme
ChimeraEntityStore Vue Integration
This package provides Vue 3 composables for seamless integration with ChimeraEntityStore, enabling fully reactive data queries in Vue applications.
Features
- Vue Composables: Use
useChimeraCollectionanduseChimeraItemwith the Composition API - TypeScript Support: Strong typing for entities, queries, and repositories
- Automatic Reactivity: Components update automatically on data, status, and error changes
- Query Builder Support: Fluent query builder function for strong types and readability
Installation
# Install both the core store and Vue adapter
npm install @hf-chimera/store @hf-chimera/vue
# Vue is a peer dependency
npm install vue
# Or install all at once
npm install @hf-chimera/store @hf-chimera/vue vueUsage
For Vue Applications
Import from the Vue-specific entry point:
import { createChimeraComposables } from "@hf-chimera/store/vue";
// In your app, call createChimeraComposables(store) and export the returned composablesFor Non-Vue Usage
Import and use the core store directly:
import { createChimeraEntityStore } from "@hf-chimera/store";
import { createChimeraStoreComposables } from "@hf-chimera/vue";Quick Start
1. Prepare composables for the store
Use createChimeraStoreComposables to create Vue composables bound to your entity store instance.
import { createChimeraEntityStore } from "@hf-chimera/store";
import { createChimeraStoreComposables } from "@hf-chimera/vue";
// Define your entity type
type Customer = {
id: number;
name: string;
email: string;
};
// Create your entity store instance
const customerStore = createChimeraEntityStore<"customer", Customer>({
name: "customer",
idGetter: "id",
async collectionFetcher(params, requestParams) {
const response = await fetch("/api/customers", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ filter: params.filter, order: params.order }),
signal: requestParams.signal,
});
return { data: await response.json() };
},
async itemFetcher(params, requestParams) {
const response = await fetch(`/api/customers/${params.id}`, {
signal: requestParams.signal,
});
return { data: await response.json() };
},
// ... other CRUD operations
});
// Create composables bound to your customer store
// This generates: useChimeraCustomerStore, useChimeraCustomerCollection, useChimeraCustomerItem
export const {
useChimeraCustomerStore,
useChimeraCustomerCollection,
useChimeraCustomerItem,
} = createChimeraStoreComposables(customerStore);2. Use Collection Queries in a component
useChimeraCustomerCollection returns a Vue Ref to a ChimeraCollectionQuery. In <template>, refs are auto-unwrapped. In <script setup>, access via .value.
<script setup lang="ts">
import { useChimeraCustomerCollection } from "@/store/chimera";
const customers = useChimeraCustomerCollection({
filter: { status: "active" },
order: [{ field: "name", direction: "asc" }],
});
function addCustomer() {
customers.value.create({ name: "New Customer" });
}
</script>
<template>
<div>
<div v-if="!customers.ready">Loading...</div>
<div v-else-if="customers.lastError">
Error: {{ String(customers.lastError) }}
</div>
<template v-else>
<div v-for="c in customers" :key="c.id">
{{ c.name }}
<button @click="customers.delete(c.id)">Delete</button>
</div>
<button @click="addCustomer">Add Customer</button>
</template>
</div>
</template>3. Use Item Queries in a component
<script setup lang="ts">
import { useChimeraCustomerItem } from "@/store/chimera";
interface Props {
customerId: string;
}
const props = defineProps<Props>();
const customer = useChimeraCustomerItem(() => props.customerId);
function updateName() {
if (!customer.value.data) return;
customer.value.mutable.name = "Updated Name";
customer.value.commit();
}
</script>
<template>
<div>
<div v-if="!customer.ready">Loading...</div>
<div v-else-if="customer.lastError">
Error: {{ String(customer.lastError) }}
</div>
<div v-else-if="!customer.data">Customer not found</div>
<div v-else>
<h3>{{ customer.data.name }}</h3>
<button @click="updateName">Update Name</button>
</div>
</div>
</template>4. Using the Query Builder
You can pass a builder function instead of a params object. The composable will call it to build the query.
import { useChimeraCollection } from "@/store/chimera";
const activeUsers = useChimeraCollection("customer", (q) => {
q.where("email", "contains", "@example.com").orderBy("createdAt", true);
});Complex example with groups:
const featuredOrders = useChimeraCollection("order", (q) => {
q.where("status", "eq", "completed")
// Must be either high value OR from VIP customer
.group("or", (group) => {
group
.where("totalAmount", "gte", 1000)
.where("customerId", "in", [1, 2, 3]);
})
// But not cancelled
.whereNot("status", "eq", "cancelled")
.orderBy("totalAmount", true);
});For more information on the query builder, see the ChimeraQueryBuilder documentation.
API Reference
Composables
useChimeraCustomerCollection<Meta>(params)
Composable for collection queries with automatic reactivity.
Parameters:
entityName: EntityName— Entity nameparams: ChimeraCollectionParams | QueryBuilderCreator | Ref | Getter— Query params or builder; can be a value, aref, or a function getter
Returns: Ref<ChimeraCollectionQuery<Item, OperatorsMap>> — see ChimeraCollectionQuery
useChimeraItem<EntityName, Meta>(entityName, id, meta?)
Composable for single item queries with automatic reactivity.
Parameters:
entityName: EntityName— Entity nameid: ChimeraEntityId | Ref | Getter— Item ID (can be reactive)meta?: Meta | Ref | Getter— Optional metadata (can be reactive)
Returns: Ref<ChimeraItemQuery<Item>> — see ChimeraItemQuery
Vue-specific Notes
- All composables return Vue
Refs. In<template>, refs are automatically unwrapped; in<script>, access via.value. - Subscribes internally to store events and triggers updates on:
- Collections:
ready,updated,selfUpdated,selfItemCreated,itemAdded,itemUpdated,selfItemUpdated,itemDeleted,selfItemDeleted,error. - Items:
initialized,selfCreated,ready,updated,selfUpdated,deleted,selfDeleted,error.
- Collections:
- You can pass reactive inputs (refs or getters) to
entityName,params,id, andmeta. The composables will react to changes automatically.
Tips
- Type Safety: Consider exposing a typed facade (e.g.,
getChimeraTypedComposables) in your project for strict types. - Error Handling: Always check
readyandlastErrorbefore rendering critical UI. - Optimistic Updates: Use the
mutableobject on item queries and callcommit(). - Batch Operations: Prefer collection-level operations when possible.
- Query Builder: Prefer the builder function for complex filtering and ordering with strong types.
