Releases: diphyx/harlemify
Releases · diphyx/harlemify
5.4.2
Fix
- Resolve ViewDefinition union contravariance —
view.merge()return types are now correctly assignable to theViewDefinitionunion by usinganyfor contravariant type parameters, matching the existing pattern inModelDefinition.
API
- Export
isErrorandtoErrorfrom runtime — Error utility functions are now part of the public API via@diphyx/harlemify/runtime.
5.4.1
Refactor
- Remove proxy option from useStoreView —
datais now always a standard VueComputedRef. Theproxy,UseStoreViewProxy,UseStoreViewComputed, andUseStoreViewDatatypes have been removed. Usedata.valuein script anddatadirectly in templates.
Docs
- Fix
.valueusage inside Vue<template>blocks across all documentation - Fix import paths to use
@diphyx/harlemify/runtimefor runtime exports - Correct log messages in logging docs to match source code
- Add SSR documentation page
- Rewrite useStoreView docs to reflect simplified API
- Update README with feature list and corrected examples
5.4.0
Features
- Compose layer — New
useStoreComposecomposable for orchestrating actions, models, and views together - Lazy store — New
lazyoption forcreateStoreto defer initialization until first use - Function default — Support sync function default in model definitions for dynamic initial values
- Pre/post hooks & silent mode — Model commits now support
pre/posthooks andsilentoption to skip hooks - Pure reset — New
pureoption for model reset to restore shape defaults without side effects - Custom SSR — Replace
@harlem/plugin-ssrwith built-in SSR implementation and automatic state hydration
Fixes
- Restore
@nuxt/kitto dependencies for Nuxt 3 compatibility - Allow synchronous callbacks in
handler() - Narrow Nuxt compatibility range and add setup logging
- Enforce function-only default in model definitions
Playground
- Redesign playground UI with improved layout, components, and richer visual styling
- Add dashboard page with compose layer demo
- Add composables page showcasing
useStoreAction,useStoreModel,useStoreView - Add meta model with function default demo
Tests
- Update e2e selectors and assertions to match redesigned playground
Docs
- Reorganize and improve documentation content
- Revamp README with before/after comparison and badges
5.3.0
Features
- Many record model — New
manymodel type for keyed collections, enabling record-based state management with identifier-driven CRUD operations - Generic handler payload — Handler factory now supports a generic payload type for stronger type inference
Fixes
- Preserve API action return type — API action calls now correctly preserve the return type instead of erasing it
useStoreActiontype narrowing —execute()options type is now narrowed based on the action kind (API vs handler)- Type-safe
model.remove()—model.remove()now uses identifier generic and field matching for compile-time safety
Playground
- Add teams page demo with keyed collection CRUD (create, update, delete)
- Add teams API endpoints and server utils
Tests
- Add many record model test suites
- Add e2e tests for teams page
- Update action, store, and view tests
Docs
- Add many record model documentation with examples
- Update action documentation
Chore
- Bump version to 5.3.0
5.2.0
Features
- Handler payload — Handler actions now receive
payloadin the callback context ({ model, view, payload }), supporting both call-time and definition-level default values (#18) wrapBaseDefinitionutility — Shared utility for addingkey/setKeyto layer definitions, used across model, view, and action layers
Fixes
- Store config type inference —
StoreConfig.actionnow preserves concrete action types instead of erasing them toRecord<string, ActionDefinition> useStoreActionconstraint — Changed fromActionCalltoActionCall<any>to accept handler actions with non-void return types
Refactor
- Layers — Model, view, and action layers refactored to use shared
wrapBaseDefinition - Section comments — Added section comments to
utils/model.tsandutils/view.tsfor consistency
Playground
- Demo handler payload with toggle (call-time) and rename (definition default) actions
Tests
- Add handler payload, context, concurrent, and
wrapBaseDefinitiontest suites - Add e2e tests for handler payload composable features
Docs
- Add handler payload documentation with call-time and definition-level examples
- Add "When to Use API vs Handler" decision table
- Consolidate duplicated content, add cross-references between concurrency and cancellation
Chore
- Update
.npmignoreto cover all non-essential files - Bump version to 5.2.0
Closes #18
5.1.0
What's Changed
Features
- composables: add useStoreAction, useStoreModel, useStoreView composables
- core: add toReactiveProxy utility and timing helpers
- core: export composables and types from public API
- playground: add composables demo with todo store
Refactor
- action: remove action.data from core
Tests
- Add composable tests and update docs
Chore
- Remove global $fetch type declaration
- Bump version to 5.1.0
5.0.0
What's Changed
Features
- action: add alias mapping and explicit json response type
- model: add aliases method to ModelCall
- shape: add alias meta and resolve helpers, add defaults() method and createShape utility
- view: add clone option with ViewClone enum
- playground: add contacts demo with alias mapping, clone view demos, shape.defaults() for form initialization
Refactor
- utils: extract base helpers and error classes
Tests
- e2e: add contacts, clone view, and shape.defaults() coverage
- test: add alias, error import, clone option, and defaults test suites
Docs
- Add alias documentation and remove api reference
- Add clone option and ViewClone types documentation
- Add defaults() documentation and ShapeCall types
- Update version badge to 5.0.0
Chore
- Bump version to 5.0.0
4.0.1
Features
AUTOSymbol — New exportedAUTOsymbol for explicit auto-commit value resolution. Use it instead ofundefinedwhen passing commit options to signal that the action result should be used as the commit value:
import { AUTO } from "@diphyx/harlemify";
.commit("list", ActionManyMode.ADD, AUTO, { unique: true })
.commit("list", ActionManyMode.ADD, AUTO, { prepend: true })
.commit("list", ActionManyMode.PATCH, AUTO, { by: "email" })Bug Fixes
- Fix factory argument order in test files (
action.test.ts,view.test.ts)
Documentation
- Document
AUTOsymbol usage in action, types, collection, and nested store pattern docs
4.0.0
Features
- Factory-Driven Store API - New
createStore()withmodel(),view(), andaction()factory callbacks replacing the flat action-based config - Shape Layer - New
shape()factory for Zod schema definitions withShapeInfertype helper - Model Layer - Define state slots with
one()(singleton) andmany()(collection) factories - View Layer - Readonly computed queries with
from()andmerge()factories - Action Layer - State mutations via
api(),handle(), andcommit()factories - Per-Store Debug Logging - Built-in debug logging via consola for each store
- Improved Type Safety - Enhanced type-safety across core types, layers, and utils
Breaking Changes
- Store Definition Changed:
createStore()now uses factory callbacks (model,view,action) instead of flat action config - Schema → Shape:
Schemaconcept replaced withshape()factory - useStoreAlias Removed: Replaced with new composable pattern
- Utility Files Restructured: Internal utils reorganized into layers (
layers/,types/,utils/) - Runtime Config: Config passed through factories instead of direct imports
Migration
// Before (v3.x) - Flat action config
import { createStore } from "@diphyx/harlemify";
export const taskStore = createStore("task", TaskSchema, {
list: { method: "GET", url: "/tasks/" },
create: { method: "POST", url: "/tasks/" },
});
// After (v4.x) - Factory-driven API
import { createStore, shape } from "@diphyx/harlemify";
const taskShape = shape({
id: z.number().meta({ identifier: true }),
title: z.string(),
});
export const taskStore = createStore({
name: "task",
model({ one, many }) {
return {
selected: one(taskShape),
list: many(taskShape),
};
},
view({ from }) {
return {
selectedName: from("selected", (task) => task?.name),
};
},
action({ api }) {
return {
list: api("GET", "/tasks/"),
create: api("POST", "/tasks/"),
};
},
});Architecture
New layered architecture with clear separation of concerns:
| Layer | Purpose | Factories |
|---|---|---|
| Shape | Schema definition | shape() |
| Model | State slots | one(), many() |
| View | Readonly queries | from(), merge() |
| Action | State changes | api(), handle(), commit() |
Documentation
Full documentation: https://diphyx.github.io/harlemify/
3.0.0
Features
- Function-Based Monitor API - Access monitors as functions (
listIsPending()) instead of refs (listIsPending.value) - Unit-to-Units Sync on Edit - Automatically sync unit changes to units array when editing
- Free-Form Action Names - Replace fixed
Endpointenum with custom action names for flexible API patterns - Sub-Resource Schemas - Define different schemas per action for sub-resources
- Memory Behavior Control - Configure how actions affect store memory (
set,add,edit,drop,none)
Breaking Changes
- Monitor API Changed: Monitors are now functions instead of refs
- Endpoint Enum Removed: Use free-form action names instead of fixed
Endpointenum - Store Definition Changed: New action-based configuration structure
Migration
// Before (v2.x) - Monitors as refs
const { listIsPending } = useStoreAlias(taskStore);
if (listIsPending.value) { ... }
// After (v3.x) - Monitors as functions
const { listIsPending } = useStoreAlias(taskStore);
if (listIsPending()) { ... }// Before (v2.x) - Fixed endpoints
import { Endpoint } from '@diphyx/harlemify/runtime';
export const taskStore = createStore("task", TaskSchema, {
[Endpoint.GET_UNITS]: { url: "/tasks/" },
[Endpoint.POST_UNIT]: { url: "/tasks/" },
});
// After (v3.x) - Free-form action names
export const taskStore = createStore("task", TaskSchema, {
list: { method: "GET", url: "/tasks/" },
create: { method: "POST", url: "/tasks/" },
start: { method: "PUT", url: "/tasks/start/" },
pause: { method: "PUT", url: "/tasks/pause/" },
});Performance
- Schema memoization and Set-based action lookups
- Optimized bulk edit with temp index map for O(1) lookups
- Module-level Set constants in pluralize utility
- Simplified cache implementation
Documentation
Full documentation: https://diphyx.github.io/harlemify/
Closes #8