patch
@rotorsoft/act-root / act/src / patch
Function: patch()
patch<
S>(original,patches):Readonly<S>
Defined in: libs/act/src/utils.ts:131
Immutably applies patches to a state object, creating a new copy.
This function performs deep merging for plain objects while preserving
immutability. Special types (Arrays, Dates, Maps, etc.) are replaced
entirely rather than merged. Setting a property to undefined or null
removes it from the resulting object.
Used internally by the framework to apply event patches to state, but can also be used directly for state transformations.
Merging rules:
- Plain objects: Deep merge recursively
- Arrays, Dates, RegExp, Maps, Sets, TypedArrays: Replace entirely
undefinedornullvalues: Delete the property- Primitives: Replace with patch value
Type Parameters
S
S extends Schema
Parameters
original
Readonly<S>
The original state object to patch
patches
Readonly<Patch<S>>
The patches to apply (partial state)
Returns
Readonly<S>
A new state object with patches applied
Examples
import { patch } from "@rotorsoft/act";
const state = { count: 0, name: "Alice" };
const updated = patch(state, { count: 5 });
// Result: { count: 5, name: "Alice" }
// Original unchanged: { count: 0, name: "Alice" }
const state = {
user: { id: 1, name: "Alice", email: "alice@example.com" },
settings: { theme: "dark" }
};
const updated = patch(state, {
user: { email: "newemail@example.com" }
});
// Result: {
// user: { id: 1, name: "Alice", email: "newemail@example.com" },
// settings: { theme: "dark" }
// }
const state = { count: 5, temp: "value", flag: true };
const updated = patch(state, {
temp: undefined, // Delete temp
flag: null // Delete flag
});
// Result: { count: 5 }
const state = { items: [1, 2, 3], meta: { count: 3 } };
const updated = patch(state, {
items: [4, 5] // Arrays are replaced, not merged
});
// Result: { items: [4, 5], meta: { count: 3 } }
import { state } from "@rotorsoft/act";
import { z } from "zod";
const Counter = state({ Counter: z.object({ count: z.number() }) })
.init(() => ({ count: 0 }))
.emits({ Incremented: z.object({ by: z.number() }) })
.patch({
Incremented: (event, state) => {
// patch() is called internally here
return { count: state.count + event.data.by };
}
});
See
Patch for the patch type definition