@mappoh/nova 0.1.16

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 (383) hide show
  1. package/dist/animation/parallax.d.ts +23 -0
  2. package/dist/animation/parallax.d.ts.map +1 -0
  3. package/dist/animation/parallax.js +96 -0
  4. package/dist/animation/parallax.js.map +1 -0
  5. package/dist/animation/scroll-animate.d.ts +30 -0
  6. package/dist/animation/scroll-animate.d.ts.map +1 -0
  7. package/dist/animation/scroll-animate.js +65 -0
  8. package/dist/animation/scroll-animate.js.map +1 -0
  9. package/dist/animation/scroll-observer.d.ts +32 -0
  10. package/dist/animation/scroll-observer.d.ts.map +1 -0
  11. package/dist/animation/scroll-observer.js +63 -0
  12. package/dist/animation/scroll-observer.js.map +1 -0
  13. package/dist/animation/smooth-scroll.d.ts +47 -0
  14. package/dist/animation/smooth-scroll.d.ts.map +1 -0
  15. package/dist/animation/smooth-scroll.js +169 -0
  16. package/dist/animation/smooth-scroll.js.map +1 -0
  17. package/dist/animation/text-reveal.d.ts +30 -0
  18. package/dist/animation/text-reveal.d.ts.map +1 -0
  19. package/dist/animation/text-reveal.js +164 -0
  20. package/dist/animation/text-reveal.js.map +1 -0
  21. package/dist/animation/ticker.d.ts +32 -0
  22. package/dist/animation/ticker.d.ts.map +1 -0
  23. package/dist/animation/ticker.js +62 -0
  24. package/dist/animation/ticker.js.map +1 -0
  25. package/dist/canvas/dot-grid.d.ts +50 -0
  26. package/dist/canvas/dot-grid.d.ts.map +1 -0
  27. package/dist/canvas/dot-grid.js +123 -0
  28. package/dist/canvas/dot-grid.js.map +1 -0
  29. package/dist/canvas/noise.d.ts +33 -0
  30. package/dist/canvas/noise.d.ts.map +1 -0
  31. package/dist/canvas/noise.js +241 -0
  32. package/dist/canvas/noise.js.map +1 -0
  33. package/dist/canvas/particles.d.ts +44 -0
  34. package/dist/canvas/particles.d.ts.map +1 -0
  35. package/dist/canvas/particles.js +138 -0
  36. package/dist/canvas/particles.js.map +1 -0
  37. package/dist/canvas/sequence.d.ts +43 -0
  38. package/dist/canvas/sequence.d.ts.map +1 -0
  39. package/dist/canvas/sequence.js +162 -0
  40. package/dist/canvas/sequence.js.map +1 -0
  41. package/dist/component/bind.d.ts +25 -0
  42. package/dist/component/bind.d.ts.map +1 -0
  43. package/dist/component/bind.js +28 -0
  44. package/dist/component/bind.js.map +1 -0
  45. package/dist/component/component.d.ts +76 -0
  46. package/dist/component/component.d.ts.map +1 -0
  47. package/dist/component/component.js +219 -0
  48. package/dist/component/component.js.map +1 -0
  49. package/dist/component/connect.d.ts +60 -0
  50. package/dist/component/connect.d.ts.map +1 -0
  51. package/dist/component/connect.js +115 -0
  52. package/dist/component/connect.js.map +1 -0
  53. package/dist/component/html.d.ts +35 -0
  54. package/dist/component/html.d.ts.map +1 -0
  55. package/dist/component/html.js +51 -0
  56. package/dist/component/html.js.map +1 -0
  57. package/dist/component/hydrate.d.ts +37 -0
  58. package/dist/component/hydrate.d.ts.map +1 -0
  59. package/dist/component/hydrate.js +242 -0
  60. package/dist/component/hydrate.js.map +1 -0
  61. package/dist/component/index.d.ts +9 -0
  62. package/dist/component/index.d.ts.map +1 -0
  63. package/dist/component/index.js +6 -0
  64. package/dist/component/index.js.map +1 -0
  65. package/dist/component/template.d.ts +30 -0
  66. package/dist/component/template.d.ts.map +1 -0
  67. package/dist/component/template.js +469 -0
  68. package/dist/component/template.js.map +1 -0
  69. package/dist/css/gradient-text.d.ts +40 -0
  70. package/dist/css/gradient-text.d.ts.map +1 -0
  71. package/dist/css/gradient-text.js +90 -0
  72. package/dist/css/gradient-text.js.map +1 -0
  73. package/dist/css/index.d.ts +3 -0
  74. package/dist/css/index.d.ts.map +1 -0
  75. package/dist/css/index.js +2 -0
  76. package/dist/css/index.js.map +1 -0
  77. package/dist/devtools/devtools.d.ts +27 -0
  78. package/dist/devtools/devtools.d.ts.map +1 -0
  79. package/dist/devtools/devtools.js +237 -0
  80. package/dist/devtools/devtools.js.map +1 -0
  81. package/dist/devtools/index.d.ts +3 -0
  82. package/dist/devtools/index.d.ts.map +1 -0
  83. package/dist/devtools/index.js +2 -0
  84. package/dist/devtools/index.js.map +1 -0
  85. package/dist/drag/drag.d.ts +38 -0
  86. package/dist/drag/drag.d.ts.map +1 -0
  87. package/dist/drag/drag.js +181 -0
  88. package/dist/drag/drag.js.map +1 -0
  89. package/dist/drag/index.d.ts +3 -0
  90. package/dist/drag/index.d.ts.map +1 -0
  91. package/dist/drag/index.js +2 -0
  92. package/dist/drag/index.js.map +1 -0
  93. package/dist/dropdown/dropdown.d.ts +55 -0
  94. package/dist/dropdown/dropdown.d.ts.map +1 -0
  95. package/dist/dropdown/dropdown.js +314 -0
  96. package/dist/dropdown/dropdown.js.map +1 -0
  97. package/dist/dropdown/group.d.ts +18 -0
  98. package/dist/dropdown/group.d.ts.map +1 -0
  99. package/dist/dropdown/group.js +119 -0
  100. package/dist/dropdown/group.js.map +1 -0
  101. package/dist/dropdown/index.d.ts +5 -0
  102. package/dist/dropdown/index.d.ts.map +1 -0
  103. package/dist/dropdown/index.js +3 -0
  104. package/dist/dropdown/index.js.map +1 -0
  105. package/dist/forms/form-engine.d.ts +91 -0
  106. package/dist/forms/form-engine.d.ts.map +1 -0
  107. package/dist/forms/form-engine.js +228 -0
  108. package/dist/forms/form-engine.js.map +1 -0
  109. package/dist/forms/index.d.ts +3 -0
  110. package/dist/forms/index.d.ts.map +1 -0
  111. package/dist/forms/index.js +2 -0
  112. package/dist/forms/index.js.map +1 -0
  113. package/dist/forms/validators.d.ts +20 -0
  114. package/dist/forms/validators.d.ts.map +1 -0
  115. package/dist/forms/validators.js +82 -0
  116. package/dist/forms/validators.js.map +1 -0
  117. package/dist/gallery/gallery.d.ts +66 -0
  118. package/dist/gallery/gallery.d.ts.map +1 -0
  119. package/dist/gallery/gallery.js +347 -0
  120. package/dist/gallery/gallery.js.map +1 -0
  121. package/dist/gallery/index.d.ts +3 -0
  122. package/dist/gallery/index.d.ts.map +1 -0
  123. package/dist/gallery/index.js +2 -0
  124. package/dist/gallery/index.js.map +1 -0
  125. package/dist/gesture/gesture.d.ts +44 -0
  126. package/dist/gesture/gesture.d.ts.map +1 -0
  127. package/dist/gesture/gesture.js +152 -0
  128. package/dist/gesture/gesture.js.map +1 -0
  129. package/dist/gesture/index.d.ts +3 -0
  130. package/dist/gesture/index.d.ts.map +1 -0
  131. package/dist/gesture/index.js +2 -0
  132. package/dist/gesture/index.js.map +1 -0
  133. package/dist/http/http.d.ts +44 -0
  134. package/dist/http/http.d.ts.map +1 -0
  135. package/dist/http/http.js +135 -0
  136. package/dist/http/http.js.map +1 -0
  137. package/dist/http/index.d.ts +3 -0
  138. package/dist/http/index.d.ts.map +1 -0
  139. package/dist/http/index.js +2 -0
  140. package/dist/http/index.js.map +1 -0
  141. package/dist/i18n/i18n.d.ts +28 -0
  142. package/dist/i18n/i18n.d.ts.map +1 -0
  143. package/dist/i18n/i18n.js +84 -0
  144. package/dist/i18n/i18n.js.map +1 -0
  145. package/dist/i18n/index.d.ts +3 -0
  146. package/dist/i18n/index.d.ts.map +1 -0
  147. package/dist/i18n/index.js +2 -0
  148. package/dist/i18n/index.js.map +1 -0
  149. package/dist/image/effects.d.ts +33 -0
  150. package/dist/image/effects.d.ts.map +1 -0
  151. package/dist/image/effects.js +236 -0
  152. package/dist/image/effects.js.map +1 -0
  153. package/dist/image/image.d.ts +83 -0
  154. package/dist/image/image.d.ts.map +1 -0
  155. package/dist/image/image.js +236 -0
  156. package/dist/image/image.js.map +1 -0
  157. package/dist/image/index.d.ts +5 -0
  158. package/dist/image/index.d.ts.map +1 -0
  159. package/dist/image/index.js +3 -0
  160. package/dist/image/index.js.map +1 -0
  161. package/dist/interaction/index.d.ts +3 -0
  162. package/dist/interaction/index.d.ts.map +1 -0
  163. package/dist/interaction/index.js +2 -0
  164. package/dist/interaction/index.js.map +1 -0
  165. package/dist/interaction/tilt.d.ts +30 -0
  166. package/dist/interaction/tilt.d.ts.map +1 -0
  167. package/dist/interaction/tilt.js +131 -0
  168. package/dist/interaction/tilt.js.map +1 -0
  169. package/dist/lazy/index.d.ts +3 -0
  170. package/dist/lazy/index.d.ts.map +1 -0
  171. package/dist/lazy/index.js +2 -0
  172. package/dist/lazy/index.js.map +1 -0
  173. package/dist/lazy/lazy.d.ts +42 -0
  174. package/dist/lazy/lazy.d.ts.map +1 -0
  175. package/dist/lazy/lazy.js +80 -0
  176. package/dist/lazy/lazy.js.map +1 -0
  177. package/dist/modal/index.d.ts +3 -0
  178. package/dist/modal/index.d.ts.map +1 -0
  179. package/dist/modal/index.js +2 -0
  180. package/dist/modal/index.js.map +1 -0
  181. package/dist/modal/modal.d.ts +39 -0
  182. package/dist/modal/modal.d.ts.map +1 -0
  183. package/dist/modal/modal.js +174 -0
  184. package/dist/modal/modal.js.map +1 -0
  185. package/dist/router/index.d.ts +3 -0
  186. package/dist/router/index.d.ts.map +1 -0
  187. package/dist/router/index.js +2 -0
  188. package/dist/router/index.js.map +1 -0
  189. package/dist/router/router.d.ts +80 -0
  190. package/dist/router/router.d.ts.map +1 -0
  191. package/dist/router/router.js +256 -0
  192. package/dist/router/router.js.map +1 -0
  193. package/dist/router/speculate.d.ts +28 -0
  194. package/dist/router/speculate.d.ts.map +1 -0
  195. package/dist/router/speculate.js +36 -0
  196. package/dist/router/speculate.js.map +1 -0
  197. package/dist/search/fuzzy.d.ts +16 -0
  198. package/dist/search/fuzzy.d.ts.map +1 -0
  199. package/dist/search/fuzzy.js +77 -0
  200. package/dist/search/fuzzy.js.map +1 -0
  201. package/dist/search/index.d.ts +5 -0
  202. package/dist/search/index.d.ts.map +1 -0
  203. package/dist/search/index.js +3 -0
  204. package/dist/search/index.js.map +1 -0
  205. package/dist/search/search.d.ts +56 -0
  206. package/dist/search/search.d.ts.map +1 -0
  207. package/dist/search/search.js +540 -0
  208. package/dist/search/search.js.map +1 -0
  209. package/dist/search/wasm.d.ts +35 -0
  210. package/dist/search/wasm.d.ts.map +1 -0
  211. package/dist/search/wasm.js +51 -0
  212. package/dist/search/wasm.js.map +1 -0
  213. package/dist/security/cors.d.ts +61 -0
  214. package/dist/security/cors.d.ts.map +1 -0
  215. package/dist/security/cors.js +174 -0
  216. package/dist/security/cors.js.map +1 -0
  217. package/dist/security/csp.d.ts +49 -0
  218. package/dist/security/csp.d.ts.map +1 -0
  219. package/dist/security/csp.js +143 -0
  220. package/dist/security/csp.js.map +1 -0
  221. package/dist/security/csrf.d.ts +47 -0
  222. package/dist/security/csrf.d.ts.map +1 -0
  223. package/dist/security/csrf.js +122 -0
  224. package/dist/security/csrf.js.map +1 -0
  225. package/dist/security/encrypt.d.ts +64 -0
  226. package/dist/security/encrypt.d.ts.map +1 -0
  227. package/dist/security/encrypt.js +129 -0
  228. package/dist/security/encrypt.js.map +1 -0
  229. package/dist/security/index.d.ts +21 -0
  230. package/dist/security/index.d.ts.map +1 -0
  231. package/dist/security/index.js +11 -0
  232. package/dist/security/index.js.map +1 -0
  233. package/dist/security/rate-limit.d.ts +57 -0
  234. package/dist/security/rate-limit.d.ts.map +1 -0
  235. package/dist/security/rate-limit.js +222 -0
  236. package/dist/security/rate-limit.js.map +1 -0
  237. package/dist/security/rbac.d.ts +84 -0
  238. package/dist/security/rbac.d.ts.map +1 -0
  239. package/dist/security/rbac.js +164 -0
  240. package/dist/security/rbac.js.map +1 -0
  241. package/dist/security/sanitize.d.ts +44 -0
  242. package/dist/security/sanitize.d.ts.map +1 -0
  243. package/dist/security/sanitize.js +230 -0
  244. package/dist/security/sanitize.js.map +1 -0
  245. package/dist/security/secure-store.d.ts +44 -0
  246. package/dist/security/secure-store.d.ts.map +1 -0
  247. package/dist/security/secure-store.js +164 -0
  248. package/dist/security/secure-store.js.map +1 -0
  249. package/dist/security/session.d.ts +76 -0
  250. package/dist/security/session.d.ts.map +1 -0
  251. package/dist/security/session.js +251 -0
  252. package/dist/security/session.js.map +1 -0
  253. package/dist/security/sri.d.ts +66 -0
  254. package/dist/security/sri.d.ts.map +1 -0
  255. package/dist/security/sri.js +159 -0
  256. package/dist/security/sri.js.map +1 -0
  257. package/dist/shortcuts/index.d.ts +3 -0
  258. package/dist/shortcuts/index.d.ts.map +1 -0
  259. package/dist/shortcuts/index.js +2 -0
  260. package/dist/shortcuts/index.js.map +1 -0
  261. package/dist/shortcuts/shortcuts.d.ts +43 -0
  262. package/dist/shortcuts/shortcuts.d.ts.map +1 -0
  263. package/dist/shortcuts/shortcuts.js +141 -0
  264. package/dist/shortcuts/shortcuts.js.map +1 -0
  265. package/dist/ssr/index.d.ts +3 -0
  266. package/dist/ssr/index.d.ts.map +1 -0
  267. package/dist/ssr/index.js +2 -0
  268. package/dist/ssr/index.js.map +1 -0
  269. package/dist/ssr/ssr.d.ts +62 -0
  270. package/dist/ssr/ssr.d.ts.map +1 -0
  271. package/dist/ssr/ssr.js +132 -0
  272. package/dist/ssr/ssr.js.map +1 -0
  273. package/dist/state/index.d.ts +5 -0
  274. package/dist/state/index.d.ts.map +1 -0
  275. package/dist/state/index.js +3 -0
  276. package/dist/state/index.js.map +1 -0
  277. package/dist/state/persistent.d.ts +31 -0
  278. package/dist/state/persistent.d.ts.map +1 -0
  279. package/dist/state/persistent.js +132 -0
  280. package/dist/state/persistent.js.map +1 -0
  281. package/dist/state/store.d.ts +31 -0
  282. package/dist/state/store.d.ts.map +1 -0
  283. package/dist/state/store.js +107 -0
  284. package/dist/state/store.js.map +1 -0
  285. package/dist/store/index.d.ts +3 -0
  286. package/dist/store/index.d.ts.map +1 -0
  287. package/dist/store/index.js +2 -0
  288. package/dist/store/index.js.map +1 -0
  289. package/dist/store/store.d.ts +36 -0
  290. package/dist/store/store.d.ts.map +1 -0
  291. package/dist/store/store.js +175 -0
  292. package/dist/store/store.js.map +1 -0
  293. package/dist/supabase/auth.d.ts +28 -0
  294. package/dist/supabase/auth.d.ts.map +1 -0
  295. package/dist/supabase/auth.js +47 -0
  296. package/dist/supabase/auth.js.map +1 -0
  297. package/dist/supabase/client.d.ts +18 -0
  298. package/dist/supabase/client.d.ts.map +1 -0
  299. package/dist/supabase/client.js +36 -0
  300. package/dist/supabase/client.js.map +1 -0
  301. package/dist/supabase/realtime.d.ts +22 -0
  302. package/dist/supabase/realtime.d.ts.map +1 -0
  303. package/dist/supabase/realtime.js +51 -0
  304. package/dist/supabase/realtime.js.map +1 -0
  305. package/dist/sw/index.d.ts +3 -0
  306. package/dist/sw/index.d.ts.map +1 -0
  307. package/dist/sw/index.js +2 -0
  308. package/dist/sw/index.js.map +1 -0
  309. package/dist/sw/sw.d.ts +49 -0
  310. package/dist/sw/sw.d.ts.map +1 -0
  311. package/dist/sw/sw.js +125 -0
  312. package/dist/sw/sw.js.map +1 -0
  313. package/dist/tabs/index.d.ts +3 -0
  314. package/dist/tabs/index.d.ts.map +1 -0
  315. package/dist/tabs/index.js +2 -0
  316. package/dist/tabs/index.js.map +1 -0
  317. package/dist/tabs/tabs.d.ts +34 -0
  318. package/dist/tabs/tabs.d.ts.map +1 -0
  319. package/dist/tabs/tabs.js +173 -0
  320. package/dist/tabs/tabs.js.map +1 -0
  321. package/dist/test/index.d.ts +3 -0
  322. package/dist/test/index.d.ts.map +1 -0
  323. package/dist/test/index.js +2 -0
  324. package/dist/test/index.js.map +1 -0
  325. package/dist/test/test.d.ts +37 -0
  326. package/dist/test/test.d.ts.map +1 -0
  327. package/dist/test/test.js +108 -0
  328. package/dist/test/test.js.map +1 -0
  329. package/dist/theme/index.d.ts +3 -0
  330. package/dist/theme/index.d.ts.map +1 -0
  331. package/dist/theme/index.js +2 -0
  332. package/dist/theme/index.js.map +1 -0
  333. package/dist/theme/theme.d.ts +40 -0
  334. package/dist/theme/theme.d.ts.map +1 -0
  335. package/dist/theme/theme.js +142 -0
  336. package/dist/theme/theme.js.map +1 -0
  337. package/dist/timeline/index.d.ts +3 -0
  338. package/dist/timeline/index.d.ts.map +1 -0
  339. package/dist/timeline/index.js +2 -0
  340. package/dist/timeline/index.js.map +1 -0
  341. package/dist/timeline/timeline.d.ts +44 -0
  342. package/dist/timeline/timeline.d.ts.map +1 -0
  343. package/dist/timeline/timeline.js +196 -0
  344. package/dist/timeline/timeline.js.map +1 -0
  345. package/dist/toast/index.d.ts +3 -0
  346. package/dist/toast/index.d.ts.map +1 -0
  347. package/dist/toast/index.js +2 -0
  348. package/dist/toast/index.js.map +1 -0
  349. package/dist/toast/toast.d.ts +31 -0
  350. package/dist/toast/toast.d.ts.map +1 -0
  351. package/dist/toast/toast.js +198 -0
  352. package/dist/toast/toast.js.map +1 -0
  353. package/dist/tooltip/index.d.ts +3 -0
  354. package/dist/tooltip/index.d.ts.map +1 -0
  355. package/dist/tooltip/index.js +2 -0
  356. package/dist/tooltip/index.js.map +1 -0
  357. package/dist/tooltip/tooltip.d.ts +27 -0
  358. package/dist/tooltip/tooltip.d.ts.map +1 -0
  359. package/dist/tooltip/tooltip.js +229 -0
  360. package/dist/tooltip/tooltip.js.map +1 -0
  361. package/dist/transition/index.d.ts +3 -0
  362. package/dist/transition/index.d.ts.map +1 -0
  363. package/dist/transition/index.js +2 -0
  364. package/dist/transition/index.js.map +1 -0
  365. package/dist/transition/transition.d.ts +31 -0
  366. package/dist/transition/transition.d.ts.map +1 -0
  367. package/dist/transition/transition.js +95 -0
  368. package/dist/transition/transition.js.map +1 -0
  369. package/dist/webgl/index.d.ts +3 -0
  370. package/dist/webgl/index.d.ts.map +1 -0
  371. package/dist/webgl/index.js +2 -0
  372. package/dist/webgl/index.js.map +1 -0
  373. package/dist/webgl/webgl.d.ts +49 -0
  374. package/dist/webgl/webgl.d.ts.map +1 -0
  375. package/dist/webgl/webgl.js +401 -0
  376. package/dist/webgl/webgl.js.map +1 -0
  377. package/package.json +269 -0
  378. package/styles/base/global.css +47 -0
  379. package/styles/base/reset.css +73 -0
  380. package/styles/tokens/colors.css +50 -0
  381. package/styles/tokens/spacing.css +46 -0
  382. package/styles/tokens/typography.css +37 -0
  383. package/styles/utilities/layout.css +46 -0
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Nova Engine — Supabase Client
3
+ *
4
+ * Singleton Supabase client. Call initSupabase() in your app entry point,
5
+ * or fall back to VITE_SUPABASE_* environment variables.
6
+ */
7
+ import { type SupabaseClient } from '@supabase/supabase-js';
8
+ /**
9
+ * Initialize the Supabase client with explicit credentials.
10
+ * Call this once at app startup before any other supabase module is used.
11
+ */
12
+ export declare function initSupabase(url: string, anonKey: string): SupabaseClient;
13
+ /**
14
+ * Get the Supabase client singleton.
15
+ * If initSupabase() was not called, falls back to import.meta.env variables.
16
+ */
17
+ export declare function getSupabase(): SupabaseClient;
18
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/supabase/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAM1E;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,cAAc,CAKzE;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,cAAc,CAc5C"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Nova Engine — Supabase Client
3
+ *
4
+ * Singleton Supabase client. Call initSupabase() in your app entry point,
5
+ * or fall back to VITE_SUPABASE_* environment variables.
6
+ */
7
+ import { createClient } from '@supabase/supabase-js';
8
+ let client = null;
9
+ let configUrl;
10
+ let configKey;
11
+ /**
12
+ * Initialize the Supabase client with explicit credentials.
13
+ * Call this once at app startup before any other supabase module is used.
14
+ */
15
+ export function initSupabase(url, anonKey) {
16
+ configUrl = url;
17
+ configKey = anonKey;
18
+ client = createClient(url, anonKey);
19
+ return client;
20
+ }
21
+ /**
22
+ * Get the Supabase client singleton.
23
+ * If initSupabase() was not called, falls back to import.meta.env variables.
24
+ */
25
+ export function getSupabase() {
26
+ if (!client) {
27
+ const url = configUrl ?? import.meta.env?.VITE_SUPABASE_URL;
28
+ const key = configKey ?? import.meta.env?.VITE_SUPABASE_ANON_KEY;
29
+ if (!url || !key) {
30
+ throw new Error('[Nova] Supabase not configured. Call initSupabase(url, key) or set VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY.');
31
+ }
32
+ client = createClient(url, key);
33
+ }
34
+ return client;
35
+ }
36
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/supabase/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAuB,MAAM,uBAAuB,CAAC;AAE1E,IAAI,MAAM,GAA0B,IAAI,CAAC;AACzC,IAAI,SAA6B,CAAC;AAClC,IAAI,SAA6B,CAAC;AAElC;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,OAAe;IACvD,SAAS,GAAG,GAAG,CAAC;IAChB,SAAS,GAAG,OAAO,CAAC;IACpB,MAAM,GAAG,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACpC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW;IACzB,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,GAAG,SAAS,IAAK,MAAM,CAAC,IAAY,CAAC,GAAG,EAAE,iBAAiB,CAAC;QACrE,MAAM,GAAG,GAAG,SAAS,IAAK,MAAM,CAAC,IAAY,CAAC,GAAG,EAAE,sBAAsB,CAAC;QAE1E,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACb,kHAAkH,CACnH,CAAC;QACJ,CAAC;QAED,MAAM,GAAG,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Nova Engine — Realtime Subscription Manager
3
+ *
4
+ * Subscribe to Supabase table changes with easy cleanup.
5
+ */
6
+ import type { RealtimePostgresChangesPayload } from '@supabase/supabase-js';
7
+ type ChangeEvent = 'INSERT' | 'UPDATE' | 'DELETE' | '*';
8
+ interface SubscribeOptions<T extends Record<string, unknown>> {
9
+ table: string;
10
+ event?: ChangeEvent;
11
+ schema?: string;
12
+ filter?: string;
13
+ onInsert?: (record: T) => void;
14
+ onUpdate?: (record: T, old: Partial<T>) => void;
15
+ onDelete?: (old: Partial<T>) => void;
16
+ onChange?: (payload: RealtimePostgresChangesPayload<T>) => void;
17
+ }
18
+ export declare function subscribe<T extends Record<string, unknown>>(id: string, options: SubscribeOptions<T>): () => void;
19
+ export declare function unsubscribe(id: string): void;
20
+ export declare function unsubscribeAll(): void;
21
+ export {};
22
+ //# sourceMappingURL=realtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime.d.ts","sourceRoot":"","sources":["../../src/supabase/realtime.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAmB,8BAA8B,EAAE,MAAM,uBAAuB,CAAC;AAE7F,KAAK,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,GAAG,CAAC;AAExD,UAAU,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC;IAC/B,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IAChD,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,8BAA8B,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;CACjE;AAID,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzD,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAC3B,MAAM,IAAI,CAwCZ;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAM5C;AAED,wBAAgB,cAAc,IAAI,IAAI,CAIrC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Nova Engine — Realtime Subscription Manager
3
+ *
4
+ * Subscribe to Supabase table changes with easy cleanup.
5
+ */
6
+ import { getSupabase } from './client';
7
+ const channels = new Map();
8
+ export function subscribe(id, options) {
9
+ // Unsubscribe existing channel with same id
10
+ unsubscribe(id);
11
+ const { table, event = '*', schema = 'public', filter } = options;
12
+ const channelConfig = {
13
+ event,
14
+ schema,
15
+ table,
16
+ ...(filter ? { filter } : {}),
17
+ };
18
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
+ const channel = getSupabase()
20
+ .channel(id)
21
+ .on('postgres_changes', channelConfig, (payload) => {
22
+ options.onChange?.(payload);
23
+ switch (payload.eventType) {
24
+ case 'INSERT':
25
+ options.onInsert?.(payload.new);
26
+ break;
27
+ case 'UPDATE':
28
+ options.onUpdate?.(payload.new, payload.old);
29
+ break;
30
+ case 'DELETE':
31
+ options.onDelete?.(payload.old);
32
+ break;
33
+ }
34
+ })
35
+ .subscribe();
36
+ channels.set(id, channel);
37
+ return () => unsubscribe(id);
38
+ }
39
+ export function unsubscribe(id) {
40
+ const channel = channels.get(id);
41
+ if (channel) {
42
+ getSupabase().removeChannel(channel);
43
+ channels.delete(id);
44
+ }
45
+ }
46
+ export function unsubscribeAll() {
47
+ for (const id of channels.keys()) {
48
+ unsubscribe(id);
49
+ }
50
+ }
51
+ //# sourceMappingURL=realtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime.js","sourceRoot":"","sources":["../../src/supabase/realtime.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAgBvC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA2B,CAAC;AAEpD,MAAM,UAAU,SAAS,CACvB,EAAU,EACV,OAA4B;IAE5B,4CAA4C;IAC5C,WAAW,CAAC,EAAE,CAAC,CAAC;IAEhB,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,GAAG,EAAE,MAAM,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAElE,MAAM,aAAa,GAAG;QACpB,KAAK;QACL,MAAM;QACN,KAAK;QACL,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACrB,CAAC;IAEX,8DAA8D;IAC9D,MAAM,OAAO,GAAI,WAAW,EAAE;SAC3B,OAAO,CAAC,EAAE,CAAS;SACnB,EAAE,CACD,kBAAkB,EAClB,aAAa,EACb,CAAC,OAA0C,EAAE,EAAE;QAC7C,OAAO,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC;QAE5B,QAAQ,OAAO,CAAC,SAAS,EAAE,CAAC;YAC1B,KAAK,QAAQ;gBACX,OAAO,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,GAAQ,CAAC,CAAC;gBACrC,MAAM;YACR,KAAK,QAAQ;gBACX,OAAO,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,GAAQ,EAAE,OAAO,CAAC,GAAiB,CAAC,CAAC;gBAChE,MAAM;YACR,KAAK,QAAQ;gBACX,OAAO,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,GAAiB,CAAC,CAAC;gBAC9C,MAAM;QACV,CAAC;IACH,CAAC,CACF;SACA,SAAS,EAAqB,CAAC;IAElC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAE1B,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,EAAU;IACpC,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjC,IAAI,OAAO,EAAE,CAAC;QACZ,WAAW,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,KAAK,MAAM,EAAE,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;QACjC,WAAW,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { generateSW, registerSW, unregisterAllSW } from './sw';
2
+ export type { CacheStrategy, RouteRule, SWOptions } from './sw';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sw/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AAC/D,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { generateSW, registerSW, unregisterAllSW } from './sw';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sw/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Nova Engine — Service Worker Toolkit
3
+ *
4
+ * Precaching, runtime caching strategies, and offline fallback utilities.
5
+ * This module provides helpers to GENERATE service worker code,
6
+ * not to run inside the SW context directly.
7
+ */
8
+ export type CacheStrategy = 'cache-first' | 'network-first' | 'stale-while-revalidate' | 'network-only' | 'cache-only';
9
+ export interface RouteRule {
10
+ /** URL pattern to match (string prefix or RegExp) */
11
+ match: string | RegExp;
12
+ /** Caching strategy for matched requests */
13
+ strategy: CacheStrategy;
14
+ /** Cache name. Default: 'nova-runtime' */
15
+ cacheName?: string;
16
+ /** Max entries in cache. Default: 50 */
17
+ maxEntries?: number;
18
+ /** Max age in seconds. Default: 86400 (1 day) */
19
+ maxAge?: number;
20
+ }
21
+ export interface SWOptions {
22
+ /** Cache name for precached assets. Default: 'nova-precache-v1' */
23
+ precacheName?: string;
24
+ /** URLs to precache on install */
25
+ precache?: string[];
26
+ /** Runtime caching rules */
27
+ routes?: RouteRule[];
28
+ /** Offline fallback page URL */
29
+ offlineFallback?: string;
30
+ /** Skip waiting on install. Default: true */
31
+ skipWaiting?: boolean;
32
+ /** Claim clients on activate. Default: true */
33
+ claimClients?: boolean;
34
+ }
35
+ /**
36
+ * Generate service worker JavaScript code as a string.
37
+ * Write this to a .js file and register it.
38
+ */
39
+ export declare function generateSW(options?: SWOptions): string;
40
+ /**
41
+ * Register a service worker from a given URL.
42
+ * Returns the ServiceWorkerRegistration.
43
+ */
44
+ export declare function registerSW(url: string, scope?: string): Promise<ServiceWorkerRegistration>;
45
+ /**
46
+ * Unregister all service workers.
47
+ */
48
+ export declare function unregisterAllSW(): Promise<void>;
49
+ //# sourceMappingURL=sw.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sw.d.ts","sourceRoot":"","sources":["../../src/sw/sw.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,eAAe,GAAG,wBAAwB,GAAG,cAAc,GAAG,YAAY,CAAC;AAEvH,MAAM,WAAW,SAAS;IACxB,qDAAqD;IACrD,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,4CAA4C;IAC5C,QAAQ,EAAE,aAAa,CAAC;IACxB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,4BAA4B;IAC5B,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,gCAAgC;IAChC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,+CAA+C;IAC/C,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,SAAc,GAAG,MAAM,CAmG1D;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAOhG;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAIrD"}
package/dist/sw/sw.js ADDED
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Nova Engine — Service Worker Toolkit
3
+ *
4
+ * Precaching, runtime caching strategies, and offline fallback utilities.
5
+ * This module provides helpers to GENERATE service worker code,
6
+ * not to run inside the SW context directly.
7
+ */
8
+ /**
9
+ * Generate service worker JavaScript code as a string.
10
+ * Write this to a .js file and register it.
11
+ */
12
+ export function generateSW(options = {}) {
13
+ const { precacheName = 'nova-precache-v1', precache = [], routes = [], offlineFallback, skipWaiting = true, claimClients = true, } = options;
14
+ const precacheList = JSON.stringify(precache);
15
+ const routeHandlers = routes.map((rule) => {
16
+ const match = rule.match instanceof RegExp ? rule.match.toString() : `'${rule.match}'`;
17
+ const cacheName = rule.cacheName ?? 'nova-runtime';
18
+ const maxEntries = rule.maxEntries ?? 50;
19
+ const maxAge = rule.maxAge ?? 86400;
20
+ return ` { match: ${match}, strategy: '${rule.strategy}', cacheName: '${cacheName}', maxEntries: ${maxEntries}, maxAge: ${maxAge} }`;
21
+ }).join(',\n');
22
+ return `// Nova Service Worker — Auto-generated
23
+ const PRECACHE_NAME = '${precacheName}';
24
+ const PRECACHE_URLS = ${precacheList};
25
+ const ROUTES = [\n${routeHandlers}\n];
26
+ ${offlineFallback ? `const OFFLINE_FALLBACK = '${offlineFallback}';` : 'const OFFLINE_FALLBACK = null;'}
27
+
28
+ self.addEventListener('install', (event) => {
29
+ ${skipWaiting ? 'self.skipWaiting();' : ''}
30
+ event.waitUntil(
31
+ caches.open(PRECACHE_NAME).then((cache) => cache.addAll(PRECACHE_URLS))
32
+ );
33
+ });
34
+
35
+ self.addEventListener('activate', (event) => {
36
+ ${claimClients ? 'event.waitUntil(self.clients.claim());' : ''}
37
+ });
38
+
39
+ function matchRoute(url) {
40
+ for (const route of ROUTES) {
41
+ if (typeof route.match === 'string') {
42
+ if (url.startsWith(route.match) || url.includes(route.match)) return route;
43
+ } else if (route.match.test && route.match.test(url)) {
44
+ return route;
45
+ }
46
+ }
47
+ return null;
48
+ }
49
+
50
+ async function cacheFirst(request, cacheName, maxAge) {
51
+ const cached = await caches.match(request);
52
+ if (cached) return cached;
53
+ const response = await fetch(request);
54
+ if (response.ok) {
55
+ const cache = await caches.open(cacheName);
56
+ cache.put(request, response.clone());
57
+ }
58
+ return response;
59
+ }
60
+
61
+ async function networkFirst(request, cacheName) {
62
+ try {
63
+ const response = await fetch(request);
64
+ if (response.ok) {
65
+ const cache = await caches.open(cacheName);
66
+ cache.put(request, response.clone());
67
+ }
68
+ return response;
69
+ } catch {
70
+ const cached = await caches.match(request);
71
+ return cached || (OFFLINE_FALLBACK ? caches.match(OFFLINE_FALLBACK) : new Response('Offline', { status: 503 }));
72
+ }
73
+ }
74
+
75
+ async function staleWhileRevalidate(request, cacheName) {
76
+ const cache = await caches.open(cacheName);
77
+ const cached = await cache.match(request);
78
+ const fetchPromise = fetch(request).then((response) => {
79
+ if (response.ok) cache.put(request, response.clone());
80
+ return response;
81
+ });
82
+ return cached || fetchPromise;
83
+ }
84
+
85
+ self.addEventListener('fetch', (event) => {
86
+ const url = event.request.url;
87
+ const route = matchRoute(url);
88
+ if (!route) return;
89
+
90
+ if (route.strategy === 'cache-first') {
91
+ event.respondWith(cacheFirst(event.request, route.cacheName, route.maxAge));
92
+ } else if (route.strategy === 'network-first') {
93
+ event.respondWith(networkFirst(event.request, route.cacheName));
94
+ } else if (route.strategy === 'stale-while-revalidate') {
95
+ event.respondWith(staleWhileRevalidate(event.request, route.cacheName));
96
+ } else if (route.strategy === 'cache-only') {
97
+ event.respondWith(caches.match(event.request).then(r => r || new Response('Not cached', { status: 404 })));
98
+ }
99
+ // network-only: do nothing, let browser handle
100
+ });
101
+ `;
102
+ }
103
+ /**
104
+ * Register a service worker from a given URL.
105
+ * Returns the ServiceWorkerRegistration.
106
+ */
107
+ export async function registerSW(url, scope) {
108
+ if (!('serviceWorker' in navigator)) {
109
+ throw new Error('Service Workers are not supported in this browser.');
110
+ }
111
+ const opts = {};
112
+ if (scope)
113
+ opts.scope = scope;
114
+ return navigator.serviceWorker.register(url, opts);
115
+ }
116
+ /**
117
+ * Unregister all service workers.
118
+ */
119
+ export async function unregisterAllSW() {
120
+ if (!('serviceWorker' in navigator))
121
+ return;
122
+ const registrations = await navigator.serviceWorker.getRegistrations();
123
+ await Promise.all(registrations.map((r) => r.unregister()));
124
+ }
125
+ //# sourceMappingURL=sw.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sw.js","sourceRoot":"","sources":["../../src/sw/sw.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgCH;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,UAAqB,EAAE;IAChD,MAAM,EACJ,YAAY,GAAG,kBAAkB,EACjC,QAAQ,GAAG,EAAE,EACb,MAAM,GAAG,EAAE,EACX,eAAe,EACf,WAAW,GAAG,IAAI,EAClB,YAAY,GAAG,IAAI,GACpB,GAAG,OAAO,CAAC;IAEZ,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,aAAa,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,YAAY,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC;QACvF,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,cAAc,CAAC;QACnD,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC;QACpC,OAAO,cAAc,KAAK,gBAAgB,IAAI,CAAC,QAAQ,kBAAkB,SAAS,kBAAkB,UAAU,aAAa,MAAM,IAAI,CAAC;IACxI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAEf,OAAO;yBACgB,YAAY;wBACb,YAAY;oBAChB,aAAa;EAC/B,eAAe,CAAC,CAAC,CAAC,6BAA6B,eAAe,IAAI,CAAC,CAAC,CAAC,gCAAgC;;;IAGnG,WAAW,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE;;;;;;;IAOxC,YAAY,CAAC,CAAC,CAAC,wCAAwC,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiE/D,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW,EAAE,KAAc;IAC1D,IAAI,CAAC,CAAC,eAAe,IAAI,SAAS,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IACD,MAAM,IAAI,GAAwB,EAAE,CAAC;IACrC,IAAI,KAAK;QAAE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IAC9B,OAAO,SAAS,CAAC,aAAa,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AACrD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,CAAC,CAAC,eAAe,IAAI,SAAS,CAAC;QAAE,OAAO;IAC5C,MAAM,aAAa,GAAG,MAAM,SAAS,CAAC,aAAa,CAAC,gBAAgB,EAAE,CAAC;IACvE,MAAM,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { createTabs } from './tabs';
2
+ export type { TabsOptions, TabsInstance } from './tabs';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tabs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { createTabs } from './tabs';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tabs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Nova Engine — Tabs
3
+ *
4
+ * Accessible tab panel switcher with full keyboard navigation,
5
+ * ARIA roles, and optional URL hash synchronisation.
6
+ * Purely behavioural — no injected styles.
7
+ */
8
+ export interface TabsOptions {
9
+ /** Container element holding tabs and panels */
10
+ container: HTMLElement;
11
+ /** Tab button selector or elements. Auto-discovers [role="tab"] if omitted */
12
+ tabs?: string | HTMLElement[];
13
+ /** Panel selector or elements. Auto-discovers [role="tabpanel"] if omitted */
14
+ panels?: string | HTMLElement[];
15
+ /** Initially active tab index. Default: 0 */
16
+ defaultIndex?: number;
17
+ /** Sync active tab with URL hash. Default: false */
18
+ syncHash?: boolean;
19
+ /** Vertical layout — use ArrowUp/Down instead of Left/Right. Default: false */
20
+ vertical?: boolean;
21
+ /** Callback when active tab changes */
22
+ onChange?: (index: number) => void;
23
+ }
24
+ export interface TabsInstance {
25
+ /** Programmatically switch to a tab by index */
26
+ select(index: number): void;
27
+ /** Current active tab index */
28
+ readonly index: number;
29
+ /** Cleanup all listeners and ARIA attributes */
30
+ destroy(): void;
31
+ }
32
+ /** Create an accessible tab switcher. */
33
+ export declare function createTabs(options: TabsOptions): TabsInstance;
34
+ //# sourceMappingURL=tabs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../src/tabs/tabs.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,WAAW;IAC1B,gDAAgD;IAChD,SAAS,EAAE,WAAW,CAAC;IACvB,8EAA8E;IAC9E,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,EAAE,CAAC;IAC9B,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,EAAE,CAAC;IAChC,6CAA6C;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oDAAoD;IACpD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,gDAAgD;IAChD,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,+BAA+B;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,gDAAgD;IAChD,OAAO,IAAI,IAAI,CAAC;CACjB;AA2BD,yCAAyC;AACzC,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,YAAY,CAyK7D"}
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Nova Engine — Tabs
3
+ *
4
+ * Accessible tab panel switcher with full keyboard navigation,
5
+ * ARIA roles, and optional URL hash synchronisation.
6
+ * Purely behavioural — no injected styles.
7
+ */
8
+ /* ---- Helpers ---- */
9
+ let idCounter = 0;
10
+ function ensureId(el, prefix) {
11
+ if (!el.id)
12
+ el.id = `${prefix}-${++idCounter}`;
13
+ return el.id;
14
+ }
15
+ function resolveElements(container, option, fallbackSelector) {
16
+ if (!option) {
17
+ return Array.from(container.querySelectorAll(fallbackSelector));
18
+ }
19
+ if (typeof option === 'string') {
20
+ return Array.from(container.querySelectorAll(option));
21
+ }
22
+ return option;
23
+ }
24
+ /* ---- Factory ---- */
25
+ /** Create an accessible tab switcher. */
26
+ export function createTabs(options) {
27
+ const { container, defaultIndex = 0, syncHash = false, vertical = false, onChange, } = options;
28
+ const tabEls = resolveElements(container, options.tabs, '[role="tab"]');
29
+ const panelEls = resolveElements(container, options.panels, '[role="tabpanel"]');
30
+ if (tabEls.length === 0 || panelEls.length === 0) {
31
+ throw new Error('[Nova Tabs] No tabs or panels found in container.');
32
+ }
33
+ let activeIndex = -1;
34
+ let destroyed = false;
35
+ const listeners = [];
36
+ function on(target, evt, fn) {
37
+ target.addEventListener(evt, fn);
38
+ listeners.push([target, evt, fn]);
39
+ }
40
+ // --- ARIA setup ---
41
+ // Find or designate the tablist
42
+ let tablist = container.querySelector('[role="tablist"]');
43
+ if (!tablist) {
44
+ // Use the container itself or the common parent of tabs
45
+ const parent = tabEls[0].parentElement;
46
+ tablist = parent && container.contains(parent) ? parent : container;
47
+ tablist.setAttribute('role', 'tablist');
48
+ }
49
+ if (vertical) {
50
+ tablist.setAttribute('aria-orientation', 'vertical');
51
+ }
52
+ for (let i = 0; i < tabEls.length; i++) {
53
+ const tab = tabEls[i];
54
+ const panel = panelEls[i];
55
+ if (!panel)
56
+ continue;
57
+ const tabId = ensureId(tab, 'nova-tab');
58
+ const panelId = ensureId(panel, 'nova-tabpanel');
59
+ tab.setAttribute('role', 'tab');
60
+ tab.setAttribute('aria-controls', panelId);
61
+ panel.setAttribute('role', 'tabpanel');
62
+ panel.setAttribute('aria-labelledby', tabId);
63
+ }
64
+ // --- Selection logic ---
65
+ function select(index, focus = true) {
66
+ if (destroyed)
67
+ return;
68
+ if (index < 0 || index >= tabEls.length)
69
+ return;
70
+ if (index === activeIndex)
71
+ return;
72
+ // Deactivate previous
73
+ if (activeIndex >= 0 && activeIndex < tabEls.length) {
74
+ tabEls[activeIndex].setAttribute('aria-selected', 'false');
75
+ tabEls[activeIndex].setAttribute('tabindex', '-1');
76
+ if (panelEls[activeIndex]) {
77
+ panelEls[activeIndex].setAttribute('hidden', '');
78
+ }
79
+ }
80
+ // Activate new
81
+ activeIndex = index;
82
+ tabEls[index].setAttribute('aria-selected', 'true');
83
+ tabEls[index].setAttribute('tabindex', '0');
84
+ if (focus)
85
+ tabEls[index].focus();
86
+ if (panelEls[index]) {
87
+ panelEls[index].removeAttribute('hidden');
88
+ }
89
+ // Hash sync
90
+ if (syncHash) {
91
+ const hash = tabEls[index].getAttribute('data-hash') || tabEls[index].id;
92
+ if (hash)
93
+ history.replaceState(null, '', `#${hash}`);
94
+ }
95
+ onChange?.(index);
96
+ }
97
+ // --- Click handler ---
98
+ for (let i = 0; i < tabEls.length; i++) {
99
+ on(tabEls[i], 'click', () => select(i));
100
+ }
101
+ // --- Keyboard handler ---
102
+ on(container, 'keydown', ((e) => {
103
+ const target = e.target;
104
+ if (!tabEls.includes(target))
105
+ return;
106
+ const prevKey = vertical ? 'ArrowUp' : 'ArrowLeft';
107
+ const nextKey = vertical ? 'ArrowDown' : 'ArrowRight';
108
+ let newIndex = activeIndex;
109
+ if (e.key === nextKey) {
110
+ e.preventDefault();
111
+ newIndex = activeIndex < tabEls.length - 1 ? activeIndex + 1 : 0;
112
+ }
113
+ else if (e.key === prevKey) {
114
+ e.preventDefault();
115
+ newIndex = activeIndex > 0 ? activeIndex - 1 : tabEls.length - 1;
116
+ }
117
+ else if (e.key === 'Home') {
118
+ e.preventDefault();
119
+ newIndex = 0;
120
+ }
121
+ else if (e.key === 'End') {
122
+ e.preventDefault();
123
+ newIndex = tabEls.length - 1;
124
+ }
125
+ if (newIndex !== activeIndex) {
126
+ select(newIndex);
127
+ }
128
+ }));
129
+ // --- Hash sync: initial check ---
130
+ function indexFromHash() {
131
+ const hash = location.hash.slice(1);
132
+ if (!hash)
133
+ return -1;
134
+ for (let i = 0; i < tabEls.length; i++) {
135
+ const tabHash = tabEls[i].getAttribute('data-hash') || tabEls[i].id;
136
+ if (tabHash === hash)
137
+ return i;
138
+ }
139
+ return -1;
140
+ }
141
+ if (syncHash) {
142
+ on(window, 'hashchange', () => {
143
+ const idx = indexFromHash();
144
+ if (idx >= 0)
145
+ select(idx, false);
146
+ });
147
+ }
148
+ // --- Initialise ---
149
+ const initialIndex = syncHash ? Math.max(indexFromHash(), 0) : defaultIndex;
150
+ // Set all tabs to inactive first
151
+ for (let i = 0; i < tabEls.length; i++) {
152
+ tabEls[i].setAttribute('aria-selected', 'false');
153
+ tabEls[i].setAttribute('tabindex', '-1');
154
+ if (panelEls[i])
155
+ panelEls[i].setAttribute('hidden', '');
156
+ }
157
+ // Activate the initial tab (without focus on init)
158
+ activeIndex = -1; // Reset so select() doesn't bail
159
+ select(initialIndex, false);
160
+ // --- Instance ---
161
+ return {
162
+ select(index) { select(index); },
163
+ get index() { return activeIndex; },
164
+ destroy() {
165
+ if (destroyed)
166
+ return;
167
+ destroyed = true;
168
+ for (const [t, e, fn] of listeners)
169
+ t.removeEventListener(e, fn);
170
+ },
171
+ };
172
+ }
173
+ //# sourceMappingURL=tabs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tabs.js","sourceRoot":"","sources":["../../src/tabs/tabs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { mount, simulate, waitForElement, flush, shadowSnapshot } from './test';
2
+ export type { MountOptions, MountedComponent } from './test';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAChF,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { mount, simulate, waitForElement, flush, shadowSnapshot } from './test';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Nova Engine — Testing Utilities
3
+ *
4
+ * Shadow DOM querying helpers, event simulation, and component lifecycle
5
+ * testing utilities for Nova components.
6
+ */
7
+ export interface MountOptions {
8
+ /** HTML attributes to set on the element */
9
+ attributes?: Record<string, string>;
10
+ /** Slot content (light DOM) as text */
11
+ slotText?: string;
12
+ /** Container to mount into. Default: creates a detached div */
13
+ container?: HTMLElement;
14
+ }
15
+ export interface MountedComponent {
16
+ element: HTMLElement;
17
+ shadow: ShadowRoot | null;
18
+ shadowQuery<T extends HTMLElement = HTMLElement>(selector: string): T | null;
19
+ shadowQueryAll<T extends HTMLElement = HTMLElement>(selector: string): T[];
20
+ query<T extends HTMLElement = HTMLElement>(selector: string): T | null;
21
+ shadowText(selector: string): string;
22
+ shadowClick(selector: string): void;
23
+ shadowInput(selector: string, value: string): void;
24
+ waitForUpdate(): Promise<void>;
25
+ unmount(): void;
26
+ }
27
+ /** Mount a custom element for testing. */
28
+ export declare function mount(tag: string, options?: MountOptions): MountedComponent;
29
+ /** Simulate a DOM event on an element. */
30
+ export declare function simulate(target: Element, eventType: string, options?: EventInit & Record<string, unknown>): void;
31
+ /** Wait for a custom element to be defined. */
32
+ export declare function waitForElement(tag: string, timeout?: number): Promise<void>;
33
+ /** Flush pending microtasks and animation frames. */
34
+ export declare function flush(): Promise<void>;
35
+ /** Create a text snapshot of a shadow DOM for comparison. */
36
+ export declare function shadowSnapshot(element: HTMLElement): string;
37
+ //# sourceMappingURL=test.d.ts.map