insertSelect
insertSelect is the unified API to select a nested sub-state and add insertions to it, whether the parent is:
- an object
- an array
This makes it possible to write nested insertions with a single API, without switching helpers based on the state shape, and it helps drive complex object logic.
INFO
This insertion can only be used by state primitive.
Import
import { insertSelect, state } from '@craft-ng/core';Basic Usage (object)
const board = state(
{
cell: {
color: 'white',
paintCount: 0,
},
},
insertSelect('cell', ({ update, state }) => ({
paint: () =>
update((cell) => ({
...cell,
color: 'black',
paintCount: cell.paintCount + 1,
})),
paintCountStr: () => `Painted ${state().paintCount} times`,
})),
);
board.selectCell().paint();
console.log(board.selectCell().paintCountStr()); // "Painted 1 times"Basic Usage (array)
const cells = state(
[{ color: 'white', paintCount: 0 }],
insertSelect('cell', ({ update }) => ({
paint: () =>
update((cell) => ({
...cell,
color: 'black',
paintCount: cell.paintCount + 1,
})),
})),
);
cells.selectCell(0)?.paint();
console.log(cells.selectCell(0)?.paintCount); // 1Why use it
- A single API for selections on both object and array states
- Simplifies nested insertions (object -> array -> object, etc.)
- Helps drive complex object logic close to the relevant nested sub-state
Current limitation
insertSelect (on object states) does not yet support targeting a property that is not an object (for example: string, number, boolean).
This currently breaks type inference. An improvement is planned.
TypeScript inference limitation (workaround)
In some nested cases, TypeScript can lose contextual typing (for example when selecting an array property and chaining another insertSelect immediately).
You can force TypeScript to preserve the typing context by inserting the no-op helper insertNoopTypingAnchor before the nested insertion:
insertSelect(
'grid',
insertNoopTypingAnchor,
insertSelect('row', ({ update }) => ({
// ...
})),
);