@conorroberts/utils 0.0.44 → 0.0.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/env.mjs CHANGED
@@ -13,7 +13,7 @@ const createEnv = (args) => {
13
13
  const serverEnv = /* @__PURE__ */ new Map();
14
14
  const invalidKeys = [];
15
15
  for (const [key, value] of pairs) {
16
- const result = v.safeParse(value, args.env[key] ?? null);
16
+ const result = v.safeParse(value, args.env[key]);
17
17
  if (!result.success) invalidKeys.push(key);
18
18
  serverEnv.set(key, result.output);
19
19
  }
package/dist/env.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"env.mjs","names":["invalidKeys: string[]","pairs"],"sources":["../src/env.ts"],"sourcesContent":["import { pipe } from \"remeda\";\nimport * as v from \"valibot\";\n\nconst PUBLIC_ENV_PREFIX = \"PUBLIC_\" as const;\n\n/**\n * Validates your environment variables against the given Valibot schema;\n * @param args\n * @returns An object containing client environment variables and another containing server environment variables\n */\nexport const createEnv = <\n Schema extends Record<string, v.GenericSchema>,\n Env = {\n [K in keyof Schema]: v.InferOutput<Schema[K]>;\n },\n>(args: {\n schema: Schema;\n // oxlint-disable-next-line no-explicit-any\n env: any;\n}) => {\n const pairs = Object.entries(args.schema);\n const serverEnv = new Map();\n const invalidKeys: string[] = [];\n\n for (const [key, value] of pairs) {\n const result = v.safeParse(value, args.env[key] ?? null);\n\n if (!result.success) {\n invalidKeys.push(key);\n }\n\n serverEnv.set(key, result.output);\n }\n\n if (invalidKeys.length > 0) {\n console.error(`Invalid environment variable(s): ${invalidKeys.map((e) => `\"${e}\"`).join(\", \")}`);\n process.exit(1);\n }\n\n type ClientEnvKeys = Exclude<\n {\n [K in keyof Env]: K extends `${typeof PUBLIC_ENV_PREFIX}${string}` ? K : never;\n }[keyof Env],\n undefined\n >;\n\n type ClientEnv = {\n [B in ClientEnvKeys]: Env[B];\n };\n\n const clientEnv = pipe(\n serverEnv,\n (obj) => Array.from(obj.entries()),\n (pairs) => pairs.filter(([k]) => k.startsWith(PUBLIC_ENV_PREFIX)),\n (pairs) => Object.fromEntries(pairs),\n ) as ClientEnv;\n\n return {\n client: clientEnv,\n server: Object.fromEntries(serverEnv.entries()) as Env,\n };\n};\n"],"mappings":";;;;AAGA,MAAM,oBAAoB;;;;;;AAO1B,MAAa,aAKX,SAII;CACJ,MAAM,QAAQ,OAAO,QAAQ,KAAK,OAAO;CACzC,MAAM,4BAAY,IAAI,KAAK;CAC3B,MAAMA,cAAwB,EAAE;AAEhC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO;EAChC,MAAM,SAAS,EAAE,UAAU,OAAO,KAAK,IAAI,QAAQ,KAAK;AAExD,MAAI,CAAC,OAAO,QACV,aAAY,KAAK,IAAI;AAGvB,YAAU,IAAI,KAAK,OAAO,OAAO;;AAGnC,KAAI,YAAY,SAAS,GAAG;AAC1B,UAAQ,MAAM,oCAAoC,YAAY,KAAK,MAAM,IAAI,EAAE,GAAG,CAAC,KAAK,KAAK,GAAG;AAChG,UAAQ,KAAK,EAAE;;AAqBjB,QAAO;EACL,QARgB,KAChB,YACC,QAAQ,MAAM,KAAK,IAAI,SAAS,CAAC,GACjC,YAAUC,QAAM,QAAQ,CAAC,OAAO,EAAE,WAAW,kBAAkB,CAAC,GAChE,YAAU,OAAO,YAAYA,QAAM,CACrC;EAIC,QAAQ,OAAO,YAAY,UAAU,SAAS,CAAC;EAChD"}
1
+ {"version":3,"file":"env.mjs","names":["invalidKeys: string[]","pairs"],"sources":["../src/env.ts"],"sourcesContent":["import { pipe } from \"remeda\";\nimport * as v from \"valibot\";\n\nconst PUBLIC_ENV_PREFIX = \"PUBLIC_\" as const;\n\n/**\n * Validates your environment variables against the given Valibot schema;\n * @param args\n * @returns An object containing client environment variables and another containing server environment variables\n */\nexport const createEnv = <\n Schema extends Record<string, v.GenericSchema>,\n Env = {\n [K in keyof Schema]: v.InferOutput<Schema[K]>;\n },\n>(args: {\n schema: Schema;\n // oxlint-disable-next-line no-explicit-any\n env: any;\n}) => {\n const pairs = Object.entries(args.schema);\n const serverEnv = new Map();\n const invalidKeys: string[] = [];\n\n for (const [key, value] of pairs) {\n const result = v.safeParse(value, args.env[key]);\n\n if (!result.success) {\n invalidKeys.push(key);\n }\n\n serverEnv.set(key, result.output);\n }\n\n if (invalidKeys.length > 0) {\n console.error(`Invalid environment variable(s): ${invalidKeys.map((e) => `\"${e}\"`).join(\", \")}`);\n process.exit(1);\n }\n\n type ClientEnvKeys = Exclude<\n {\n [K in keyof Env]: K extends `${typeof PUBLIC_ENV_PREFIX}${string}` ? K : never;\n }[keyof Env],\n undefined\n >;\n\n type ClientEnv = {\n [B in ClientEnvKeys]: Env[B];\n };\n\n const clientEnv = pipe(\n serverEnv,\n (obj) => Array.from(obj.entries()),\n (pairs) => pairs.filter(([k]) => k.startsWith(PUBLIC_ENV_PREFIX)),\n (pairs) => Object.fromEntries(pairs),\n ) as ClientEnv;\n\n return {\n client: clientEnv,\n server: Object.fromEntries(serverEnv.entries()) as Env,\n };\n};\n"],"mappings":";;;;AAGA,MAAM,oBAAoB;;;;;;AAO1B,MAAa,aAKX,SAII;CACJ,MAAM,QAAQ,OAAO,QAAQ,KAAK,OAAO;CACzC,MAAM,4BAAY,IAAI,KAAK;CAC3B,MAAMA,cAAwB,EAAE;AAEhC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO;EAChC,MAAM,SAAS,EAAE,UAAU,OAAO,KAAK,IAAI,KAAK;AAEhD,MAAI,CAAC,OAAO,QACV,aAAY,KAAK,IAAI;AAGvB,YAAU,IAAI,KAAK,OAAO,OAAO;;AAGnC,KAAI,YAAY,SAAS,GAAG;AAC1B,UAAQ,MAAM,oCAAoC,YAAY,KAAK,MAAM,IAAI,EAAE,GAAG,CAAC,KAAK,KAAK,GAAG;AAChG,UAAQ,KAAK,EAAE;;AAqBjB,QAAO;EACL,QARgB,KAChB,YACC,QAAQ,MAAM,KAAK,IAAI,SAAS,CAAC,GACjC,YAAUC,QAAM,QAAQ,CAAC,OAAO,EAAE,WAAW,kBAAkB,CAAC,GAChE,YAAU,OAAO,YAAYA,QAAM,CACrC;EAIC,QAAQ,OAAO,YAAY,UAAU,SAAS,CAAC;EAChD"}
@@ -1,20 +1,20 @@
1
- import * as oxlint24 from "oxlint";
1
+ import * as oxlint4 from "oxlint";
2
2
 
