feat(react): add useWrnStore bridge over useSyncExternalStore
Resolves WRNexus stores from inside islands, reading through the cached snapshot so React sees a stable reference. Unknown store names throw with the list of registered stores rather than failing opaquely. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import { getStoreForTest, setStoreResolver } from "../src/store-bridge.ts";
|
||||
|
||||
function fakeStore(initial: { count: number }) {
|
||||
let state = { ...initial };
|
||||
const listeners = new Set<() => void>();
|
||||
return {
|
||||
snapshot: () => Object.freeze({ ...state }),
|
||||
subscribe(listener: () => void) {
|
||||
listeners.add(listener);
|
||||
return () => listeners.delete(listener);
|
||||
},
|
||||
actions: {
|
||||
increment: () => {
|
||||
state = { count: state.count + 1 };
|
||||
for (const listener of [...listeners]) listener();
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
test("resolves a registered store and caches its snapshot", () => {
|
||||
const store = fakeStore({ count: 0 });
|
||||
setStoreResolver((name) => (name === "counter" ? store : undefined), ["counter"]);
|
||||
|
||||
const bound = getStoreForTest<{ count: number }>("counter");
|
||||
expect(bound.getSnapshot()).toBe(bound.getSnapshot());
|
||||
|
||||
bound.store.actions.increment!();
|
||||
expect(bound.getSnapshot().count).toBe(1);
|
||||
|
||||
setStoreResolver(null);
|
||||
});
|
||||
|
||||
test("throws a helpful error for an unknown store name", () => {
|
||||
setStoreResolver(
|
||||
(name) => (name === "counter" ? fakeStore({ count: 0 }) : undefined),
|
||||
["counter"],
|
||||
);
|
||||
|
||||
expect(() => getStoreForTest("typo")).toThrow(/Unknown WRNexus store "typo"/);
|
||||
expect(() => getStoreForTest("typo")).toThrow(/counter/);
|
||||
|
||||
setStoreResolver(null);
|
||||
});
|
||||
|
||||
test("throws when no resolver has been registered yet", () => {
|
||||
setStoreResolver(null);
|
||||
expect(() => getStoreForTest("counter")).toThrow(/before the island runtime registered/);
|
||||
});
|
||||
Reference in New Issue
Block a user