fynixui 1.0.10 → 1.0.11

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 (92) hide show
  1. package/dist/package.json +35 -37
  2. package/{dist → dist-types}/context/context.d.ts +0 -1
  3. package/{dist → dist-types}/custom/button.d.ts +0 -1
  4. package/{dist → dist-types}/custom/index.d.ts +0 -1
  5. package/{dist → dist-types}/custom/path.d.ts +0 -1
  6. package/{dist → dist-types}/error/errorOverlay.d.ts +0 -1
  7. package/{dist → dist-types}/fynix/index.d.ts +0 -1
  8. package/{dist → dist-types}/hooks/nixAsync.d.ts +0 -1
  9. package/{dist → dist-types}/hooks/nixAsyncCache.d.ts +0 -1
  10. package/{dist → dist-types}/hooks/nixAsyncDebounce.d.ts +0 -1
  11. package/{dist → dist-types}/hooks/nixAsyncQuery.d.ts +0 -1
  12. package/{dist → dist-types}/hooks/nixCallback.d.ts +0 -1
  13. package/{dist → dist-types}/hooks/nixComputed.d.ts +0 -1
  14. package/{dist → dist-types}/hooks/nixDebounce.d.ts +0 -1
  15. package/{dist → dist-types}/hooks/nixEffect.d.ts +0 -1
  16. package/{dist → dist-types}/hooks/nixFor.d.ts +0 -1
  17. package/{dist → dist-types}/hooks/nixForm.d.ts +0 -1
  18. package/{dist → dist-types}/hooks/nixFormAsync.d.ts +0 -1
  19. package/{dist → dist-types}/hooks/nixInterval.d.ts +0 -1
  20. package/{dist → dist-types}/hooks/nixLazy.d.ts +0 -1
  21. package/{dist → dist-types}/hooks/nixLazyAsync.d.ts +0 -1
  22. package/{dist → dist-types}/hooks/nixLazyFormAsync.d.ts +0 -1
  23. package/{dist → dist-types}/hooks/nixLocalStorage.d.ts +0 -1
  24. package/{dist → dist-types}/hooks/nixMemo.d.ts +0 -1
  25. package/{dist → dist-types}/hooks/nixPrevious.d.ts +0 -1
  26. package/{dist → dist-types}/hooks/nixRef.d.ts +0 -1
  27. package/{dist → dist-types}/hooks/nixState.d.ts +0 -1
  28. package/{dist → dist-types}/hooks/nixStore.d.ts +0 -1
  29. package/{dist → dist-types}/plugins/vite-plugin-res.d.ts +0 -1
  30. package/{dist → dist-types}/router/router.d.ts +0 -1
  31. package/{dist → dist-types}/runtime.d.ts +0 -1
  32. package/package.json +38 -38
  33. package/dist/context/context.d.ts.map +0 -1
  34. package/dist/context/context.js.map +0 -7
  35. package/dist/custom/button.d.ts.map +0 -1
  36. package/dist/custom/button.js.map +0 -7
  37. package/dist/custom/index.d.ts.map +0 -1
  38. package/dist/custom/index.js.map +0 -7
  39. package/dist/custom/path.d.ts.map +0 -1
  40. package/dist/custom/path.js.map +0 -7
  41. package/dist/error/errorOverlay.d.ts.map +0 -1
  42. package/dist/error/errorOverlay.js.map +0 -7
  43. package/dist/fynix/index.d.ts.map +0 -1
  44. package/dist/fynix/index.js.map +0 -7
  45. package/dist/hooks/nixAsync.d.ts.map +0 -1
  46. package/dist/hooks/nixAsync.js.map +0 -7
  47. package/dist/hooks/nixAsyncCache.d.ts.map +0 -1
  48. package/dist/hooks/nixAsyncCache.js.map +0 -7
  49. package/dist/hooks/nixAsyncDebounce.d.ts.map +0 -1
  50. package/dist/hooks/nixAsyncDebounce.js.map +0 -7
  51. package/dist/hooks/nixAsyncQuery.d.ts.map +0 -1
  52. package/dist/hooks/nixAsyncQuery.js.map +0 -7
  53. package/dist/hooks/nixCallback.d.ts.map +0 -1
  54. package/dist/hooks/nixCallback.js.map +0 -7
  55. package/dist/hooks/nixComputed.d.ts.map +0 -1
  56. package/dist/hooks/nixComputed.js.map +0 -7
  57. package/dist/hooks/nixDebounce.d.ts.map +0 -1
  58. package/dist/hooks/nixDebounce.js.map +0 -7
  59. package/dist/hooks/nixEffect.d.ts.map +0 -1
  60. package/dist/hooks/nixEffect.js.map +0 -7
  61. package/dist/hooks/nixFor.d.ts.map +0 -1
  62. package/dist/hooks/nixFor.js.map +0 -7
  63. package/dist/hooks/nixForm.d.ts.map +0 -1
  64. package/dist/hooks/nixForm.js.map +0 -7
  65. package/dist/hooks/nixFormAsync.d.ts.map +0 -1
  66. package/dist/hooks/nixFormAsync.js.map +0 -7
  67. package/dist/hooks/nixInterval.d.ts.map +0 -1
  68. package/dist/hooks/nixInterval.js.map +0 -7
  69. package/dist/hooks/nixLazy.d.ts.map +0 -1
  70. package/dist/hooks/nixLazy.js.map +0 -7
  71. package/dist/hooks/nixLazyAsync.d.ts.map +0 -1
  72. package/dist/hooks/nixLazyAsync.js.map +0 -7
  73. package/dist/hooks/nixLazyFormAsync.d.ts.map +0 -1
  74. package/dist/hooks/nixLazyFormAsync.js.map +0 -7
  75. package/dist/hooks/nixLocalStorage.d.ts.map +0 -1
  76. package/dist/hooks/nixLocalStorage.js.map +0 -7
  77. package/dist/hooks/nixMemo.d.ts.map +0 -1
  78. package/dist/hooks/nixMemo.js.map +0 -7
  79. package/dist/hooks/nixPrevious.d.ts.map +0 -1
  80. package/dist/hooks/nixPrevious.js.map +0 -7
  81. package/dist/hooks/nixRef.d.ts.map +0 -1
  82. package/dist/hooks/nixRef.js.map +0 -7
  83. package/dist/hooks/nixState.d.ts.map +0 -1
  84. package/dist/hooks/nixState.js.map +0 -7
  85. package/dist/hooks/nixStore.d.ts.map +0 -1
  86. package/dist/hooks/nixStore.js.map +0 -7
  87. package/dist/plugins/vite-plugin-res.d.ts.map +0 -1
  88. package/dist/plugins/vite-plugin-res.js.map +0 -7
  89. package/dist/router/router.d.ts.map +0 -1
  90. package/dist/router/router.js.map +0 -7
  91. package/dist/runtime.d.ts.map +0 -1
  92. package/dist/runtime.js.map +0 -7
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../custom/index.ts"],"names":[],"mappings":"AA8BA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC"}
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../custom/index.ts"],
4
- "sourcesContent": ["/* MIT License\r\n\r\n* Copyright (c) 2026 Resty Gonzales\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n* SOFTWARE.\r\n */\r\n/**\r\n * @fileoverview Custom Fynix components export module.\r\n * Re-exports Button and Path components for convenient importing.\r\n *\r\n * @example\r\n * import { Button, Path } from '@fynixorg/ui/custom';\r\n */\r\n\r\nexport { Button } from \"./button\";\r\n\r\nexport { Path } from \"./path\";\r\n"],
5
- "mappings": "AA8BA,SAAS,cAAc;AAEvB,SAAS,YAAY;",
6
- "names": []
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../custom/path.ts"],"names":[],"mappings":"AA0CA,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KAC1C;CACF;AA0CD,wBAAgB,IAAI,CAAC,EACnB,EAAQ,EACR,KAAU,EACV,KAAK,EAAE,UAAe,EACtB,GAAG,KAAK,EACT,EAAE;IACD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB,GAAG,GAAG,CAoCN"}
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../custom/path.ts"],
4
- "sourcesContent": ["/* MIT License\r\n\r\n* Copyright (c) 2026 Resty Gonzales\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n* SOFTWARE.\r\n */\r\n/**\r\n * @fileoverview Path component for SPA navigation in Fynix applications.\r\n * Provides client-side routing with prop passing between routes.\r\n */\r\n\r\nimport { Fynix, nixState } from \"../runtime.js\";\r\n\r\n/**\r\n * @typedef {Object} PathProps\r\n * @property {string} [to=\"#\"] - URL to navigate to (relative or absolute)\r\n * @property {string} [value=\"\"] - Link text content\r\n * @property {Record<string, any>} [props={}] - Props to pass to the destination route component\r\n * @property {string} [target] - Link target (_blank, _self, etc.)\r\n * @property {string} [rel] - Link relationship (noopener, noreferrer, etc.)\r\n * @property {string} [rc] - Reactive class attribute (Fynix-specific)\r\n * @property {string} [class] - CSS class names\r\n * @property {string} [id] - Element ID\r\n */\r\n\r\n/** Extend Window interface for __fynixLinkProps__ */\r\ndeclare global {\r\n interface Window {\r\n __fynixLinkProps__?: Record<string, any>;\r\n }\r\n}\r\n\r\n/** Unique counter for props keys */\r\nlet propsCounter = 0;\r\n\r\n/**\r\n * SPA navigation link component for Fynix router.\r\n * Automatically handles client-side navigation and prop passing between routes.\r\n *\r\n * @param {PathProps & Record<string, any>} options - Component props\r\n * @returns {VNode} Anchor element virtual node\r\n *\r\n * @example\r\n * // Basic navigation\r\n * <Path to=\"/about\" value=\"About Us\" />\r\n *\r\n * @example\r\n * // Navigate with props\r\n * <Path\r\n * to=\"/user/123\"\r\n * value=\"View Profile\"\r\n * props={{ userId: 123, fromSearch: true }}\r\n * />\r\n *\r\n * @example\r\n * // External link\r\n * <Path\r\n * to=\"https://github.com\"\r\n * value=\"GitHub\"\r\n * target=\"_blank\"\r\n * rel=\"noopener noreferrer\"\r\n * />\r\n *\r\n * @example\r\n * // With styling\r\n * <Path\r\n * to=\"/dashboard\"\r\n * value=\"Dashboard\"\r\n * rc=\"px-4 py-2 bg-blue-500 text-white rounded\"\r\n * />\r\n */\r\n// Use 'any' as the return type to avoid the VNode type export error\r\nexport function Path({\r\n to = \"#\",\r\n value = \"\",\r\n props: routeProps = {},\r\n ...attrs\r\n}: {\r\n to?: string;\r\n value?: string;\r\n props?: { [key: string]: any };\r\n [key: string]: any;\r\n}): any {\r\n ///console.log(\"[Path Component] Received routeProps:\", routeProps);\r\n\r\n // Wrap plain props in nixState if not already\r\n const wrappedProps: { [key: string]: any } = {};\r\n for (const [k, v] of Object.entries(routeProps as { [key: string]: any })) {\r\n wrappedProps[k] = v && v._isNixState ? v : nixState(v);\r\n }\r\n\r\n // Generate a unique key for this props object\r\n // FIX: Do not use __ prefix as router blocks it for security\r\n const propsKey = `fynixProp_${Date.now()}_${propsCounter++}`;\r\n\r\n // FIX: Store props in the namespace expected by the router\r\n if (!window.__fynixLinkProps__) {\r\n window.__fynixLinkProps__ = {};\r\n }\r\n\r\n // Debug log\r\n // console.log(\"[Path] Storage props:\", propsKey, wrappedProps);\r\n\r\n window.__fynixLinkProps__[propsKey] = wrappedProps;\r\n\r\n // Create the anchor element\r\n const el = Fynix(\r\n \"a\",\r\n {\r\n href: to,\r\n \"data-fynix-link\": true, // SPA link detection\r\n \"data-props-key\": propsKey,\r\n ...attrs,\r\n },\r\n value\r\n );\r\n\r\n return el;\r\n}\r\n"],
5
- "mappings": ";;AA2BA,SAAS,OAAO,gBAAgB;AAsBhC,IAAI,eAAe;AAuCZ,SAAS,KAAK;AAAA,EACnB,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,OAAO,aAAa,CAAC;AAAA,EACrB,GAAG;AACL,GAKQ;AAIN,QAAM,eAAuC,CAAC;AAC9C,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,UAAoC,GAAG;AACzE,iBAAa,CAAC,IAAI,KAAK,EAAE,cAAc,IAAI,SAAS,CAAC;AAAA,EACvD;AAIA,QAAM,WAAW,aAAa,KAAK,IAAI,CAAC,IAAI,cAAc;AAG1D,MAAI,CAAC,OAAO,oBAAoB;AAC9B,WAAO,qBAAqB,CAAC;AAAA,EAC/B;AAKA,SAAO,mBAAmB,QAAQ,IAAI;AAGtC,QAAM,KAAK;AAAA,IACT;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,mBAAmB;AAAA;AAAA,MACnB,kBAAkB;AAAA,MAClB,GAAG;AAAA,IACL;AAAA,IACA;AAAA,EACF;AAEA,SAAO;AACT;AA9CgB;",
6
- "names": []
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"errorOverlay.d.ts","sourceRoot":"","sources":["../../error/errorOverlay.ts"],"names":[],"mappings":"AAyCA,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CA2FnD;AAQD,wBAAgB,kBAAkB,IAAI,IAAI,CAMzC"}
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../error/errorOverlay.ts"],
4
- "sourcesContent": ["/* MIT License\r\n\r\n* Copyright (c) 2026 Resty Gonzales\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n* SOFTWARE.\r\n */\r\n/**\r\n * @fileoverview Development error overlay for Fynix applications.\r\n * Displays runtime errors in a user-friendly overlay during development.\r\n */\r\n\r\n/**\r\n * Display an error overlay with error details.\r\n * Shows error message, stack trace, and a close button.\r\n *\r\n * @param {Error} error - The error object to display\r\n * @returns {void}\r\n *\r\n * @example\r\n * try {\r\n * // some code\r\n * } catch (err) {\r\n * showErrorOverlay(err);\r\n * }\r\n */\r\nexport function showErrorOverlay(error: Error): void {\r\n removeErrorOverlay();\r\n\r\n const overlay = document.createElement(\"div\");\r\n overlay.id = \"dev-error-overlay\";\r\n Object.assign(overlay.style, {\r\n position: \"fixed\",\r\n inset: 0,\r\n width: \"100%\",\r\n height: \"100%\",\r\n backgroundColor: \"rgba(0, 0, 0, 0.9)\",\r\n color: \"#fff\",\r\n fontFamily: \"Consolas, monospace\",\r\n padding: \"30px\",\r\n zIndex: 99999,\r\n overflowY: \"auto\",\r\n transition: \"opacity 0.25s ease\",\r\n opacity: \"0\",\r\n });\r\n\r\n const container = document.createElement(\"div\");\r\n container.style.position = \"relative\"; // important for absolute button\r\n container.style.maxWidth = \"900px\";\r\n container.style.margin = \"50px auto\";\r\n container.style.background = \"rgba(255, 255, 255, 0.05)\";\r\n container.style.borderRadius = \"8px\";\r\n container.style.padding = \"20px 30px\";\r\n container.style.boxShadow = \"0 0 10px rgba(255, 0, 0, 0.3)\";\r\n\r\n // Close Button\r\n const closeBtn = document.createElement(\"button\");\r\n closeBtn.textContent = \"\u00D7 Close\";\r\n Object.assign(closeBtn.style, {\r\n position: \"absolute\",\r\n top: \"10px\",\r\n right: \"10px\",\r\n background: \"#ff5555\",\r\n color: \"#fff\",\r\n border: \"none\",\r\n padding: \"6px 12px\",\r\n fontSize: \"16px\",\r\n borderRadius: \"4px\",\r\n cursor: \"pointer\",\r\n zIndex: 10,\r\n });\r\n closeBtn.addEventListener(\"click\", () => removeErrorOverlay());\r\n container.appendChild(closeBtn);\r\n\r\n // Title\r\n const title = document.createElement(\"h1\");\r\n title.textContent = \"Runtime Error\";\r\n Object.assign(title.style, {\r\n color: \"#ff5555\",\r\n fontSize: \"24px\",\r\n marginBottom: \"10px\",\r\n });\r\n\r\n // Message\r\n const message = document.createElement(\"pre\");\r\n message.textContent = error?.message || \"Unknown error\";\r\n Object.assign(message.style, {\r\n whiteSpace: \"pre-wrap\",\r\n background: \"rgba(255, 255, 255, 0.1)\",\r\n padding: \"10px\",\r\n borderRadius: \"6px\",\r\n marginTop: \"10px\",\r\n color: \"#ffaaaa\",\r\n });\r\n\r\n // Stack trace\r\n const stack = document.createElement(\"pre\");\r\n stack.textContent = error?.stack || \"\";\r\n Object.assign(stack.style, {\r\n whiteSpace: \"pre-wrap\",\r\n marginTop: \"15px\",\r\n color: \"#ccc\",\r\n });\r\n\r\n container.appendChild(title);\r\n container.appendChild(message);\r\n container.appendChild(stack);\r\n overlay.appendChild(container);\r\n document.body.appendChild(overlay);\r\n\r\n // Smooth fade-in\r\n requestAnimationFrame(() => {\r\n overlay.style.opacity = \"1\";\r\n });\r\n\r\n // Console log\r\n console.error(\"[FynixJS Runtime Error]\", error);\r\n}\r\n\r\n/**\r\n * Remove the error overlay from the DOM.\r\n * Fades out the overlay before removing it.\r\n *\r\n * @returns {void}\r\n */\r\nexport function removeErrorOverlay(): void {\r\n const existing = document.getElementById(\"dev-error-overlay\");\r\n if (existing) {\r\n existing.style.opacity = \"0\";\r\n setTimeout(() => existing.remove(), 200);\r\n }\r\n}\r\n"],
5
- "mappings": ";;AAyCO,SAAS,iBAAiB,OAAoB;AACnD,qBAAmB;AAEnB,QAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,UAAQ,KAAK;AACb,SAAO,OAAO,QAAQ,OAAO;AAAA,IAC3B,UAAU;AAAA,IACV,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,iBAAiB;AAAA,IACjB,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,SAAS;AAAA,EACX,CAAC;AAED,QAAM,YAAY,SAAS,cAAc,KAAK;AAC9C,YAAU,MAAM,WAAW;AAC3B,YAAU,MAAM,WAAW;AAC3B,YAAU,MAAM,SAAS;AACzB,YAAU,MAAM,aAAa;AAC7B,YAAU,MAAM,eAAe;AAC/B,YAAU,MAAM,UAAU;AAC1B,YAAU,MAAM,YAAY;AAG5B,QAAM,WAAW,SAAS,cAAc,QAAQ;AAChD,WAAS,cAAc;AACvB,SAAO,OAAO,SAAS,OAAO;AAAA,IAC5B,UAAU;AAAA,IACV,KAAK;AAAA,IACL,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,UAAU;AAAA,IACV,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,CAAC;AACD,WAAS,iBAAiB,SAAS,MAAM,mBAAmB,CAAC;AAC7D,YAAU,YAAY,QAAQ;AAG9B,QAAM,QAAQ,SAAS,cAAc,IAAI;AACzC,QAAM,cAAc;AACpB,SAAO,OAAO,MAAM,OAAO;AAAA,IACzB,OAAO;AAAA,IACP,UAAU;AAAA,IACV,cAAc;AAAA,EAChB,CAAC;AAGD,QAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,UAAQ,cAAc,OAAO,WAAW;AACxC,SAAO,OAAO,QAAQ,OAAO;AAAA,IAC3B,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,cAAc;AAAA,IACd,WAAW;AAAA,IACX,OAAO;AAAA,EACT,CAAC;AAGD,QAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,QAAM,cAAc,OAAO,SAAS;AACpC,SAAO,OAAO,MAAM,OAAO;AAAA,IACzB,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,OAAO;AAAA,EACT,CAAC;AAED,YAAU,YAAY,KAAK;AAC3B,YAAU,YAAY,OAAO;AAC7B,YAAU,YAAY,KAAK;AAC3B,UAAQ,YAAY,SAAS;AAC7B,WAAS,KAAK,YAAY,OAAO;AAGjC,wBAAsB,MAAM;AAC1B,YAAQ,MAAM,UAAU;AAAA,EAC1B,CAAC;AAGD,UAAQ,MAAM,2BAA2B,KAAK;AAChD;AA3FgB;AAmGT,SAAS,qBAA2B;AACzC,QAAM,WAAW,SAAS,eAAe,mBAAmB;AAC5D,MAAI,UAAU;AACZ,aAAS,MAAM,UAAU;AACzB,eAAW,MAAM,SAAS,OAAO,GAAG,GAAG;AAAA,EACzC;AACF;AANgB;",
6
- "names": []
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../fynix/index.ts"],"names":[],"mappings":"AA2BA,cAAc,eAAe,CAAC;AAE9B,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC"}
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../fynix/index.ts"],
4
- "sourcesContent": ["/* MIT License\r\n\r\n* Copyright (c) 2026 Resty Gonzales\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n* SOFTWARE.\r\n */\r\n// fynix/index.js - Single entry point for all core functionality\r\n\r\n/// <reference path=\"../types/jsx.d.ts\" />\r\n/// <reference path=\"../types/global.d.ts\" />\r\n\r\nexport * from \"../runtime.js\";\r\n// Re-export Fynix namespace and hooks under new names\r\nexport * from \"../router/router.js\";\r\nexport { default as createFynix } from \"../router/router.js\";\r\nexport { Fynix } from \"../runtime.js\";\r\nexport { For } from \"../hooks/nixFor.js\";\r\n"],
5
- "mappings": "AA2BA,cAAc;AAEd,cAAc;AACd,SAAoB,WAAXA,gBAA8B;AACvC,SAAS,aAAa;AACtB,SAAS,WAAW;",
6
- "names": ["default"]
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"nixAsync.d.ts","sourceRoot":"","sources":["../../hooks/nixAsync.ts"],"names":[],"mappings":"AAmCA,wBAAgB,QAAQ,CAAC,CAAC,EACxB,cAAc,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,EACnD,OAAO,GAAE;IACP,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACd,GACL;IACD,IAAI,EAAE;QAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAAA;KAAE,CAAC;IAC1B,KAAK,EAAE;QAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;KAAE,CAAC;IAC/B,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;IAC5B,GAAG,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,MAAM,CAAC;CACzB,CA8IA"}
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../hooks/nixAsync.ts"],
4
- "sourcesContent": ["/* MIT License\r\n\r\n* Copyright (c) 2026 Resty Gonzales\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n* SOFTWARE.\r\n */\r\n\r\nimport { nixState } from \"./nixState\";\r\n\r\n/**\r\n * Async state helper with AbortController support and race condition protection.\r\n *\r\n * @template T\r\n * @param {(signal: AbortSignal) => Promise<T>} promiseFactory\r\n * @param {Object} options - Configuration options\r\n * @param {number} options.timeout - Request timeout in milliseconds (default: 30000)\r\n * @param {number} options.retries - Number of retry attempts (default: 0)\r\n * @param {boolean} options.autoRun - Whether to run immediately (default: false)\r\n */\r\nexport function nixAsync<T>(\r\n promiseFactory: (signal: AbortSignal) => Promise<T>,\r\n options: {\r\n timeout?: number;\r\n retries?: number;\r\n autoRun?: boolean;\r\n } = {}\r\n): {\r\n data: { value: T | null };\r\n error: { value: Error | null };\r\n loading: { value: boolean };\r\n run: () => Promise<void>;\r\n cancel: () => void;\r\n cleanup: () => void;\r\n getCallId: () => number;\r\n} {\r\n const { timeout = 30000, retries = 0, autoRun = false } = options;\r\n\r\n if (typeof promiseFactory !== \"function\") {\r\n throw new TypeError(\"[nixAsync] promiseFactory must be a function\");\r\n }\r\n\r\n const data = nixState<T | null>(null);\r\n const error = nixState<Error | null>(null);\r\n const loading = nixState<boolean>(false);\r\n\r\n let active = true;\r\n let controller: AbortController | null = null;\r\n let callId = 0;\r\n let timeoutId: NodeJS.Timeout | null = null;\r\n let retryCount = 0;\r\n\r\n const cleanup = (): void => {\r\n active = false;\r\n if (controller) {\r\n controller.abort();\r\n controller = null;\r\n }\r\n if (timeoutId) {\r\n clearTimeout(timeoutId);\r\n timeoutId = null;\r\n }\r\n callId = 0;\r\n retryCount = 0;\r\n };\r\n\r\n const run = async (): Promise<void> => {\r\n if (!active) {\r\n console.warn(\"[nixAsync] Attempted to run on destroyed async hook\");\r\n return;\r\n }\r\n\r\n // Cancel previous request\r\n if (controller) {\r\n controller.abort();\r\n }\r\n if (timeoutId) {\r\n clearTimeout(timeoutId);\r\n }\r\n\r\n controller = new AbortController();\r\n const signal = controller.signal;\r\n const currentCallId = ++callId;\r\n retryCount = 0;\r\n\r\n loading.value = true;\r\n error.value = null;\r\n\r\n // Set timeout\r\n if (timeout > 0) {\r\n timeoutId = setTimeout(() => {\r\n if (controller && currentCallId === callId) {\r\n controller.abort();\r\n if (active && currentCallId === callId) {\r\n error.value = new Error(`Request timeout after ${timeout}ms`);\r\n loading.value = false;\r\n }\r\n }\r\n }, timeout);\r\n }\r\n\r\n try {\r\n const result = await promiseFactory(signal);\r\n\r\n // Check if this is still the current call and component is active\r\n if (!active || currentCallId !== callId || signal.aborted) {\r\n return;\r\n }\r\n\r\n data.value = result;\r\n retryCount = 0;\r\n } catch (e: unknown) {\r\n // Check if this is still the current call and component is active\r\n if (!active || currentCallId !== callId) {\r\n return;\r\n }\r\n\r\n // Don't set error if aborted (user cancelled)\r\n if (signal.aborted) {\r\n return;\r\n }\r\n\r\n const errorInstance = e instanceof Error ? e : new Error(String(e));\r\n\r\n // Retry logic\r\n if (retryCount < retries && active && currentCallId === callId) {\r\n retryCount++;\r\n console.warn(\r\n `[nixAsync] Retrying (${retryCount}/${retries}):`,\r\n errorInstance.message\r\n );\r\n // Exponential backoff: 1s, 2s, 4s, etc.\r\n const retryDelay = Math.min(1000 * Math.pow(2, retryCount - 1), 10000);\r\n setTimeout(() => {\r\n if (active && currentCallId === callId) {\r\n run();\r\n }\r\n }, retryDelay);\r\n return;\r\n }\r\n\r\n error.value = errorInstance;\r\n } finally {\r\n if (timeoutId) {\r\n clearTimeout(timeoutId);\r\n timeoutId = null;\r\n }\r\n\r\n if (active && currentCallId === callId && !signal.aborted) {\r\n loading.value = false;\r\n }\r\n }\r\n };\r\n\r\n const cancel = (): void => {\r\n if (controller) {\r\n controller.abort();\r\n }\r\n if (timeoutId) {\r\n clearTimeout(timeoutId);\r\n timeoutId = null;\r\n }\r\n loading.value = false;\r\n retryCount = 0;\r\n };\r\n\r\n const getCallId = (): number => callId;\r\n\r\n // Auto-run if requested\r\n if (autoRun) {\r\n // Use setTimeout to avoid running during component initialization\r\n setTimeout(() => {\r\n if (active) run();\r\n }, 0);\r\n }\r\n\r\n return { data, error, loading, run, cancel, cleanup, getCallId };\r\n}\r\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"nixAsyncCache.d.ts","sourceRoot":"","sources":["../../hooks/nixAsyncCache.ts"],"names":[],"mappings":"AAoEA,wBAAgB,cAAc,CAC5B,GAAG,EAAE,GAAG,EACR,cAAc,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,EAClC,OAAO,GAAE;IACP,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CAChC,GACL;IACD,IAAI,EAAE;QAAE,KAAK,EAAE,GAAG,CAAA;KAAE,CAAC;IACrB,KAAK,EAAE;QAAE,KAAK,EAAE,GAAG,CAAA;KAAE,CAAC;IACtB,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;IAC5B,GAAG,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB,CA6IA"}
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../hooks/nixAsyncCache.ts"],
4
- "sourcesContent": ["/* MIT License\r\n\r\n* Copyright (c) 2026 Resty Gonzales\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n* SOFTWARE.\r\n */\r\nimport { nixState } from \"./nixState\";\r\n\r\nconst asyncCache: Map<\r\n any,\r\n {\r\n data?: any;\r\n promise?: Promise<any>;\r\n timestamp?: number;\r\n ttl?: number;\r\n }\r\n> = new Map();\r\n\r\n// Cache cleanup to prevent memory leaks\r\nconst CACHE_CLEANUP_INTERVAL = 60000; // 1 minute\r\nlet cacheCleanupTimer: NodeJS.Timeout | null = null;\r\n\r\nconst startCacheCleanup = () => {\r\n if (cacheCleanupTimer) return;\r\n\r\n cacheCleanupTimer = setInterval(() => {\r\n const now = Date.now();\r\n const entries = Array.from(asyncCache.entries());\r\n\r\n for (const [key, entry] of entries) {\r\n if (entry.timestamp && entry.ttl && now - entry.timestamp > entry.ttl) {\r\n asyncCache.delete(key);\r\n }\r\n }\r\n\r\n // If cache is empty, stop cleanup timer\r\n if (asyncCache.size === 0 && cacheCleanupTimer) {\r\n clearInterval(cacheCleanupTimer);\r\n cacheCleanupTimer = null;\r\n }\r\n }, CACHE_CLEANUP_INTERVAL);\r\n};\r\n\r\n/**\r\n * Cached async hook with enhanced security and memory management.\r\n *\r\n * @param {any} key - Cache key (must be serializable)\r\n * @param {() => Promise<any>} promiseFactory - Function that returns a promise\r\n * @param {object} options - Configuration options\r\n * @returns {object} Reactive state object with data, error, loading, and control methods\r\n */\r\n\r\nexport function nixAsyncCached(\r\n key: any,\r\n promiseFactory: () => Promise<any>,\r\n options: {\r\n ttl?: number; // Time to live in ms\r\n maxCacheSize?: number;\r\n validateKey?: (key: any) => boolean;\r\n } = {}\r\n): {\r\n data: { value: any };\r\n error: { value: any };\r\n loading: { value: boolean };\r\n run: () => Promise<void>;\r\n cancel: () => void;\r\n clearCache: () => void;\r\n} {\r\n // Input validation\r\n if (!promiseFactory || typeof promiseFactory !== \"function\") {\r\n throw new Error(\"[nixAsyncCache] promiseFactory must be a function\");\r\n }\r\n\r\n // Validate cache key\r\n if (key == null) {\r\n throw new Error(\"[nixAsyncCache] Key cannot be null or undefined\");\r\n }\r\n\r\n if (options.validateKey && !options.validateKey(key)) {\r\n throw new Error(\"[nixAsyncCache] Invalid cache key\");\r\n }\r\n\r\n const { ttl = 300000, maxCacheSize = 100 } = options; // 5 min default TTL\r\n\r\n // Enforce cache size limits to prevent memory attacks\r\n if (asyncCache.size >= maxCacheSize) {\r\n // Remove oldest entries\r\n const entries = Array.from(asyncCache.entries());\r\n const entriesToRemove = Math.max(1, Math.floor(maxCacheSize * 0.1)); // Remove 10%\r\n\r\n for (let i = 0; i < entriesToRemove; i++) {\r\n const entry = entries[i];\r\n if (entry) {\r\n asyncCache.delete(entry[0]);\r\n }\r\n }\r\n }\r\n\r\n const data = nixState(null) as { value: any };\r\n const error = nixState(null) as { value: any };\r\n const loading = nixState(false) as { value: boolean };\r\n\r\n let active: boolean = true;\r\n let abortController: AbortController | null = null;\r\n\r\n startCacheCleanup();\r\n\r\n const run = async (): Promise<void> => {\r\n if (!active) return;\r\n\r\n // Cancel previous request if still running\r\n if (abortController) {\r\n abortController.abort();\r\n }\r\n\r\n abortController = new AbortController();\r\n loading.value = true;\r\n error.value = null;\r\n\r\n try {\r\n // Cache hit with resolved data\r\n if (asyncCache.has(key)) {\r\n const cached = asyncCache.get(key)!;\r\n const now = Date.now();\r\n\r\n // Check TTL\r\n if (cached.timestamp && now - cached.timestamp > ttl) {\r\n asyncCache.delete(key);\r\n } else if (cached.data !== undefined) {\r\n data.value = cached.data;\r\n loading.value = false;\r\n return;\r\n }\r\n\r\n // Deduping: reuse in-flight promise if still valid\r\n if (cached.promise) {\r\n try {\r\n const result = await cached.promise;\r\n if (!active || abortController?.signal.aborted) return;\r\n data.value = result;\r\n loading.value = false;\r\n return;\r\n } catch (e) {\r\n if (!active || abortController?.signal.aborted) return;\r\n error.value = e;\r\n loading.value = false;\r\n return;\r\n }\r\n }\r\n }\r\n\r\n // Cache miss - create new promise\r\n const promise = Promise.resolve().then(() => {\r\n if (abortController?.signal.aborted) {\r\n throw new Error(\"Request was aborted\");\r\n }\r\n return promiseFactory();\r\n });\r\n\r\n asyncCache.set(key, {\r\n promise,\r\n timestamp: Date.now(),\r\n ttl,\r\n });\r\n\r\n const result = await promise;\r\n\r\n if (!active || abortController?.signal.aborted) return;\r\n\r\n // Cache successful result\r\n asyncCache.set(key, {\r\n data: result,\r\n timestamp: Date.now(),\r\n ttl,\r\n });\r\n\r\n data.value = result;\r\n } catch (e) {\r\n // Remove failed promise from cache\r\n if (asyncCache.has(key)) {\r\n const cached = asyncCache.get(key)!;\r\n if (cached.promise && !cached.data) {\r\n asyncCache.delete(key);\r\n }\r\n }\r\n\r\n if (!active || abortController?.signal.aborted) return;\r\n error.value = e;\r\n } finally {\r\n if (active && !abortController?.signal.aborted) {\r\n loading.value = false;\r\n }\r\n }\r\n };\r\n\r\n const cancel = (): void => {\r\n active = false;\r\n if (abortController) {\r\n abortController.abort();\r\n abortController = null;\r\n }\r\n };\r\n\r\n const clearCache = (): void => {\r\n asyncCache.delete(key);\r\n };\r\n\r\n return { data, error, loading, run, cancel, clearCache };\r\n}\r\n"],
5
- "mappings": "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",
6
- "names": ["result"]
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"nixAsyncDebounce.d.ts","sourceRoot":"","sources":["../../hooks/nixAsyncDebounce.ts"],"names":[],"mappings":"AA4CA,MAAM,WAAW,uBAAuB;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,wBAAgB,gBAAgB,CAC9B,cAAc,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,EAClC,OAAO,GAAE,uBAA4B,GACpC;IACD,IAAI,EAAE;QAAE,KAAK,EAAE,GAAG,CAAA;KAAE,CAAC;IACrB,KAAK,EAAE;QAAE,KAAK,EAAE,GAAG,CAAA;KAAE,CAAC;IACtB,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;IAC5B,GAAG,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB,CA8FA"}
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../hooks/nixAsyncDebounce.ts"],
4
- "sourcesContent": ["/* MIT License\r\n\r\n* Copyright (c) 2026 Resty Gonzales\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n* SOFTWARE.\r\n */\r\nimport { nixState } from \"./nixState\";\r\n\r\n/**\r\n * Debounced and cancellable async data fetcher with caching and deduping.\r\n *\r\n * @param {() => Promise<any>} promiseFactory - Async function that returns a promise.\r\n * @param {Object} [options={}] - Options for debounce, caching, and abort.\r\n * @param {number} [options.delay=300] - Debounce delay in ms.\r\n * @param {boolean} [options.leading=false] - Run on leading edge.\r\n * @param {boolean} [options.trailing=true] - Run on trailing edge.\r\n * @param {number} [options.maxWait] - Max wait time before forced invocation.\r\n * @param {boolean} [options.cache=true] - Enable caching of last result.\r\n * @param {AbortSignal} [options.signal] - Optional AbortSignal to cancel request.\r\n * @returns {Object} { data, error, loading, run, cancel }\r\n *\r\n * @example\r\n * const controller = new AbortController();\r\n * const { data, error, loading, run, cancel } = nixAsyncDebounce(\r\n * () => fetch('/api/data').then(r => r.json()),\r\n * { delay: 500, maxWait: 2000, leading: true, signal: controller.signal }\r\n * );\r\n */\r\nexport interface NixAsyncDebounceOptions {\r\n delay?: number;\r\n leading?: boolean;\r\n trailing?: boolean;\r\n maxWait?: number;\r\n cache?: boolean;\r\n signal?: AbortSignal;\r\n}\r\n\r\nexport function nixAsyncDebounce(\r\n promiseFactory: () => Promise<any>,\r\n options: NixAsyncDebounceOptions = {}\r\n): {\r\n data: { value: any };\r\n error: { value: any };\r\n loading: { value: boolean };\r\n run: () => void | Promise<any>;\r\n cancel: () => void;\r\n} {\r\n const data = nixState(null) as { value: any };\r\n const error = nixState(null) as { value: any };\r\n const loading = nixState(false) as { value: boolean };\r\n\r\n const {\r\n delay = 300,\r\n leading = false,\r\n trailing = true,\r\n maxWait,\r\n cache = true,\r\n signal,\r\n } = options;\r\n\r\n let lastResult: any = null;\r\n let lastError: any = null;\r\n let timerId: ReturnType<typeof setTimeout> | null = null;\r\n let lastInvokeTime: number = 0;\r\n let pendingPromise: Promise<any> | null = null;\r\n\r\n const invoke = async (): Promise<any> => {\r\n if (cache && lastResult !== null) {\r\n data.value = lastResult;\r\n error.value = lastError;\r\n loading.value = false;\r\n return lastResult;\r\n }\r\n\r\n loading.value = true;\r\n error.value = null;\r\n\r\n const abortController = new AbortController();\r\n if (signal) {\r\n signal.addEventListener(\"abort\", () => {\r\n abortController.abort();\r\n cancel();\r\n });\r\n }\r\n\r\n pendingPromise = promiseFactory();\r\n\r\n try {\r\n const result = await pendingPromise;\r\n lastResult = result;\r\n data.value = result;\r\n return result;\r\n } catch (e: any) {\r\n if (e.name !== \"AbortError\") {\r\n lastError = e;\r\n error.value = e;\r\n }\r\n throw e;\r\n } finally {\r\n loading.value = false;\r\n pendingPromise = null;\r\n lastInvokeTime = Date.now();\r\n }\r\n };\r\n\r\n const run = (): void | Promise<any> => {\r\n const now = Date.now();\r\n const timeSinceLastInvoke = now - lastInvokeTime;\r\n const remainingTime = delay - timeSinceLastInvoke;\r\n\r\n const shouldInvokeLeading = leading && !timerId;\r\n\r\n if (maxWait !== undefined && timeSinceLastInvoke >= maxWait) {\r\n if (timerId) clearTimeout(timerId);\r\n timerId = null;\r\n return invoke();\r\n }\r\n\r\n if (timerId) clearTimeout(timerId);\r\n\r\n if (shouldInvokeLeading) return invoke();\r\n\r\n if (trailing) {\r\n timerId = setTimeout(\r\n () => {\r\n timerId = null;\r\n invoke();\r\n },\r\n remainingTime > 0 ? remainingTime : delay\r\n );\r\n }\r\n };\r\n\r\n const cancel = (): void => {\r\n if (timerId) clearTimeout(timerId);\r\n timerId = null;\r\n pendingPromise = null;\r\n };\r\n\r\n return { data, error, loading, run, cancel };\r\n}\r\n"],
5
- "mappings": ";;AAsBA,SAAS,gBAAgB;AA+BlB,SAAS,iBACd,gBACA,UAAmC,CAAC,GAOpC;AACA,QAAM,OAAO,SAAS,IAAI;AAC1B,QAAM,QAAQ,SAAS,IAAI;AAC3B,QAAM,UAAU,SAAS,KAAK;AAE9B,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,WAAW;AAAA,IACX;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,EACF,IAAI;AAEJ,MAAI,aAAkB;AACtB,MAAI,YAAiB;AACrB,MAAI,UAAgD;AACpD,MAAI,iBAAyB;AAC7B,MAAI,iBAAsC;AAE1C,QAAM,SAAS,mCAA0B;AACvC,QAAI,SAAS,eAAe,MAAM;AAChC,WAAK,QAAQ;AACb,YAAM,QAAQ;AACd,cAAQ,QAAQ;AAChB,aAAO;AAAA,IACT;AAEA,YAAQ,QAAQ;AAChB,UAAM,QAAQ;AAEd,UAAM,kBAAkB,IAAI,gBAAgB;AAC5C,QAAI,QAAQ;AACV,aAAO,iBAAiB,SAAS,MAAM;AACrC,wBAAgB,MAAM;AACtB,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAEA,qBAAiB,eAAe;AAEhC,QAAI;AACF,YAAM,SAAS,MAAM;AACrB,mBAAa;AACb,WAAK,QAAQ;AACb,aAAO;AAAA,IACT,SAAS,GAAQ;AACf,UAAI,EAAE,SAAS,cAAc;AAC3B,oBAAY;AACZ,cAAM,QAAQ;AAAA,MAChB;AACA,YAAM;AAAA,IACR,UAAE;AACA,cAAQ,QAAQ;AAChB,uBAAiB;AACjB,uBAAiB,KAAK,IAAI;AAAA,IAC5B;AAAA,EACF,GArCe;AAuCf,QAAM,MAAM,6BAA2B;AACrC,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,sBAAsB,MAAM;AAClC,UAAM,gBAAgB,QAAQ;AAE9B,UAAM,sBAAsB,WAAW,CAAC;AAExC,QAAI,YAAY,UAAa,uBAAuB,SAAS;AAC3D,UAAI,QAAS,cAAa,OAAO;AACjC,gBAAU;AACV,aAAO,OAAO;AAAA,IAChB;AAEA,QAAI,QAAS,cAAa,OAAO;AAEjC,QAAI,oBAAqB,QAAO,OAAO;AAEvC,QAAI,UAAU;AACZ,gBAAU;AAAA,QACR,MAAM;AACJ,oBAAU;AACV,iBAAO;AAAA,QACT;AAAA,QACA,gBAAgB,IAAI,gBAAgB;AAAA,MACtC;AAAA,IACF;AAAA,EACF,GA1BY;AA4BZ,QAAM,SAAS,6BAAY;AACzB,QAAI,QAAS,cAAa,OAAO;AACjC,cAAU;AACV,qBAAiB;AAAA,EACnB,GAJe;AAMf,SAAO,EAAE,MAAM,OAAO,SAAS,KAAK,OAAO;AAC7C;AAvGgB;",
6
- "names": []
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"nixAsyncQuery.d.ts","sourceRoot":"","sources":["../../hooks/nixAsyncQuery.ts"],"names":[],"mappings":"AAsEA,wBAAgB,aAAa,CAAC,CAAC,EAC7B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,EAC5C,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7B;IACD,IAAI,EAAE;QAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAAA;KAAE,CAAC;IAC1B,KAAK,EAAE;QAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;KAAE,CAAC;IAC/B,OAAO,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;IAC5B,GAAG,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB,CA+FA"}
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../hooks/nixAsyncQuery.ts"],
4
- "sourcesContent": ["/* MIT License\r\n\r\n* Copyright (c) 2026 Resty Gonzales\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n* SOFTWARE.\r\n */\r\nimport { nixState } from \"./nixState\";\r\n\r\n/**\r\n * Global async cache.\r\n * key -> {\r\n * data?: any,\r\n * error?: Error,\r\n * promise?: Promise<any>,\r\n * controller?: AbortController,\r\n * timestamp?: number\r\n * }\r\n */\r\nconst asyncCache: Map<\r\n string,\r\n {\r\n data?: any;\r\n error?: Error;\r\n promise?: Promise<any>;\r\n controller?: AbortController;\r\n timestamp?: number;\r\n }\r\n> = new Map();\r\n\r\n/**\r\n * Unified async query helper with:\r\n * - AbortController cancellation\r\n * - Request deduping\r\n * - Shared caching\r\n *\r\n * @template T\r\n * @param {string} key\r\n * Unique cache key representing the request\r\n *\r\n * @param {(signal: AbortSignal) => Promise<T>} queryFn\r\n * Function that performs the async operation\r\n *\r\n * @param {{\r\n * ttl?: number\r\n * }} [options]\r\n *\r\n * @returns {{\r\n * data: { value: T | null },\r\n * error: { value: Error | null },\r\n * loading: { value: boolean },\r\n * run: () => Promise<void>,\r\n * cancel: () => void\r\n * }}\r\n */\r\nexport function nixAsyncQuery<T>(\r\n key: string,\r\n queryFn: (signal: AbortSignal) => Promise<T>,\r\n options: { ttl?: number } = {}\r\n): {\r\n data: { value: T | null };\r\n error: { value: Error | null };\r\n loading: { value: boolean };\r\n run: () => Promise<void>;\r\n cancel: () => void;\r\n} {\r\n const data = nixState(null) as { value: T | null };\r\n const error = nixState(null) as { value: Error | null };\r\n const loading = nixState(false) as { value: boolean };\r\n\r\n const ttl: number = options.ttl ?? 0;\r\n let active: boolean = true;\r\n let callId: number = 0;\r\n\r\n const run = async (): Promise<void> => {\r\n const id = ++callId;\r\n loading.value = true;\r\n error.value = null;\r\n\r\n const now = Date.now();\r\n const cached = asyncCache.get(key);\r\n\r\n // Serve fresh cached data\r\n if (\r\n cached?.data &&\r\n (!ttl ||\r\n (typeof cached.timestamp === \"number\" && now - cached.timestamp < ttl))\r\n ) {\r\n data.value = cached.data;\r\n loading.value = false;\r\n return;\r\n }\r\n\r\n // Deduping: reuse in-flight request\r\n if (cached?.promise) {\r\n try {\r\n const result = await cached.promise;\r\n if (!active || id !== callId) return;\r\n // Sanitize result before storing in state\r\n const safeResult =\r\n typeof result === \"object\" && result !== null\r\n ? JSON.parse(JSON.stringify(result))\r\n : result;\r\n data.value = safeResult;\r\n } catch (e: any) {\r\n if (!active || id !== callId) return;\r\n error.value = e instanceof Error ? e : new Error(String(e));\r\n } finally {\r\n if (active && id === callId) loading.value = false;\r\n }\r\n return;\r\n }\r\n\r\n // New request\r\n const controller = new AbortController();\r\n const promise = (async () => {\r\n try {\r\n const result = await queryFn(controller.signal);\r\n asyncCache.set(key, {\r\n data: result,\r\n timestamp: Date.now(),\r\n });\r\n return result;\r\n } catch (e) {\r\n asyncCache.delete(key);\r\n throw e instanceof Error ? e : new Error(String(e));\r\n }\r\n })();\r\n\r\n asyncCache.set(key, { promise, controller });\r\n\r\n try {\r\n const result = await promise;\r\n if (!active || id !== callId) return;\r\n // Sanitize result before storing in state\r\n const safeResult =\r\n typeof result === \"object\" && result !== null\r\n ? JSON.parse(JSON.stringify(result))\r\n : result;\r\n data.value = safeResult;\r\n } catch (e: any) {\r\n if (!active || id !== callId) return;\r\n error.value = e instanceof Error ? e : new Error(String(e));\r\n } finally {\r\n if (active && id === callId) loading.value = false;\r\n }\r\n };\r\n\r\n /**\r\n * Cancels in-flight request and prevents state updates.\r\n */\r\n const cancel = (): void => {\r\n active = false;\r\n const cached = asyncCache.get(key);\r\n if (cached?.controller) {\r\n cached.controller.abort();\r\n }\r\n };\r\n\r\n return { data, error, loading, run, cancel };\r\n}\r\n"],
5
- "mappings": ";;AAsBA,SAAS,gBAAgB;AAYzB,MAAM,aASF,oBAAI,IAAI;AA2BL,SAAS,cACd,KACA,SACA,UAA4B,CAAC,GAO7B;AACA,QAAM,OAAO,SAAS,IAAI;AAC1B,QAAM,QAAQ,SAAS,IAAI;AAC3B,QAAM,UAAU,SAAS,KAAK;AAE9B,QAAM,MAAc,QAAQ,OAAO;AACnC,MAAI,SAAkB;AACtB,MAAI,SAAiB;AAErB,QAAM,MAAM,mCAA2B;AACrC,UAAM,KAAK,EAAE;AACb,YAAQ,QAAQ;AAChB,UAAM,QAAQ;AAEd,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,SAAS,WAAW,IAAI,GAAG;AAGjC,QACE,QAAQ,SACP,CAAC,OACC,OAAO,OAAO,cAAc,YAAY,MAAM,OAAO,YAAY,MACpE;AACA,WAAK,QAAQ,OAAO;AACpB,cAAQ,QAAQ;AAChB;AAAA,IACF;AAGA,QAAI,QAAQ,SAAS;AACnB,UAAI;AACF,cAAM,SAAS,MAAM,OAAO;AAC5B,YAAI,CAAC,UAAU,OAAO,OAAQ;AAE9B,cAAM,aACJ,OAAO,WAAW,YAAY,WAAW,OACrC,KAAK,MAAM,KAAK,UAAU,MAAM,CAAC,IACjC;AACN,aAAK,QAAQ;AAAA,MACf,SAAS,GAAQ;AACf,YAAI,CAAC,UAAU,OAAO,OAAQ;AAC9B,cAAM,QAAQ,aAAa,QAAQ,IAAI,IAAI,MAAM,OAAO,CAAC,CAAC;AAAA,MAC5D,UAAE;AACA,YAAI,UAAU,OAAO,OAAQ,SAAQ,QAAQ;AAAA,MAC/C;AACA;AAAA,IACF;AAGA,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,WAAW,YAAY;AAC3B,UAAI;AACF,cAAM,SAAS,MAAM,QAAQ,WAAW,MAAM;AAC9C,mBAAW,IAAI,KAAK;AAAA,UAClB,MAAM;AAAA,UACN,WAAW,KAAK,IAAI;AAAA,QACtB,CAAC;AACD,eAAO;AAAA,MACT,SAAS,GAAG;AACV,mBAAW,OAAO,GAAG;AACrB,cAAM,aAAa,QAAQ,IAAI,IAAI,MAAM,OAAO,CAAC,CAAC;AAAA,MACpD;AAAA,IACF,GAAG;AAEH,eAAW,IAAI,KAAK,EAAE,SAAS,WAAW,CAAC;AAE3C,QAAI;AACF,YAAM,SAAS,MAAM;AACrB,UAAI,CAAC,UAAU,OAAO,OAAQ;AAE9B,YAAM,aACJ,OAAO,WAAW,YAAY,WAAW,OACrC,KAAK,MAAM,KAAK,UAAU,MAAM,CAAC,IACjC;AACN,WAAK,QAAQ;AAAA,IACf,SAAS,GAAQ;AACf,UAAI,CAAC,UAAU,OAAO,OAAQ;AAC9B,YAAM,QAAQ,aAAa,QAAQ,IAAI,IAAI,MAAM,OAAO,CAAC,CAAC;AAAA,IAC5D,UAAE;AACA,UAAI,UAAU,OAAO,OAAQ,SAAQ,QAAQ;AAAA,IAC/C;AAAA,EACF,GAxEY;AA6EZ,QAAM,SAAS,6BAAY;AACzB,aAAS;AACT,UAAM,SAAS,WAAW,IAAI,GAAG;AACjC,QAAI,QAAQ,YAAY;AACtB,aAAO,WAAW,MAAM;AAAA,IAC1B;AAAA,EACF,GANe;AAQf,SAAO,EAAE,MAAM,OAAO,SAAS,KAAK,OAAO;AAC7C;AAzGgB;",
6
- "names": []
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"nixCallback.d.ts","sourceRoot":"","sources":["../../hooks/nixCallback.ts"],"names":[],"mappings":"AAqDA,wBAAgB,WAAW,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAC3D,EAAE,EAAE,CAAC,EACL,IAAI,GAAE,GAAG,EAAO,GACf,CAAC,CAiCH"}
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../hooks/nixCallback.ts"],
4
- "sourcesContent": ["/* MIT License\r\n\r\n* Copyright (c) 2026 Resty Gonzales\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n* SOFTWARE.\r\n */\r\nimport { activeContext } from \"../context/context\";\r\n\r\n/**\r\n * Memoizes a callback function based on a dependency array.\r\n * Similar to React's useCallback.\r\n *\r\n * @param {Function} fn\r\n * Function to memoize. Should be pure and not mutate external state.\r\n *\r\n * @param {Array<any>} [deps=[]]\r\n * Dependency array. Callback identity changes only when deps change.\r\n *\r\n * @returns {Function}\r\n * Memoized callback function.\r\n *\r\n * @throws {Error}\r\n * If called outside of a component context.\r\n *\r\n * @example\r\n * const onClick = nixCallback(() => {\r\n * console.log(count.value);\r\n * }, [count.value]);\r\n *\r\n * @security\r\n * - Avoids JSON.stringify to prevent crashes on circular references\r\n * - Limits dependency array size to prevent performance abuse\r\n *\r\n * @memory\r\n * - Does not allocate large temporary strings\r\n * - Reuses function reference when deps are unchanged\r\n */\r\nexport function nixCallback<T extends (...args: any[]) => any>(\r\n fn: T,\r\n deps: any[] = []\r\n): T {\r\n const ctx = activeContext as {\r\n hookIndex: number;\r\n hooks: Array<{ value: T; deps: any[] } | undefined>;\r\n };\r\n if (!ctx) throw new Error(\"nixCallback() called outside component\");\r\n\r\n if (typeof fn !== \"function\") {\r\n console.error(\"[nixCallback] First argument must be a function\");\r\n return fn;\r\n }\r\n\r\n if (!Array.isArray(deps)) {\r\n console.error(\"[nixCallback] Second argument must be an array\");\r\n deps = [];\r\n }\r\n\r\n const MAX_DEPS = 100;\r\n if (deps.length > MAX_DEPS) {\r\n console.warn(\r\n `[nixCallback] Dependency array too large (${deps.length}). Limited to ${MAX_DEPS}.`\r\n );\r\n deps = deps.slice(0, MAX_DEPS);\r\n }\r\n\r\n const idx: number = ctx.hookIndex++;\r\n const prev: { value: T; deps: any[] } | undefined = ctx.hooks[idx];\r\n\r\n if (!prev || !shallowArrayEqual(prev.deps, deps)) {\r\n ctx.hooks[idx] = { value: fn, deps };\r\n }\r\n\r\n return ctx.hooks[idx]!.value;\r\n}\r\n\r\n/**\r\n * Shallow comparison for dependency arrays.\r\n *\r\n * @param {Array<any>} a\r\n * @param {Array<any>} b\r\n * @returns {boolean}\r\n */\r\nfunction shallowArrayEqual(a: any[], b: any[]): boolean {\r\n if (a.length !== b.length) return false;\r\n for (let i = 0; i < a.length; i++) {\r\n if (!Object.is(a[i], b[i])) return false;\r\n }\r\n return true;\r\n}\r\n"],
5
- "mappings": ";;AAsBA,SAAS,qBAAqB;AA+BvB,SAAS,YACd,IACA,OAAc,CAAC,GACZ;AACH,QAAM,MAAM;AAIZ,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,wCAAwC;AAElE,MAAI,OAAO,OAAO,YAAY;AAC5B,YAAQ,MAAM,iDAAiD;AAC/D,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;AACxB,YAAQ,MAAM,gDAAgD;AAC9D,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,WAAW;AACjB,MAAI,KAAK,SAAS,UAAU;AAC1B,YAAQ;AAAA,MACN,6CAA6C,KAAK,MAAM,iBAAiB,QAAQ;AAAA,IACnF;AACA,WAAO,KAAK,MAAM,GAAG,QAAQ;AAAA,EAC/B;AAEA,QAAM,MAAc,IAAI;AACxB,QAAM,OAA8C,IAAI,MAAM,GAAG;AAEjE,MAAI,CAAC,QAAQ,CAAC,kBAAkB,KAAK,MAAM,IAAI,GAAG;AAChD,QAAI,MAAM,GAAG,IAAI,EAAE,OAAO,IAAI,KAAK;AAAA,EACrC;AAEA,SAAO,IAAI,MAAM,GAAG,EAAG;AACzB;AApCgB;AA6ChB,SAAS,kBAAkB,GAAU,GAAmB;AACtD,MAAI,EAAE,WAAW,EAAE,OAAQ,QAAO;AAClC,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AACjC,QAAI,CAAC,OAAO,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAG,QAAO;AAAA,EACrC;AACA,SAAO;AACT;AANS;",
6
- "names": []
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"nixComputed.d.ts","sourceRoot":"","sources":["../../hooks/nixComputed.ts"],"names":[],"mappings":"AAuFA,wBAAgB,WAAW,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG;IAClD,KAAK,EAAE,CAAC,CAAC;IACT,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;IAClD,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,kBAAkB,EAAE,MAAM,MAAM,CAAC;IACjC,kBAAkB,EAAE,MAAM,MAAM,CAAC;IACjC,WAAW,EAAE,MAAM,OAAO,CAAC;IAC3B,iBAAiB,EAAE,MAAM,KAAK,CAAC;QAC7B,KAAK,EAAE,GAAG,CAAC;QACX,UAAU,EAAE,OAAO,CAAC;QACpB,UAAU,EAAE,OAAO,CAAC;KACrB,CAAC,CAAC;IACH,WAAW,EAAE,IAAI,CAAC;IAClB,WAAW,EAAE,IAAI,CAAC;CACnB,CA8LA"}
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../hooks/nixComputed.ts"],
4
- "sourcesContent": ["/* MIT License\r\n\r\n* Copyright (c) 2026 Resty Gonzales\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n* SOFTWARE.\r\n */\r\n/* ----------------------\r\n nixComputed - Computed/Derived State\r\n Memory Leaks & Security Issues Resolved\r\n---------------------- */\r\nimport { activeContext, setActiveContext } from \"../context/context\";\r\n\r\n/**\r\n * @template T\r\n * @typedef {Object} ComputedState\r\n * @property {T} value - Get the computed value (read-only)\r\n * @property {(fn: (value: T) => void) => (() => void)} subscribe - Subscribe to computed value changes\r\n * @property {() => void} cleanup - Cleanup all subscriptions and dependencies\r\n * @property {() => number} getSubscriberCount - Get number of active subscribers (debugging)\r\n * @property {() => number} getDependencyCount - Get number of tracked dependencies (debugging)\r\n * @property {() => boolean} isDestroyed - Check if computed state has been destroyed\r\n * @property {boolean} _isNixState - Internal flag (computed states behave like states)\r\n * @property {boolean} _isComputed - Internal flag to identify computed states\r\n */\r\n\r\n/**\r\n * Create a derived/computed state from other states.\r\n * Automatically tracks dependencies and updates when any dependency changes.\r\n *\r\n * @template T\r\n * @param {() => T} computeFn - Function that computes the derived value\r\n * @returns {ComputedState<T>} A reactive state object with the computed value\r\n *\r\n * @example\r\n * const count = nixState(5);\r\n * const doubled = nixComputed(() => count.value * 2);\r\n * console.log(doubled.value); // 10\r\n * count.value = 10;\r\n * console.log(doubled.value); // 20\r\n *\r\n * @example\r\n * // Multiple dependencies\r\n * const a = nixState(5);\r\n * const b = nixState(10);\r\n * const sum = nixComputed(() => a.value + b.value);\r\n * console.log(sum.value); // 15\r\n *\r\n * @example\r\n * // Conditional dependencies\r\n * const flag = nixState(true);\r\n * const x = nixState(1);\r\n * const y = nixState(2);\r\n * const result = nixComputed(() => flag.value ? x.value : y.value);\r\n *\r\n * @example\r\n * // With cleanup\r\n * const MyComponent = () => {\r\n * const count = nixState(0);\r\n * const doubled = nixComputed(() => count.value * 2);\r\n *\r\n * nixEffect(() => {\r\n * return () => {\r\n * doubled.cleanup();\r\n * count.cleanup();\r\n * };\r\n * }, []);\r\n * };\r\n *\r\n * @throws {Error} If called outside a component context\r\n * @throws {TypeError} If computeFn is not a function\r\n */\r\nexport function nixComputed<T>(computeFn: () => T): {\r\n value: T;\r\n subscribe: (fn: (value: T) => void) => () => void;\r\n cleanup: () => void;\r\n getSubscriberCount: () => number;\r\n getDependencyCount: () => number;\r\n isDestroyed: () => boolean;\r\n getDependencyInfo: () => Array<{\r\n state: any;\r\n hasCleanup: boolean;\r\n isComputed: boolean;\r\n }>;\r\n _isNixState: true;\r\n _isComputed: true;\r\n} {\r\n const ctx = activeContext as\r\n | (typeof activeContext & {\r\n hookIndex: number;\r\n hooks: Array<any>;\r\n stateCleanups?: Array<() => void>;\r\n })\r\n | undefined;\r\n if (!ctx) throw new Error(\"nixComputed() called outside component\");\r\n\r\n if (typeof computeFn !== \"function\") {\r\n throw new TypeError(\"[nixComputed] First argument must be a function\");\r\n }\r\n\r\n const idx = ctx.hookIndex++;\r\n if (!ctx.hooks[idx]) {\r\n const subscribers: Set<(value: T) => void> = new Set();\r\n const dependencies: Set<any> = new Set();\r\n const unsubscribers: Map<any, () => void> = new Map();\r\n let cachedValue: T;\r\n let isStale = true;\r\n let isDestroyed = false;\r\n let isComputing = false;\r\n\r\n function compute(): T {\r\n if (isDestroyed) return cachedValue;\r\n if (isComputing) {\r\n console.error(\"[nixComputed] Circular dependency detected\");\r\n return cachedValue;\r\n }\r\n isComputing = true;\r\n // Provide all required properties for ComponentContext type\r\n // Use type assertion for safety and future-proofing\r\n const trackingContext = {\r\n _accessedStates: new Set(),\r\n hookIndex: 0,\r\n hooks: [],\r\n _subscriptions: new Set(),\r\n _subscriptionCleanups: [],\r\n effects: [],\r\n cleanups: [],\r\n _vnode: null,\r\n version: 0,\r\n props: {},\r\n stateCleanups: [],\r\n parent: null,\r\n context: {},\r\n rerender: () => {},\r\n Component: null,\r\n _isMounted: false,\r\n _isRerendering: false,\r\n } as any; // Use 'as any' to satisfy ComponentContext type\r\n const prevContext = activeContext;\r\n try {\r\n setActiveContext(trackingContext);\r\n cachedValue = computeFn();\r\n const oldDeps = Array.from(dependencies);\r\n oldDeps.forEach((dep) => {\r\n if (!trackingContext._accessedStates.has(dep)) {\r\n if (unsubscribers.has(dep)) {\r\n try {\r\n unsubscribers.get(dep)!();\r\n } catch (e) {\r\n console.error(\r\n \"[nixComputed] Error unsubscribing from old dependency:\",\r\n e\r\n );\r\n }\r\n unsubscribers.delete(dep);\r\n }\r\n dependencies.delete(dep);\r\n }\r\n });\r\n trackingContext._accessedStates.forEach((state: any) => {\r\n if (!dependencies.has(state)) {\r\n const unsub = state.subscribe(() => {\r\n if (isDestroyed) return;\r\n\r\n isStale = true;\r\n // Get fresh value when dependency changes\r\n const newValue = s.value;\r\n const subsArray = Array.from(subscribers);\r\n subsArray.forEach((fn) => {\r\n try {\r\n fn(newValue);\r\n } catch (e) {\r\n console.error(\"[nixComputed] Subscriber error:\", e);\r\n subscribers.delete(fn);\r\n }\r\n });\r\n });\r\n unsubscribers.set(state, unsub);\r\n dependencies.add(state);\r\n }\r\n });\r\n isStale = false;\r\n } catch (err) {\r\n console.error(\"[nixComputed] Compute error:\", err);\r\n isStale = false;\r\n } finally {\r\n setActiveContext(prevContext);\r\n isComputing = false;\r\n }\r\n return cachedValue;\r\n }\r\n\r\n // All cleanup functionality is now part of the s object below\r\n\r\n const s = {\r\n get value(): T {\r\n if (isDestroyed) {\r\n console.warn(\"[nixComputed] Accessing destroyed computed state\");\r\n return cachedValue;\r\n }\r\n if (isStale) {\r\n compute();\r\n }\r\n if (activeContext && (activeContext as any)._accessedStates) {\r\n (activeContext as any)._accessedStates.add(s);\r\n }\r\n return cachedValue;\r\n },\r\n subscribe(fn: (value: T) => void): () => void {\r\n if (typeof fn !== \"function\") {\r\n console.error(\"[nixComputed] subscribe() requires a function\");\r\n return () => {};\r\n }\r\n if (isDestroyed) {\r\n console.warn(\r\n \"[nixComputed] Cannot subscribe to destroyed computed state\"\r\n );\r\n return () => {};\r\n }\r\n const MAX_SUBSCRIBERS = 1000;\r\n if (subscribers.size >= MAX_SUBSCRIBERS) {\r\n console.error(\"[nixComputed] Maximum subscriber limit reached\");\r\n return () => {};\r\n }\r\n subscribers.add(fn);\r\n return () => {\r\n subscribers.delete(fn);\r\n };\r\n },\r\n cleanup(): void {\r\n if (isDestroyed) return;\r\n isDestroyed = true;\r\n unsubscribers.forEach((unsub) => {\r\n try {\r\n unsub();\r\n } catch (e) {\r\n console.error(\"[nixComputed] Cleanup error:\", e);\r\n }\r\n });\r\n unsubscribers.clear();\r\n dependencies.clear();\r\n subscribers.clear();\r\n cachedValue = null as any as T;\r\n console.log(\"[nixComputed] Computed state cleaned up\");\r\n },\r\n getSubscriberCount(): number {\r\n return subscribers.size;\r\n },\r\n getDependencyCount(): number {\r\n return dependencies.size;\r\n },\r\n isDestroyed(): boolean {\r\n return isDestroyed;\r\n },\r\n getDependencyInfo(): Array<{\r\n state: any;\r\n hasCleanup: boolean;\r\n isComputed: boolean;\r\n }> {\r\n return Array.from(dependencies).map((state) => ({\r\n state,\r\n hasCleanup: unsubscribers.has(state),\r\n isComputed: !!state._isComputed,\r\n }));\r\n },\r\n _isNixState: true as const,\r\n _isComputed: true as const,\r\n };\r\n\r\n compute();\r\n ctx.hooks[idx] = s;\r\n if (ctx.stateCleanups) {\r\n ctx.stateCleanups.push(() => s.cleanup());\r\n }\r\n }\r\n return ctx.hooks[idx] as ReturnType<typeof nixComputed<T>>;\r\n}\r\n"],
5
- "mappings": "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",
6
- "names": ["compute"]
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"nixDebounce.d.ts","sourceRoot":"","sources":["../../hooks/nixDebounce.ts"],"names":[],"mappings":"AAiDA,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,IAAI,CAAC,CAClE,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KACnB,IAAI,CAAC,GAAG;IACX,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB,CAAC;AAEF,wBAAgB,WAAW,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAC3D,EAAE,EAAE,CAAC,EACL,KAAK,GAAE,MAAY,EACnB,OAAO,GAAE,kBAAuB,GAC/B,iBAAiB,CAAC,CAAC,CAAC,CA8DtB"}
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../hooks/nixDebounce.ts"],
4
- "sourcesContent": ["/* MIT License\r\n\r\n* Copyright (c) 2026 Resty Gonzales\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n* SOFTWARE.\r\n */\r\n/**\r\n * @fileoverview Debounce utility function with advanced options.\r\n * Supports leading/trailing edge invocation, maxWait, and AbortController.\r\n */\r\n\r\n/**\r\n * Debounce a function with options for leading, trailing, maxWait, and AbortController support.\r\n *\r\n * @param {Function} fn - The function to debounce\r\n * @param {number} [delay=300] - Delay in milliseconds\r\n * @param {Object} [options={}] - Debounce options\r\n * @param {boolean} [options.leading=false] - Invoke on the leading edge\r\n * @param {boolean} [options.trailing=true] - Invoke on the trailing edge\r\n * @param {number} [options.maxWait] - Maximum wait time before forced invocation\r\n * @param {AbortSignal} [options.signal] - Optional AbortSignal to cancel pending calls\r\n * @returns {Function} Debounced function with `.cancel()` method\r\n *\r\n * @example\r\n * const controller = new AbortController();\r\n * const debounced = nixDebounce(() => console.log('Hello'), 500, {\r\n * leading: true,\r\n * maxWait: 2000,\r\n * signal: controller.signal\r\n * });\r\n * debounced();\r\n * controller.abort(); // Cancel pending invocation\r\n */\r\nexport interface NixDebounceOptions {\r\n leading?: boolean;\r\n trailing?: boolean;\r\n maxWait?: number;\r\n signal?: AbortSignal;\r\n}\r\n\r\nexport type DebouncedFunction<T extends (...args: any[]) => any> = ((\r\n ...args: Parameters<T>\r\n) => void) & {\r\n cancel: () => void;\r\n};\r\n\r\nexport function nixDebounce<T extends (...args: any[]) => any>(\r\n fn: T,\r\n delay: number = 300,\r\n options: NixDebounceOptions = {}\r\n): DebouncedFunction<T> {\r\n let timerId: ReturnType<typeof setTimeout> | null = null;\r\n let lastInvokeTime = 0;\r\n let lastArgs: Parameters<T> | null = null;\r\n let lastThis: any = null;\r\n\r\n const { leading = false, trailing = true, maxWait, signal } = options;\r\n\r\n if (signal) {\r\n signal.addEventListener(\"abort\", () => {\r\n if (timerId) {\r\n clearTimeout(timerId);\r\n timerId = null;\r\n }\r\n lastArgs = null;\r\n lastThis = null;\r\n });\r\n }\r\n\r\n const invoke = () => {\r\n lastInvokeTime = Date.now();\r\n if (lastArgs) {\r\n fn.apply(lastThis, lastArgs);\r\n lastArgs = lastThis = null;\r\n }\r\n };\r\n\r\n const debounced = function (this: unknown, ...args: Parameters<T>) {\r\n const now = Date.now();\r\n lastArgs = args;\r\n lastThis = this;\r\n\r\n const shouldInvokeLeading = leading && !timerId;\r\n const timeSinceLastInvoke = now - lastInvokeTime;\r\n const remainingTime = delay - timeSinceLastInvoke;\r\n\r\n if (maxWait !== undefined && timeSinceLastInvoke >= maxWait) {\r\n if (timerId) clearTimeout(timerId);\r\n timerId = null;\r\n invoke();\r\n return;\r\n }\r\n\r\n if (timerId) clearTimeout(timerId);\r\n\r\n if (shouldInvokeLeading) {\r\n invoke();\r\n }\r\n\r\n if (trailing) {\r\n timerId = setTimeout(invoke, remainingTime > 0 ? remainingTime : delay);\r\n }\r\n } as DebouncedFunction<T>;\r\n\r\n debounced.cancel = () => {\r\n if (timerId) clearTimeout(timerId);\r\n timerId = null;\r\n lastArgs = null;\r\n lastThis = null;\r\n };\r\n\r\n return debounced;\r\n}\r\n"],
5
- "mappings": ";;AA8DO,SAAS,YACd,IACA,QAAgB,KAChB,UAA8B,CAAC,GACT;AACtB,MAAI,UAAgD;AACpD,MAAI,iBAAiB;AACrB,MAAI,WAAiC;AACrC,MAAI,WAAgB;AAEpB,QAAM,EAAE,UAAU,OAAO,WAAW,MAAM,SAAS,OAAO,IAAI;AAE9D,MAAI,QAAQ;AACV,WAAO,iBAAiB,SAAS,MAAM;AACrC,UAAI,SAAS;AACX,qBAAa,OAAO;AACpB,kBAAU;AAAA,MACZ;AACA,iBAAW;AACX,iBAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,6BAAM;AACnB,qBAAiB,KAAK,IAAI;AAC1B,QAAI,UAAU;AACZ,SAAG,MAAM,UAAU,QAAQ;AAC3B,iBAAW,WAAW;AAAA,IACxB;AAAA,EACF,GANe;AAQf,QAAM,YAAY,mCAA4B,MAAqB;AACjE,UAAM,MAAM,KAAK,IAAI;AACrB,eAAW;AACX,eAAW;AAEX,UAAM,sBAAsB,WAAW,CAAC;AACxC,UAAM,sBAAsB,MAAM;AAClC,UAAM,gBAAgB,QAAQ;AAE9B,QAAI,YAAY,UAAa,uBAAuB,SAAS;AAC3D,UAAI,QAAS,cAAa,OAAO;AACjC,gBAAU;AACV,aAAO;AACP;AAAA,IACF;AAEA,QAAI,QAAS,cAAa,OAAO;AAEjC,QAAI,qBAAqB;AACvB,aAAO;AAAA,IACT;AAEA,QAAI,UAAU;AACZ,gBAAU,WAAW,QAAQ,gBAAgB,IAAI,gBAAgB,KAAK;AAAA,IACxE;AAAA,EACF,GAzBkB;AA2BlB,YAAU,SAAS,MAAM;AACvB,QAAI,QAAS,cAAa,OAAO;AACjC,cAAU;AACV,eAAW;AACX,eAAW;AAAA,EACb;AAEA,SAAO;AACT;AAlEgB;",
6
- "names": []
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"nixEffect.d.ts","sourceRoot":"","sources":["../../hooks/nixEffect.ts"],"names":[],"mappings":"AAmEA,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,EACjC,IAAI,GAAE,GAAG,EAAO,GACf,IAAI,CAyDN;AAgCD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAErE;AAaD,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAUvE"}
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../hooks/nixEffect.ts"],
4
- "sourcesContent": ["/* MIT License\r\n\r\n* Copyright (c) 2026 Resty Gonzales\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n* SOFTWARE.\r\n */\r\n/* ----------------------\r\n nixEffect - Side Effects Hook\r\n Memory Leaks & Security Issues Resolved\r\n---------------------- */\r\nimport { activeContext } from \"../context/context\";\r\n\r\n/**\r\n * Execute side effects in a component with automatic cleanup and security enhancements.\r\n * Similar to React's useEffect but with enhanced security and memory leak prevention.\r\n *\r\n * @param {() => (void | (() => void))} effect - Effect function, optionally returns cleanup function\r\n * @param {Array<any>} [deps=[]] - Dependency array. Effect re-runs when dependencies change.\r\n * @param {object} [options={}] - Configuration options\r\n *\r\n * @example\r\n * // Run once on mount\r\n * nixEffect(() => {\r\n * console.log('Component mounted');\r\n * return () => console.log('Component unmounted');\r\n * }, []);\r\n *\r\n * @example\r\n * // Run when count changes with timeout\r\n * const count = nixState(0);\r\n * nixEffect(() => {\r\n * console.log('Count is:', count.value);\r\n * }, [count.value], { timeout: 5000 });\r\n *\r\n * @example\r\n * // Timer with cleanup\r\n * nixEffect(() => {\r\n * const timer = setInterval(() => console.log('tick'), 1000);\r\n * return () => clearInterval(timer);\r\n * }, []);\r\n *\r\n * @example\r\n * // Event listener with cleanup\r\n * nixEffect(() => {\r\n * const handler = (e) => console.log('clicked', e);\r\n * document.addEventListener('click', handler);\r\n * return () => document.removeEventListener('click', handler);\r\n * }, []);\r\n *\r\n * @throws {Error} If called outside a component context\r\n */\r\nexport function nixEffect(\r\n effect: () => void | (() => void),\r\n deps: any[] = []\r\n): void {\r\n const ctx = activeContext as\r\n | (typeof activeContext & {\r\n hookIndex: number;\r\n hooks: Array<any>;\r\n cleanups?: Array<() => void>;\r\n })\r\n | undefined;\r\n if (!ctx) throw new Error(\"nixEffect() called outside component\");\r\n\r\n if (typeof effect !== \"function\") {\r\n console.error(\"[nixEffect] First argument must be a function\");\r\n return;\r\n }\r\n if (!Array.isArray(deps)) {\r\n console.error(\"[nixEffect] Second argument must be an array\");\r\n deps = [];\r\n }\r\n const MAX_DEPS = 100;\r\n if (deps.length > MAX_DEPS) {\r\n console.warn(\r\n `[nixEffect] Dependency array too large (${deps.length}). Limited to ${MAX_DEPS}.`\r\n );\r\n deps = deps.slice(0, MAX_DEPS);\r\n }\r\n const idx = ctx.hookIndex++;\r\n const prev = ctx.hooks[idx];\r\n const hasChanged = !prev || !shallowArrayEqual(prev.deps, deps);\r\n if (hasChanged) {\r\n if (prev?.cleanup) {\r\n try {\r\n if (typeof prev.cleanup === \"function\") {\r\n prev.cleanup();\r\n }\r\n } catch (err) {\r\n console.error(\"[nixEffect] Cleanup error:\", err);\r\n }\r\n }\r\n let cleanup: void | (() => void);\r\n try {\r\n cleanup = effect();\r\n if (cleanup !== undefined && typeof cleanup !== \"function\") {\r\n console.warn(\r\n \"[nixEffect] Effect should return undefined or a cleanup function\"\r\n );\r\n cleanup = undefined;\r\n }\r\n } catch (err) {\r\n console.error(\"[nixEffect] Effect error:\", err);\r\n cleanup = undefined;\r\n }\r\n ctx.hooks[idx] = { deps, cleanup };\r\n if (cleanup && typeof cleanup === \"function\") {\r\n if (!ctx.cleanups) ctx.cleanups = [];\r\n ctx.cleanups.push(cleanup);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Shallow comparison of two arrays for dependency checking.\r\n * More reliable and secure than JSON.stringify.\r\n *\r\n * @param {Array<any>} arr1 - First array\r\n * @param {Array<any>} arr2 - Second array\r\n * @returns {boolean} True if arrays are shallowly equal\r\n */\r\nfunction shallowArrayEqual(arr1: any[], arr2: any[]): boolean {\r\n if (arr1.length !== arr2.length) return false;\r\n for (let i = 0; i < arr1.length; i++) {\r\n if (!Object.is(arr1[i], arr2[i])) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n}\r\n\r\n/**\r\n * Run an effect only once on component mount.\r\n * Convenience wrapper around nixEffect.\r\n *\r\n * @param {() => (void | (() => void))} effect - Effect function\r\n *\r\n * @example\r\n * nixEffectOnce(() => {\r\n * console.log('Mounted');\r\n * return () => console.log('Unmounted');\r\n * });\r\n */\r\nexport function nixEffectOnce(effect: () => void | (() => void)): void {\r\n return nixEffect(effect, []);\r\n}\r\n\r\n/**\r\n * Run an effect every time the component renders.\r\n * Use with caution - can cause performance issues.\r\n *\r\n * @param {() => (void | (() => void))} effect - Effect function\r\n *\r\n * @example\r\n * nixEffectAlways(() => {\r\n * console.log('Component rendered');\r\n * });\r\n */\r\nexport function nixEffectAlways(effect: () => void | (() => void)): void {\r\n const ctx = activeContext as\r\n | (typeof activeContext & { version: any })\r\n | undefined;\r\n if (!ctx) throw new Error(\"nixEffectAlways() called outside component\");\r\n if (typeof effect !== \"function\") {\r\n console.error(\"[nixEffectAlways] Argument must be a function\");\r\n return;\r\n }\r\n return nixEffect(effect, [ctx.version]);\r\n}\r\n"],
5
- "mappings": ";;AA0BA,SAAS,qBAAqB;AAyCvB,SAAS,UACd,QACA,OAAc,CAAC,GACT;AACN,QAAM,MAAM;AAOZ,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,sCAAsC;AAEhE,MAAI,OAAO,WAAW,YAAY;AAChC,YAAQ,MAAM,+CAA+C;AAC7D;AAAA,EACF;AACA,MAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;AACxB,YAAQ,MAAM,8CAA8C;AAC5D,WAAO,CAAC;AAAA,EACV;AACA,QAAM,WAAW;AACjB,MAAI,KAAK,SAAS,UAAU;AAC1B,YAAQ;AAAA,MACN,2CAA2C,KAAK,MAAM,iBAAiB,QAAQ;AAAA,IACjF;AACA,WAAO,KAAK,MAAM,GAAG,QAAQ;AAAA,EAC/B;AACA,QAAM,MAAM,IAAI;AAChB,QAAM,OAAO,IAAI,MAAM,GAAG;AAC1B,QAAM,aAAa,CAAC,QAAQ,CAAC,kBAAkB,KAAK,MAAM,IAAI;AAC9D,MAAI,YAAY;AACd,QAAI,MAAM,SAAS;AACjB,UAAI;AACF,YAAI,OAAO,KAAK,YAAY,YAAY;AACtC,eAAK,QAAQ;AAAA,QACf;AAAA,MACF,SAAS,KAAK;AACZ,gBAAQ,MAAM,8BAA8B,GAAG;AAAA,MACjD;AAAA,IACF;AACA,QAAI;AACJ,QAAI;AACF,gBAAU,OAAO;AACjB,UAAI,YAAY,UAAa,OAAO,YAAY,YAAY;AAC1D,gBAAQ;AAAA,UACN;AAAA,QACF;AACA,kBAAU;AAAA,MACZ;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,MAAM,6BAA6B,GAAG;AAC9C,gBAAU;AAAA,IACZ;AACA,QAAI,MAAM,GAAG,IAAI,EAAE,MAAM,QAAQ;AACjC,QAAI,WAAW,OAAO,YAAY,YAAY;AAC5C,UAAI,CAAC,IAAI,SAAU,KAAI,WAAW,CAAC;AACnC,UAAI,SAAS,KAAK,OAAO;AAAA,IAC3B;AAAA,EACF;AACF;AA5DgB;AAsEhB,SAAS,kBAAkB,MAAa,MAAsB;AAC5D,MAAI,KAAK,WAAW,KAAK,OAAQ,QAAO;AACxC,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,QAAI,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG;AAChC,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AARS;AAsBF,SAAS,cAAc,QAAyC;AACrE,SAAO,UAAU,QAAQ,CAAC,CAAC;AAC7B;AAFgB;AAeT,SAAS,gBAAgB,QAAyC;AACvE,QAAM,MAAM;AAGZ,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,4CAA4C;AACtE,MAAI,OAAO,WAAW,YAAY;AAChC,YAAQ,MAAM,+CAA+C;AAC7D;AAAA,EACF;AACA,SAAO,UAAU,QAAQ,CAAC,IAAI,OAAO,CAAC;AACxC;AAVgB;",
6
- "names": []
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"nixFor.d.ts","sourceRoot":"","sources":["../../hooks/nixFor.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAErC,UAAU,aAAa,CAAC,CAAC;IACrB,KAAK,EAAE,CAAC,CAAC;IACT,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CACvD;AAED,UAAU,QAAQ,CAAC,CAAC;IAChB,IAAI,EAAE,CAAC,EAAE,GAAG,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC;IAC/B,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,EAAE,CAAC;CAC1F;AAkBD,wBAAgB,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,CAoDhD"}
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../hooks/nixFor.ts"],
4
- "sourcesContent": ["/* MIT License\r\n* Copyright (c) 2026 Resty Gonzales\r\n*/\r\n\r\nimport { Fragment } from \"../runtime\";\r\nimport { VNode } from \"../types/fnx\";\r\n\r\ninterface ReactiveState<T> {\r\n value: T;\r\n _isNixState: boolean;\r\n subscribe(callback: (value: T) => void): () => void;\r\n}\r\n\r\ninterface ForProps<T> {\r\n each: T[] | ReactiveState<T[]>;\r\n children?: ((item: T, index: number) => VNode) | ((item: T, index: number) => VNode)[];\r\n}\r\n\r\n/**\r\n * <For> Component\r\n *\r\n * A reactive list iteration component that efficiently renders items from an array or reactive state.\r\n *\r\n * @example\r\n * ```tsx\r\n * <For each={items}>\r\n * {(item, index) => <div key={index}>{item.name}</div>}\r\n * </For>\r\n * ```\r\n *\r\n * @param props - Component properties\r\n * @param props.each - The array or reactive state of array to iterate over\r\n * @param props.children - Render function that receives (item, index) and returns a VNode\r\n */\r\nexport function For<T>(props: ForProps<T>): VNode {\r\n // Extract items from reactive state or plain array\r\n let items: T[] = [];\r\n\r\n if (props.each && typeof props.each === \"object\" && \"_isNixState\" in props.each) {\r\n // Access .value to subscribe to reactive state\r\n items = (props.each as ReactiveState<T[]>).value;\r\n } else if (Array.isArray(props.each)) {\r\n items = props.each;\r\n }\r\n\r\n // Get the renderer function\r\n // In Fynix's JSX transform, children passed as {() => ...} becomes props.children directly\r\n let renderer: ((item: T, index: number) => VNode) | undefined;\r\n\r\n // Handle both direct function and array of children (depends on JSX transform)\r\n if (typeof props.children === \"function\") {\r\n renderer = props.children;\r\n } else if (Array.isArray(props.children)) {\r\n // If JSX transform wraps it in an array, get first element\r\n const firstChild = props.children[0];\r\n if (typeof firstChild === \"function\") {\r\n renderer = firstChild as (item: T, index: number) => VNode;\r\n }\r\n }\r\n\r\n if (!renderer) {\r\n if (items.length > 0) {\r\n console.warn(\"[Fynix] <For> expects a function as its child. Received:\", typeof props.children);\r\n }\r\n return { type: Fragment, props: { children: [] }, key: null };\r\n }\r\n\r\n // Map items to VNodes\r\n const mapped = items.map((item, index) => {\r\n try {\r\n return renderer!(item, index);\r\n } catch (error) {\r\n console.error(`[Fynix] Error rendering item at index ${index}:`, error);\r\n // Return a safe fallback\r\n return {\r\n type: \"div\",\r\n props: {\r\n children: [\"Error rendering item\"],\r\n style: \"color: red;\"\r\n },\r\n key: index\r\n } as VNode;\r\n }\r\n });\r\n\r\n return { type: Fragment, props: { children: mapped }, key: null };\r\n}"],
5
- "mappings": ";;AAIA,SAAS,gBAAgB;AA8BlB,SAAS,IAAO,OAA2B;AAE9C,MAAI,QAAa,CAAC;AAElB,MAAI,MAAM,QAAQ,OAAO,MAAM,SAAS,YAAY,iBAAiB,MAAM,MAAM;AAE7E,YAAS,MAAM,KAA4B;AAAA,EAC/C,WAAW,MAAM,QAAQ,MAAM,IAAI,GAAG;AAClC,YAAQ,MAAM;AAAA,EAClB;AAIA,MAAI;AAGJ,MAAI,OAAO,MAAM,aAAa,YAAY;AACtC,eAAW,MAAM;AAAA,EACrB,WAAW,MAAM,QAAQ,MAAM,QAAQ,GAAG;AAEtC,UAAM,aAAa,MAAM,SAAS,CAAC;AACnC,QAAI,OAAO,eAAe,YAAY;AAClC,iBAAW;AAAA,IACf;AAAA,EACJ;AAEA,MAAI,CAAC,UAAU;AACX,QAAI,MAAM,SAAS,GAAG;AAClB,cAAQ,KAAK,4DAA4D,OAAO,MAAM,QAAQ;AAAA,IAClG;AACA,WAAO,EAAE,MAAM,UAAU,OAAO,EAAE,UAAU,CAAC,EAAE,GAAG,KAAK,KAAK;AAAA,EAChE;AAGA,QAAM,SAAS,MAAM,IAAI,CAAC,MAAM,UAAU;AACtC,QAAI;AACA,aAAO,SAAU,MAAM,KAAK;AAAA,IAChC,SAAS,OAAO;AACZ,cAAQ,MAAM,yCAAyC,KAAK,KAAK,KAAK;AAEtE,aAAO;AAAA,QACH,MAAM;AAAA,QACN,OAAO;AAAA,UACH,UAAU,CAAC,sBAAsB;AAAA,UACjC,OAAO;AAAA,QACX;AAAA,QACA,KAAK;AAAA,MACT;AAAA,IACJ;AAAA,EACJ,CAAC;AAED,SAAO,EAAE,MAAM,UAAU,OAAO,EAAE,UAAU,OAAO,GAAG,KAAK,KAAK;AACpE;AApDgB;",
6
- "names": []
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"nixForm.d.ts","sourceRoot":"","sources":["../../hooks/nixForm.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,KAAK,cAAc,CAAC,CAAC,IAAI;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,KAAK,eAAe,CAAC,CAAC,IAAI;KACvB,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;CACnC,CAAC;AAEF,KAAK,SAAS,CAAC,CAAC,IAAI;IAClB,MAAM,EAAE,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACvC,MAAM,EAAE,UAAU,CAAC,OAAO,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,OAAO,EAAE,UAAU,CAAC,OAAO,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,YAAY,EAAE,UAAU,CAAC,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IACnD,OAAO,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;IACjD,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IACvD,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IACzC,YAAY,EAAE,CACZ,QAAQ,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,KACxD,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK;QACrC,KAAK,EAAE,GAAG,CAAC;QACX,SAAS,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;QAC5B,QAAQ,EAAE,MAAM,IAAI,CAAC;KACtB,CAAC;CACH,CAAC;AAgBF,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzE,aAAa,GAAE,CAAW,EAC1B,eAAe,GAAE,eAAe,CAAC,CAAC,CAA4B,GAC7D,SAAS,CAAC,CAAC,CAAC,CA2Id"}
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../hooks/nixForm.ts"],
4
- "sourcesContent": ["/* MIT License\r\n\r\n* Copyright (c) 2026 Resty Gonzales\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n* SOFTWARE.\r\n */\r\n// core/hooks/nixForm.js - Form handling utilities with memory-safe async support\r\nimport { nixComputed } from \"./nixComputed.js\";\r\nimport { nixState } from \"./nixState.js\";\r\n\r\ntype ValidationRule<T> = {\r\n required?: boolean;\r\n minLength?: number;\r\n maxLength?: number;\r\n pattern?: RegExp;\r\n custom?: (value: any, values: T) => boolean;\r\n message?: string;\r\n};\r\n\r\ntype ValidationRules<T> = {\r\n [K in keyof T]?: ValidationRule<T>;\r\n};\r\n\r\ntype FormState<T> = {\r\n values: ReturnType<typeof nixState<T>>;\r\n errors: ReturnType<typeof nixState<Partial<Record<keyof T, string>>>>;\r\n touched: ReturnType<typeof nixState<Partial<Record<keyof T, boolean>>>>;\r\n isSubmitting: ReturnType<typeof nixState<boolean>>;\r\n isValid: ReturnType<typeof nixComputed<boolean>>;\r\n handleChange: (fieldName: keyof T, value: any) => void;\r\n handleBlur: (fieldName: keyof T) => void;\r\n handleSubmit: (\r\n onSubmit: (values: T, signal: AbortSignal) => Promise<void>\r\n ) => Promise<void>;\r\n cancelSubmit: () => void;\r\n reset: () => void;\r\n getFieldProps: (fieldName: keyof T) => {\r\n value: any;\r\n \"r-input\": (e: any) => void;\r\n \"r-blur\": () => void;\r\n };\r\n};\r\n\r\n/**\r\n * Reactive form handler with validation, reactive state, and safe async submit.\r\n *\r\n * @param {Object} [initialValues={}] - Initial values for form fields.\r\n * @param {Object} [validationRules={}] - Validation rules for fields.\r\n * @returns {Object} Form utilities: values, errors, touched, isSubmitting, isValid,\r\n * handleChange, handleBlur, handleSubmit, reset, getFieldProps, cancelSubmit\r\n *\r\n * @example\r\n * const form = nixForm({ email: \"\" }, {\r\n * email: { required: true, pattern: /^\\S+@\\S+$/, message: \"Invalid email\" }\r\n * });\r\n * form.handleSubmit(async (values) => { await api.submit(values); });\r\n */\r\nexport function nixForm<T extends Record<string, any> = Record<string, any>>(\r\n initialValues: T = {} as T,\r\n validationRules: ValidationRules<T> = {} as ValidationRules<T>\r\n): FormState<T> {\r\n const values = nixState<T>({ ...initialValues });\r\n const errors = nixState<Partial<Record<keyof T, string>>>({});\r\n const touched = nixState<Partial<Record<keyof T, boolean>>>({});\r\n const isSubmitting = nixState<boolean>(false);\r\n\r\n const isValid = nixComputed<boolean>(\r\n () => Object.keys(errors.value).length === 0\r\n );\r\n\r\n let abortController: AbortController | null = null;\r\n\r\n function validate(fieldName: keyof T, value: any): string | null {\r\n const rules = validationRules[fieldName];\r\n if (!rules) return null;\r\n\r\n if (rules.required && !value) {\r\n return rules.message || `${String(fieldName)} is required`;\r\n }\r\n if (rules.minLength && value.length < rules.minLength) {\r\n return (\r\n rules.message ||\r\n `${String(fieldName)} must be at least ${rules.minLength} characters`\r\n );\r\n }\r\n if (rules.maxLength && value.length > rules.maxLength) {\r\n return (\r\n rules.message ||\r\n `${String(fieldName)} must be at most ${rules.maxLength} characters`\r\n );\r\n }\r\n if (rules.pattern && !rules.pattern.test(value)) {\r\n return rules.message || `${String(fieldName)} is invalid`;\r\n }\r\n if (rules.custom && !rules.custom(value, values.value)) {\r\n return rules.message || `${String(fieldName)} is invalid`;\r\n }\r\n return null;\r\n }\r\n\r\n function handleChange(fieldName: keyof T, value: any): void {\r\n values.value = { ...values.value, [fieldName]: value };\r\n\r\n if (touched.value[fieldName]) {\r\n const error = validate(fieldName, value);\r\n if (error) {\r\n errors.value = { ...errors.value, [fieldName]: error };\r\n } else {\r\n const newErrors = { ...errors.value };\r\n delete newErrors[fieldName];\r\n errors.value = newErrors;\r\n }\r\n }\r\n }\r\n\r\n function handleBlur(fieldName: keyof T): void {\r\n touched.value = { ...touched.value, [fieldName]: true };\r\n const error = validate(fieldName, values.value[fieldName]);\r\n if (error) {\r\n errors.value = { ...errors.value, [fieldName]: error };\r\n }\r\n }\r\n\r\n function validateAll(): boolean {\r\n const newErrors: Partial<Record<keyof T, string>> = {};\r\n (Object.keys(validationRules) as Array<keyof T>).forEach((fieldName) => {\r\n const error = validate(fieldName, values.value[fieldName]);\r\n if (error) newErrors[fieldName] = error;\r\n });\r\n errors.value = newErrors;\r\n return Object.keys(newErrors).length === 0;\r\n }\r\n\r\n async function handleSubmit(\r\n onSubmit: (values: T, signal: AbortSignal) => Promise<void>\r\n ): Promise<void> {\r\n const allTouched = (Object.keys(validationRules) as Array<keyof T>).reduce(\r\n (acc, key) => {\r\n acc[key] = true;\r\n return acc;\r\n },\r\n {} as Partial<Record<keyof T, boolean>>\r\n );\r\n touched.value = allTouched;\r\n\r\n if (!validateAll()) return;\r\n\r\n if (abortController) abortController.abort();\r\n abortController = new AbortController();\r\n const signal = abortController.signal;\r\n\r\n isSubmitting.value = true;\r\n try {\r\n await onSubmit(values.value, signal);\r\n } catch (err: any) {\r\n if (err.name !== \"AbortError\") {\r\n console.error(\"[nixForm] Submission error:\", err);\r\n }\r\n } finally {\r\n if (!signal.aborted) isSubmitting.value = false;\r\n }\r\n }\r\n\r\n function cancelSubmit(): void {\r\n if (abortController) {\r\n abortController.abort();\r\n abortController = null;\r\n }\r\n }\r\n\r\n function reset(): void {\r\n values.value = { ...initialValues };\r\n errors.value = {};\r\n touched.value = {};\r\n isSubmitting.value = false;\r\n cancelSubmit();\r\n }\r\n\r\n function getFieldProps(fieldName: keyof T) {\r\n return {\r\n value: values.value[fieldName] || \"\",\r\n \"r-input\": (e: any) => handleChange(fieldName, e.target.value),\r\n \"r-blur\": () => handleBlur(fieldName),\r\n };\r\n }\r\n\r\n return {\r\n values,\r\n errors,\r\n touched,\r\n isSubmitting,\r\n isValid,\r\n handleChange,\r\n handleBlur,\r\n handleSubmit,\r\n cancelSubmit,\r\n reset,\r\n getFieldProps,\r\n };\r\n}\r\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"nixFormAsync.d.ts","sourceRoot":"","sources":["../../hooks/nixFormAsync.ts"],"names":[],"mappings":"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"}
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../hooks/nixFormAsync.ts"],
4
- "sourcesContent": ["/* MIT License\r\n\r\n* Copyright (c) 2026 Resty Gonzales\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n* SOFTWARE.\r\n */\r\n// core/hooks/nixFormAsync.js\r\n\r\nimport { nixComputed } from \"./nixComputed.js\";\r\nimport { nixState } from \"./nixState.js\";\r\n\r\ntype ValidationRule<T> = {\r\n required?: boolean;\r\n minLength?: number;\r\n maxLength?: number;\r\n pattern?: RegExp;\r\n custom?: (value: any, values: T) => boolean;\r\n message?: string;\r\n};\r\n\r\ntype ValidationRules<T> = {\r\n [K in keyof T]?: ValidationRule<T>;\r\n};\r\n\r\ntype FormAsyncState<T, D = any, E = any> = {\r\n values: ReturnType<typeof nixState<T>>;\r\n errors: ReturnType<typeof nixState<Partial<Record<keyof T, string>>>>;\r\n touched: ReturnType<typeof nixState<Partial<Record<keyof T, boolean>>>>;\r\n isSubmitting: ReturnType<typeof nixState<boolean>>;\r\n isValid: ReturnType<typeof nixComputed<boolean>>;\r\n data: ReturnType<typeof nixState<D | null>>;\r\n error: ReturnType<typeof nixState<E | null>>;\r\n loading: ReturnType<typeof nixState<boolean>>;\r\n handleChange: (fieldName: keyof T, value: any) => void;\r\n handleBlur: (fieldName: keyof T) => void;\r\n handleSubmit: (\r\n onSubmit: (values: T, signal: AbortSignal) => Promise<D>\r\n ) => void;\r\n cancelSubmit: () => void;\r\n reset: () => void;\r\n getFieldProps: (fieldName: keyof T) => {\r\n value: any;\r\n \"r-input\": (e: any) => void;\r\n \"r-blur\": () => void;\r\n };\r\n};\r\n\r\n/**\r\n * Full-featured reactive form with debounced async API submission.\r\n *\r\n * @param {Object} [initialValues={}] - Initial field values.\r\n * @param {Object} [validationRules={}] - Validation rules for each field.\r\n * @param {Object} [options={}] - Async submit options.\r\n * @param {number} [options.delay=300] - Debounce delay in ms.\r\n * @param {boolean} [options.leading=false] - Invoke submit on leading edge.\r\n * @param {boolean} [options.trailing=true] - Invoke submit on trailing edge.\r\n * @param {number} [options.maxWait] - Maximum wait time before forced invocation.\r\n * @param {boolean} [options.cache=true] - Cache last submission result.\r\n * @returns {Object} Form API with state, validation, and debounced async submission.\r\n */\r\nexport function nixFormAsync<\r\n T extends Record<string, any> = Record<string, any>,\r\n D = any,\r\n E = any,\r\n>(\r\n initialValues: T = {} as T,\r\n validationRules: ValidationRules<T> = {} as ValidationRules<T>,\r\n options: {\r\n delay?: number;\r\n leading?: boolean;\r\n trailing?: boolean;\r\n maxWait?: number;\r\n cache?: boolean;\r\n } = {}\r\n): FormAsyncState<T, D, E> {\r\n const values = nixState<T>({ ...initialValues });\r\n const errors = nixState<Partial<Record<keyof T, string>>>({});\r\n const touched = nixState<Partial<Record<keyof T, boolean>>>({});\r\n const isSubmitting = nixState<boolean>(false);\r\n const isValid = nixComputed<boolean>(\r\n () => Object.keys(errors.value).length === 0\r\n );\r\n\r\n const {\r\n delay = 300,\r\n leading = false,\r\n trailing = true,\r\n maxWait,\r\n cache = true,\r\n } = options;\r\n const data = nixState<D | null>(null);\r\n const error = nixState<E | null>(null);\r\n const loading = nixState<boolean>(false);\r\n\r\n let abortController: AbortController | null = null;\r\n let timerId: ReturnType<typeof setTimeout> | null = null;\r\n let lastInvokeTime = 0;\r\n let lastResult: D | null = null;\r\n let lastError: E | null = null;\r\n let pendingPromise: Promise<D> | null = null;\r\n\r\n function validate(fieldName: keyof T, value: any): string | null {\r\n const rules = validationRules[fieldName];\r\n if (!rules) return null;\r\n\r\n if (rules.required && !value)\r\n return rules.message || `${String(fieldName)} is required`;\r\n if (rules.minLength && value.length < rules.minLength)\r\n return (\r\n rules.message ||\r\n `${String(fieldName)} must be at least ${rules.minLength} characters`\r\n );\r\n if (rules.maxLength && value.length > rules.maxLength)\r\n return (\r\n rules.message ||\r\n `${String(fieldName)} must be at most ${rules.maxLength} characters`\r\n );\r\n if (rules.pattern && !rules.pattern.test(value))\r\n return rules.message || `${String(fieldName)} is invalid`;\r\n if (rules.custom && !rules.custom(value, values.value))\r\n return rules.message || `${String(fieldName)} is invalid`;\r\n\r\n return null;\r\n }\r\n\r\n function handleChange(fieldName: keyof T, value: any): void {\r\n values.value = { ...values.value, [fieldName]: value };\r\n\r\n if (touched.value[fieldName]) {\r\n const err = validate(fieldName, value);\r\n if (err) errors.value = { ...errors.value, [fieldName]: err };\r\n else {\r\n const newErrors = { ...errors.value };\r\n delete newErrors[fieldName];\r\n errors.value = newErrors;\r\n }\r\n }\r\n }\r\n\r\n function handleBlur(fieldName: keyof T): void {\r\n touched.value = { ...touched.value, [fieldName]: true };\r\n const err = validate(fieldName, values.value[fieldName]);\r\n if (err) errors.value = { ...errors.value, [fieldName]: err };\r\n }\r\n\r\n function validateAll(): boolean {\r\n const newErrors: Partial<Record<keyof T, string>> = {};\r\n (Object.keys(validationRules) as Array<keyof T>).forEach((fieldName) => {\r\n const err = validate(fieldName, values.value[fieldName]);\r\n if (err) newErrors[fieldName] = err;\r\n });\r\n errors.value = newErrors;\r\n return Object.keys(newErrors).length === 0;\r\n }\r\n\r\n async function invokeAsync(\r\n onSubmit: (values: T, signal: AbortSignal) => Promise<D>\r\n ): Promise<D | undefined> {\r\n if (cache && lastResult !== null) {\r\n data.value = lastResult;\r\n error.value = lastError;\r\n loading.value = false;\r\n return lastResult;\r\n }\r\n if (abortController) abortController.abort();\r\n abortController = new AbortController();\r\n const signal = abortController.signal;\r\n loading.value = true;\r\n error.value = null;\r\n pendingPromise = onSubmit(values.value, signal);\r\n try {\r\n const result = await pendingPromise;\r\n lastResult = result;\r\n data.value = result;\r\n return result;\r\n } catch (err: any) {\r\n if (err.name !== \"AbortError\") {\r\n lastError = err;\r\n error.value = err;\r\n console.error(\"[nixFormAsync] submit error:\", err);\r\n }\r\n throw err;\r\n } finally {\r\n loading.value = false;\r\n pendingPromise = null;\r\n lastInvokeTime = Date.now();\r\n }\r\n }\r\n\r\n function handleSubmit(\r\n onSubmit: (values: T, signal: AbortSignal) => Promise<D>\r\n ): void {\r\n if (!validateAll()) return;\r\n const now = Date.now();\r\n const timeSinceLastInvoke = now - lastInvokeTime;\r\n const remainingTime = delay - timeSinceLastInvoke;\r\n const shouldInvokeLeading = leading && !timerId;\r\n if (maxWait !== undefined && timeSinceLastInvoke >= maxWait) {\r\n if (timerId) clearTimeout(timerId);\r\n timerId = null;\r\n void invokeAsync(onSubmit);\r\n return;\r\n }\r\n if (timerId) clearTimeout(timerId);\r\n if (shouldInvokeLeading) {\r\n void invokeAsync(onSubmit);\r\n return;\r\n }\r\n if (trailing) {\r\n timerId = setTimeout(\r\n () => {\r\n timerId = null;\r\n void invokeAsync(onSubmit);\r\n },\r\n remainingTime > 0 ? remainingTime : delay\r\n );\r\n }\r\n }\r\n\r\n function cancelSubmit(): void {\r\n if (abortController) {\r\n abortController.abort();\r\n abortController = null;\r\n }\r\n if (timerId) clearTimeout(timerId);\r\n timerId = null;\r\n }\r\n\r\n function reset(): void {\r\n values.value = { ...initialValues };\r\n errors.value = {};\r\n touched.value = {};\r\n isSubmitting.value = false;\r\n cancelSubmit();\r\n data.value = null;\r\n error.value = null;\r\n loading.value = false;\r\n }\r\n\r\n function getFieldProps(fieldName: keyof T) {\r\n return {\r\n value: values.value[fieldName] || \"\",\r\n \"r-input\": (e: any) => handleChange(fieldName, e.target.value),\r\n \"r-blur\": () => handleBlur(fieldName),\r\n };\r\n }\r\n\r\n return {\r\n values,\r\n errors,\r\n touched,\r\n isSubmitting,\r\n isValid,\r\n data,\r\n error,\r\n loading,\r\n handleChange,\r\n handleBlur,\r\n handleSubmit,\r\n cancelSubmit,\r\n reset,\r\n getFieldProps,\r\n };\r\n}\r\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"nixInterval.d.ts","sourceRoot":"","sources":["../../hooks/nixInterval.ts"],"names":[],"mappings":"AAgDA,wBAAgB,WAAW,CACzB,EAAE,EAAE,MAAM,IAAI,EACd,EAAE,EAAE,MAAM,EACV,MAAM,CAAC,EAAE,WAAW,GACnB,MAAM,IAAI,CA2BZ"}
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../hooks/nixInterval.ts"],
4
- "sourcesContent": ["/* MIT License\r\n\r\n* Copyright (c) 2026 Resty Gonzales\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n* SOFTWARE.\r\n */\r\n/**\r\n * @fileoverview Safe interval utility with automatic cleanup support.\r\n * Provides AbortController integration for cancellable intervals.\r\n */\r\n\r\n/**\r\n * Safe interval with automatic cleanup support and optional AbortController.\r\n * Must be called within a component and cleaned up on unmount.\r\n *\r\n * @param {() => void} fn - Function to run at each interval\r\n * @param {number} ms - Interval duration in milliseconds\r\n * @param {AbortSignal} [signal] - Optional AbortSignal to cancel the interval\r\n * @returns {() => void} Cleanup function to stop the interval\r\n *\r\n * @example\r\n * const cancel = nixInterval(() => console.log('tick'), 1000);\r\n * // stop interval\r\n * cancel();\r\n *\r\n * @example\r\n * const controller = new AbortController();\r\n * nixInterval(() => console.log('tick'), 1000, controller.signal);\r\n * controller.abort(); // automatically clears interval\r\n *\r\n * @throws {TypeError} If fn is not a function or ms is not a non-negative number\r\n */\r\nexport function nixInterval(\r\n fn: () => void,\r\n ms: number,\r\n signal?: AbortSignal\r\n): () => void {\r\n if (typeof fn !== \"function\") {\r\n throw new TypeError(\"nixInterval: first argument must be a function\");\r\n }\r\n if (typeof ms !== \"number\" || ms < 0) {\r\n throw new TypeError(\r\n \"nixInterval: second argument must be a non-negative number\"\r\n );\r\n }\r\n\r\n const id = setInterval(fn, ms);\r\n\r\n const cancel = () => clearInterval(id);\r\n\r\n if (signal) {\r\n if (signal.aborted) {\r\n cancel();\r\n } else {\r\n const listener = () => {\r\n cancel();\r\n signal.removeEventListener(\"abort\", listener);\r\n };\r\n signal.addEventListener(\"abort\", listener);\r\n }\r\n }\r\n\r\n return cancel;\r\n}\r\n"],
5
- "mappings": ";;AAgDO,SAAS,YACd,IACA,IACA,QACY;AACZ,MAAI,OAAO,OAAO,YAAY;AAC5B,UAAM,IAAI,UAAU,gDAAgD;AAAA,EACtE;AACA,MAAI,OAAO,OAAO,YAAY,KAAK,GAAG;AACpC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,KAAK,YAAY,IAAI,EAAE;AAE7B,QAAM,SAAS,6BAAM,cAAc,EAAE,GAAtB;AAEf,MAAI,QAAQ;AACV,QAAI,OAAO,SAAS;AAClB,aAAO;AAAA,IACT,OAAO;AACL,YAAM,WAAW,6BAAM;AACrB,eAAO;AACP,eAAO,oBAAoB,SAAS,QAAQ;AAAA,MAC9C,GAHiB;AAIjB,aAAO,iBAAiB,SAAS,QAAQ;AAAA,IAC3C;AAAA,EACF;AAEA,SAAO;AACT;AA/BgB;",
6
- "names": []
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"nixLazy.d.ts","sourceRoot":"","sources":["../../hooks/nixLazy.ts"],"names":[],"mappings":"AAgCA,wBAAgB,OAAO,CAAC,MAAM,GAAG,GAAG,EAClC,QAAQ,EAAE,MAAM,OAAO,CACrB;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,GAAG,CAAA;CAAE,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,GAAG,CAAC,CAChE,GACA,CAAC,KAAK,EAAE,MAAM,KAAK,GAAG,CA4CxB;AAUD,wBAAgB,QAAQ,CAAC,CAAC,GAAG,GAAG,EAAE,EAChC,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,GAAG,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC,CAAC;CACnB,GAAG,CAAC,GAAG,GAAG,CAqBV"}
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../hooks/nixLazy.ts"],
4
- "sourcesContent": ["/* MIT License\r\n\r\n* Copyright (c) 2026 Resty Gonzales\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n* SOFTWARE.\r\n */\r\n// core/hooks/nixLazy.js\r\nimport { activeContext } from \"../context/context.js\";\r\nimport { nixState } from \"./nixState.js\";\r\n\r\n/**\r\n * Lazy-load a module/component with caching.\r\n *\r\n * @param {() => Promise<any>} importFn - Function that returns a dynamic import.\r\n * @returns {Function} Component wrapper for lazy-loaded module.\r\n */\r\nexport function nixLazy<TProps = any>(\r\n importFn: () => Promise<\r\n { default?: (props: TProps) => any } | ((props: TProps) => any)\r\n >\r\n): (props: TProps) => any {\r\n type Cache = {\r\n status: \"pending\" | \"success\" | \"error\";\r\n component: ((props: TProps) => any) | null;\r\n error: any;\r\n promise: Promise<any> | null;\r\n };\r\n const cache: Cache = {\r\n status: \"pending\",\r\n component: null,\r\n error: null,\r\n promise: null,\r\n };\r\n\r\n let canceled = false;\r\n\r\n cache.promise = importFn()\r\n .then((module) => {\r\n if (!canceled) {\r\n cache.status = \"success\";\r\n cache.component = (module as any).default || module;\r\n }\r\n })\r\n .catch((err) => {\r\n if (!canceled) {\r\n cache.status = \"error\";\r\n cache.error = err;\r\n }\r\n });\r\n\r\n return function LazyWrapper(props: TProps): any {\r\n const ctx = activeContext;\r\n if (!ctx) throw new Error(\"nixLazy() called outside component\");\r\n\r\n if (cache.status === \"pending\") {\r\n throw cache.promise; // Suspense-like behavior\r\n }\r\n\r\n if (cache.status === \"error\") {\r\n throw cache.error;\r\n }\r\n\r\n return cache.component!(props);\r\n };\r\n}\r\n\r\n/**\r\n * Suspense-like wrapper for lazy components.\r\n *\r\n * @param {Object} props\r\n * @param {any} props.fallback - Element to render while loading.\r\n * @param {Function} props.children - Function returning child component.\r\n * @returns {any} Rendered fallback or child.\r\n */\r\nexport function Suspense<T = any>({\r\n fallback,\r\n children,\r\n}: {\r\n fallback: any;\r\n children: () => T;\r\n}): T | any {\r\n const loading = nixState<boolean>(false);\r\n const error = nixState<any>(null);\r\n\r\n try {\r\n return children();\r\n } catch (promise) {\r\n if (promise instanceof Promise) {\r\n loading.value = true;\r\n promise\r\n .then(() => {\r\n loading.value = false;\r\n })\r\n .catch((err) => {\r\n error.value = err;\r\n loading.value = false;\r\n });\r\n return fallback;\r\n }\r\n throw promise;\r\n }\r\n}\r\n"],
5
- "mappings": ";;AAuBA,SAAS,qBAAqB;AAC9B,SAAS,gBAAgB;AAQlB,SAAS,QACd,UAGwB;AAOxB,QAAM,QAAe;AAAA,IACnB,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,OAAO;AAAA,IACP,SAAS;AAAA,EACX;AAEA,MAAI,WAAW;AAEf,QAAM,UAAU,SAAS,EACtB,KAAK,CAAC,WAAW;AAChB,QAAI,CAAC,UAAU;AACb,YAAM,SAAS;AACf,YAAM,YAAa,OAAe,WAAW;AAAA,IAC/C;AAAA,EACF,CAAC,EACA,MAAM,CAAC,QAAQ;AACd,QAAI,CAAC,UAAU;AACb,YAAM,SAAS;AACf,YAAM,QAAQ;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,SAAO,gCAAS,YAAY,OAAoB;AAC9C,UAAM,MAAM;AACZ,QAAI,CAAC,IAAK,OAAM,IAAI,MAAM,oCAAoC;AAE9D,QAAI,MAAM,WAAW,WAAW;AAC9B,YAAM,MAAM;AAAA,IACd;AAEA,QAAI,MAAM,WAAW,SAAS;AAC5B,YAAM,MAAM;AAAA,IACd;AAEA,WAAO,MAAM,UAAW,KAAK;AAAA,EAC/B,GAbO;AAcT;AAhDgB;AA0DT,SAAS,SAAkB;AAAA,EAChC;AAAA,EACA;AACF,GAGY;AACV,QAAM,UAAU,SAAkB,KAAK;AACvC,QAAM,QAAQ,SAAc,IAAI;AAEhC,MAAI;AACF,WAAO,SAAS;AAAA,EAClB,SAAS,SAAS;AAChB,QAAI,mBAAmB,SAAS;AAC9B,cAAQ,QAAQ;AAChB,cACG,KAAK,MAAM;AACV,gBAAQ,QAAQ;AAAA,MAClB,CAAC,EACA,MAAM,CAAC,QAAQ;AACd,cAAM,QAAQ;AACd,gBAAQ,QAAQ;AAAA,MAClB,CAAC;AACH,aAAO;AAAA,IACT;AACA,UAAM;AAAA,EACR;AACF;AA3BgB;",
6
- "names": []
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"nixLazyAsync.d.ts","sourceRoot":"","sources":["../../hooks/nixLazyAsync.ts"],"names":[],"mappings":"AAqCA,wBAAgB,YAAY,CAAC,MAAM,GAAG,GAAG,EACvC,QAAQ,EAAE,MAAM,OAAO,CACrB;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,GAAG,CAAA;CAAE,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,GAAG,CAAC,CAChE,EACD,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/B,CAAC,KAAK,EAAE,MAAM,KAAK,GAAG,CAgExB;AAUD,wBAAgB,QAAQ,CAAC,CAAC,GAAG,GAAG,EAAE,EAChC,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,GAAG,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC,CAAC;CACnB,GAAG,CAAC,GAAG,GAAG,CAmBV"}
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../hooks/nixLazyAsync.ts"],
4
- "sourcesContent": ["/* MIT License\r\n\r\n* Copyright (c) 2026 Resty Gonzales\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n* SOFTWARE.\r\n */\r\n// core/hooks/nixLazyAsync.js\r\nimport { activeContext } from \"../context/context.js\";\r\nimport { nixState } from \"./nixState.js\";\r\n\r\n/**\r\n * Lazy-load a module/component with caching, retry, and abort support.\r\n *\r\n * @param {() => Promise<any>} importFn - Function returning a dynamic import.\r\n * @param {Object} [options={}] - Options for lazy loading.\r\n * @param {number} [options.retry=0] - Number of retry attempts on failure.\r\n * @returns {Function} Component wrapper for lazy-loaded module.\r\n *\r\n * @example\r\n * const LazyComp = nixLazyAsync(() => import(\"./MyComponent\"), { retry: 2 });\r\n */\r\nexport function nixLazyAsync<TProps = any>(\r\n importFn: () => Promise<\r\n { default?: (props: TProps) => any } | ((props: TProps) => any)\r\n >,\r\n options: { retry?: number } = {}\r\n): (props: TProps) => any {\r\n const { retry = 0 } = options;\r\n\r\n type Cache = {\r\n status: \"pending\" | \"success\" | \"error\";\r\n component: ((props: TProps) => any) | null;\r\n error: any;\r\n promise: Promise<any> | null;\r\n retriesLeft: number;\r\n };\r\n const cache: Cache = {\r\n status: \"pending\",\r\n component: null,\r\n error: null,\r\n promise: null,\r\n retriesLeft: retry,\r\n };\r\n\r\n let canceled = false;\r\n\r\n const loadModule = (): Promise<any> => {\r\n cache.promise = importFn()\r\n .then((module) => {\r\n if (!canceled) {\r\n cache.status = \"success\";\r\n cache.component = (module as any).default || module;\r\n }\r\n return cache.component;\r\n })\r\n .catch((err) => {\r\n if (!canceled) {\r\n if (cache.retriesLeft > 0) {\r\n cache.retriesLeft--;\r\n return loadModule();\r\n }\r\n cache.status = \"error\";\r\n cache.error = err;\r\n }\r\n return Promise.reject(cache.error);\r\n });\r\n return cache.promise;\r\n };\r\n\r\n loadModule();\r\n\r\n // Removed unused 'cancel' function\r\n\r\n return function LazyWrapper(props: TProps): any {\r\n const ctx = activeContext;\r\n if (!ctx) throw new Error(\"nixLazyAsync() called outside component\");\r\n\r\n if (cache.status === \"pending\") {\r\n throw cache.promise; // Suspense fallback\r\n }\r\n\r\n if (cache.status === \"error\") {\r\n throw cache.error;\r\n }\r\n\r\n if (!cache.component) {\r\n throw new Error(\"nixLazyAsync: component not loaded\");\r\n }\r\n return cache.component(props);\r\n };\r\n}\r\n\r\n/**\r\n * Suspense wrapper to catch pending promises and render fallback.\r\n *\r\n * @param {Object} props\r\n * @param {any} props.fallback - Element to render while loading.\r\n * @param {Function} props.children - Function returning child component.\r\n * @returns {any} Rendered fallback or child component.\r\n */\r\nexport function Suspense<T = any>({\r\n fallback,\r\n children,\r\n}: {\r\n fallback: any;\r\n children: () => T;\r\n}): T | any {\r\n const loading = nixState<boolean>(false);\r\n const error = nixState<any>(null);\r\n\r\n try {\r\n return children();\r\n } catch (promise) {\r\n if (promise instanceof Promise) {\r\n loading.value = true;\r\n promise\r\n .then(() => (loading.value = false))\r\n .catch((err) => {\r\n error.value = err;\r\n loading.value = false;\r\n });\r\n return fallback;\r\n }\r\n throw promise;\r\n }\r\n}\r\n"],
5
- "mappings": ";;AAuBA,SAAS,qBAAqB;AAC9B,SAAS,gBAAgB;AAalB,SAAS,aACd,UAGA,UAA8B,CAAC,GACP;AACxB,QAAM,EAAE,QAAQ,EAAE,IAAI;AAStB,QAAM,QAAe;AAAA,IACnB,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,OAAO;AAAA,IACP,SAAS;AAAA,IACT,aAAa;AAAA,EACf;AAEA,MAAI,WAAW;AAEf,QAAM,aAAa,6BAAoB;AACrC,UAAM,UAAU,SAAS,EACtB,KAAK,CAAC,WAAW;AAChB,UAAI,CAAC,UAAU;AACb,cAAM,SAAS;AACf,cAAM,YAAa,OAAe,WAAW;AAAA,MAC/C;AACA,aAAO,MAAM;AAAA,IACf,CAAC,EACA,MAAM,CAAC,QAAQ;AACd,UAAI,CAAC,UAAU;AACb,YAAI,MAAM,cAAc,GAAG;AACzB,gBAAM;AACN,iBAAO,WAAW;AAAA,QACpB;AACA,cAAM,SAAS;AACf,cAAM,QAAQ;AAAA,MAChB;AACA,aAAO,QAAQ,OAAO,MAAM,KAAK;AAAA,IACnC,CAAC;AACH,WAAO,MAAM;AAAA,EACf,GArBmB;AAuBnB,aAAW;AAIX,SAAO,gCAAS,YAAY,OAAoB;AAC9C,UAAM,MAAM;AACZ,QAAI,CAAC,IAAK,OAAM,IAAI,MAAM,yCAAyC;AAEnE,QAAI,MAAM,WAAW,WAAW;AAC9B,YAAM,MAAM;AAAA,IACd;AAEA,QAAI,MAAM,WAAW,SAAS;AAC5B,YAAM,MAAM;AAAA,IACd;AAEA,QAAI,CAAC,MAAM,WAAW;AACpB,YAAM,IAAI,MAAM,oCAAoC;AAAA,IACtD;AACA,WAAO,MAAM,UAAU,KAAK;AAAA,EAC9B,GAhBO;AAiBT;AArEgB;AA+ET,SAAS,SAAkB;AAAA,EAChC;AAAA,EACA;AACF,GAGY;AACV,QAAM,UAAU,SAAkB,KAAK;AACvC,QAAM,QAAQ,SAAc,IAAI;AAEhC,MAAI;AACF,WAAO,SAAS;AAAA,EAClB,SAAS,SAAS;AAChB,QAAI,mBAAmB,SAAS;AAC9B,cAAQ,QAAQ;AAChB,cACG,KAAK,MAAO,QAAQ,QAAQ,KAAM,EAClC,MAAM,CAAC,QAAQ;AACd,cAAM,QAAQ;AACd,gBAAQ,QAAQ;AAAA,MAClB,CAAC;AACH,aAAO;AAAA,IACT;AACA,UAAM;AAAA,EACR;AACF;AAzBgB;",
6
- "names": []
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"nixLazyFormAsync.d.ts","sourceRoot":"","sources":["../../hooks/nixLazyFormAsync.ts"],"names":[],"mappings":"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"}
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../hooks/nixLazyFormAsync.ts"],
4
- "sourcesContent": ["/* MIT License\r\n\r\n* Copyright (c) 2026 Resty Gonzales\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n* SOFTWARE.\r\n */\r\n// core/hooks/nixLazyFormAsync.js\r\nimport { activeContext } from \"../context/context.js\";\r\nimport { nixComputed } from \"./nixComputed.js\";\r\nimport { nixState } from \"./nixState.js\";\r\n\r\n/**\r\n * Lazy-load a form component and manage its state with debounced async submissions.\r\n *\r\n * @param {() => Promise<any>} importFn - Function returning a dynamic import of the form component.\r\n * @param {Object} [formOptions={}] - Initial values and validation rules.\r\n * @param {Object} [formOptions.initialValues={}] - Initial field values.\r\n * @param {Object} [formOptions.validationRules={}] - Validation rules per field.\r\n * @param {Object} [submitOptions={}] - Debounce and async submission options.\r\n * @param {number} [submitOptions.delay=300] - Debounce delay.\r\n * @param {boolean} [submitOptions.leading=false] - Invoke submit on leading edge.\r\n * @param {boolean} [submitOptions.trailing=true] - Invoke submit on trailing edge.\r\n * @param {number} [submitOptions.maxWait] - Max wait before forced submission.\r\n * @param {boolean} [submitOptions.cache=true] - Cache last submission result.\r\n * @param {Object} [lazyOptions={}] - Options for lazy-loaded component import.\r\n * @param {number} [lazyOptions.retry=0] - Retry count for lazy-loaded component import.\r\n * @returns {Object} Lazy-loaded form component and reactive form API.\r\n */\r\ntype ValidationRule<T> = {\r\n required?: boolean;\r\n minLength?: number;\r\n maxLength?: number;\r\n pattern?: RegExp;\r\n custom?: (value: any, values: T) => boolean;\r\n message?: string;\r\n};\r\n\r\ntype ValidationRules<T> = {\r\n [K in keyof T]?: ValidationRule<T>;\r\n};\r\n\r\ntype LazyFormAsyncReturn<T, D = any, E = any, P = any> = {\r\n LazyComponentWrapper: (props: P) => any;\r\n values: ReturnType<typeof nixState<T>>;\r\n errors: ReturnType<typeof nixState<Partial<Record<keyof T, string>>>>;\r\n touched: ReturnType<typeof nixState<Partial<Record<keyof T, boolean>>>>;\r\n isSubmitting: ReturnType<typeof nixState<boolean>>;\r\n isValid: ReturnType<typeof nixComputed<boolean>>;\r\n data: ReturnType<typeof nixState<D | null>>;\r\n error: ReturnType<typeof nixState<E | null>>;\r\n loading: ReturnType<typeof nixState<boolean>>;\r\n handleChange: (fieldName: keyof T, value: any) => void;\r\n handleBlur: (fieldName: keyof T) => void;\r\n handleSubmit: (\r\n onSubmit: (values: T, signal: AbortSignal) => Promise<D>\r\n ) => void;\r\n cancelSubmit: () => void;\r\n reset: () => void;\r\n getFieldProps: (fieldName: keyof T) => {\r\n value: any;\r\n \"r-input\": (e: any) => void;\r\n \"r-blur\": () => void;\r\n };\r\n};\r\n\r\nexport function nixLazyFormAsync<\r\n T extends Record<string, any> = Record<string, any>,\r\n D = any,\r\n E = any,\r\n P = any,\r\n>(\r\n importFn: () => Promise<\r\n { default?: (props: P) => any } | ((props: P) => any)\r\n >,\r\n formOptions: { initialValues?: T; validationRules?: ValidationRules<T> } = {},\r\n submitOptions: {\r\n delay?: number;\r\n leading?: boolean;\r\n trailing?: boolean;\r\n maxWait?: number;\r\n cache?: boolean;\r\n } = {},\r\n lazyOptions: { retry?: number } = {}\r\n): LazyFormAsyncReturn<T, D, E, P> {\r\n const {\r\n initialValues = {} as T,\r\n validationRules = {} as ValidationRules<T>,\r\n } = formOptions;\r\n const { retry = 0 } = lazyOptions;\r\n const {\r\n delay = 300,\r\n leading = false,\r\n trailing = true,\r\n maxWait,\r\n cache = true,\r\n } = submitOptions;\r\n\r\n type LazyCache = {\r\n status: \"pending\" | \"success\" | \"error\";\r\n component: ((props: P) => any) | null;\r\n error: any;\r\n promise: Promise<any> | null;\r\n retriesLeft: number;\r\n };\r\n const lazyCache: LazyCache = {\r\n status: \"pending\",\r\n component: null,\r\n error: null,\r\n promise: null,\r\n retriesLeft: retry,\r\n };\r\n\r\n let lazyAbortController: AbortController | null = new AbortController();\r\n let lazyCanceled = false;\r\n\r\n const loadLazy = (): Promise<any> => {\r\n lazyCache.promise = importFn()\r\n .then((module) => {\r\n if (!lazyCanceled) {\r\n lazyCache.status = \"success\";\r\n lazyCache.component = (module as any).default || module;\r\n }\r\n })\r\n .catch((err) => {\r\n if (!lazyCanceled) {\r\n if (lazyCache.retriesLeft > 0) {\r\n lazyCache.retriesLeft--;\r\n return loadLazy();\r\n }\r\n lazyCache.status = \"error\";\r\n lazyCache.error = err;\r\n }\r\n return Promise.reject(err);\r\n });\r\n return lazyCache.promise;\r\n };\r\n\r\n loadLazy();\r\n\r\n const cancelLazyLoad = (): void => {\r\n lazyCanceled = true;\r\n if (lazyAbortController) {\r\n lazyAbortController.abort();\r\n lazyAbortController = null;\r\n }\r\n };\r\n\r\n const LazyComponentWrapper = (props: P): any => {\r\n const ctx = activeContext;\r\n if (!ctx) throw new Error(\"nixLazyFormAsync: called outside component\");\r\n if (lazyCache.status === \"pending\") throw lazyCache.promise;\r\n if (lazyCache.status === \"error\") throw lazyCache.error;\r\n return lazyCache.component!(props);\r\n };\r\n\r\n /** ---------------- Form State ---------------- */\r\n const values = nixState({ ...initialValues });\r\n const errors = nixState<Partial<Record<keyof T, string>>>({});\r\n const touched = nixState<Partial<Record<keyof T, boolean>>>({});\r\n const isSubmitting = nixState(false);\r\n const isValid = nixComputed(() => Object.keys(errors.value).length === 0);\r\n\r\n /** Async submit state */\r\n const data = nixState<D | null>(null);\r\n const error = nixState<E | null>(null);\r\n const loading = nixState(false);\r\n\r\n let abortController: AbortController | null = null;\r\n let timerId: ReturnType<typeof setTimeout> | null = null;\r\n let lastInvokeTime = 0;\r\n let lastResult: D | null = null;\r\n let lastError: E | null = null;\r\n let pendingPromise: Promise<D> | null = null;\r\n\r\n /** ---------------- Form Validation ---------------- */\r\n\r\n function validate(fieldName: keyof T, value: any): string | null {\r\n const rules = validationRules[fieldName];\r\n if (!rules) return null;\r\n\r\n if (rules.required && !value)\r\n return rules.message || `${String(fieldName)} is required`;\r\n if (rules.minLength && value.length < rules.minLength)\r\n return (\r\n rules.message ||\r\n `${String(fieldName)} must be at least ${rules.minLength} characters`\r\n );\r\n if (rules.maxLength && value.length > rules.maxLength)\r\n return (\r\n rules.message ||\r\n `${String(fieldName)} must be at most ${rules.maxLength} characters`\r\n );\r\n if (rules.pattern && !rules.pattern.test(value))\r\n return rules.message || `${String(fieldName)} is invalid`;\r\n if (rules.custom && !rules.custom(value, values.value))\r\n return rules.message || `${String(fieldName)} is invalid`;\r\n\r\n return null;\r\n }\r\n\r\n function handleChange(fieldName: keyof T, value: any): void {\r\n values.value = { ...values.value, [fieldName]: value };\r\n\r\n if ((touched.value as Partial<Record<keyof T, boolean>>)[fieldName]) {\r\n const err = validate(fieldName, value);\r\n if (err) errors.value = { ...errors.value, [fieldName]: err };\r\n else {\r\n const newErrors = { ...errors.value };\r\n delete newErrors[fieldName];\r\n errors.value = newErrors;\r\n }\r\n }\r\n }\r\n\r\n function handleBlur(fieldName: keyof T): void {\r\n touched.value = { ...touched.value, [fieldName]: true };\r\n const err = validate(fieldName, values.value[fieldName]);\r\n if (err) errors.value = { ...errors.value, [fieldName]: err };\r\n }\r\n\r\n function validateAll(): boolean {\r\n const newErrors: Partial<Record<keyof T, string>> = {};\r\n (Object.keys(validationRules) as Array<keyof T>).forEach((fieldName) => {\r\n const err = validate(fieldName, values.value[fieldName]);\r\n if (err) newErrors[fieldName] = err;\r\n });\r\n errors.value = newErrors;\r\n return Object.keys(newErrors).length === 0;\r\n }\r\n\r\n /** ---------------- Debounced Async Submit ---------------- */\r\n\r\n async function invokeAsync(\r\n onSubmit: (values: T, signal: AbortSignal) => Promise<D>\r\n ): Promise<D | undefined> {\r\n // Use cache if enabled and lastResult exists\r\n if (cache && lastResult !== null) {\r\n data.value = lastResult ?? null;\r\n error.value = lastError ?? null;\r\n loading.value = false;\r\n return lastResult;\r\n }\r\n\r\n if (abortController) abortController.abort();\r\n abortController = new AbortController();\r\n const signal = abortController.signal;\r\n\r\n loading.value = true;\r\n error.value = null;\r\n\r\n pendingPromise = onSubmit(values.value, signal);\r\n\r\n try {\r\n const result = await pendingPromise;\r\n lastResult = result;\r\n data.value = result ?? null;\r\n return result;\r\n } catch (err: any) {\r\n if (err.name !== \"AbortError\") {\r\n lastError = err;\r\n error.value = err;\r\n }\r\n throw err;\r\n } finally {\r\n loading.value = false;\r\n pendingPromise = null;\r\n lastInvokeTime = Date.now();\r\n }\r\n }\r\n\r\n function handleSubmit(\r\n onSubmit: (values: T, signal: AbortSignal) => Promise<D>\r\n ): void {\r\n if (!validateAll()) return;\r\n\r\n const now = Date.now();\r\n const timeSinceLastInvoke = now - lastInvokeTime;\r\n const remainingTime = delay - timeSinceLastInvoke;\r\n const shouldInvokeLeading = leading && !timerId;\r\n\r\n if (maxWait !== undefined && timeSinceLastInvoke >= maxWait) {\r\n if (timerId) clearTimeout(timerId);\r\n timerId = null;\r\n void invokeAsync(onSubmit);\r\n return;\r\n }\r\n\r\n if (timerId) clearTimeout(timerId);\r\n\r\n if (shouldInvokeLeading) {\r\n void invokeAsync(onSubmit);\r\n return;\r\n }\r\n\r\n if (trailing) {\r\n timerId = setTimeout(\r\n () => {\r\n timerId = null;\r\n void invokeAsync(onSubmit);\r\n },\r\n remainingTime > 0 ? remainingTime : delay\r\n );\r\n }\r\n }\r\n\r\n /** Cancel pending submit */\r\n\r\n function cancelSubmit(): void {\r\n if (abortController) {\r\n abortController.abort();\r\n abortController = null;\r\n }\r\n if (timerId) clearTimeout(timerId);\r\n timerId = null;\r\n }\r\n\r\n function reset(): void {\r\n values.value = { ...initialValues };\r\n errors.value = {};\r\n touched.value = {};\r\n isSubmitting.value = false;\r\n cancelSubmit();\r\n cancelLazyLoad();\r\n data.value = null;\r\n error.value = null;\r\n loading.value = false;\r\n }\r\n\r\n function getFieldProps(fieldName: keyof T) {\r\n return {\r\n value: values.value[fieldName] || \"\",\r\n \"r-input\": (e: any) => handleChange(fieldName, e.target.value),\r\n \"r-blur\": () => handleBlur(fieldName),\r\n };\r\n }\r\n\r\n return {\r\n LazyComponentWrapper,\r\n values,\r\n errors,\r\n touched,\r\n isSubmitting,\r\n isValid,\r\n data,\r\n error,\r\n loading,\r\n handleChange,\r\n handleBlur,\r\n handleSubmit,\r\n cancelSubmit,\r\n reset,\r\n getFieldProps,\r\n };\r\n}\r\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"nixLocalStorage.d.ts","sourceRoot":"","sources":["../../hooks/nixLocalStorage.ts"],"names":[],"mappings":"AAiIA,wBAAgB,eAAe,CAAC,CAAC,EAC/B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,CAAC,GACT;IACD,KAAK,EAAE,CAAC,CAAC;IACT,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC;IACvB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,OAAO,EAAE,MAAM,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,OAAO,CAAC;CACxB,CA8FA"}