@mappoh/nova 0.1.16 → 0.2.1

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 (120) hide show
  1. package/README.md +46 -0
  2. package/dist/accordion/accordion.d.ts +39 -0
  3. package/dist/accordion/accordion.d.ts.map +1 -0
  4. package/dist/accordion/accordion.js +203 -0
  5. package/dist/accordion/accordion.js.map +1 -0
  6. package/dist/accordion/index.d.ts +3 -0
  7. package/dist/accordion/index.d.ts.map +1 -0
  8. package/dist/accordion/index.js +2 -0
  9. package/dist/accordion/index.js.map +1 -0
  10. package/dist/breadcrumb/breadcrumb.d.ts +37 -0
  11. package/dist/breadcrumb/breadcrumb.d.ts.map +1 -0
  12. package/dist/breadcrumb/breadcrumb.js +139 -0
  13. package/dist/breadcrumb/breadcrumb.js.map +1 -0
  14. package/dist/breadcrumb/index.d.ts +3 -0
  15. package/dist/breadcrumb/index.d.ts.map +1 -0
  16. package/dist/breadcrumb/index.js +2 -0
  17. package/dist/breadcrumb/index.js.map +1 -0
  18. package/dist/canvas/noise-wasm.d.ts +30 -0
  19. package/dist/canvas/noise-wasm.d.ts.map +1 -0
  20. package/dist/canvas/noise-wasm.js +82 -0
  21. package/dist/canvas/noise-wasm.js.map +1 -0
  22. package/dist/canvas/physics-wasm.d.ts +48 -0
  23. package/dist/canvas/physics-wasm.d.ts.map +1 -0
  24. package/dist/canvas/physics-wasm.js +66 -0
  25. package/dist/canvas/physics-wasm.js.map +1 -0
  26. package/dist/carousel/carousel.d.ts +51 -0
  27. package/dist/carousel/carousel.d.ts.map +1 -0
  28. package/dist/carousel/carousel.js +236 -0
  29. package/dist/carousel/carousel.js.map +1 -0
  30. package/dist/carousel/index.d.ts +3 -0
  31. package/dist/carousel/index.d.ts.map +1 -0
  32. package/dist/carousel/index.js +2 -0
  33. package/dist/carousel/index.js.map +1 -0
  34. package/dist/clipboard/clipboard.d.ts +15 -0
  35. package/dist/clipboard/clipboard.d.ts.map +1 -0
  36. package/dist/clipboard/clipboard.js +76 -0
  37. package/dist/clipboard/clipboard.js.map +1 -0
  38. package/dist/clipboard/index.d.ts +2 -0
  39. package/dist/clipboard/index.d.ts.map +1 -0
  40. package/dist/clipboard/index.js +2 -0
  41. package/dist/clipboard/index.js.map +1 -0
  42. package/dist/component/diff-wasm.d.ts +35 -0
  43. package/dist/component/diff-wasm.d.ts.map +1 -0
  44. package/dist/component/diff-wasm.js +52 -0
  45. package/dist/component/diff-wasm.js.map +1 -0
  46. package/dist/component/template.d.ts.map +1 -1
  47. package/dist/component/template.js +16 -5
  48. package/dist/component/template.js.map +1 -1
  49. package/dist/forms/wasm-validators.d.ts +60 -0
  50. package/dist/forms/wasm-validators.d.ts.map +1 -0
  51. package/dist/forms/wasm-validators.js +121 -0
  52. package/dist/forms/wasm-validators.js.map +1 -0
  53. package/dist/image/wasm.d.ts +47 -0
  54. package/dist/image/wasm.d.ts.map +1 -0
  55. package/dist/image/wasm.js +133 -0
  56. package/dist/image/wasm.js.map +1 -0
  57. package/dist/infinite-scroll/index.d.ts +3 -0
  58. package/dist/infinite-scroll/index.d.ts.map +1 -0
  59. package/dist/infinite-scroll/index.js +2 -0
  60. package/dist/infinite-scroll/index.js.map +1 -0
  61. package/dist/infinite-scroll/infinite-scroll.d.ts +33 -0
  62. package/dist/infinite-scroll/infinite-scroll.d.ts.map +1 -0
  63. package/dist/infinite-scroll/infinite-scroll.js +94 -0
  64. package/dist/infinite-scroll/infinite-scroll.js.map +1 -0
  65. package/dist/markdown/index.d.ts +2 -0
  66. package/dist/markdown/index.d.ts.map +1 -0
  67. package/dist/markdown/index.js +2 -0
  68. package/dist/markdown/index.js.map +1 -0
  69. package/dist/markdown/markdown.d.ts +14 -0
  70. package/dist/markdown/markdown.d.ts.map +1 -0
  71. package/dist/markdown/markdown.js +194 -0
  72. package/dist/markdown/markdown.js.map +1 -0
  73. package/dist/markdown/wasm.d.ts +11 -0
  74. package/dist/markdown/wasm.d.ts.map +1 -0
  75. package/dist/markdown/wasm.js +28 -0
  76. package/dist/markdown/wasm.js.map +1 -0
  77. package/dist/modal/modal.d.ts.map +1 -1
  78. package/dist/modal/modal.js +11 -1
  79. package/dist/modal/modal.js.map +1 -1
  80. package/dist/popover/index.d.ts +3 -0
  81. package/dist/popover/index.d.ts.map +1 -0
  82. package/dist/popover/index.js +2 -0
  83. package/dist/popover/index.js.map +1 -0
  84. package/dist/popover/popover.d.ts +56 -0
  85. package/dist/popover/popover.d.ts.map +1 -0
  86. package/dist/popover/popover.js +242 -0
  87. package/dist/popover/popover.js.map +1 -0
  88. package/dist/progress/index.d.ts +3 -0
  89. package/dist/progress/index.d.ts.map +1 -0
  90. package/dist/progress/index.js +2 -0
  91. package/dist/progress/index.js.map +1 -0
  92. package/dist/progress/progress.d.ts +39 -0
  93. package/dist/progress/progress.d.ts.map +1 -0
  94. package/dist/progress/progress.js +172 -0
  95. package/dist/progress/progress.js.map +1 -0
  96. package/dist/search/wasm.d.ts +2 -2
  97. package/dist/search/wasm.d.ts.map +1 -1
  98. package/dist/search/wasm.js +2 -3
  99. package/dist/search/wasm.js.map +1 -1
  100. package/dist/security/wasm-crypto.d.ts +53 -0
  101. package/dist/security/wasm-crypto.d.ts.map +1 -0
  102. package/dist/security/wasm-crypto.js +84 -0
  103. package/dist/security/wasm-crypto.js.map +1 -0
  104. package/dist/stepper/index.d.ts +3 -0
  105. package/dist/stepper/index.d.ts.map +1 -0
  106. package/dist/stepper/index.js +2 -0
  107. package/dist/stepper/index.js.map +1 -0
  108. package/dist/stepper/stepper.d.ts +49 -0
  109. package/dist/stepper/stepper.d.ts.map +1 -0
  110. package/dist/stepper/stepper.js +173 -0
  111. package/dist/stepper/stepper.js.map +1 -0
  112. package/dist/virtual-list/index.d.ts +3 -0
  113. package/dist/virtual-list/index.d.ts.map +1 -0
  114. package/dist/virtual-list/index.js +2 -0
  115. package/dist/virtual-list/index.js.map +1 -0
  116. package/dist/virtual-list/virtual-list.d.ts +37 -0
  117. package/dist/virtual-list/virtual-list.d.ts.map +1 -0
  118. package/dist/virtual-list/virtual-list.js +190 -0
  119. package/dist/virtual-list/virtual-list.js.map +1 -0
  120. package/package.json +80 -2
