Skip to content

Commit

Permalink
Merge branch 'main' into static-store
Browse files Browse the repository at this point in the history
  • Loading branch information
thetarnav committed Mar 31, 2023
2 parents ab62e82 + a1b88c9 commit 19e77e1
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/light-seals-impress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@solid-primitives/memo": patch
---

Improve lazy memo reads in another memo.
20 changes: 15 additions & 5 deletions packages/memo/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
NoInfer,
Owner,
SignalOptions,
DEV,
} from "solid-js";
import { isServer } from "solid-js/web";
import { debounce, throttle } from "@solid-primitives/scheduled";
Expand Down Expand Up @@ -338,6 +339,8 @@ export function createAsyncMemo<T>(
return state;
}

const EQUALS_FALSE = { equals: false } as const;

/**
* Lazily evaluated `createMemo`. Will run the calculation only if is being listened to.
*
Expand Down Expand Up @@ -379,16 +382,23 @@ export function createLazyMemo<T>(
};
}

let isStale = true;
let isReading = false,
isStale: boolean | undefined = true;

const [isDirty, setDirty] = createSignal({ v: false }),
const [track, trigger] = createSignal(void 0, EQUALS_FALSE),
memo = createMemo<T>(
p => (isDirty().v ? ((isStale = isDirty().v = false), calc(p)) : ((isStale = true), p)),
p => (isReading ? calc(p) : ((isStale = !track()), p)),
value as T,
{ equals: false, name: options?.name },
DEV ? { name: options?.name, equals: false } : EQUALS_FALSE,
);

return (): T => (isStale && setDirty({ v: true }), memo());
return (): T => {
isReading = true;
if (isStale) isStale = trigger();
const v = memo();
isReading = false;
return v;
};
}

/*
Expand Down
21 changes: 20 additions & 1 deletion packages/memo/test/lazy.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, it, expect } from "vitest";
import { createLazyMemo } from "../src";
import { createComputed, createEffect, createRoot, createSignal } from "solid-js";
import { createComputed, createEffect, createMemo, createRoot, createSignal } from "solid-js";

describe("createLazyMemo", () => {
it("won't run if not accessed", () =>
Expand Down Expand Up @@ -256,4 +256,23 @@ describe("createLazyMemo", () => {

dispose();
}));

it("stays in sync when read in a memo", () => {
const { dispose, setA, memo } = createRoot(dispose => {
const [a, setA] = createSignal(1);
const b = createLazyMemo(() => a());

const memo = createMemo(() => {
expect(a()).toBe(b());
});

return { dispose, setA, memo };
});

memo();
setA(2);
memo();

dispose();
});
});

0 comments on commit 19e77e1

Please sign in to comment.