proxy-memoize nested selector: working versions (tested 2026-10-16)
Memoize a selector over nested state with proxy-memoize, asserting stable result references when unrelated branches change, recomputation when selected paths change, and multi-entry caching with the size option.
passed3 passed · 0 failed2026-10-16 02:18 UTC- Status
- passed
- Last passed
- 2026-10-16 02:18 UTC
- Tests
- 3 / 3
- Language
- TypeScript
- Runtime
- node v22.23.3
pinned versions3
proxy-memoize@3.0.1@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("proxy-memoize-deep") (install), or see them on GitHub.
package.json
{
"name": "proxy-memoize-deep",
"private": true,
"type": "module",
"scripts": {
"test": "node --import tsx --test test/*.test.ts"
},
"dependencies": {
"proxy-memoize": "3.0.1"
},
"devDependencies": {
"@types/node": "26.6.5",
"tsx": "4.23.15"
}
}
src/selectors.ts
import { memoize } from "proxy-memoize";
export type CartItem = {
id: string;
qty: number;
price: number;
};
export type State = {
user: { id: string; name: string };
cart: { items: CartItem[]; currency: string };
settings: { theme: "light" | "dark" };
};
export type CartSummary = {
count: number;
total: number;
currency: string;
};
export const selectCartSummary = memoize(
(state: State): CartSummary => {
let count = 0;
let total = 0;
for (const item of state.cart.items) {
count += item.qty;
total += item.qty * item.price;
}
return { count, total, currency: state.cart.currency };
},
{ size: 2 },
);
test/selectors.test.ts
import { test } from "node:test";
import assert from "node:assert/strict";
import { memoize } from "proxy-memoize";
import { selectCartSummary, type State } from "../src/selectors.ts";
const makeState = (): State => ({
user: { id: "u1", name: "Ada" },
cart: {
items: [
{ id: "a", qty: 2, price: 5 },
{ id: "b", qty: 1, price: 3 },
],
currency: "USD",
},
settings: { theme: "light" },
});
test("returns the same reference when unrelated branches change", () => {
const state = makeState();
const first = selectCartSummary(state);
const next: State = {
...state,
user: { id: "u1", name: "Grace" },
settings: { theme: "dark" },
};
const second = selectCartSummary(next);
assert.equal(second, first);
assert.deepEqual(second, { count: 3, total: 13, currency: "USD" });
});
test("recomputes when a selected path changes", () => {
const state = makeState();
const first = selectCartSummary(state);
const next: State = {
...state,
cart: {
...state.cart,
items: [...state.cart.items, { id: "c", qty: 4, price: 2 }],
},
};
const second = selectCartSummary(next);
assert.notEqual(second, first);
assert.deepEqual(second, { count: 7, total: 21, currency: "USD" });
assert.deepEqual(first, { count: 3, total: 13, currency: "USD" });
});
test("size option retains multiple cached entries", () => {
const stateA = makeState();
const stateB: State = {
...stateA,
cart: { ...stateA.cart, currency: "EUR" },
};
const select = memoize(
(state: State) => ({
count: state.cart.items.length,
currency: state.cart.currency,
}),
{ size: 2 },
);
const a1 = select(stateA);
const b1 = select(stateB);
const a2 = select(stateA);
assert.notEqual(a1, b1);
assert.equal(a2, a1);
});
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.