package/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # Nova v0.2.0
2
+
3
+ ## What's New
4
+
5
+ ### 9 TypeScript Modules
6
+
7
+ | Module | Import | Description |
8
+ |--------|--------|-------------|
9
+ | Clipboard | `@mappoh/nova/clipboard` | Copy/read text and HTML via Clipboard API with `execCommand` fallback |
10
+ | Accordion | `@mappoh/nova/accordion` | Collapsible panels with ARIA, keyboard nav, single/multiple mode |
11
+ | Breadcrumb | `@mappoh/nova/breadcrumb` | Navigation breadcrumbs with JSON-LD structured data |
12
+ | Progress | `@mappoh/nova/progress` | Linear and circular (SVG) progress bars, determinate/indeterminate |
13
+ | Infinite Scroll | `@mappoh/nova/infinite-scroll` | IntersectionObserver-based loading with idle/loading/done states |
14
+ | Popover | `@mappoh/nova/popover` | Positioned popovers with flip/shift, click/hover/focus triggers |
15
+ | Stepper | `@mappoh/nova/stepper` | Multi-step wizard with async validation, horizontal/vertical layout |
16
+ | Carousel | `@mappoh/nova/carousel` | CSS scroll-snap carousel with pointer drag, auto-play, dots, arrows |
17
+ | Virtual List | `@mappoh/nova/virtual-list` | DOM-recycling virtual scroller with fixed or variable row heights |
18
+
19
+ ### 7 WASM Accelerators
20
+
21
+ Optional Rust-compiled modules for performance-critical paths. Each has a pure TypeScript fallback.
22
+
23
+ | Module | Import | Description |
24
+ |--------|--------|-------------|
25
+ | Markdown | `@mappoh/nova/markdown/wasm` | CommonMark + GFM parser |
26
+ | Noise | `@mappoh/nova/canvas/noise-wasm` | Batch simplex/Perlin/Worley noise with FBM buffer fill |
27
+ | Validation | `@mappoh/nova/forms/wasm-validators` | RFC 5322 email, Luhn credit card, IBAN, password strength |
28
+ | Image | `@mappoh/nova/image/wasm` | Pixel-level grayscale, sepia, blur, sharpen, crop, rotate, resize |
29
+ | Physics | `@mappoh/nova/canvas/physics-wasm` | 2D particle dynamics with Verlet integration and spatial hashing |
30
+ | Crypto | `@mappoh/nova/security/wasm-crypto` | Argon2id, bcrypt, PBKDF2-SHA256 password hashing |
31
+ | Diff | `@mappoh/nova/component/diff-wasm` | LIS-based keyed list reconciliation for minimal DOM ops |
32
+
33
+ ### Infrastructure
34
+
35
+ - **Cargo workspace** — `wasm/` is now a workspace with 8 crates sharing deps and release profile
36
+ - **Build scripts** — `npm run build:all` compiles WASM + TypeScript in one step
37
+ - **17 new package exports** — every module has a dedicated entry point
38
+
39
+ ## Security Hardening
40
+
41
+ - **Modal** — HTML string content is sanitized (scripts and `on*` handlers stripped)
42
+ - **Markdown** — URL attributes are escaped; `javascript:`/`vbscript:` URIs blocked
43
+ - **Breadcrumb** — `href` sanitized against dangerous URIs; `icon` renders as text
44
+ - **Crypto WASM** — CSPRNG for salt generation; minimum parameter bounds on verify; defaults raised to OWASP recommendations
45
+
46
+ See [CHANGELOG.md](./CHANGELOG.md) for the full release notes and breaking changes.
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Nova Engine — Accordion
3
+ *
4
+ * Accessible expandable panels with keyboard navigation,
5
+ * ARIA attributes, and CSS-animated expand/collapse.
6
+ */
7
+ export interface AccordionOptions {
8
+ /** Container element holding accordion headers and panels */
9
+ container: HTMLElement;
10
+ /** Header selector or elements. Auto-discovers [data-accordion-header] if omitted */
11
+ headers?: string | HTMLElement[];
12
+ /** Panel selector or elements. Auto-discovers [data-accordion-panel] if omitted */
13
+ panels?: string | HTMLElement[];
14
+ /** Allow multiple panels to be open simultaneously. Default: false */
15
+ multiple?: boolean;
16
+ /** Initially open panel indices. Default: [] */
17
+ defaultOpen?: number[];
18
+ /** Enable animated expand/collapse. Default: true */
19
+ animated?: boolean;
20
+ /** Callback when a panel is toggled */
21
+ onChange?: (index: number, open: boolean) => void;
22
+ }
23
+ export interface AccordionInstance {
24
+ /** Open a panel by index */
25
+ open(index: number): void;
26
+ /** Close a panel by index */
27
+ close(index: number): void;
28
+ /** Toggle a panel by index */
29
+ toggle(index: number): void;
30
+ /** Open all panels (only in multiple mode) */
31
+ openAll(): void;
32
+ /** Close all panels */
33
+ closeAll(): void;
34
+ /** Cleanup all listeners and ARIA attributes */
35
+ destroy(): void;
36
+ }
37
+ /** Create an accessible accordion. */
38
+ export declare function createAccordion(options: AccordionOptions): AccordionInstance;
39
+ //# sourceMappingURL=accordion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accordion.d.ts","sourceRoot":"","sources":["../../src/accordion/accordion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,6DAA6D;IAC7D,SAAS,EAAE,WAAW,CAAC;IACvB,qFAAqF;IACrF,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW,EAAE,CAAC;IACjC,mFAAmF;IACnF,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,EAAE,CAAC;IAChC,sEAAsE;IACtE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACnD;AAED,MAAM,WAAW,iBAAiB;IAChC,4BAA4B;IAC5B,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,6BAA6B;IAC7B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,8BAA8B;IAC9B,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,8CAA8C;IAC9C,OAAO,IAAI,IAAI,CAAC;IAChB,uBAAuB;IACvB,QAAQ,IAAI,IAAI,CAAC;IACjB,gDAAgD;IAChD,OAAO,IAAI,IAAI,CAAC;CACjB;AAqCD,sCAAsC;AACtC,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,iBAAiB,CAsL5E"}
@@ -0,0 +1,203 @@
1
+ /**
2
+ * Nova Engine — Accordion
3
+ *
4
+ * Accessible expandable panels with keyboard navigation,
5
+ * ARIA attributes, and CSS-animated expand/collapse.
6
+ */
7
+ let idCounter = 0;
8
+ function ensureId(el, prefix) {
9
+ if (!el.id)
10
+ el.id = `${prefix}-${++idCounter}`;
11
+ return el.id;
12
+ }
13
+ function resolveElements(container, option, fallbackSelector) {
14
+ if (!option) {
15
+ return Array.from(container.querySelectorAll(fallbackSelector));
16
+ }
17
+ if (typeof option === 'string') {
18
+ return Array.from(container.querySelectorAll(option));
19
+ }
20
+ return option;
21
+ }
22
+ const STYLE_ID = 'nova-accordion-styles';
23
+ function injectStyles() {
24
+ if (document.getElementById(STYLE_ID))
25
+ return;
26
+ const s = document.createElement('style');
27
+ s.id = STYLE_ID;
28
+ s.textContent = `
29
+ .nova-accordion-panel{overflow:hidden;transition:max-height 0.3s ease,opacity 0.3s ease}
30
+ .nova-accordion-panel[hidden]{display:block!important;max-height:0!important;opacity:0;pointer-events:none}
31
+ .nova-accordion-panel--open{opacity:1;pointer-events:auto}
32
+ `;
33
+ document.head.appendChild(s);
34
+ }
35
+ /** Create an accessible accordion. */
36
+ export function createAccordion(options) {
37
+ const { container, multiple = false, defaultOpen = [], animated = true, onChange, } = options;
38
+ const headerEls = resolveElements(container, options.headers, '[data-accordion-header]');
39
+ const panelEls = resolveElements(container, options.panels, '[data-accordion-panel]');
40
+ if (headerEls.length === 0 || panelEls.length === 0) {
41
+ throw new Error('[Nova Accordion] No headers or panels found in container.');
42
+ }
43
+ let destroyed = false;
44
+ const openSet = new Set(defaultOpen);
45
+ const listeners = [];
46
+ function on(target, evt, fn) {
47
+ target.addEventListener(evt, fn);
48
+ listeners.push([target, evt, fn]);
49
+ }
50
+ if (animated)
51
+ injectStyles();
52
+ // --- ARIA setup ---
53
+ for (let i = 0; i < headerEls.length; i++) {
54
+ const header = headerEls[i];
55
+ const panel = panelEls[i];
56
+ if (!panel)
57
+ continue;
58
+ const headerId = ensureId(header, 'nova-accordion-header');
59
+ const panelId = ensureId(panel, 'nova-accordion-panel');
60
+ header.setAttribute('role', 'button');
61
+ header.setAttribute('aria-expanded', 'false');
62
+ header.setAttribute('aria-controls', panelId);
63
+ header.setAttribute('tabindex', '0');
64
+ panel.setAttribute('role', 'region');
65
+ panel.setAttribute('aria-labelledby', headerId);
66
+ if (animated) {
67
+ panel.classList.add('nova-accordion-panel');
68
+ }
69
+ }
70
+ // --- Open/close logic ---
71
+ function applyState(index, open) {
72
+ if (index < 0 || index >= headerEls.length)
73
+ return;
74
+ const header = headerEls[index];
75
+ const panel = panelEls[index];
76
+ if (!panel)
77
+ return;
78
+ header.setAttribute('aria-expanded', String(open));
79
+ if (open) {
80
+ panel.removeAttribute('hidden');
81
+ if (animated) {
82
+ panel.classList.add('nova-accordion-panel--open');
83
+ panel.style.maxHeight = `${panel.scrollHeight}px`;
84
+ }
85
+ }
86
+ else {
87
+ if (animated) {
88
+ panel.classList.remove('nova-accordion-panel--open');
89
+ panel.style.maxHeight = '0';
90
+ panel.setAttribute('hidden', '');
91
+ }
92
+ else {
93
+ panel.setAttribute('hidden', '');
94
+ }
95
+ }
96
+ }
97
+ function openPanel(index) {
98
+ if (destroyed)
99
+ return;
100
+ if (openSet.has(index))
101
+ return;
102
+ if (!multiple) {
103
+ // Close all others
104
+ for (const i of openSet) {
105
+ openSet.delete(i);
106
+ applyState(i, false);
107
+ onChange?.(i, false);
108
+ }
109
+ }
110
+ openSet.add(index);
111
+ applyState(index, true);
112
+ onChange?.(index, true);
113
+ }
114
+ function closePanel(index) {
115
+ if (destroyed)
116
+ return;
117
+ if (!openSet.has(index))
118
+ return;
119
+ openSet.delete(index);
120
+ applyState(index, false);
121
+ onChange?.(index, false);
122
+ }
123
+ function togglePanel(index) {
124
+ if (openSet.has(index)) {
125
+ closePanel(index);
126
+ }
127
+ else {
128
+ openPanel(index);
129
+ }
130
+ }
131
+ // --- Click handlers ---
132
+ for (let i = 0; i < headerEls.length; i++) {
133
+ on(headerEls[i], 'click', () => togglePanel(i));
134
+ on(headerEls[i], 'keydown', ((e) => {
135
+ if (e.key === 'Enter' || e.key === ' ') {
136
+ e.preventDefault();
137
+ togglePanel(i);
138
+ }
139
+ }));
140
+ }
141
+ // --- Keyboard navigation ---
142
+ on(container, 'keydown', ((e) => {
143
+ const target = e.target;
144
+ const idx = headerEls.indexOf(target);
145
+ if (idx === -1)
146
+ return;
147
+ let newIndex = idx;
148
+ if (e.key === 'ArrowDown') {
149
+ e.preventDefault();
150
+ newIndex = idx < headerEls.length - 1 ? idx + 1 : 0;
151
+ }
152
+ else if (e.key === 'ArrowUp') {
153
+ e.preventDefault();
154
+ newIndex = idx > 0 ? idx - 1 : headerEls.length - 1;
155
+ }
156
+ else if (e.key === 'Home') {
157
+ e.preventDefault();
158
+ newIndex = 0;
159
+ }
160
+ else if (e.key === 'End') {
161
+ e.preventDefault();
162
+ newIndex = headerEls.length - 1;
163
+ }
164
+ if (newIndex !== idx) {
165
+ headerEls[newIndex].focus();
166
+ }
167
+ }));
168
+ // --- Initialise ---
169
+ for (let i = 0; i < panelEls.length; i++) {
170
+ if (openSet.has(i)) {
171
+ applyState(i, true);
172
+ }
173
+ else {
174
+ applyState(i, false);
175
+ }
176
+ }
177
+ // --- Instance ---
178
+ return {
179
+ open(index) { openPanel(index); },
180
+ close(index) { closePanel(index); },
181
+ toggle(index) { togglePanel(index); },
182
+ openAll() {
183
+ if (destroyed)
184
+ return;
185
+ for (let i = 0; i < headerEls.length; i++)
186
+ openPanel(i);
187
+ },
188
+ closeAll() {
189
+ if (destroyed)
190
+ return;
191
+ for (const i of [...openSet])
192
+ closePanel(i);
193
+ },
194
+ destroy() {
195
+ if (destroyed)
196
+ return;
197
+ destroyed = true;
198
+ for (const [t, e, fn] of listeners)
199
+ t.removeEventListener(e, fn);
200
+ },
201
+ };
202
+ }
203
+ //# sourceMappingURL=accordion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accordion.js","sourceRoot":"","sources":["../../src/accordion/accordion.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { createAccordion } from './accordion';
2
+ export type { AccordionOptions, AccordionInstance } from './accordion';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/accordion/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { createAccordion } from './accordion';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/accordion/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Nova Engine — Breadcrumb
3
+ *
4
+ * Accessible breadcrumb navigation with ARIA landmarks
5
+ * and optional JSON-LD structured data injection.
6
+ */
7
+ export interface BreadcrumbItem {
8
+ /** Display label */
9
+ label: string;
10
+ /** URL to link to (omit for the current page) */
11
+ href?: string;
12
+ /** Optional icon text (emoji or character) */
13
+ icon?: string;
14
+ }
15
+ export interface BreadcrumbOptions {
16
+ /** Container element to render into */
17
+ container: HTMLElement;
18
+ /** Breadcrumb items (last item is current page) */
19
+ items: BreadcrumbItem[];
20
+ /** Separator string between items. Default: '/' */
21
+ separator?: string;
22
+ /** Extra CSS class on the nav element */
23
+ class?: string;
24
+ /** Click callback (for SPA navigation) */
25
+ onClick?: (item: BreadcrumbItem, index: number, event: MouseEvent) => void;
26
+ /** Inject JSON-LD structured data. Default: true */
27
+ jsonLd?: boolean;
28
+ }
29
+ export interface BreadcrumbInstance {
30
+ /** Replace all breadcrumb items */
31
+ setItems(items: BreadcrumbItem[]): void;
32
+ /** Remove breadcrumb from DOM and clean up */
33
+ destroy(): void;
34
+ }
35
+ /** Create an accessible breadcrumb navigation. */
36
+ export declare function createBreadcrumb(options: BreadcrumbOptions): BreadcrumbInstance;
37
+ //# sourceMappingURL=breadcrumb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"breadcrumb.d.ts","sourceRoot":"","sources":["../../src/breadcrumb/breadcrumb.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,cAAc;IAC7B,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,uCAAuC;IACvC,SAAS,EAAE,WAAW,CAAC;IACvB,mDAAmD;IACnD,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IAC3E,oDAAoD;IACpD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,mCAAmC;IACnC,QAAQ,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;IACxC,8CAA8C;IAC9C,OAAO,IAAI,IAAI,CAAC;CACjB;AAiCD,kDAAkD;AAClD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,kBAAkB,CAkH/E"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Nova Engine — Breadcrumb
3
+ *
4
+ * Accessible breadcrumb navigation with ARIA landmarks
5
+ * and optional JSON-LD structured data injection.
6
+ */
7
+ const STYLE_ID = 'nova-breadcrumb-styles';
8
+ function injectStyles() {
9
+ if (document.getElementById(STYLE_ID))
10
+ return;
11
+ const s = document.createElement('style');
12
+ s.id = STYLE_ID;
13
+ s.textContent = `
14
+ .nova-breadcrumb{display:flex;align-items:center;gap:0.5rem;font-size:0.875rem;list-style:none;margin:0;padding:0}
15
+ .nova-breadcrumb li{display:flex;align-items:center;gap:0.5rem}
16
+ .nova-breadcrumb a{color:var(--color-link,#a78bfa);text-decoration:none}
17
+ .nova-breadcrumb a:hover{text-decoration:underline}
18
+ .nova-breadcrumb-separator{color:var(--color-muted,rgba(255,255,255,0.4));user-select:none}
19
+ .nova-breadcrumb-current{color:var(--color-text,rgba(255,255,255,0.87))}
20
+ `;
21
+ document.head.appendChild(s);
22
+ }
23
+ function sanitizeHref(href) {
24
+ const trimmed = href.trim().toLowerCase();
25
+ if (trimmed.startsWith('javascript:') || trimmed.startsWith('data:') || trimmed.startsWith('vbscript:')) {
26
+ return '#';
27
+ }
28
+ return href;
29
+ }
30
+ function appendIcon(parent, icon) {
31
+ const span = document.createElement('span');
32
+ span.textContent = icon;
33
+ parent.appendChild(span);
34
+ }
35
+ /** Create an accessible breadcrumb navigation. */
36
+ export function createBreadcrumb(options) {
37
+ const { container, separator = '/', class: className, onClick, jsonLd = true, } = options;
38
+ let destroyed = false;
39
+ let items = options.items;
40
+ let nav = null;
41
+ let scriptEl = null;
42
+ const listeners = [];
43
+ function on(target, evt, fn) {
44
+ target.addEventListener(evt, fn);
45
+ listeners.push([target, evt, fn]);
46
+ }
47
+ injectStyles();
48
+ function render() {
49
+ // Clean up old listeners
50
+ for (const [t, e, fn] of listeners)
51
+ t.removeEventListener(e, fn);
52
+ listeners.length = 0;
53
+ // Remove old elements
54
+ if (nav)
55
+ nav.remove();
56
+ if (scriptEl)
57
+ scriptEl.remove();
58
+ // Build nav
59
+ nav = document.createElement('nav');
60
+ nav.setAttribute('aria-label', 'Breadcrumb');
61
+ if (className)
62
+ nav.className = className;
63
+ const ol = document.createElement('ol');
64
+ ol.className = 'nova-breadcrumb';
65
+ for (let i = 0; i < items.length; i++) {
66
+ const item = items[i];
67
+ const isLast = i === items.length - 1;
68
+ const li = document.createElement('li');
69
+ if (isLast) {
70
+ const span = document.createElement('span');
71
+ span.className = 'nova-breadcrumb-current';
72
+ span.setAttribute('aria-current', 'page');
73
+ if (item.icon)
74
+ appendIcon(span, item.icon);
75
+ span.append(item.label);
76
+ li.appendChild(span);
77
+ }
78
+ else {
79
+ const a = document.createElement('a');
80
+ a.href = sanitizeHref(item.href || '#');
81
+ if (item.icon)
82
+ appendIcon(a, item.icon);
83
+ a.append(item.label);
84
+ if (onClick) {
85
+ on(a, 'click', ((e) => {
86
+ onClick(item, i, e);
87
+ }));
88
+ }
89
+ li.appendChild(a);
90
+ // Separator
91
+ const sep = document.createElement('span');
92
+ sep.className = 'nova-breadcrumb-separator';
93
+ sep.setAttribute('aria-hidden', 'true');
94
+ sep.textContent = separator;
95
+ li.appendChild(sep);
96
+ }
97
+ ol.appendChild(li);
98
+ }
99
+ nav.appendChild(ol);
100
+ container.appendChild(nav);
101
+ // JSON-LD
102
+ if (jsonLd && items.length > 0) {
103
+ scriptEl = document.createElement('script');
104
+ scriptEl.type = 'application/ld+json';
105
+ scriptEl.textContent = JSON.stringify({
106
+ '@context': 'https://schema.org',
107
+ '@type': 'BreadcrumbList',
108
+ itemListElement: items.map((item, i) => ({
109
+ '@type': 'ListItem',
110
+ position: i + 1,
111
+ name: item.label,
112
+ ...(item.href ? { item: item.href } : {}),
113
+ })),
114
+ });
115
+ container.appendChild(scriptEl);
116
+ }
117
+ }
118
+ render();
119
+ return {
120
+ setItems(newItems) {
121
+ if (destroyed)
122
+ return;
123
+ items = newItems;
124
+ render();
125
+ },
126
+ destroy() {
127
+ if (destroyed)
128
+ return;
129
+ destroyed = true;
130
+ for (const [t, e, fn] of listeners)
131
+ t.removeEventListener(e, fn);
132
+ if (nav)
133
+ nav.remove();
134
+ if (scriptEl)
135
+ scriptEl.remove();
136
+ },
137
+ };
138
+ }
139
+ //# sourceMappingURL=breadcrumb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"breadcrumb.js","sourceRoot":"","sources":["../../src/breadcrumb/breadcrumb.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { createBreadcrumb } from './breadcrumb';
2
+ export type { BreadcrumbOptions, BreadcrumbInstance, BreadcrumbItem } from './breadcrumb';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/breadcrumb/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { createBreadcrumb } from './breadcrumb';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/breadcrumb/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Nova Engine — Noise WASM Accelerator
3
+ *
4
+ * High-performance noise generation for canvas rendering.
5
+ * Replaces the per-pixel JS loop with a single WASM call.
6
+ */
7
+ /** Initialize the WASM noise module. */
8
+ export declare function initWasm(): Promise<void>;
9
+ /** Check if the WASM noise module is loaded. */
10
+ export declare function isReady(): boolean;
11
+ export type NoiseType = 'simplex' | 'perlin' | 'worley';
12
+ /** Generate a full FBM noise buffer using WASM. Returns null if WASM not loaded. */
13
+ export declare function fbmBuffer(seed: number, width: number, height: number, options?: {
14
+ scale?: number;
15
+ octaves?: number;
16
+ lacunarity?: number;
17
+ gain?: number;
18
+ type?: NoiseType;
19
+ }): Float32Array | null;
20
+ /** Render noise to a canvas using WASM. Returns a cleanup function. */
21
+ export declare function renderNoiseWasm(canvas: string | HTMLCanvasElement, options?: {
22
+ seed?: number;
23
+ scale?: number;
24
+ octaves?: number;
25
+ type?: NoiseType;
26
+ animate?: boolean;
27
+ speed?: number;
28
+ colorFn?: (value: number) => [number, number, number, number];
29
+ }): () => void;
30
+ //# sourceMappingURL=noise-wasm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"noise-wasm.d.ts","sourceRoot":"","sources":["../../src/canvas/noise-wasm.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAgBH,wCAAwC;AACxC,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAW9C;AAED,gDAAgD;AAChD,wBAAgB,OAAO,IAAI,OAAO,CAEjC;AAED,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAExD,oFAAoF;AACpF,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAC3C,OAAO,GAAE;IACP,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,SAAS,CAAC;CAC5B,GACL,YAAY,GAAG,IAAI,CAarB;AAED,uEAAuE;AACvE,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,GAAG,iBAAiB,EAClC,OAAO,GAAE;IACP,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAChD,IAAI,CAAC,EAAE,SAAS,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACpD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1D,GACL,MAAM,IAAI,CAmDZ"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Nova Engine — Noise WASM Accelerator
3
+ *
4
+ * High-performance noise generation for canvas rendering.
5
+ * Replaces the per-pixel JS loop with a single WASM call.
6
+ */
7
+ let wasm = null;
8
+ let initPromise = null;
9
+ /** Initialize the WASM noise module. */
10
+ export async function initWasm() {
11
+ if (wasm)
12
+ return;
13
+ if (initPromise)
14
+ return initPromise;
15
+ initPromise = (async () => {
16
+ // @ts-ignore — wasm-bindgen generated glue
17
+ const mod = await import('./wasm/noise/nova_noise_wasm.js');
18
+ wasm = mod;
19
+ })();
20
+ return initPromise;
21
+ }
22
+ /** Check if the WASM noise module is loaded. */
23
+ export function isReady() {
24
+ return wasm !== null;
25
+ }
26
+ /** Generate a full FBM noise buffer using WASM. Returns null if WASM not loaded. */
27
+ export function fbmBuffer(seed, width, height, options = {}) {
28
+ if (!wasm)
29
+ return null;
30
+ const typeMap = { simplex: 0, perlin: 1, worley: 2 };
31
+ return wasm.fbmBuffer(seed, width, height, options.scale ?? 100, options.octaves ?? 6, options.lacunarity ?? 2.0, options.gain ?? 0.5, typeMap[options.type ?? 'simplex']);
32
+ }
33
+ /** Render noise to a canvas using WASM. Returns a cleanup function. */
34
+ export function renderNoiseWasm(canvas, options = {}) {
35
+ const el = typeof canvas === 'string'
36
+ ? document.querySelector(canvas)
37
+ : canvas;
38
+ if (!el)
39
+ throw new Error('[Nova Noise WASM] Canvas not found');
40
+ const ctx = el.getContext('2d');
41
+ const seed = options.seed ?? 42;
42
+ const scale = options.scale ?? 100;
43
+ const octaves = options.octaves ?? 6;
44
+ const type = options.type ?? 'simplex';
45
+ const animate = options.animate ?? false;
46
+ const speed = options.speed ?? 0.001;
47
+ const colorFn = options.colorFn ?? defaultColor;
48
+ let rafId;
49
+ let offset = 0;
50
+ function draw() {
51
+ const w = el.width;
52
+ const h = el.height;
53
+ const buffer = fbmBuffer(seed, w, h, { scale: scale + offset, octaves, type });
54
+ if (!buffer)
55
+ return;
56
+ const imageData = ctx.createImageData(w, h);
57
+ const data = imageData.data;
58
+ for (let i = 0; i < buffer.length; i++) {
59
+ const [r, g, b, a] = colorFn(buffer[i]);
60
+ const idx = i * 4;
61
+ data[idx] = r;
62
+ data[idx + 1] = g;
63
+ data[idx + 2] = b;
64
+ data[idx + 3] = a;
65
+ }
66
+ ctx.putImageData(imageData, 0, 0);
67
+ if (animate) {
68
+ offset += speed;
69
+ rafId = requestAnimationFrame(draw);
70
+ }
71
+ }
72
+ draw();
73
+ return () => {
74
+ if (rafId)
75
+ cancelAnimationFrame(rafId);
76
+ };
77
+ }
78
+ function defaultColor(value) {
79
+ const v = Math.floor((value * 0.5 + 0.5) * 255);
80
+ return [v, v, v, 255];
81
+ }
82
+ //# sourceMappingURL=noise-wasm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"noise-wasm.js","sourceRoot":"","sources":["../../src/canvas/noise-wasm.ts"],"names":[],"mappings":"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"}