3
3
  //#region src/oxlint-plugins/jsx-component-pascal-case.d.ts
4
- declare const jsxComponentPascalCaseRule: oxlint24.Rule;
4
+ declare const jsxComponentPascalCaseRule: oxlint4.Rule;
5
5
  declare namespace _default {
6
6
  namespace meta {
7
7
  let name: string;
8
8
  }
9
9
  let rules: {
10
- "jsx-component-pascal-case": oxlint24.Rule;
10
+ "jsx-component-pascal-case": oxlint4.Rule;
11
11
  };
12
12
  }
13
- type RuleContext = oxlint24.Context;
14
- type ESTNode = oxlint24.ESTree.Node;
15
- type ESTExpression = oxlint24.ESTree.Expression;
16
- type ReturnStatementNode = oxlint24.ESTree.ReturnStatement;
17
- type FunctionLikeNode = oxlint24.ESTree.Function | oxlint24.ESTree.ArrowFunctionExpression;
13
+ type RuleContext = oxlint4.Context;
14
+ type ESTNode = oxlint4.ESTree.Node;
15
+ type ESTExpression = oxlint4.ESTree.Expression;
16
+ type ReturnStatementNode = oxlint4.ESTree.ReturnStatement;
17
+ type FunctionLikeNode = oxlint4.ESTree.Function | oxlint4.ESTree.ArrowFunctionExpression;
18
18
  type FunctionContext = {
19
19
  node: FunctionLikeNode;
20
20
  name: string;
@@ -1,20 +1,20 @@
1
- import * as oxlint32 from "oxlint";
1
+ import * as oxlint12 from "oxlint";
2
2
 
3
3
  //#region src/oxlint-plugins/no-component-date-instantiation.d.ts
4
- declare const noComponentDateInstantiationRule: oxlint32.Rule;
4
+ declare const noComponentDateInstantiationRule: oxlint12.Rule;
5
5
  declare namespace _default {
6
6
  namespace meta {
7
7
  let name: string;
8
8
  }
9
9
  let rules: {
10
- "no-component-date-instantiation": oxlint32.Rule;
10
+ "no-component-date-instantiation": oxlint12.Rule;
11
11
  };
12
12
  }
13
- type RuleContext = oxlint32.Context;
14
- type ESTNode = oxlint32.ESTree.Node;
15
- type NewExpressionNode = oxlint32.ESTree.NewExpression;
16
- type ReturnStatementNode = oxlint32.ESTree.ReturnStatement;
17
- type FunctionLikeNode = oxlint32.ESTree.Function | oxlint32.ESTree.ArrowFunctionExpression;
13
+ type RuleContext = oxlint12.Context;
14
+ type ESTNode = oxlint12.ESTree.Node;
15
+ type NewExpressionNode = oxlint12.ESTree.NewExpression;
16
+ type ReturnStatementNode = oxlint12.ESTree.ReturnStatement;
17
+ type FunctionLikeNode = oxlint12.ESTree.Function | oxlint12.ESTree.ArrowFunctionExpression;
18
18
  type FunctionContext = {
19
19
  node: FunctionLikeNode;
20
20
  parent: FunctionContext | null;
@@ -1,16 +1,16 @@
1
- import * as oxlint10 from "oxlint";
1
+ import * as oxlint40 from "oxlint";
2
2
 
3
3
  //#region src/oxlint-plugins/no-emoji.d.ts
4
- declare const noEmojiRule: oxlint10.Rule;
4
+ declare const noEmojiRule: oxlint40.Rule;
5
5
  declare namespace _default {
6
6
  namespace meta {
7
7
  let name: string;
8
8
  }
9
9
  let rules: {
10
- "no-emoji": oxlint10.Rule;
10
+ "no-emoji": oxlint40.Rule;
11
11
  };
12
12
  }
13
- type ESTNode = oxlint10.ESTree.Node;
13
+ type ESTNode = oxlint40.ESTree.Node;
14
14
  //#endregion
15
15
  export { ESTNode, _default as default, noEmojiRule };
16
16
  //# sourceMappingURL=no-emoji.d.mts.map
@@ -1,16 +1,16 @@
1
- import * as oxlint18 from "oxlint";
1
+ import * as oxlint34 from "oxlint";
2
2
 
3
3
  //#region src/oxlint-plugins/no-finally.d.ts
4
- declare const noFinallyRule: oxlint18.Rule;
4
+ declare const noFinallyRule: oxlint34.Rule;
5
5
  declare namespace _default {
6
6
  namespace meta {
7
7
  let name: string;
8
8
  }
9
9
  let rules: {
10
- "no-finally": oxlint18.Rule;
10
+ "no-finally": oxlint34.Rule;
11
11
  };
12
12
  }
13
- type ESTNode = oxlint18.ESTree.Node;
13
+ type ESTNode = oxlint34.ESTree.Node;
14
14
  //#endregion
15
15
  export { ESTNode, _default as default, noFinallyRule };
16
16
  //# sourceMappingURL=no-finally.d.mts.map
@@ -1,27 +1,27 @@
1
- import * as oxlint0 from "oxlint";
1
+ import * as oxlint23 from "oxlint";
2
2
 
3
3
  //#region src/oxlint-plugins/no-inline-components.d.ts
4
4
  declare function isComponentName(name: unknown): name is string;
5
5
  declare function isHookName(name: unknown): name is string;
6
6
  declare function getEnclosingFunction(node: ESTNode | null | undefined): FunctionLikeNode | null;
7
7
  declare function getFunctionName(node: FunctionLikeNode): string;
8
- declare const noInlineComponentsRule: oxlint0.Rule;
8
+ declare const noInlineComponentsRule: oxlint23.Rule;
9
9
  declare namespace _default {
10
10
  namespace meta {
11
11
  let name: string;
12
12
  }
13
13
  let rules: {
14
- "no-inline-components": oxlint0.Rule;
14
+ "no-inline-components": oxlint23.Rule;
15
15
  };
16
16
  }
17
- type RuleContext = oxlint0.Context;
18
- type ESTNode = oxlint0.ESTree.Node;
19
- type ESTExpression = oxlint0.ESTree.Expression;
20
- type ESTPattern = oxlint0.ESTree.Pattern;
21
- type ReturnStatementNode = oxlint0.ESTree.ReturnStatement;
22
- type VariableDeclaratorNode = oxlint0.ESTree.VariableDeclarator;
23
- type AssignmentExpressionNode = oxlint0.ESTree.AssignmentExpression;
24
- type FunctionLikeNode = oxlint0.ESTree.Function | oxlint0.ESTree.ArrowFunctionExpression;
17
+ type RuleContext = oxlint23.Context;
18
+ type ESTNode = oxlint23.ESTree.Node;
19
+ type ESTExpression = oxlint23.ESTree.Expression;
20
+ type ESTPattern = oxlint23.ESTree.Pattern;
21
+ type ReturnStatementNode = oxlint23.ESTree.ReturnStatement;
22
+ type VariableDeclaratorNode = oxlint23.ESTree.VariableDeclarator;
23
+ type AssignmentExpressionNode = oxlint23.ESTree.AssignmentExpression;
24
+ type FunctionLikeNode = oxlint23.ESTree.Function | oxlint23.ESTree.ArrowFunctionExpression;
25
25
  type RecordedAssignment = {
26
26
  node: ESTExpression;
27
27
  names: string[];
@@ -1,16 +1,16 @@
1
- import * as oxlint21 from "oxlint";
1
+ import * as oxlint0 from "oxlint";
2
2
 
3
3
  //#region src/oxlint-plugins/no-react-namespace.d.ts
4
- declare const noReactNamespaceRule: oxlint21.Rule;
4
+ declare const noReactNamespaceRule: oxlint0.Rule;
5
5
  declare namespace _default {
6
6
  namespace meta {
7
7
  let name: string;
8
8
  }
9
9
  let rules: {
10
- "no-react-namespace": oxlint21.Rule;
10
+ "no-react-namespace": oxlint0.Rule;
11
11
  };
12
12
  }
13
- type ESTNode = oxlint21.ESTree.Node;
13
+ type ESTNode = oxlint0.ESTree.Node;
14
14
  //#endregion
15
15
  export { ESTNode, _default as default, noReactNamespaceRule };
16
16
  //# sourceMappingURL=no-react-namespace.d.mts.map
@@ -1,4 +1,4 @@
1
- import * as oxlint16 from "oxlint";
1
+ import * as oxlint2 from "oxlint";
2
2
 
3
3
  //#region src/oxlint-plugins/no-switch-plugin.d.ts
4
4
  declare namespace _default {
@@ -6,10 +6,10 @@ declare namespace _default {
6
6
  let name: string;
7
7
  }
8
8
  let rules: {
9
- "no-switch": oxlint16.Rule;
9
+ "no-switch": oxlint2.Rule;
10
10
  };
11
11
  }
12
- type ESTNode = oxlint16.ESTree.Node;
12
+ type ESTNode = oxlint2.ESTree.Node;
13
13
  //#endregion
14
14
  export { ESTNode, _default as default };
15
15
  //# sourceMappingURL=no-switch-plugin.d.mts.map
@@ -1,16 +1,16 @@
1
- import * as oxlint13 from "oxlint";
1
+ import * as oxlint20 from "oxlint";
2
2
 
3
3
  //#region src/oxlint-plugins/no-top-level-let.d.ts
4
- declare const noTopLevelLetRule: oxlint13.Rule;
4
+ declare const noTopLevelLetRule: oxlint20.Rule;
5
5
  declare namespace _default {
6
6
  namespace meta {
7
7
  let name: string;
8
8
  }
9
9
  let rules: {
10
- "no-top-level-let": oxlint13.Rule;
10
+ "no-top-level-let": oxlint20.Rule;
11
11
  };
12
12
  }
13
- type ESTNode = oxlint13.ESTree.Node;
13
+ type ESTNode = oxlint20.ESTree.Node;
14
14
  //#endregion
15
15
  export { ESTNode, _default as default, noTopLevelLetRule };
16
16
  //# sourceMappingURL=no-top-level-let.d.mts.map
@@ -1,16 +1,16 @@
1
- import * as oxlint40 from "oxlint";
1
+ import * as oxlint37 from "oxlint";
2
2
 
3
3
  //#region src/oxlint-plugins/no-type-cast.d.ts
4
- declare const noTypeCastRule: oxlint40.Rule;
4
+ declare const noTypeCastRule: oxlint37.Rule;
5
5
  declare namespace _default {
6
6
  namespace meta {
7
7
  let name: string;
8
8
  }
9
9
  let rules: {
10
- "no-type-cast": oxlint40.Rule;
10
+ "no-type-cast": oxlint37.Rule;
11
11
  };
12
12
  }
13
- type ESTNode = oxlint40.ESTree.Node;
13
+ type ESTNode = oxlint37.ESTree.Node;
14
14
  //#endregion
15
15
  export { ESTNode, _default as default, noTypeCastRule };
16
16
  //# sourceMappingURL=no-type-cast.d.mts.map
package/dist/react.d.mts CHANGED
@@ -46,6 +46,22 @@ declare const useOnce: (condition: unknown, callback: () => void) => void;
46
46
  */
47
47
  declare const useLocalOnce: (condition: unknown, callback: () => void) => void;
48
48
  //#endregion
49
+ //#region src/react/useOnMount.d.ts
50
+ /**
51
+ * Calls the given callback when the component mounts.
52
+ * Uses useStableCallback internally to ensure the latest version is called.
53
+ *
54
+ * @param callback - The function to run when the component mounts.
55
+ *
56
+ * @example
57
+ * ```tsx
58
+ * useOnMount(() => {
59
+ * console.log("Component mounted!");
60
+ * });
61
+ * ```
62
+ */
63
+ declare const useOnMount: (callback: () => void) => void;
64
+ //#endregion
49
65
  //#region src/react/useOnUnmount.d.ts
50
66
  /**
51
67
  * Calls the given callback when the component unmounts.
@@ -53,5 +69,5 @@ declare const useLocalOnce: (condition: unknown, callback: () => void) => void;
53
69
  */
54
70
  declare const useOnUnmount: (callback: () => void) => void;
55
71
  //#endregion
56
- export { useLocalOnce, useOnUnmount, useOnce, useStableCallback };
72
+ export { useLocalOnce, useOnMount, useOnUnmount, useOnce, useStableCallback };
57
73
  //# sourceMappingURL=react.d.mts.map
package/dist/react.mjs CHANGED
@@ -71,6 +71,28 @@ const useLocalOnce = (condition, callback) => {
71
71
  }
72
72
  };
73
73
 
74
+ //#endregion
75
+ //#region src/react/useOnMount.ts
76
+ /**
77
+ * Calls the given callback when the component mounts.
78
+ * Uses useStableCallback internally to ensure the latest version is called.
79
+ *
80
+ * @param callback - The function to run when the component mounts.
81
+ *
82
+ * @example
83
+ * ```tsx
84
+ * useOnMount(() => {
85
+ * console.log("Component mounted!");
86
+ * });
87
+ * ```
88
+ */
89
+ const useOnMount = (callback) => {
90
+ const stableCallback = useStableCallback(callback);
91
+ useEffect(() => {
92
+ stableCallback();
93
+ }, [stableCallback]);
94
+ };
95
+
74
96
  //#endregion
75
97
  //#region src/react/useOnUnmount.ts
76
98
  /**
@@ -87,5 +109,5 @@ const useOnUnmount = (callback) => {
87
109
  };
88
110
 
89
111
  //#endregion
90
- export { useLocalOnce, useOnUnmount, useOnce, useStableCallback };
112
+ export { useLocalOnce, useOnMount, useOnUnmount, useOnce, useStableCallback };
91
113
  //# sourceMappingURL=react.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"react.mjs","names":[],"sources":["../src/react/useStableCallback.ts","../src/react/useOnce.ts","../src/react/useLocalOnce.ts","../src/react/useOnUnmount.ts"],"sourcesContent":["// oxlint-disable no-explicit-any\r\n\r\nimport { useCallback, useRef } from \"react\";\r\n\r\ntype AnyFunction = (...args: any[]) => any;\r\ntype AnyArgs = any[];\r\n\r\n/**\r\n * Creates a stable callback that always calls the latest version of the function.\r\n * Useful for callbacks that need to be used in dependency arrays but should always\r\n * execute the most recent version of the callback.\r\n */\r\nexport const useStableCallback = <T extends AnyFunction>(callback: T): T => {\r\n const callbackRef = useRef(callback);\r\n\r\n // Update the ref on every render\r\n callbackRef.current = callback;\r\n\r\n return useCallback((...args: AnyArgs) => {\r\n return callbackRef.current(...args);\r\n }, []) as T;\r\n};\r\n","import { useEffect, useRef } from \"react\";\r\nimport { useStableCallback } from \"./useStableCallback\";\r\n\r\n/**\r\n * Runs a callback only once when a condition becomes truthy.\r\n * The callback is stabilized internally to always reference the latest version.\r\n *\r\n * @param condition - When truthy (evaluated via Boolean()), the callback will be executed (only once).\r\n * @param callback - The function to run once when the condition is met.\r\n *\r\n * @example\r\n * ```tsx\r\n * const isReady = true;\r\n * useOnce(isReady, () => {\r\n * console.log(\"Ready!\");\r\n * });\r\n * ```\r\n */\r\nexport const useOnce = (condition: unknown, callback: () => void): void => {\r\n const hasRunRef = useRef(false);\r\n const stableCallback = useStableCallback(callback);\r\n\r\n useEffect(() => {\r\n if (Boolean(condition) && !hasRunRef.current) {\r\n hasRunRef.current = true;\r\n stableCallback();\r\n }\r\n }, [condition, stableCallback]);\r\n};\r\n","import { useRef } from \"react\";\r\nimport { useStableCallback } from \"./useStableCallback\";\r\n\r\n/**\r\n * Runs a callback only once when a condition becomes truthy, executing synchronously\r\n * during render. The callback is stabilized internally to always reference the latest version.\r\n *\r\n * Unlike `useOnce`, this runs at the top level of the hook (not in useEffect),\r\n * making it suitable for state updates that need to happen synchronously during render.\r\n *\r\n * @param condition - When truthy (evaluated via Boolean()), the callback will be executed (only once).\r\n * @param callback - The function to run once when the condition is met.\r\n *\r\n * @example\r\n * ```tsx\r\n * const user: User | null = getUser();\r\n * useLocalOnce(user, () => {\r\n * setState(user.name);\r\n * });\r\n * ```\r\n */\r\nexport const useLocalOnce = (condition: unknown, callback: () => void): void => {\r\n const hasRunRef = useRef(false);\r\n const stableCallback = useStableCallback(callback);\r\n\r\n if (Boolean(condition) && !hasRunRef.current) {\r\n hasRunRef.current = true;\r\n stableCallback();\r\n }\r\n};\r\n","import { useEffect } from \"react\";\r\nimport { useStableCallback } from \"./useStableCallback\";\r\n\r\n/**\r\n * Calls the given callback when the component unmounts.\r\n * Uses useStableCallback internally to ensure the latest version is called.\r\n */\r\nexport const useOnUnmount = (callback: () => void): void => {\r\n const stableCallback = useStableCallback(callback);\r\n\r\n useEffect(() => {\r\n return () => {\r\n stableCallback();\r\n };\r\n }, [stableCallback]);\r\n};\r\n"],"mappings":";;;;;;;;AAYA,MAAa,qBAA4C,aAAmB;CAC1E,MAAM,cAAc,OAAO,SAAS;AAGpC,aAAY,UAAU;AAEtB,QAAO,aAAa,GAAG,SAAkB;AACvC,SAAO,YAAY,QAAQ,GAAG,KAAK;IAClC,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;ACFR,MAAa,WAAW,WAAoB,aAA+B;CACzE,MAAM,YAAY,OAAO,MAAM;CAC/B,MAAM,iBAAiB,kBAAkB,SAAS;AAElD,iBAAgB;AACd,MAAI,QAAQ,UAAU,IAAI,CAAC,UAAU,SAAS;AAC5C,aAAU,UAAU;AACpB,mBAAgB;;IAEjB,CAAC,WAAW,eAAe,CAAC;;;;;;;;;;;;;;;;;;;;;;;ACNjC,MAAa,gBAAgB,WAAoB,aAA+B;CAC9E,MAAM,YAAY,OAAO,MAAM;CAC/B,MAAM,iBAAiB,kBAAkB,SAAS;AAElD,KAAI,QAAQ,UAAU,IAAI,CAAC,UAAU,SAAS;AAC5C,YAAU,UAAU;AACpB,kBAAgB;;;;;;;;;;ACpBpB,MAAa,gBAAgB,aAA+B;CAC1D,MAAM,iBAAiB,kBAAkB,SAAS;AAElD,iBAAgB;AACd,eAAa;AACX,mBAAgB;;IAEjB,CAAC,eAAe,CAAC"}
1
+ {"version":3,"file":"react.mjs","names":[],"sources":["../src/react/useStableCallback.ts","../src/react/useOnce.ts","../src/react/useLocalOnce.ts","../src/react/useOnMount.ts","../src/react/useOnUnmount.ts"],"sourcesContent":["// oxlint-disable no-explicit-any\r\n\r\nimport { useCallback, useRef } from \"react\";\r\n\r\ntype AnyFunction = (...args: any[]) => any;\r\ntype AnyArgs = any[];\r\n\r\n/**\r\n * Creates a stable callback that always calls the latest version of the function.\r\n * Useful for callbacks that need to be used in dependency arrays but should always\r\n * execute the most recent version of the callback.\r\n */\r\nexport const useStableCallback = <T extends AnyFunction>(callback: T): T => {\r\n const callbackRef = useRef(callback);\r\n\r\n // Update the ref on every render\r\n callbackRef.current = callback;\r\n\r\n return useCallback((...args: AnyArgs) => {\r\n return callbackRef.current(...args);\r\n }, []) as T;\r\n};\r\n","import { useEffect, useRef } from \"react\";\r\nimport { useStableCallback } from \"./useStableCallback\";\r\n\r\n/**\r\n * Runs a callback only once when a condition becomes truthy.\r\n * The callback is stabilized internally to always reference the latest version.\r\n *\r\n * @param condition - When truthy (evaluated via Boolean()), the callback will be executed (only once).\r\n * @param callback - The function to run once when the condition is met.\r\n *\r\n * @example\r\n * ```tsx\r\n * const isReady = true;\r\n * useOnce(isReady, () => {\r\n * console.log(\"Ready!\");\r\n * });\r\n * ```\r\n */\r\nexport const useOnce = (condition: unknown, callback: () => void): void => {\r\n const hasRunRef = useRef(false);\r\n const stableCallback = useStableCallback(callback);\r\n\r\n useEffect(() => {\r\n if (Boolean(condition) && !hasRunRef.current) {\r\n hasRunRef.current = true;\r\n stableCallback();\r\n }\r\n }, [condition, stableCallback]);\r\n};\r\n","import { useRef } from \"react\";\r\nimport { useStableCallback } from \"./useStableCallback\";\r\n\r\n/**\r\n * Runs a callback only once when a condition becomes truthy, executing synchronously\r\n * during render. The callback is stabilized internally to always reference the latest version.\r\n *\r\n * Unlike `useOnce`, this runs at the top level of the hook (not in useEffect),\r\n * making it suitable for state updates that need to happen synchronously during render.\r\n *\r\n * @param condition - When truthy (evaluated via Boolean()), the callback will be executed (only once).\r\n * @param callback - The function to run once when the condition is met.\r\n *\r\n * @example\r\n * ```tsx\r\n * const user: User | null = getUser();\r\n * useLocalOnce(user, () => {\r\n * setState(user.name);\r\n * });\r\n * ```\r\n */\r\nexport const useLocalOnce = (condition: unknown, callback: () => void): void => {\r\n const hasRunRef = useRef(false);\r\n const stableCallback = useStableCallback(callback);\r\n\r\n if (Boolean(condition) && !hasRunRef.current) {\r\n hasRunRef.current = true;\r\n stableCallback();\r\n }\r\n};\r\n","import { useEffect } from \"react\";\nimport { useStableCallback } from \"./useStableCallback\";\n\n/**\n * Calls the given callback when the component mounts.\n * Uses useStableCallback internally to ensure the latest version is called.\n *\n * @param callback - The function to run when the component mounts.\n *\n * @example\n * ```tsx\n * useOnMount(() => {\n * console.log(\"Component mounted!\");\n * });\n * ```\n */\nexport const useOnMount = (callback: () => void): void => {\n const stableCallback = useStableCallback(callback);\n\n useEffect(() => {\n stableCallback();\n }, [stableCallback]);\n};\n","import { useEffect } from \"react\";\r\nimport { useStableCallback } from \"./useStableCallback\";\r\n\r\n/**\r\n * Calls the given callback when the component unmounts.\r\n * Uses useStableCallback internally to ensure the latest version is called.\r\n */\r\nexport const useOnUnmount = (callback: () => void): void => {\r\n const stableCallback = useStableCallback(callback);\r\n\r\n useEffect(() => {\r\n return () => {\r\n stableCallback();\r\n };\r\n }, [stableCallback]);\r\n};\r\n"],"mappings":";;;;;;;;AAYA,MAAa,qBAA4C,aAAmB;CAC1E,MAAM,cAAc,OAAO,SAAS;AAGpC,aAAY,UAAU;AAEtB,QAAO,aAAa,GAAG,SAAkB;AACvC,SAAO,YAAY,QAAQ,GAAG,KAAK;IAClC,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;ACFR,MAAa,WAAW,WAAoB,aAA+B;CACzE,MAAM,YAAY,OAAO,MAAM;CAC/B,MAAM,iBAAiB,kBAAkB,SAAS;AAElD,iBAAgB;AACd,MAAI,QAAQ,UAAU,IAAI,CAAC,UAAU,SAAS;AAC5C,aAAU,UAAU;AACpB,mBAAgB;;IAEjB,CAAC,WAAW,eAAe,CAAC;;;;;;;;;;;;;;;;;;;;;;;ACNjC,MAAa,gBAAgB,WAAoB,aAA+B;CAC9E,MAAM,YAAY,OAAO,MAAM;CAC/B,MAAM,iBAAiB,kBAAkB,SAAS;AAElD,KAAI,QAAQ,UAAU,IAAI,CAAC,UAAU,SAAS;AAC5C,YAAU,UAAU;AACpB,kBAAgB;;;;;;;;;;;;;;;;;;;ACXpB,MAAa,cAAc,aAA+B;CACxD,MAAM,iBAAiB,kBAAkB,SAAS;AAElD,iBAAgB;AACd,kBAAgB;IACf,CAAC,eAAe,CAAC;;;;;;;;;ACdtB,MAAa,gBAAgB,aAA+B;CAC1D,MAAM,iBAAiB,kBAAkB,SAAS;AAElD,iBAAgB;AACd,eAAa;AACX,mBAAgB;;IAEjB,CAAC,eAAe,CAAC"}
package/package.json CHANGED
@@ -82,7 +82,7 @@
82
82
  "typescript": "5.9.3",
83
83
  "vitest": "4.0.15"
84
84
  },
85
- "version": "0.0.44",
85
+ "version": "0.0.46",
86
86
  "scripts": {
87
87
  "dev": "tsdown --watch",
88
88
  "build": "tsc --noEmit && tsdown",