reselect createSelector memoized selectors: working versions (tested 2026-10-16)
Build memoized derived state with reselect createSelector: input selectors plus a combiner, assert the combiner runs once for identical inputs, use weakMapMemoize/default and a parameterized selector pattern, fully offline.
passed6 passed · 0 failed2026-10-16 02:18 UTC- Status
- passed
- Last passed
- 2026-10-16 02:18 UTC
- Tests
- 6 / 6
- Language
- TypeScript
- Runtime
- node v22.23.3
pinned versions3
reselect@5.3.0@types/node@26.6.5tsx@4.23.15
run it
npm install --no-audit --no-fund --ignore-scripts=false npm test
test environment
node v22.23.3 linux 6.17.0-1022-azure x64 runner: github-actions 38839686104
The code
Exactly the files that passed. Your agent can pull them with get_recipe("reselect-create-selector") (install), or see them on GitHub.
package.json
{
"name": "reselect-create-selector",
"private": true,
"type": "module",
"scripts": {
"test": "node --import tsx --test test/*.test.ts"
},
"dependencies": {
"reselect": "5.3.0"
},
"devDependencies": {
"@types/node": "26.6.5",
"tsx": "4.23.15"
}
}
src/selectors.ts
import { createSelector, weakMapMemoize } from "reselect";
export type Todo = {
id: string;
text: string;
done: boolean;
};
export type Filter = "all" | "active" | "completed";
export type User = { id: string; name: string };
export type RootState = {
todos: {
items: Todo[];
filter: Filter;
};
users: {
byId: Record<string, User>;
};
};
export const selectTodoItems = (state: RootState) => state.todos.items;
export const selectTodoFilter = (state: RootState) => state.todos.filter;
export const selectUsersById = (state: RootState) => state.users.byId;
export const selectVisibleTodos = createSelector(
[selectTodoItems, selectTodoFilter],
(items, filter) => {
switch (filter) {
case "active":
return items.filter((todo) => !todo.done);
case "completed":
return items.filter((todo) => todo.done);
default:
return items;
}
}
);
export const selectTodoStats = createSelector(
[selectTodoItems],
(items) => ({
total: items.length,
done: items.filter((todo) => todo.done).length,
}),
{ memoize: weakMapMemoize }
);
export const makeSelectTodoById = () =>
createSelector(
[
(state: RootState) => state.todos.items,
(_state: RootState, id: string) => id,
],
(items, id) => items.find((todo) => todo.id === id) ?? null
);
export const selectUserById = createSelector(
[selectUsersById, (_state: RootState, id: string) => id],
(byId, id) => byId[id] ?? null
);
test/selectors.test.ts
import { test } from "node:test";
import assert from "node:assert/strict";
import { createSelector } from "reselect";
import {
makeSelectTodoById,
selectTodoStats,
selectUserById,
selectVisibleTodos,
type RootState,
} from "../src/selectors.ts";
const state: RootState = {
todos: {
items: [
{ id: "1", text: "write tests", done: true },
{ id: "2", text: "ship recipe", done: false },
],
filter: "active",
},
users: { byId: { u1: { id: "u1", name: "Ada" } } },
};
test("combines multiple input selectors", () => {
assert.deepEqual(
selectVisibleTodos(state).map((todo) => todo.id),
["2"]
);
});
test("runs the combiner once for identical inputs", () => {
let calls = 0;
const selectCount = createSelector(
[(s: RootState) => s.todos.items],
(items) => {
calls++;
return items.length;
}
);
assert.equal(selectCount(state), 2);
assert.equal(selectCount(state), 2);
assert.equal(calls, 1);
});
test("recomputes the combiner when inputs change", () => {
let calls = 0;
const selectCount = createSelector(
[(s: RootState) => s.todos.items],
(items) => {
calls++;
return items.length;
}
);
selectCount(state);
selectCount({
...state,
todos: { ...state.todos, items: state.todos.items.slice(0, 1) },
});
assert.equal(calls, 2);
});
test("weakMapMemoize returns a stable reference for stable inputs", () => {
const first = selectTodoStats(state);
const second = selectTodoStats(state);
assert.equal(first, second);
assert.deepEqual(first, { total: 2, done: 1 });
});
test("parameterized selector resolves per-argument results", () => {
const selectTodoById = makeSelectTodoById();
assert.equal(selectTodoById(state, "1")?.text, "write tests");
assert.equal(selectTodoById(state, "2")?.text, "ship recipe");
assert.equal(selectTodoById(state, "missing"), null);
});
test("parameterized selector memoizes repeated arguments", () => {
const first = selectUserById(state, "u1");
const second = selectUserById(state, "u1");
assert.equal(first, second);
assert.equal(first?.name, "Ada");
});
Connect to ProvenPin
Add the free MCP server so your agent can pull this recipe and others like it. Same setup as the docs.
terminal
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp
~/.cursor/mcp.json
{ "mcpServers": { "provenpin": { "url": "https://mcp.provenpin.com/mcp" } } }.vscode/mcp.json
{ "servers": { "provenpin": { "type": "http", "url": "https://mcp.provenpin.com/mcp" } } }~/.codeium/windsurf/mcp_config.json
{ "mcpServers": { "provenpin": { "serverUrl": "https://mcp.provenpin.com/mcp" } } }MCP settings
{ "mcpServers": { "provenpin": { "type": "streamableHttp", "url": "https://mcp.provenpin.com/mcp" } } }Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.