From 3f64b50f9fee6c9661a7e845a49d0a16da489d4f Mon Sep 17 00:00:00 2001 From: Abdelrahman Bahaa Date: Tue, 19 Nov 2024 11:57:44 +0200 Subject: [PATCH 1/3] add Lazy utility --- .../runed/src/lib/utilities/Lazy/Lazy.spec.ts | 27 +++++++++++++++++++ .../src/lib/utilities/Lazy/Lazy.svelte.ts | 27 +++++++++++++++++++ .../runed/src/lib/utilities/Lazy/index.ts | 1 + packages/runed/src/lib/utilities/index.ts | 1 + 4 files changed, 56 insertions(+) create mode 100644 packages/runed/src/lib/utilities/Lazy/Lazy.spec.ts create mode 100644 packages/runed/src/lib/utilities/Lazy/Lazy.svelte.ts create mode 100644 packages/runed/src/lib/utilities/Lazy/index.ts diff --git a/packages/runed/src/lib/utilities/Lazy/Lazy.spec.ts b/packages/runed/src/lib/utilities/Lazy/Lazy.spec.ts new file mode 100644 index 00000000..8fa7f16b --- /dev/null +++ b/packages/runed/src/lib/utilities/Lazy/Lazy.spec.ts @@ -0,0 +1,27 @@ +import { describe, test, vi } from "vitest"; +import { Lazy } from "./Lazy.svelte.js"; + +describe("Lazy", () => { + test("Lazy calls the initialization function only when current is initially accessed", () => { + const init = vi.fn(() => 0); + const counter = new Lazy(init); + expect(init).toHaveBeenCalledTimes(0); + + counter.current; + expect(init).toHaveBeenCalledTimes(1); + expect(counter.current).toBe(0); + + counter.current; + expect(init).toHaveBeenCalledTimes(1); + expect(counter.current).toBe(0); + }); + + test("Lazy does not call the initialization function when current is set", () => { + const init = vi.fn(() => 0); + const counter = new Lazy(init); + + counter.current = 1; + expect(init).toHaveBeenCalledTimes(0); + expect(counter.current).toBe(1); + }); +}); diff --git a/packages/runed/src/lib/utilities/Lazy/Lazy.svelte.ts b/packages/runed/src/lib/utilities/Lazy/Lazy.svelte.ts new file mode 100644 index 00000000..496ac89b --- /dev/null +++ b/packages/runed/src/lib/utilities/Lazy/Lazy.svelte.ts @@ -0,0 +1,27 @@ +import { untrack } from "svelte"; + +export class Lazy { + #init: () => T; + + constructor(init: () => T) { + this.#init = init; + } + + #current: T | undefined = $state(); + #initialized = false; + + get current(): T { + if (!this.#initialized) { + untrack(() => { + this.#current = this.#init(); + this.#initialized = true; + }); + } + return this.#current as T; + } + + set current(value: T) { + this.#current = value; + this.#initialized = true; + } +} diff --git a/packages/runed/src/lib/utilities/Lazy/index.ts b/packages/runed/src/lib/utilities/Lazy/index.ts new file mode 100644 index 00000000..91a41913 --- /dev/null +++ b/packages/runed/src/lib/utilities/Lazy/index.ts @@ -0,0 +1 @@ +export { Lazy } from "./Lazy.svelte.js"; diff --git a/packages/runed/src/lib/utilities/index.ts b/packages/runed/src/lib/utilities/index.ts index e9614b7d..08a5da35 100644 --- a/packages/runed/src/lib/utilities/index.ts +++ b/packages/runed/src/lib/utilities/index.ts @@ -20,3 +20,4 @@ export * from "./AnimationFrames/index.js"; export * from "./useIntersectionObserver/index.js"; export * from "./IsFocusWithin/index.js"; export * from "./FiniteStateMachine/index.js"; +export * from "./Lazy/index.js"; From b30e69cb8f3f79d721092871e8bd580de4aae9cb Mon Sep 17 00:00:00 2001 From: Abdelrahman Bahaa Date: Tue, 19 Nov 2024 12:02:30 +0200 Subject: [PATCH 2/3] fix lint --- packages/runed/src/lib/utilities/Lazy/Lazy.spec.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/runed/src/lib/utilities/Lazy/Lazy.spec.ts b/packages/runed/src/lib/utilities/Lazy/Lazy.spec.ts index 8fa7f16b..bf9ebaaf 100644 --- a/packages/runed/src/lib/utilities/Lazy/Lazy.spec.ts +++ b/packages/runed/src/lib/utilities/Lazy/Lazy.spec.ts @@ -1,8 +1,8 @@ -import { describe, test, vi } from "vitest"; +import { describe, vi } from "vitest"; import { Lazy } from "./Lazy.svelte.js"; -describe("Lazy", () => { - test("Lazy calls the initialization function only when current is initially accessed", () => { +describe("lazy", () => { + it("calls the initialization function only when current is initially accessed", () => { const init = vi.fn(() => 0); const counter = new Lazy(init); expect(init).toHaveBeenCalledTimes(0); @@ -16,7 +16,7 @@ describe("Lazy", () => { expect(counter.current).toBe(0); }); - test("Lazy does not call the initialization function when current is set", () => { + it("does not call the initialization function when current is set", () => { const init = vi.fn(() => 0); const counter = new Lazy(init); From 880a2ac368f5fa48b63b3fb16fc914547d612416 Mon Sep 17 00:00:00 2001 From: Abdelrahman Bahaa Date: Sun, 1 Dec 2024 04:24:42 +0200 Subject: [PATCH 3/3] refactor --- packages/runed/src/lib/utilities/Lazy/Lazy.spec.ts | 12 +++++------- packages/runed/src/lib/utilities/Lazy/Lazy.svelte.ts | 8 ++++---- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/packages/runed/src/lib/utilities/Lazy/Lazy.spec.ts b/packages/runed/src/lib/utilities/Lazy/Lazy.spec.ts index bf9ebaaf..be4140cd 100644 --- a/packages/runed/src/lib/utilities/Lazy/Lazy.spec.ts +++ b/packages/runed/src/lib/utilities/Lazy/Lazy.spec.ts @@ -2,26 +2,24 @@ import { describe, vi } from "vitest"; import { Lazy } from "./Lazy.svelte.js"; describe("lazy", () => { - it("calls the initialization function only when current is initially accessed", () => { + it("calls the initialization function only when `current` is first accessed", () => { const init = vi.fn(() => 0); const counter = new Lazy(init); expect(init).toHaveBeenCalledTimes(0); - counter.current; - expect(init).toHaveBeenCalledTimes(1); expect(counter.current).toBe(0); - - counter.current; expect(init).toHaveBeenCalledTimes(1); + expect(counter.current).toBe(0); + expect(init).toHaveBeenCalledTimes(1); }); - it("does not call the initialization function when current is set", () => { + it("does not call the initialization function when `current` is set", () => { const init = vi.fn(() => 0); const counter = new Lazy(init); counter.current = 1; - expect(init).toHaveBeenCalledTimes(0); expect(counter.current).toBe(1); + expect(init).toHaveBeenCalledTimes(0); }); }); diff --git a/packages/runed/src/lib/utilities/Lazy/Lazy.svelte.ts b/packages/runed/src/lib/utilities/Lazy/Lazy.svelte.ts index 496ac89b..93b92fa8 100644 --- a/packages/runed/src/lib/utilities/Lazy/Lazy.svelte.ts +++ b/packages/runed/src/lib/utilities/Lazy/Lazy.svelte.ts @@ -7,20 +7,20 @@ export class Lazy { this.#init = init; } - #current: T | undefined = $state(); + #current: T = $state()!; #initialized = false; - get current(): T { + get current() { if (!this.#initialized) { untrack(() => { this.#current = this.#init(); this.#initialized = true; }); } - return this.#current as T; + return this.#current; } - set current(value: T) { + set current(value) { this.#current = value; this.#initialized = true; }