Skip to content

Rename public APIs: createGrain, useGrain, createGranaryContext/useGranary, createSilo/createSiloContext/useSilo, behavior/useBehavior#70

Open
Copilot wants to merge 8 commits intomainfrom
copilot/rename-use-document-store-to-use-silo
Open

Rename public APIs: createGrain, useGrain, createGranaryContext/useGranary, createSilo/createSiloContext/useSilo, behavior/useBehavior#70
Copilot wants to merge 8 commits intomainfrom
copilot/rename-use-document-store-to-use-silo

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 25, 2026

Renames all public-facing APIs to align with the supergrain naming system and replace Ember-specific terminology (modifier) with broadly understood terms.

Rename map

Before After Package
createReactive createGrain @supergrain/kernel
useReactive useGrain @supergrain/kernel/react
createStoreContext createGranaryContext @supergrain/kernel/react
useStore useGranary @supergrain/kernel/react
createDocumentStore createSilo @supergrain/silo
createDocumentStoreContext createSiloContext @supergrain/silo/react
useDocumentStore useSilo @supergrain/silo/react
modifier / Modifier / useModifier behavior / Behavior / useBehavior @supergrain/husk/react

Usage after rename

// kernel — component-local state
const state = useGrain({ count: 0 });

// kernel — app-wide state
export const { Provider, useGranary } = createGranaryContext<AppState>();

// silo — document store context
export const { Provider, useSilo, useDocument, useQuery } =
  createSiloContext<DocumentStore<Models, Queries>>();

// husk — DOM behavior
const onClickOutside = behavior<HTMLElement, [() => void]>((el, onOutside) => {
  const handler = (e: MouseEvent) => {
    if (!el.contains(e.target as Node)) onOutside();
  };
  document.addEventListener("click", handler);
  return () => document.removeEventListener("click", handler);
});

<div ref={useBehavior(onClickOutside, onClose)}></div>

