Skip to content

Commit

Permalink
Merge pull request #65 from jrTilak/feat/once
Browse files Browse the repository at this point in the history
feat: add once method
  • Loading branch information
Tilak Thapa authored Apr 28, 2024
2 parents 8deced9 + a3dffd8 commit 5d73937
Show file tree
Hide file tree
Showing 10 changed files with 190 additions and 64 deletions.
12 changes: 8 additions & 4 deletions src/www/src/configs/nav-links.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,6 @@
"label": "Functional",
"url": "/docs/functions/functional",
"methods": [
{
"label": "retry",
"url": "/docs/functions/functional/retry"
},
{
"label": "callAfter",
"url": "/docs/functions/functional/callAfter"
Expand All @@ -97,6 +93,14 @@
"label": "nTimes",
"url": "/docs/functions/functional/nTimes"
},
{
"label": "once",
"url": "/docs/functions/functional/once"
},
{
"label": "retry",
"url": "/docs/functions/functional/retry"
},
{
"label": "sleep",
"url": "/docs/functions/functional/sleep"
Expand Down
12 changes: 8 additions & 4 deletions src/www/src/configs/prev-next-button-links.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,6 @@
"label": "zip",
"url": "/docs/functions/arrays/zip"
},
{
"label": "retry",
"url": "/docs/functions/functional/retry"
},
{
"label": "callAfter",
"url": "/docs/functions/functional/callAfter"
Expand All @@ -83,6 +79,14 @@
"label": "nTimes",
"url": "/docs/functions/functional/nTimes"
},
{
"label": "once",
"url": "/docs/functions/functional/once"
},
{
"label": "retry",
"url": "/docs/functions/functional/retry"
},
{
"label": "sleep",
"url": "/docs/functions/functional/sleep"
Expand Down
144 changes: 89 additions & 55 deletions src/www/src/configs/registry.json

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions src/www/src/registry/functions/functional/callAfter/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
/**
* Creates a function that delays the execution of the provided function until it has been called a specified number of times.
*
* @param fn - The function to be called after a certain number of invocations.
* @param count - The number of times the function needs to be called before it is executed.
* @returns A new function that delays the execution of the provided function until it has been called a specified number of times.
*/
const callAfter = <T, S extends any[]>(
fn: (...args: S) => T,
count: number
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const Props: IRegistryFunctionPropTable[] = [
title: "count",
required: true,
defaultValue: undefined,
propDesc: "The number of times the function can be called.",
propDesc: "The number of times the function needs to be called before it is executed",
type: "number",
},
];
Expand Down
7 changes: 7 additions & 0 deletions src/www/src/registry/functions/functional/once/docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
desc: Returns a new function that can be called only once.
---

The `once` function is used to create a new function that can be called only once. After the first call, the function will always return undefined without executing the original function.

This is useful when you want to ensure that a function is called only once, regardless of how many times it is called. For example, a subscribe button on a website should only be clicked once, and the function should not be executed again if the button is clicked multiple times.
26 changes: 26 additions & 0 deletions src/www/src/registry/functions/functional/once/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { describe, expect, it, vi } from "vitest";
import once from ".";

describe("once", () => {
it("calls the provided function only once", () => {
const fn = vi.fn((x: number) => x + 1);
const onceFn = once(() => fn(1));
const result1 = onceFn();
const result2 = onceFn();
const result3 = onceFn();
expect(result1).toBe(2);
expect(result2).toBe(undefined);
expect(result3).toBe(undefined);
});

it("should also accept functions with arguments", () => {
const fn = vi.fn((x: number) => x + 1);
const onceFn = once(fn);
const result1 = onceFn(1);
const result2 = onceFn(2);
const result3 = onceFn(3);
expect(result1).toBe(2);
expect(result2).toBe(undefined);
expect(result3).toBe(undefined);
});
});
20 changes: 20 additions & 0 deletions src/www/src/registry/functions/functional/once/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* Creates a function that can only be called once. Subsequent calls to the function will return undefined.
*
* @param fn - The function to be called once.
* @returns A new function that can only be called once.
*/
const once = <T, S extends any[]>(
fn: (...args: S) => T
): ((...args: S) => T | undefined) => {
let isCalled = false;
return (...args: S): T | undefined => {
if (!isCalled) {
isCalled = true;
return fn(...args);
}
return undefined;
};
};

export default once;
11 changes: 11 additions & 0 deletions src/www/src/registry/functions/functional/once/once.example.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import once from ".";

const subscribe = once(() => {
console.log("Subscribed");
});

const result = subscribe();
// Expected Output: Subscribed

const result2 = subscribe();
// Expected Output: undefined : as the function has been called once already.
13 changes: 13 additions & 0 deletions src/www/src/registry/functions/functional/once/props.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { IRegistryFunctionPropTable } from "@/types/registry.types";

const Props: IRegistryFunctionPropTable[] = [
{
title: "function",
required: true,
defaultValue: undefined,
propDesc: "The function to be called",
type: "Function",
},
];

export default Props;

0 comments on commit 5d73937

Please sign in to comment.