@conorroberts/utils 0.0.58 → 0.0.60

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.
Files changed (47) hide show
  1. package/package.json +1 -45
  2. package/dist/env.d.mts +0 -19
  3. package/dist/env.mjs +0 -32
  4. package/dist/env.mjs.map +0 -1
  5. package/dist/images.d.mts +0 -101
  6. package/dist/images.mjs +0 -130
  7. package/dist/images.mjs.map +0 -1
  8. package/dist/oxlint/config.json +0 -72
  9. package/dist/oxlint/index.d.mts +0 -7
  10. package/dist/oxlint/index.mjs +0 -35
  11. package/dist/oxlint/index.mjs.map +0 -1
  12. package/dist/oxlint/jsx-component-pascal-case.d.mts +0 -17
  13. package/dist/oxlint/jsx-component-pascal-case.mjs +0 -155
  14. package/dist/oxlint/jsx-component-pascal-case.mjs.map +0 -1
  15. package/dist/oxlint/no-component-date-instantiation.d.mts +0 -19
  16. package/dist/oxlint/no-component-date-instantiation.mjs +0 -156
  17. package/dist/oxlint/no-component-date-instantiation.mjs.map +0 -1
  18. package/dist/oxlint/no-emoji.d.mts +0 -8
  19. package/dist/oxlint/no-emoji.mjs +0 -85
  20. package/dist/oxlint/no-emoji.mjs.map +0 -1
  21. package/dist/oxlint/no-finally.d.mts +0 -8
  22. package/dist/oxlint/no-finally.mjs +0 -28
  23. package/dist/oxlint/no-finally.mjs.map +0 -1
  24. package/dist/oxlint/no-function-call-in-jsx.d.mts +0 -11
  25. package/dist/oxlint/no-function-call-in-jsx.mjs +0 -70
  26. package/dist/oxlint/no-function-call-in-jsx.mjs.map +0 -1
  27. package/dist/oxlint/no-inline-components.d.mts +0 -36
  28. package/dist/oxlint/no-inline-components.mjs +0 -374
  29. package/dist/oxlint/no-inline-components.mjs.map +0 -1
  30. package/dist/oxlint/no-react-namespace.d.mts +0 -8
  31. package/dist/oxlint/no-react-namespace.mjs +0 -71
  32. package/dist/oxlint/no-react-namespace.mjs.map +0 -1
  33. package/dist/oxlint/no-switch-plugin.d.mts +0 -9
  34. package/dist/oxlint/no-switch-plugin.mjs +0 -27
  35. package/dist/oxlint/no-switch-plugin.mjs.map +0 -1
  36. package/dist/oxlint/no-top-level-let.d.mts +0 -8
  37. package/dist/oxlint/no-top-level-let.mjs +0 -62
  38. package/dist/oxlint/no-top-level-let.mjs.map +0 -1
  39. package/dist/oxlint/no-type-cast.d.mts +0 -8
  40. package/dist/oxlint/no-type-cast.mjs +0 -45
  41. package/dist/oxlint/no-type-cast.mjs.map +0 -1
  42. package/dist/oxlint/pretty-props.d.mts +0 -11
  43. package/dist/oxlint/pretty-props.mjs +0 -127
  44. package/dist/oxlint/pretty-props.mjs.map +0 -1
  45. package/dist/react.d.mts +0 -73
  46. package/dist/react.mjs +0 -113
  47. package/dist/react.mjs.map +0 -1
@@ -1,45 +0,0 @@
1
- import { defineRule } from "oxlint";
2
-
3
- //#region src/oxlint-plugins/no-type-cast.js
4
- /** @typedef {import("oxlint").ESTree.Node} ESTNode */
5
- const rule = defineRule({
6
- meta: {
7
- type: "problem",
8
- docs: {
9
- description: "Disallow TypeScript type assertions (`as` and angle-bracket syntax) to prevent unsafe type casting.",
10
- recommended: false
11
- },
12
- schema: []
13
- },
14
- createOnce(context) {
15
- return {
16
- TSAsExpression(rawNode) {
17
- if (rawNode.type !== "TSAsExpression") return;
18
- if (rawNode.typeAnnotation.type === "TSTypeReference" && rawNode.typeAnnotation.typeName.type === "Identifier" && rawNode.typeAnnotation.typeName.name === "const") return;
19
- context.report({
20
- node: rawNode,
21
- message: "Type casting with `as` is not permitted. Use runtime validation with valibot or refactor to avoid type casting."
22
- });
23
- },
24
- TSTypeAssertion(rawNode) {
25
- if (rawNode.type !== "TSTypeAssertion") return;
26
- context.report({
27
- node: rawNode,
28
- message: "Type casting with angle brackets `<Type>` is not permitted. Use runtime validation with valibot or refactor to avoid type casting."
29
- });
30
- },
31
- TSNonNullExpression(rawNode) {
32
- if (rawNode.type !== "TSNonNullExpression") return;
33
- context.report({
34
- node: rawNode,
35
- message: "Non-null assertion operator `!` is not permitted. Handle null/undefined cases explicitly or use optional chaining."
36
- });
37
- }
38
- };
39
- }
40
- });
41
- const noTypeCastRule = rule;
42
-
43
- //#endregion
44
- export { noTypeCastRule };
45
- //# sourceMappingURL=no-type-cast.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"no-type-cast.mjs","names":[],"sources":["../../src/oxlint-plugins/no-type-cast.js"],"sourcesContent":["import { defineRule } from \"oxlint\";\n\n/** @typedef {import(\"oxlint\").ESTree.Node} ESTNode */\n\nconst rule = defineRule({\n meta: {\n type: \"problem\",\n docs: {\n description:\n \"Disallow TypeScript type assertions (`as` and angle-bracket syntax) to prevent unsafe type casting.\",\n recommended: false,\n },\n schema: [],\n },\n\n createOnce(context) {\n return /** @type {import(\"oxlint\").VisitorWithHooks} */ ({\n /**\n * @param {ESTNode} rawNode\n */\n TSAsExpression(rawNode) {\n if (rawNode.type !== \"TSAsExpression\") return;\n\n // Allow \"as const\" assertions\n if (\n rawNode.typeAnnotation.type === \"TSTypeReference\" &&\n rawNode.typeAnnotation.typeName.type === \"Identifier\" &&\n rawNode.typeAnnotation.typeName.name === \"const\"\n ) {\n return;\n }\n\n context.report({\n node: rawNode,\n message:\n \"Type casting with `as` is not permitted. Use runtime validation with valibot or refactor to avoid type casting.\",\n });\n },\n\n /**\n * @param {ESTNode} rawNode\n */\n TSTypeAssertion(rawNode) {\n if (rawNode.type !== \"TSTypeAssertion\") return;\n\n context.report({\n node: rawNode,\n message:\n \"Type casting with angle brackets `<Type>` is not permitted. Use runtime validation with valibot or refactor to avoid type casting.\",\n });\n },\n\n /**\n * @param {ESTNode} rawNode\n */\n TSNonNullExpression(rawNode) {\n if (rawNode.type !== \"TSNonNullExpression\") return;\n\n context.report({\n node: rawNode,\n message:\n \"Non-null assertion operator `!` is not permitted. Handle null/undefined cases explicitly or use optional chaining.\",\n });\n },\n });\n },\n});\n\nexport const noTypeCastRule = rule;\n\n"],"mappings":";;;;AAIA,MAAM,OAAO,WAAW;CACtB,MAAM;EACJ,MAAM;EACN,MAAM;GACJ,aACE;GACF,aAAa;GACd;EACD,QAAQ,EAAE;EACX;CAED,WAAW,SAAS;AAClB,SAAyD;GAIvD,eAAe,SAAS;AACtB,QAAI,QAAQ,SAAS,iBAAkB;AAGvC,QACE,QAAQ,eAAe,SAAS,qBAChC,QAAQ,eAAe,SAAS,SAAS,gBACzC,QAAQ,eAAe,SAAS,SAAS,QAEzC;AAGF,YAAQ,OAAO;KACb,MAAM;KACN,SACE;KACH,CAAC;;GAMJ,gBAAgB,SAAS;AACvB,QAAI,QAAQ,SAAS,kBAAmB;AAExC,YAAQ,OAAO;KACb,MAAM;KACN,SACE;KACH,CAAC;;GAMJ,oBAAoB,SAAS;AAC3B,QAAI,QAAQ,SAAS,sBAAuB;AAE5C,YAAQ,OAAO;KACb,MAAM;KACN,SACE;KACH,CAAC;;GAEL;;CAEJ,CAAC;AAEF,MAAa,iBAAiB"}
@@ -1,11 +0,0 @@
1
- import * as oxlint6 from "oxlint";
2
-
3
- //#region src/oxlint-plugins/pretty-props.d.ts
4
- declare const prettyPropsRule: oxlint6.Rule;
5
- type RuleContext = oxlint6.Context;
6
- type ESTNode = oxlint6.ESTree.Node;
7
- type ESTExpression = oxlint6.ESTree.Expression;
8
- type FunctionLikeNode = oxlint6.ESTree.Function | oxlint6.ESTree.ArrowFunctionExpression;
9
- //#endregion
10
- export { ESTExpression, ESTNode, FunctionLikeNode, RuleContext, prettyPropsRule };
11
- //# sourceMappingURL=pretty-props.d.mts.map
@@ -1,127 +0,0 @@
1
- import { defineRule } from "oxlint";
2
-
3
- //#region src/oxlint-plugins/pretty-props.js
4
- /**
5
- * @typedef {import("oxlint").Context} RuleContext
6
- * @typedef {import("oxlint").ESTree.Node} ESTNode
7
- * @typedef {import("oxlint").ESTree.Expression} ESTExpression
8
- * @typedef {import("oxlint").ESTree.Function | import("oxlint").ESTree.ArrowFunctionExpression} FunctionLikeNode
9
- */
10
- const JSX_NODE_TYPES = new Set(["JSXElement", "JSXFragment"]);
11
- const FUNCTION_NODE_TYPES = new Set([
12
- "FunctionDeclaration",
13
- "FunctionExpression",
14
- "ArrowFunctionExpression"
15
- ]);
16
- /**
17
- * @param {unknown} node
18
- * @returns {node is ESTNode & { type: string }}
19
- */
20
- const isNode = (node) => Boolean(node && typeof node === "object" && "type" in node);
21
- /**
22
- * @param {unknown} node
23
- * @returns {node is FunctionLikeNode}
24
- */
25
- const isFunctionLike = (node) => isNode(node) && FUNCTION_NODE_TYPES.has(node.type);
26
- /**
27
- * Check if an expression contains JSX
28
- * @param {ESTExpression | null | undefined} root
29
- */
30
- const expressionContainsJsx = (root) => {
31
- if (!root || !isNode(root)) return false;
32
- const stack = [root];
33
- while (stack.length > 0) {
34
- const current = stack.pop();
35
- if (!current || !isNode(current)) continue;
36
- if (JSX_NODE_TYPES.has(current.type)) return true;
37
- if (FUNCTION_NODE_TYPES.has(current.type) && current !== root) continue;
38
- for (const key of Object.keys(current)) {
39
- if (key === "parent") continue;
40
- const value = current[key];
41
- if (!value) continue;
42
- if (Array.isArray(value)) {
43
- for (const element of value) if (isNode(element)) stack.push(element);
44
- } else if (isNode(value)) stack.push(value);
45
- }
46
- }
47
- return false;
48
- };
49
- /**
50
- * Check if a function returns JSX
51
- * @param {FunctionLikeNode} node
52
- */
53
- const functionReturnsJsx = (node) => {
54
- if (node.type === "ArrowFunctionExpression" && node.body && node.body.type !== "BlockStatement") return expressionContainsJsx(node.body);
55
- const body = node.body;
56
- if (!body || body.type !== "BlockStatement") return false;
57
- const stack = [body];
58
- while (stack.length > 0) {
59
- const current = stack.pop();
60
- if (!current || !isNode(current)) continue;
61
- if (current.type === "ReturnStatement") {
62
- const argument = current.argument;
63
- if (argument && expressionContainsJsx(argument)) return true;
64
- }
65
- if (FUNCTION_NODE_TYPES.has(current.type) && current !== body) continue;
66
- for (const key of Object.keys(current)) {
67
- if (key === "parent") continue;
68
- const value = current[key];
69
- if (!value) continue;
70
- if (Array.isArray(value)) {
71
- for (const element of value) if (isNode(element)) stack.push(element);
72
- } else if (isNode(value)) stack.push(value);
73
- }
74
- }
75
- return false;
76
- };
77
- const rule = defineRule({
78
- meta: {
79
- type: "problem",
80
- docs: {
81
- description: "Enforce consistent props parameter naming and disallow destructuring in component parameters.",
82
- recommended: false
83
- },
84
- schema: []
85
- },
86
- createOnce(context) {
87
- /**
88
- * @param {FunctionLikeNode} node
89
- */
90
- const checkFunction = (node) => {
91
- if (!functionReturnsJsx(node)) return;
92
- const params = node.params;
93
- if (!params || params.length === 0) return;
94
- const firstParam = params[0];
95
- if (!firstParam || !isNode(firstParam)) return;
96
- if (firstParam.type === "ObjectPattern" || firstParam.type === "ArrayPattern") {
97
- context.report({
98
- node: firstParam,
99
- message: "Props should not be destructured in the component parameter. Use 'props' instead and destructure inside the component body."
100
- });
101
- return;
102
- }
103
- if (firstParam.type === "Identifier") {
104
- if (firstParam.name !== "props") context.report({
105
- node: firstParam,
106
- message: `Props parameter should be named 'props', not '${firstParam.name}'.`
107
- });
108
- }
109
- };
110
- return {
111
- FunctionDeclaration(node) {
112
- if (isFunctionLike(node)) checkFunction(node);
113
- },
114
- FunctionExpression(node) {
115
- if (isFunctionLike(node)) checkFunction(node);
116
- },
117
- ArrowFunctionExpression(node) {
118
- if (isFunctionLike(node)) checkFunction(node);
119
- }
120
- };
121
- }
122
- });
123
- const prettyPropsRule = rule;
124
-
125
- //#endregion
126
- export { prettyPropsRule };
127
- //# sourceMappingURL=pretty-props.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pretty-props.mjs","names":[],"sources":["../../src/oxlint-plugins/pretty-props.js"],"sourcesContent":["import { defineRule } from \"oxlint\";\n\n/**\n * @typedef {import(\"oxlint\").Context} RuleContext\n * @typedef {import(\"oxlint\").ESTree.Node} ESTNode\n * @typedef {import(\"oxlint\").ESTree.Expression} ESTExpression\n * @typedef {import(\"oxlint\").ESTree.Function | import(\"oxlint\").ESTree.ArrowFunctionExpression} FunctionLikeNode\n */\n\nconst JSX_NODE_TYPES = new Set([\"JSXElement\", \"JSXFragment\"]);\nconst FUNCTION_NODE_TYPES = new Set([\"FunctionDeclaration\", \"FunctionExpression\", \"ArrowFunctionExpression\"]);\n\n/**\n * @param {unknown} node\n * @returns {node is ESTNode & { type: string }}\n */\nconst isNode = (node) => Boolean(node && typeof node === \"object\" && \"type\" in node);\n\n/**\n * @param {unknown} node\n * @returns {node is FunctionLikeNode}\n */\nconst isFunctionLike = (node) => isNode(node) && FUNCTION_NODE_TYPES.has(node.type);\n\n/**\n * Check if an expression contains JSX\n * @param {ESTExpression | null | undefined} root\n */\nconst expressionContainsJsx = (root) => {\n if (!root || !isNode(root)) return false;\n\n const stack = [root];\n\n while (stack.length > 0) {\n const current = stack.pop();\n if (!current || !isNode(current)) continue;\n\n if (JSX_NODE_TYPES.has(current.type)) {\n return true;\n }\n\n if (FUNCTION_NODE_TYPES.has(current.type) && current !== root) {\n continue;\n }\n\n for (const key of Object.keys(current)) {\n if (key === \"parent\") continue;\n\n const value = current[key];\n if (!value) continue;\n\n if (Array.isArray(value)) {\n for (const element of value) {\n if (isNode(element)) {\n stack.push(element);\n }\n }\n } else if (isNode(value)) {\n stack.push(value);\n }\n }\n }\n\n return false;\n};\n\n/**\n * Check if a function returns JSX\n * @param {FunctionLikeNode} node\n */\nconst functionReturnsJsx = (node) => {\n // Check arrow functions with expression body\n if (node.type === \"ArrowFunctionExpression\" && node.body && node.body.type !== \"BlockStatement\") {\n return expressionContainsJsx(node.body);\n }\n\n // Check for return statements in function body\n const body = node.body;\n if (!body || body.type !== \"BlockStatement\") return false;\n\n const stack = [body];\n while (stack.length > 0) {\n const current = stack.pop();\n if (!current || !isNode(current)) continue;\n\n if (current.type === \"ReturnStatement\") {\n const argument = current.argument;\n if (argument && expressionContainsJsx(argument)) {\n return true;\n }\n }\n\n // Don't traverse into nested functions\n if (FUNCTION_NODE_TYPES.has(current.type) && current !== body) {\n continue;\n }\n\n for (const key of Object.keys(current)) {\n if (key === \"parent\") continue;\n\n const value = current[key];\n if (!value) continue;\n\n if (Array.isArray(value)) {\n for (const element of value) {\n if (isNode(element)) {\n stack.push(element);\n }\n }\n } else if (isNode(value)) {\n stack.push(value);\n }\n }\n }\n\n return false;\n};\n\nconst rule = defineRule({\n meta: {\n type: \"problem\",\n docs: {\n description: \"Enforce consistent props parameter naming and disallow destructuring in component parameters.\",\n recommended: false,\n },\n schema: [],\n },\n\n createOnce(context) {\n /**\n * @param {FunctionLikeNode} node\n */\n const checkFunction = (node) => {\n // Only check functions that return JSX (React components)\n if (!functionReturnsJsx(node)) {\n return;\n }\n\n const params = node.params;\n if (!params || params.length === 0) {\n return;\n }\n\n const firstParam = params[0];\n if (!firstParam || !isNode(firstParam)) {\n return;\n }\n\n // Check if the first parameter is destructured\n if (firstParam.type === \"ObjectPattern\" || firstParam.type === \"ArrayPattern\") {\n context.report({\n node: firstParam,\n message:\n \"Props should not be destructured in the component parameter. Use 'props' instead and destructure inside the component body.\",\n });\n return;\n }\n\n // Check if the first parameter is an Identifier and is named 'props'\n if (firstParam.type === \"Identifier\") {\n if (firstParam.name !== \"props\") {\n context.report({\n node: firstParam,\n message: `Props parameter should be named 'props', not '${firstParam.name}'.`,\n });\n }\n }\n };\n\n return /** @type {import(\"oxlint\").VisitorWithHooks} */ ({\n FunctionDeclaration(node) {\n if (isFunctionLike(node)) checkFunction(node);\n },\n FunctionExpression(node) {\n if (isFunctionLike(node)) checkFunction(node);\n },\n ArrowFunctionExpression(node) {\n if (isFunctionLike(node)) checkFunction(node);\n },\n });\n },\n});\n\nexport const prettyPropsRule = rule;\n\n"],"mappings":"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"}
package/dist/react.d.mts DELETED
@@ -1,73 +0,0 @@
1
- //#region src/react/useStableCallback.d.ts
2
- type AnyFunction = (...args: any[]) => any;
3
- /**
4
- * Creates a stable callback that always calls the latest version of the function.
5
- * Useful for callbacks that need to be used in dependency arrays but should always
6
- * execute the most recent version of the callback.
7
- */
8
- declare const useStableCallback: <T extends AnyFunction>(callback: T) => T;
9
- //#endregion
10
- //#region src/react/useOnce.d.ts
11
- /**
12
- * Runs a callback only once when a condition becomes truthy.
13
- * The callback is stabilized internally to always reference the latest version.
14
- *
15
- * @param condition - When truthy (evaluated via Boolean()), the callback will be executed (only once).
16
- * @param callback - The function to run once when the condition is met.
17
- *
18
- * @example
19
- * ```tsx
20
- * const isReady = true;
21
- * useOnce(isReady, () => {
22
- * console.log("Ready!");
23
- * });
24
- * ```
25
- */
26
- declare const useOnce: (condition: unknown, callback: () => void) => void;
27
- //#endregion
28
- //#region src/react/useLocalOnce.d.ts
29
- /**
30
- * Runs a callback only once when a condition becomes truthy, executing synchronously
31
- * during render. The callback is stabilized internally to always reference the latest version.
32
- *
33
- * Unlike `useOnce`, this runs at the top level of the hook (not in useEffect),
34
- * making it suitable for state updates that need to happen synchronously during render.
35
- *
36
- * @param condition - When truthy (evaluated via Boolean()), the callback will be executed (only once).
37
- * @param callback - The function to run once when the condition is met.
38
- *
39
- * @example
40
- * ```tsx
41
- * const user: User | null = getUser();
42
- * useLocalOnce(user, () => {
43
- * setState(user.name);
44
- * });
45
- * ```
46
- */
47
- declare const useLocalOnce: (condition: unknown, callback: () => void) => void;
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
65
- //#region src/react/useOnUnmount.d.ts
66
- /**
67
- * Calls the given callback when the component unmounts.
68
- * Uses useStableCallback internally to ensure the latest version is called.
69
- */
70
- declare const useOnUnmount: (callback: () => void) => void;
71
- //#endregion
72
- export { useLocalOnce, useOnMount, useOnUnmount, useOnce, useStableCallback };
73
- //# sourceMappingURL=react.d.mts.map
package/dist/react.mjs DELETED
@@ -1,113 +0,0 @@
1
- import { useCallback, useEffect, useRef } from "react";
2
-
3
- //#region src/react/useStableCallback.ts
4
- /**
5
- * Creates a stable callback that always calls the latest version of the function.
6
- * Useful for callbacks that need to be used in dependency arrays but should always
7
- * execute the most recent version of the callback.
8
- */
9
- const useStableCallback = (callback) => {
10
- const callbackRef = useRef(callback);
11
- callbackRef.current = callback;
12
- return useCallback((...args) => {
13
- return callbackRef.current(...args);
14
- }, []);
15
- };
16
-
17
- //#endregion
18
- //#region src/react/useOnce.ts
19
- /**
20
- * Runs a callback only once when a condition becomes truthy.
21
- * The callback is stabilized internally to always reference the latest version.
22
- *
23
- * @param condition - When truthy (evaluated via Boolean()), the callback will be executed (only once).
24
- * @param callback - The function to run once when the condition is met.
25
- *
26
- * @example
27
- * ```tsx
28
- * const isReady = true;
29
- * useOnce(isReady, () => {
30
- * console.log("Ready!");
31
- * });
32
- * ```
33
- */
34
- const useOnce = (condition, callback) => {
35
- const hasRunRef = useRef(false);
36
- const stableCallback = useStableCallback(callback);
37
- useEffect(() => {
38
- if (Boolean(condition) && !hasRunRef.current) {
39
- hasRunRef.current = true;
40
- stableCallback();
41
- }
42
- }, [condition, stableCallback]);
43
- };
44
-
45
- //#endregion
46
- //#region src/react/useLocalOnce.ts
47
- /**
48
- * Runs a callback only once when a condition becomes truthy, executing synchronously
49
- * during render. The callback is stabilized internally to always reference the latest version.
50
- *
51
- * Unlike `useOnce`, this runs at the top level of the hook (not in useEffect),
52
- * making it suitable for state updates that need to happen synchronously during render.
53
- *
54
- * @param condition - When truthy (evaluated via Boolean()), the callback will be executed (only once).
55
- * @param callback - The function to run once when the condition is met.
56
- *
57
- * @example
58
- * ```tsx
59
- * const user: User | null = getUser();
60
- * useLocalOnce(user, () => {
61
- * setState(user.name);
62
- * });
63
- * ```
64
- */
65
- const useLocalOnce = (condition, callback) => {
66
- const hasRunRef = useRef(false);
67
- const stableCallback = useStableCallback(callback);
68
- if (Boolean(condition) && !hasRunRef.current) {
69
- hasRunRef.current = true;
70
- stableCallback();
71
- }
72
- };
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
-
96
- //#endregion
97
- //#region src/react/useOnUnmount.ts
98
- /**
99
- * Calls the given callback when the component unmounts.
100
- * Uses useStableCallback internally to ensure the latest version is called.
101
- */
102
- const useOnUnmount = (callback) => {
103
- const stableCallback = useStableCallback(callback);
104
- useEffect(() => {
105
- return () => {
106
- stableCallback();
107
- };
108
- }, [stableCallback]);
109
- };
110
-
111
- //#endregion
112
- export { useLocalOnce, useOnMount, useOnUnmount, useOnce, useStableCallback };
113
- //# sourceMappingURL=react.mjs.map
@@ -1 +0,0 @@
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"}