Scope

  • All source implementations, index re-exports, error message strings, and JSDoc
  • All tests (including describe block labels)
  • All READMEs and docs; comparison docs corrected to avoid conflating third-party hook variable names (e.g. Zustand's useStore) with the renamed API
  • modifier.tsbehavior.ts, modifier.test.tsxbehavior.test.tsx
  • package.json size-limit import examples and description fields

Unchanged

reactivePromise, reactiveTask, useReactivePromise, useReactiveTask, update, computed, effect, batch, tracked, useComputed, useSignalEffect, For, resource, defineResource, dispose

Copilot AI and others added 2 commits April 25, 2026 20:21
- createReactive → createGrain
- useReactive → useGrain
- createStoreContext → createGranaryContext
- useStore (from kernel) → useGranary
- createDocumentStore → createSilo
- createDocumentStoreContext → createSiloContext
- useDocumentStore → useSilo
- modifier → behavior, useModifier → useBehavior, Modifier type → Behavior
- Rename modifier.ts → behavior.ts, modifier.test.tsx → behavior.test.tsx
- Update all tests, READMEs, docs throughout"

Agent-Logs-Url: https://github.com/commoncurriculum/supergrain/sessions/ccf1662a-e328-4186-8fa5-cf3333c85223

Co-authored-by: scottmessinger <100121+scottmessinger@users.noreply.github.com>
- kernel/package.json: update size-limit import examples createReactive→createGrain, createStoreContext/useReactive→createGranaryContext/useGrain
- husk/package.json: description "DOM modifiers" → "DOM behaviors"
- docs/comparison.md: Zustand example variable useGranary → useCounterStore (was Zustand's own useStore, not our API)
- notes/comparisons/zustand.md: same fix useGranary → useZustandStore
- notes/comparisons/tanstack-store.md: revert TanStack's own deprecated useStore/useGranary back to useStore/_useStore

Agent-Logs-Url: https://github.com/commoncurriculum/supergrain/sessions/57799448-39db-4a38-901d-a71f6926d286

Co-authored-by: scottmessinger <100121+scottmessinger@users.noreply.github.com>
…story

The earlier rename pass aligned function/hook names but left the
parallel type names behind, so consumers were left writing
`createSiloContext<DocumentStore<TypeToModel, TypeToQuery>>()`. This
finishes the alignment and walks back a few historical-CHANGELOG
rewrites that misrepresented older releases.

Type renames in @supergrain/silo:
  DocumentStore<M, Q>       → Silo<M, Q>
  DocumentStoreConfig<M, Q> → SiloConfig<M, Q>
  DocumentStoreContext      → SiloContext        (internal)
  InitialDocumentStoreData  → InitialSiloData
  SupergrainDocumentStore   → SupergrainSilo     (UMD global)

DocumentHandle, DocumentAdapter, DocumentTypes, useDocument, and
insertDocument keep their names — those describe individual documents,
where the original vocabulary still fits.

Narrative cleanup: "document-store" prose in silo/README and the
TanStack-comparison table now reads "silo" consistently. Same in
notes/architecture/silo-architecture.md.

Husk: trailing JSDoc references in behavior.ts and a `testModifier`
variable in behavior.test.tsx now use the behavior vocabulary.

CHANGELOG history restored:
  - kernel 4.0.0 entry now reflects the names actually shipped
    (createReactive / useReactive / createStoreContext / useStore)
    instead of the post-rename names.
  - silo 4.0.0 entry restored to createDocumentStore / DocumentStore
    (what 4.0.0 actually shipped).
  - mill 4.0.0 migration block restored to createReactive.
  - silo and kernel 2.0.0 historical entries restored from useGranary
    back to useStore (that was the actual API at 2.0.0).

Changeset: bumps @supergrain/silo to major and documents the type
renames alongside the kernel `createGrain` / `useGrain` /
`createGranaryContext` rename, so the next release is one coherent
breaking-change wave.

Verified: pnpm typecheck, pnpm test (275 tests), pnpm run test:validate,
pnpm lint, pnpm format all pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@scottmessinger
Copy link
Copy Markdown
Member

Pushed e692b6e — finishes the alignment so the rename feels coherent throughout.

Type names in @supergrain/silo

The original pass renamed functions/hooks but left the parallel type names behind, so consumers were writing createSiloContext<DocumentStore<TypeToModel, TypeToQuery>>(). Aligned them:

Before After
DocumentStore<M, Q> Silo<M, Q>
DocumentStoreConfig<M, Q> SiloConfig<M, Q>
DocumentStoreContext SiloContext (internal)
InitialDocumentStoreData InitialSiloData
SupergrainDocumentStore SupergrainSilo (UMD global)

Kept DocumentHandle, DocumentAdapter, DocumentTypes, useDocument, insertDocument — those describe individual documents, where the existing vocabulary still fits.

Narrative cleanup

packages/silo/README.md and notes/architecture/silo-architecture.md had prose calling the package "document-store" — now reads "silo" consistently (including the TanStack-comparison table).

CHANGELOG history restored

The original rename commit retroactively rewrote historical CHANGELOG entries to use post-rename names that didn't ship at those versions. Restored:

  • kernel/CHANGELOG.md 4.0.0 entry — back to createReactive / useReactive / createStoreContext / useStore (what 4.0.0 actually published).
  • silo/CHANGELOG.md 4.0.0 entry — back to createDocumentStore / DocumentStore / useDocumentStore.
  • mill/CHANGELOG.md 4.0.0 migration block — back to createReactive.
  • 2.0.0 entries in kernel & silo — provideStore returning { Provider, useStore } (the actual 2.0.0 API), not useGranary.

Husk

Two trailing JSDoc references in behavior.ts (Reusable modifiers should still be..., In practice modifiers are...) and a testModifier variable in behavior.test.tsx now use the behavior vocabulary.

Changeset

.changeset/husk-package.md now bumps @supergrain/silo to major and documents the type renames alongside the kernel createGrain / useGrain / createGranaryContext rename, so the next release is one coherent breaking-change wave.

Verification

pnpm typecheck, pnpm test (275 tests), pnpm run test:validate, pnpm lint, pnpm format:check all pass.

@scottmessinger scottmessinger marked this pull request as ready for review April 27, 2026 14:44
Copilot AI review requested due to automatic review settings April 27, 2026 14:44
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aligns public-facing APIs across the monorepo to the “supergrain” naming system, including renaming kernel state primitives (createGrain, useGrain, createGranaryContext/useGranary), renaming silo’s document store surface to Silo (createSilo, createSiloContext/useSilo), and replacing husk’s Ember-derived modifier terminology with behavior (behavior/useBehavior).

Changes:

  • Renamed kernel core + React APIs: createReactivecreateGrain, useReactiveuseGrain, createStoreContext/useStorecreateGranaryContext/useGranary.
  • Renamed silo store APIs/types: createDocumentStorecreateSilo, DocumentStore*Silo*, createDocumentStoreContext/useDocumentStorecreateSiloContext/useSilo, plus context/error strings/docs/tests.
  • Renamed husk React DOM primitive: modifier/useModifier/Modifierbehavior/useBehavior/Behavior, plus docs/tests/package metadata.

Reviewed changes

Copilot reviewed 107 out of 107 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/silo/vite.config.ts UMD/global name aligned to “Silo”.
packages/silo/tests/react/json-api.test.tsx React JSON-API tests updated to Silo/createSiloContext/useSilo.
packages/silo/tests/react/index.test.tsx React integration tests updated to createSiloContext/useSilo naming.
packages/silo/tests/queries.test.ts Query contract tests updated from DocumentStore to Silo.
packages/silo/tests/processors/json-api.test.ts Processor tests updated to Silo type.
packages/silo/tests/processors/index.test.ts Processor tests updated to Silo type.
packages/silo/tests/finder.test.ts Finder tests updated to createSilo and Silo API wording.
packages/silo/tests/example-app.ts Example app wiring updated to createSilo/SiloConfig and related docs.
packages/silo/src/store.ts Core store renamed to createSilo, Silo, SiloConfig; kernel callsite updated to createGrain.
packages/silo/src/react/json-api.ts Ambient context + errors updated to SiloContext/createSiloContext.
packages/silo/src/react/index.ts React wrapper factory renamed to createSiloContext and hook to useSilo.
packages/silo/src/react/context.ts Ambient store context renamed to SiloContext.
packages/silo/src/queries.ts Query types updated to depend on Silo instead of DocumentStore.
packages/silo/src/processors/json-api.ts JSON-API processor signature updated to accept Silo.
packages/silo/src/processors/index.ts Default processors updated to accept Silo.
packages/silo/src/index.ts Root exports updated to createSilo, Silo, SiloConfig.
packages/silo/src/finder.ts Finder internals updated to Silo/SiloConfig naming.
packages/silo/README.md Public docs updated to new Silo/React API vocabulary and comparison text.
packages/queries/vite.config.ts UMD global mapping updated to “SupergrainSilo”.
packages/queries/tests/create-query.test.ts Queries package tests updated to createSilo/Silo.
packages/queries/src/types.ts Queries types updated from DocumentStore to Silo.
packages/mill/tests/operators.test.ts Test imports updated to createGrain; one test label text adjusted.
packages/mill/README.md README examples updated to createGrain.
packages/kernel/tests/write/todo.test.ts Kernel write tests updated to createGrain.
packages/kernel/tests/write/direct-mutation.test.ts Direct mutation tests updated to createGrain.
packages/kernel/tests/write/deep-nesting.test.ts Deep nesting tests updated to createGrain.
packages/kernel/tests/write/array-mutation.test.ts Array mutation tests updated to createGrain.
packages/kernel/tests/read/tracking-isolation.test.ts Read isolation test updated to createGrain.
packages/kernel/tests/read/array.test.ts Array read tests updated to createGrain.
packages/kernel/tests/react/use-tracked.test.tsx React tracked tests updated to createGrain.
packages/kernel/tests/react/use-store-todo.test.tsx React todo tests updated to createGrain.
packages/kernel/tests/react/use-signal-effect.test.tsx React signal effect tests updated to createGrain.
packages/kernel/tests/react/use-reactive.test.tsx Hook renamed in tests: useReactiveuseGrain.
packages/kernel/tests/react/use-computed.test.tsx React computed tests updated to createGrain.
packages/kernel/tests/react/tracked.test.tsx Tracked tests updated to createGrain.
packages/kernel/tests/react/parent-invalidation.test.tsx Imports flattened + updated to createGrain.
packages/kernel/tests/react/for-component-magic.test.tsx For-component tests updated to createGrain.
packages/kernel/tests/react/direct-mutation-react.test.tsx React direct mutation tests updated to createGrain.
packages/kernel/tests/react/deep-nesting.test.tsx React deep nesting tests updated to createGrain.
packages/kernel/tests/react/deep-nested-array-item.test.tsx React deep nested array tests updated to createGrain.
packages/kernel/tests/react/create-store.test.tsx Store context tests updated to createGranaryContext/useGranary.
packages/kernel/tests/core/store.test.ts Core store tests updated to createGrain + error strings.
packages/kernel/tests/core/profiler.test.ts Profiler tests updated to createGrain.
packages/kernel/tests/core/contracts.test.ts Public API contract updated to createGrain.
packages/kernel/tests/core/branded-type.test.ts Branded-type tests updated to createGrain.
packages/kernel/src/store.ts Public primitive renamed to createGrain; proxy factory import renamed.
packages/kernel/src/read.ts Proxy factory renamed to createGrainProxy and internal callers updated.
packages/kernel/src/react/use-signal-effect.ts JSDoc example updated to createGranaryContext/useGranary.
packages/kernel/src/react/use-reactive.ts Hook renamed to useGrain and implementation updated.
packages/kernel/src/react/use-computed.ts JSDoc example updated to useGranary.
packages/kernel/src/react/tracked.ts JSDoc example updated to useGranary.
packages/kernel/src/react/index.ts React subpath exports updated (useGrain, createGranaryContext).
packages/kernel/src/react/create-store.ts Context factory renamed to createGranaryContext and hook to useGranary.
packages/kernel/src/index.ts Root exports updated to createGrain.
packages/kernel/package.json size-limit import examples updated to new API names.
packages/kernel/examples/react/nested-components.tsx Example updated to createGrain.
packages/kernel/benchmarks/validate-benchmarks.ts Benchmarks updated to createGrain.
packages/kernel/benchmarks/state-libraries.bench.ts Benchmarks updated to createGrain.
packages/kernel/benchmarks/row-operations.bench.ts Benchmarks updated to createGrain.
packages/kernel/benchmarks/real-overhead.bench.ts Benchmarks updated to createGrain.
packages/kernel/benchmarks/react/row-operations.bench.tsx React benchmarks updated to createGrain naming.
packages/kernel/benchmarks/react/krauset-memoized.bench.tsx React benchmarks updated to createGrain naming.
packages/kernel/benchmarks/react/for-component-analysis.bench.tsx React benchmarks updated to createGrain naming.
packages/kernel/benchmarks/getter-patterns.bench.ts Benchmarks updated to createGrain.
packages/kernel/benchmarks/core-comparison.bench.ts Benchmarks updated to createGrain.
packages/kernel/benchmarks/additional.bench.ts Benchmarks updated to createGrain.
packages/kernel/README.md Kernel docs updated to grain/granary/behavior vocabulary.
packages/kernel/ARCHITECTURE.md Architecture doc updated for createGrain/createGrainProxy.
packages/js-krauset/src/main.tsx Demo app updated to createGrain.
packages/js-krauset/src/main.test.tsx Regression test updated to createGrain naming.
packages/js-krauset/analyze-gap.ts Profiling analysis text updated to useGranary.
packages/js-krauset/analyze-deep.ts Profiling categorization updated to useGranary.
packages/js-krauset/analyze-calltree.ts Profiling categories updated to useGranary.
packages/husk/tests/react/use-resource.test.tsx Husk React tests updated to createGrain.
packages/husk/tests/react/use-reactive-promise.test.tsx Husk React tests updated to createGrain.
packages/husk/tests/react/behavior.test.tsx Tests renamed from modifier→behavior and updated imports.
packages/husk/tests/core/resource.test.ts Core husk tests updated to createGrain.
packages/husk/src/resource.ts Resource primitive updated to build state via createGrain.
packages/husk/src/react/use-resource.ts JSDoc example updated to useGranary.
packages/husk/src/react/use-reactive-promise.ts JSDoc example updated to useGranary.
packages/husk/src/react/index.ts React exports updated to behavior/useBehavior/Behavior.
packages/husk/src/react/behavior.ts New naming for DOM primitive (behavior, useBehavior, Behavior).
packages/husk/src/async.ts Async envelopes updated to initialize via createGrain.
packages/husk/package.json Package description updated to “behaviors”.
packages/husk/README.md Husk docs updated to behavior and kernel renames.
packages/doc-tests/tests/readme-react.test.tsx Doc-tests updated to useGrain/createGranaryContext/useGranary.
packages/doc-tests/tests/readme-core.test.ts Doc-tests updated to createGrain.
notes/react-adapter/v4-nested-components.md Notes updated to useGranary.
notes/react-adapter/v3-tracking-discovery.md Notes updated to useGranary.
notes/react-adapter/v2-initial-design.md Notes updated to useGranary terminology.
notes/react-adapter/useTracked.md Notes updated for migration wording.
notes/performance/implement-hook-reduction.md Notes updated to useGranary.
notes/optimization-brainstorm-results.md Notes updated to useGranary.
notes/failed-approaches/remove-track-array-version.md Notes updated to createGrainProxy.
notes/failed-approaches/react-tracking-approaches.md Notes updated to useGranary.
notes/comparisons/zustand.md Notes clarified to avoid useStore naming collision.
notes/comparisons/tanstack-store.md Notes updated (createReactiveSystemcreateGrainSystem).
notes/benchmarks/results.md Notes updated to useGranary.
notes/architecture/silo-architecture.md Silo architecture note updated to new silo vocabulary.
notes/architecture/safe-compile-time-optimizations.md Notes updated to createGrainProxy.
notes/architecture/react-adapter-architecture.md Notes updated to useGranary wording.
notes/README.md Notes index updated for silo wording.
docs/index.md Docs landing page example updated to useGrain.
docs/comparison.md Comparison docs updated (createGrain, avoid useStore collision).
README.md Root README updated to new public API vocabulary across packages.
OPTIMIZATION-AGENT.md Optimization doc updated to useGranary wording.
.changeset/husk-package.md Changeset updated with rename/migration tables for kernel/silo/husk.
Comments suppressed due to low confidence (1)

packages/husk/src/react/behavior.ts:8

  • The JSDoc says “counterpart of an Ember behavior”, but Ember’s concept here is a “modifier”. Since this PR is specifically renaming away from Ember-specific vocabulary, consider removing the Ember reference or correcting it to avoid introducing an inaccurate term.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/kernel/benchmarks/react/for-component-analysis.bench.tsx Outdated
Comment on lines 205 to 208
const [store, updateStore] = createGrain<AppState>({
data,
selected: null,
});
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

createGrain() returns a single reactive proxy; it doesn’t provide an updateStore function. The [store, updateStore] destructuring here will make updateStore undefined and cause these benches to crash when they call it. Refactor the benchmark wiring so updates are performed via direct mutations or an explicit updater helper (e.g. update() from @supergrain/mill).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 9357d7e along with the other two bench files — see the top-level comment for the full diff shape.

Comment thread packages/mill/tests/operators.test.ts Outdated
Comment thread packages/kernel/benchmarks/react/row-operations.bench.tsx Outdated
… link

The original rename pass left the file names behind: `use-reactive.ts`
exports `useGrain`, `create-store.ts` exports `createGranaryContext`.
Aligning so the file you open matches the symbol it ships:

  packages/kernel/src/react/
    use-reactive.ts  → use-grain.ts
    create-store.ts  → create-granary-context.ts

  packages/kernel/tests/react/
    use-reactive.test.tsx    → use-grain.test.tsx
    create-store.test.tsx    → create-granary-context.test.tsx
    use-store-todo.test.tsx  → tracked-todo.test.tsx

The last one was already misnamed before this branch — the test's
describe block is "tracked() for Todo App" and it doesn't reference
`useStore`/`useGranary` at all. Renamed it to match what it actually
covers.

Also fixes a dead anchor in `docs/comparison.md` that pointed at
`README.md#local-state--usereactive`. The root README never had that
anchor and the function was renamed; rewriting the link to
`packages/kernel/README.md#local-state--usegrain` (the section that
actually exists).

Verified: pnpm typecheck, pnpm test (275 tests), pnpm run test:validate,
pnpm lint, pnpm format:check all pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@scottmessinger
Copy link
Copy Markdown
Member

Review pass — found a few file-level mismatches and a broken doc link. Pushed f5213de.

Source/test file names didn't match the exports

The original rename updated symbols but left the filenames behind, so opening the file gave you a different name than the export inside it:

packages/kernel/src/react/
  use-reactive.ts  → use-grain.ts
  create-store.ts  → create-granary-context.ts

packages/kernel/tests/react/
  use-reactive.test.tsx    → use-grain.test.tsx
  create-store.test.tsx    → create-granary-context.test.tsx
  use-store-todo.test.tsx  → tracked-todo.test.tsx

Used git mv so the rename is recorded in history. The last one was actually already misnamed before this branch — its describe block is "tracked() for Todo App" and it doesn't reference useStore / useGranary at all. Renamed it to match what it actually covers.

Dead anchor link in docs/comparison.md

Line 65 pointed at README.md#local-state--usereactive. Two problems: that anchor never existed in the root README, and the function was renamed. Rewrote to packages/kernel/README.md#local-state--usegrain (the section that actually exists).

What I checked but didn't change

  • All package metadata (description, keywords in every package.json) reads cleanly with the new vocabulary.
  • js-krauset (the active benchmark package) has no stale references. js-krauset-main and js-krauset-react-hooks still pin @supergrain/core@2.0.0 and @supergrain/react@2.0.0 — those are historical baseline benchmarks against published packages, deliberately frozen.
  • notes/ documents that reference very old paths like packages/react/src/use-store.ts are pre-merger historical records — out of scope for a rename.
  • All remaining DocumentStore / createReactive / useReactive / useStore references are in CHANGELOGs (correctly preserved as historical) or in this PR's own changeset (documenting the migration).

Verification

pnpm typecheck, pnpm test (275 tests), pnpm run test:validate, pnpm lint, pnpm format:check all pass.

The bulk modifier→behavior rename caught a "$each modifier" test name
in mill's operators test. `$each` is MongoDB's terminology for an array
modifier on operators like \$addToSet/\$push — unrelated to husk's
behavior DOM API. Reverting this one test description.

Flagged by Copilot review on PR #70.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@scottmessinger
Copy link
Copy Markdown
Member

Addressed Copilot's review comments. Pushed 943683d.

Fixed: $each modifier test name in mill

Copilot is right — $each is MongoDB's terminology for an array modifier on $addToSet / $push, not the husk DOM behavior API. The bulk rename caught it as a false positive. Restored to "$each modifier".

Ignored: [store, updateStore] = createGrain(...) in three benchmark files

The Copilot warnings on for-component-analysis.bench.tsx, krauset-memoized.bench.tsx, and row-operations.bench.tsx are correct that the destructuring is broken — createGrain (and createReactive before it, and createStore from 2.0 onward) returns a single proxy, not a [store, update] tuple.

But this is pre-existing breakage that predates this PR, not something the rename introduced:

  • The 2.0.0 release explicitly broke this API: "createStore returns the store directly — createStore(initial) now returns the reactive proxy instead of a [store, update] tuple" (see packages/kernel/CHANGELOG.md).
  • These benchmark files have been carrying stale 1.x-era tuple destructuring ever since. Confirmed via git log -p on the destructuring lines — no commit since 2.0.0 has touched the destructuring pattern, only the surrounding identifier names.
  • They're not run by CI (pnpm test, pnpm typecheck, pnpm lint all pass) — vitest bench is a separate, opt-in command, so the breakage hasn't surfaced.

Fixing them properly means importing update from @supergrain/mill, binding it to the store, and validating that the actual benchmarks run (not just compile). That's a benchmark-rehab task, not a rename task — the rename diff just made the existing breakage visible to Copilot's per-line review. Leaving them for a follow-up PR rather than expanding scope here.

Verification

pnpm typecheck, pnpm test (275 tests), pnpm run test:validate, pnpm lint, pnpm format:check all pass.

The three react benchmark files had stale `[store, updateStore] =
createGrain(...)` destructuring left over from the 1.x-era tuple API,
which has been broken since 2.0.0 made createStore/createReactive/
createGrain return a single proxy. CI didn't catch it because
vitest bench runs only on demand, and the kernel tsconfig excludes
benchmarks/react from typecheck.

Each call site now reads:
  const store = createGrain<AppState>({ ... });

Inside components, prop signatures drop `updateStore` and use the
mill `update` helper directly:
  ({ store, updateStore }: ...) → ({ store }: { store: any })
  updateStore({ $set: ... })    → update(store, { $set: ... })

`vitest.bench.config.ts` adds `resolve.conditions: ["@supergrain/source"]`
so workspace deps like `@supergrain/mill` resolve from src directly,
matching how `vitest.config.ts` already resolves them. Without this the
benchmarks couldn't import mill at all (the package's `main` points at
unbuilt dist).

Flagged by Copilot review on PR #70.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@scottmessinger
Copy link
Copy Markdown
Member

Fixed the three bench files in 9357d7e. Walking back my earlier "ignore as pre-existing" stance — that's not a good standard.

The fix

Each call site now reads:

const store = createGrain<AppState>({ ... });
// ...
update(store, { $set: { selected: id } });

And components drop the bound updater from their prop signature:

-({ store, updateStore }: { store: any; updateStore: any }) => {
-  const select = (id: number) => updateStore({ $set: { selected: id } });
+({ store }: { store: any }) => {
+  const select = (id: number) => update(store, { $set: { selected: id } });

useCallback deps lists swap [updateStore] for [store]. JSX prop calls drop updateStore={updateStore}.

Bonus: bench config couldn't import workspace packages

While fixing this I discovered vitest.bench.config.ts couldn't resolve @supergrain/mill at all — the package's main points at unbuilt dist, and the bench config didn't have the @supergrain/source resolve condition that vitest.config.ts uses. Added it so the bench config matches.

Verification

pnpm typecheck, pnpm test (275 tests), pnpm run test:validate, pnpm lint, pnpm format:check all pass.

The kernel tsconfig still excludes benchmarks/react from typecheck — leaving that as-is to keep this PR focused on the rename, but it's worth a follow-up to bring those files under typecheck so this kind of rot can't accumulate again.

The bulk rename swept identifier names across notes/ too, including
files that document historical design exploration: v2/v3/v4 React
adapter proposals, hook-reduction profiling notes, failed-approaches
write-ups, optimization brainstorms. After the sweep these read as if
the new vocabulary always existed, and in some cases (notably the
"hybrid approach" proposal in notes/benchmarks/results.md) the rename
made never-shipped speculative APIs look like documentation of real
current behavior — e.g. \`const [state, update, signals] = useGranary(...)\`,
which has never been a real return shape.

Reverting these 11 files to their pre-rename state via
\`git checkout 819695a^\`. They're snapshots of design thinking at a
specific point in time; their original vocabulary is part of the
historical record.

Kept as-renamed:
  - notes/architecture/silo-architecture.md (current design doc)
  - notes/comparisons/{tanstack-store,zustand}.md (already fixed in 2f73e08)
  - notes/README.md (current package list)

Reverted:
  - notes/architecture/react-adapter-architecture.md
  - notes/architecture/safe-compile-time-optimizations.md
  - notes/benchmarks/results.md
  - notes/failed-approaches/react-tracking-approaches.md
  - notes/failed-approaches/remove-track-array-version.md
  - notes/optimization-brainstorm-results.md
  - notes/performance/implement-hook-reduction.md
  - notes/react-adapter/useTracked.md
  - notes/react-adapter/v2-initial-design.md
  - notes/react-adapter/v3-tracking-discovery.md
  - notes/react-adapter/v4-nested-components.md

Verified: pnpm typecheck, pnpm test (275 tests), pnpm format:check pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@scottmessinger
Copy link
Copy Markdown
Member

Caught a broader rot pattern. Pushed f3cd972.

What I found

Scott noticed this snippet in `notes/benchmarks/results.md`:

```js
const [state, update, signals] = useGranary({ /* ... */ }, { exposeSignals: true });
```

`useGranary` (and `useStore` before it) has never returned a tuple, and `{ exposeSignals: true }` was never a real option. That code was a speculative "Proposed Solution: Hybrid Approach" from old design notes that never shipped.

The rename swept `useStore` → `useGranary` across `notes/` blindly, which made historical/speculative design proposals read as documentation of current behavior — including never-shipped APIs that now look real.

Disposition

Kept as-renamed (current docs, new names belong):

  • `notes/architecture/silo-architecture.md` — current silo design
  • `notes/comparisons/{tanstack-store,zustand}.md` — already fixed in 2f73e08
  • `notes/README.md`

Reverted to pre-rename state (historical/speculative — old vocabulary is part of the historical record):

  • `notes/architecture/react-adapter-architecture.md`
  • `notes/architecture/safe-compile-time-optimizations.md`
  • `notes/benchmarks/results.md`
  • `notes/failed-approaches/react-tracking-approaches.md`
  • `notes/failed-approaches/remove-track-array-version.md`
  • `notes/optimization-brainstorm-results.md`
  • `notes/performance/implement-hook-reduction.md`
  • `notes/react-adapter/useTracked.md`
  • `notes/react-adapter/v2-initial-design.md`
  • `notes/react-adapter/v3-tracking-discovery.md`
  • `notes/react-adapter/v4-nested-components.md`

Used `git checkout 819695a^` to restore each one's pre-rename text exactly.

Verification

`pnpm typecheck`, `pnpm test` (275 tests), `pnpm format:check` all pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants