@hypen-space/web 0.2.0

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 (195) hide show
  1. package/dist/chunk-2s02mkzs.js +32 -0
  2. package/dist/chunk-2s02mkzs.js.map +9 -0
  3. package/dist/src/canvas/accessibility.js +152 -0
  4. package/dist/src/canvas/accessibility.js.map +10 -0
  5. package/dist/src/canvas/events.js +198 -0
  6. package/dist/src/canvas/events.js.map +10 -0
  7. package/dist/src/canvas/index.js +28 -0
  8. package/dist/src/canvas/index.js.map +9 -0
  9. package/dist/src/canvas/input.js +132 -0
  10. package/dist/src/canvas/input.js.map +10 -0
  11. package/dist/src/canvas/layout.js +309 -0
  12. package/dist/src/canvas/layout.js.map +10 -0
  13. package/dist/src/canvas/paint.js +878 -0
  14. package/dist/src/canvas/paint.js.map +10 -0
  15. package/dist/src/canvas/renderer.js +276 -0
  16. package/dist/src/canvas/renderer.js.map +10 -0
  17. package/dist/src/canvas/text.js +118 -0
  18. package/dist/src/canvas/text.js.map +10 -0
  19. package/dist/src/canvas/types.js +2 -0
  20. package/dist/src/canvas/types.js.map +9 -0
  21. package/dist/src/canvas/utils.js +139 -0
  22. package/dist/src/canvas/utils.js.map +10 -0
  23. package/dist/src/dom/applicators/advanced-layout.js +111 -0
  24. package/dist/src/dom/applicators/advanced-layout.js.map +10 -0
  25. package/dist/src/dom/applicators/background.js +54 -0
  26. package/dist/src/dom/applicators/background.js.map +10 -0
  27. package/dist/src/dom/applicators/border.js +33 -0
  28. package/dist/src/dom/applicators/border.js.map +10 -0
  29. package/dist/src/dom/applicators/color.js +36 -0
  30. package/dist/src/dom/applicators/color.js.map +10 -0
  31. package/dist/src/dom/applicators/display.js +57 -0
  32. package/dist/src/dom/applicators/display.js.map +10 -0
  33. package/dist/src/dom/applicators/effects.js +89 -0
  34. package/dist/src/dom/applicators/effects.js.map +10 -0
  35. package/dist/src/dom/applicators/events.js +518 -0
  36. package/dist/src/dom/applicators/events.js.map +10 -0
  37. package/dist/src/dom/applicators/font.js +39 -0
  38. package/dist/src/dom/applicators/font.js.map +10 -0
  39. package/dist/src/dom/applicators/index.js +296 -0
  40. package/dist/src/dom/applicators/index.js.map +10 -0
  41. package/dist/src/dom/applicators/layout.js +86 -0
  42. package/dist/src/dom/applicators/layout.js.map +10 -0
  43. package/dist/src/dom/applicators/margin.js +32 -0
  44. package/dist/src/dom/applicators/margin.js.map +10 -0
  45. package/dist/src/dom/applicators/padding.js +35 -0
  46. package/dist/src/dom/applicators/padding.js.map +10 -0
  47. package/dist/src/dom/applicators/size.js +42 -0
  48. package/dist/src/dom/applicators/size.js.map +10 -0
  49. package/dist/src/dom/applicators/transform.js +92 -0
  50. package/dist/src/dom/applicators/transform.js.map +10 -0
  51. package/dist/src/dom/applicators/transition.js +66 -0
  52. package/dist/src/dom/applicators/transition.js.map +10 -0
  53. package/dist/src/dom/applicators/typography.js +87 -0
  54. package/dist/src/dom/applicators/typography.js.map +10 -0
  55. package/dist/src/dom/canvas/index.js +50 -0
  56. package/dist/src/dom/canvas/index.js.map +10 -0
  57. package/dist/src/dom/components/audio.js +48 -0
  58. package/dist/src/dom/components/audio.js.map +10 -0
  59. package/dist/src/dom/components/avatar.js +58 -0
  60. package/dist/src/dom/components/avatar.js.map +10 -0
  61. package/dist/src/dom/components/badge.js +55 -0
  62. package/dist/src/dom/components/badge.js.map +10 -0
  63. package/dist/src/dom/components/button.js +29 -0
  64. package/dist/src/dom/components/button.js.map +10 -0
  65. package/dist/src/dom/components/card.js +33 -0
  66. package/dist/src/dom/components/card.js.map +10 -0
  67. package/dist/src/dom/components/center.js +32 -0
  68. package/dist/src/dom/components/center.js.map +10 -0
  69. package/dist/src/dom/components/checkbox.js +54 -0
  70. package/dist/src/dom/components/checkbox.js.map +10 -0
  71. package/dist/src/dom/components/column.js +31 -0
  72. package/dist/src/dom/components/column.js.map +10 -0
  73. package/dist/src/dom/components/container.js +29 -0
  74. package/dist/src/dom/components/container.js.map +10 -0
  75. package/dist/src/dom/components/divider.js +45 -0
  76. package/dist/src/dom/components/divider.js.map +10 -0
  77. package/dist/src/dom/components/grid.js +44 -0
  78. package/dist/src/dom/components/grid.js.map +10 -0
  79. package/dist/src/dom/components/heading.js +47 -0
  80. package/dist/src/dom/components/heading.js.map +10 -0
  81. package/dist/src/dom/components/image.js +39 -0
  82. package/dist/src/dom/components/image.js.map +10 -0
  83. package/dist/src/dom/components/index.js +217 -0
  84. package/dist/src/dom/components/index.js.map +10 -0
  85. package/dist/src/dom/components/input.js +41 -0
  86. package/dist/src/dom/components/input.js.map +10 -0
  87. package/dist/src/dom/components/link.js +42 -0
  88. package/dist/src/dom/components/link.js.map +10 -0
  89. package/dist/src/dom/components/list.js +42 -0
  90. package/dist/src/dom/components/list.js.map +10 -0
  91. package/dist/src/dom/components/paragraph.js +35 -0
  92. package/dist/src/dom/components/paragraph.js.map +10 -0
  93. package/dist/src/dom/components/progressbar.js +57 -0
  94. package/dist/src/dom/components/progressbar.js.map +10 -0
  95. package/dist/src/dom/components/route.js +44 -0
  96. package/dist/src/dom/components/route.js.map +10 -0
  97. package/dist/src/dom/components/router.js +33 -0
  98. package/dist/src/dom/components/router.js.map +10 -0
  99. package/dist/src/dom/components/row.js +31 -0
  100. package/dist/src/dom/components/row.js.map +10 -0
  101. package/dist/src/dom/components/select.js +57 -0
  102. package/dist/src/dom/components/select.js.map +10 -0
  103. package/dist/src/dom/components/slider.js +48 -0
  104. package/dist/src/dom/components/slider.js.map +10 -0
  105. package/dist/src/dom/components/spacer.js +30 -0
  106. package/dist/src/dom/components/spacer.js.map +10 -0
  107. package/dist/src/dom/components/spinner.js +65 -0
  108. package/dist/src/dom/components/spinner.js.map +10 -0
  109. package/dist/src/dom/components/stack.js +45 -0
  110. package/dist/src/dom/components/stack.js.map +10 -0
  111. package/dist/src/dom/components/switch.js +83 -0
  112. package/dist/src/dom/components/switch.js.map +10 -0
  113. package/dist/src/dom/components/text.js +37 -0
  114. package/dist/src/dom/components/text.js.map +10 -0
  115. package/dist/src/dom/components/textarea.js +51 -0
  116. package/dist/src/dom/components/textarea.js.map +10 -0
  117. package/dist/src/dom/components/video.js +51 -0
  118. package/dist/src/dom/components/video.js.map +10 -0
  119. package/dist/src/dom/debug.js +170 -0
  120. package/dist/src/dom/debug.js.map +10 -0
  121. package/dist/src/dom/events.js +112 -0
  122. package/dist/src/dom/events.js.map +10 -0
  123. package/dist/src/dom/index.js +73 -0
  124. package/dist/src/dom/index.js.map +9 -0
  125. package/dist/src/dom/renderer.js +277 -0
  126. package/dist/src/dom/renderer.js.map +10 -0
  127. package/dist/src/index.js +89 -0
  128. package/dist/src/index.js.map +9 -0
  129. package/package.json +84 -0
  130. package/src/canvas/QUICKSTART.md +421 -0
  131. package/src/canvas/README.md +376 -0
  132. package/src/canvas/accessibility.ts +218 -0
  133. package/src/canvas/events.ts +307 -0
  134. package/src/canvas/index.ts +35 -0
  135. package/src/canvas/input.ts +210 -0
  136. package/src/canvas/layout.ts +401 -0
  137. package/src/canvas/paint.ts +1321 -0
  138. package/src/canvas/renderer.ts +422 -0
  139. package/src/canvas/text.ts +182 -0
  140. package/src/canvas/types.ts +137 -0
  141. package/src/canvas/utils.ts +218 -0
  142. package/src/dom/README.md +265 -0
  143. package/src/dom/applicators/advanced-layout.ts +128 -0
  144. package/src/dom/applicators/background.ts +50 -0
  145. package/src/dom/applicators/border.ts +19 -0
  146. package/src/dom/applicators/color.ts +23 -0
  147. package/src/dom/applicators/display.ts +54 -0
  148. package/src/dom/applicators/effects.ts +97 -0
  149. package/src/dom/applicators/events.ts +689 -0
  150. package/src/dom/applicators/font.ts +27 -0
  151. package/src/dom/applicators/index.ts +354 -0
  152. package/src/dom/applicators/layout.ts +92 -0
  153. package/src/dom/applicators/margin.ts +18 -0
  154. package/src/dom/applicators/padding.ts +18 -0
  155. package/src/dom/applicators/size.ts +31 -0
  156. package/src/dom/applicators/transform.ts +93 -0
  157. package/src/dom/applicators/transition.ts +65 -0
  158. package/src/dom/applicators/typography.ts +91 -0
  159. package/src/dom/canvas/index.ts +60 -0
  160. package/src/dom/components/audio.ts +45 -0
  161. package/src/dom/components/avatar.ts +49 -0
  162. package/src/dom/components/badge.ts +45 -0
  163. package/src/dom/components/button.ts +13 -0
  164. package/src/dom/components/card.ts +19 -0
  165. package/src/dom/components/center.ts +16 -0
  166. package/src/dom/components/checkbox.ts +54 -0
  167. package/src/dom/components/column.ts +15 -0
  168. package/src/dom/components/container.ts +13 -0
  169. package/src/dom/components/divider.ts +37 -0
  170. package/src/dom/components/grid.ts +40 -0
  171. package/src/dom/components/heading.ts +41 -0
  172. package/src/dom/components/image.ts +27 -0
  173. package/src/dom/components/index.ts +115 -0
  174. package/src/dom/components/input.ts +29 -0
  175. package/src/dom/components/link.ts +35 -0
  176. package/src/dom/components/list.ts +30 -0
  177. package/src/dom/components/paragraph.ts +23 -0
  178. package/src/dom/components/progressbar.ts +51 -0
  179. package/src/dom/components/route.ts +37 -0
  180. package/src/dom/components/router.ts +22 -0
  181. package/src/dom/components/row.ts +15 -0
  182. package/src/dom/components/select.ts +56 -0
  183. package/src/dom/components/slider.ts +45 -0
  184. package/src/dom/components/spacer.ts +16 -0
  185. package/src/dom/components/spinner.ts +60 -0
  186. package/src/dom/components/stack.ts +34 -0
  187. package/src/dom/components/switch.ts +86 -0
  188. package/src/dom/components/text.ts +24 -0
  189. package/src/dom/components/textarea.ts +50 -0
  190. package/src/dom/components/video.ts +50 -0
  191. package/src/dom/debug.ts +247 -0
  192. package/src/dom/events.ts +168 -0
  193. package/src/dom/index.ts +11 -0
  194. package/src/dom/renderer.ts +327 -0
  195. package/src/index.ts +56 -0
@@ -0,0 +1,327 @@
1
+ /**
2
+ * DOM Renderer
3
+ *
4
+ * Renders Hypen patches to the DOM
5
+ */
6
+
7
+ import type { Patch } from "@hypen/core";
8
+ import type { HypenModuleInstance, RouterContext } from "@hypen/core";
9
+ import type { HypenRouter } from "@hypen/core";
10
+ import type { HypenGlobalContext } from "@hypen/core";
11
+ import { ComponentRegistry } from "./components/index.js";
12
+ import { ApplicatorRegistry } from "./applicators/index.js";
13
+ import { canvasHandler, canvasApplicators } from "./canvas/index.js";
14
+ import { RerenderTracker, type DebugConfig, defaultDebugConfig } from "./debug.js";
15
+
16
+ // Interface for the engine that renderer needs
17
+ interface IEngine {
18
+ dispatchAction(name: string, payload?: any): void;
19
+ }
20
+
21
+ export class DOMRenderer {
22
+ private container: HTMLElement;
23
+ private nodes: Map<string, HTMLElement> = new Map();
24
+ private rootId: string | null = null;
25
+ private components: ComponentRegistry;
26
+ private applicators: ApplicatorRegistry;
27
+ private engine: IEngine;
28
+ private currentState: Record<string, any> = {};
29
+ private routerContext: RouterContext | null = null;
30
+ private globalContext: HypenGlobalContext | null = null;
31
+ private componentInstances = new Map<string, HypenModuleInstance>();
32
+ private debugTracker: RerenderTracker;
33
+
34
+ constructor(container: HTMLElement, engine: IEngine, debugConfig?: Partial<DebugConfig>) {
35
+ this.container = container;
36
+ this.engine = engine;
37
+ this.components = new ComponentRegistry();
38
+ this.applicators = new ApplicatorRegistry();
39
+ this.debugTracker = new RerenderTracker({ ...defaultDebugConfig, ...debugConfig });
40
+
41
+ // Register canvas component and applicators
42
+ this.components.register("canvas", canvasHandler);
43
+ for (const [name, handler] of Object.entries(canvasApplicators)) {
44
+ this.applicators.register(name, handler);
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Set router and global context for component composition
50
+ */
51
+ setContext(routerContext: RouterContext, globalContext: HypenGlobalContext): void {
52
+ this.routerContext = routerContext;
53
+ this.globalContext = globalContext;
54
+ }
55
+
56
+ /**
57
+ * Apply a batch of patches to the DOM
58
+ */
59
+ applyPatches(patches: Patch[]): void {
60
+ for (const patch of patches) {
61
+ this.applyPatch(patch);
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Update state and interpolate text content
67
+ */
68
+ updateState(state: Record<string, any>): void {
69
+ console.log(`[Renderer] Updating state:`, state);
70
+ this.currentState = state;
71
+ this.interpolateAllText();
72
+ }
73
+
74
+ /**
75
+ * Merge component state into current state and re-interpolate
76
+ */
77
+ private mergeComponentState(componentState: Record<string, any>): void {
78
+ this.currentState = { ...this.currentState, ...componentState };
79
+ console.log(`[Renderer] Merged state:`, this.currentState);
80
+ this.interpolateAllText();
81
+ }
82
+
83
+ /**
84
+ * Interpolate state values in all text elements
85
+ */
86
+ private interpolateAllText(): void {
87
+ for (const [id, element] of this.nodes.entries()) {
88
+ if (element.dataset.hypenType === "text" && element.dataset.textTemplate) {
89
+ const template = element.dataset.textTemplate;
90
+ const interpolated = this.interpolateText(template, this.currentState);
91
+
92
+ // Track re-render if text actually changed
93
+ const currentText = element.textContent;
94
+ if (currentText !== interpolated) {
95
+ this.debugTracker.trackRerender(id, element, "interpolate");
96
+ }
97
+
98
+ element.textContent = interpolated;
99
+ }
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Interpolate state values in text template
105
+ */
106
+ private interpolateText(template: string, state: Record<string, any>): string {
107
+ return template.replace(/\$\{([^}]+)\}/g, (match, path) => {
108
+ try {
109
+ const value = path.split('.').reduce((obj: any, key: string) => {
110
+ if (key === 'state') return state;
111
+ return obj?.[key];
112
+ }, state);
113
+ return value !== undefined ? String(value) : match;
114
+ } catch {
115
+ return match;
116
+ }
117
+ });
118
+ }
119
+
120
+ /**
121
+ * Apply a single patch
122
+ */
123
+ private applyPatch(patch: Patch): void {
124
+ switch (patch.type) {
125
+ case "create":
126
+ this.onCreate(patch.id!, (patch as any).element_type!, patch.props || {});
127
+ break;
128
+ case "setProp":
129
+ this.onSetProp(patch.id!, patch.name!, patch.value);
130
+ break;
131
+ case "setText":
132
+ this.onSetText(patch.id!, patch.text!);
133
+ break;
134
+ case "insert":
135
+ this.onInsert((patch as any).parent_id!, patch.id!, (patch as any).before_id);
136
+ break;
137
+ case "move":
138
+ this.onMove((patch as any).parent_id!, patch.id!, (patch as any).before_id);
139
+ break;
140
+ case "remove":
141
+ this.onRemove(patch.id!);
142
+ break;
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Create a new element
148
+ */
149
+ private onCreate(id: string, elementType: string, props: Record<string, any> | Map<string, any>): void {
150
+ const propsObj = props instanceof Map ? Object.fromEntries(props) : props;
151
+
152
+ const element = this.components.createElement(elementType, propsObj);
153
+
154
+ if (!element) {
155
+ const fallback = document.createElement("div");
156
+ fallback.dataset.hypenType = elementType;
157
+ fallback.textContent = `Unknown component: ${elementType}`;
158
+ this.nodes.set(id, fallback);
159
+ return;
160
+ }
161
+
162
+ element.dataset.hypenType = elementType.toLowerCase();
163
+ element.dataset.hypenId = id;
164
+ (element as any).__hypenEngine = this.engine;
165
+
166
+ this.applicators.applyAll(element, propsObj);
167
+ this.nodes.set(id, element);
168
+ this.debugTracker.trackRerender(id, element, `create:${elementType}`);
169
+
170
+ if (!this.rootId) {
171
+ this.rootId = id;
172
+ if (!this.container.contains(element)) {
173
+ this.container.appendChild(element);
174
+ }
175
+ }
176
+ }
177
+
178
+ /**
179
+ * Set a property on an element
180
+ */
181
+ private onSetProp(id: string, name: string, value: any): void {
182
+ const element = this.nodes.get(id);
183
+ if (!element) return;
184
+
185
+ this.debugTracker.trackRerender(id, element, `setProp:${name}`);
186
+
187
+ if (name === "0" || name === "text") {
188
+ const elementType = element.dataset.hypenType;
189
+
190
+ if (elementType === "input") {
191
+ const inputEl = element as HTMLInputElement;
192
+ inputEl.value = String(value);
193
+ console.log(`[Renderer] Updated input value: "${value}"`);
194
+ return;
195
+ }
196
+
197
+ element.textContent = String(value);
198
+ if (element.dataset.textTemplate !== undefined) {
199
+ element.dataset.textTemplate = String(value);
200
+ }
201
+ console.log(`[Renderer] Updated text content: "${value}"`);
202
+ return;
203
+ }
204
+
205
+ this.applicators.apply(element, name, value);
206
+ }
207
+
208
+ /**
209
+ * Set text content
210
+ */
211
+ private onSetText(id: string, text: string): void {
212
+ const element = this.nodes.get(id);
213
+ if (!element) return;
214
+
215
+ this.debugTracker.trackRerender(id, element, "setText");
216
+ element.textContent = text;
217
+ }
218
+
219
+ /**
220
+ * Insert an element into the tree
221
+ */
222
+ private onInsert(parentId: string, id: string, beforeId?: string): void {
223
+ const parent = parentId === "root" ? this.container : this.nodes.get(parentId);
224
+ const child = this.nodes.get(id);
225
+
226
+ console.log(`[Renderer] Inserting ${id} into ${parentId}`, {
227
+ parent: parent ? `${parent.tagName}#${parent.id || 'no-id'}` : 'null',
228
+ child: child ? `${child.tagName}#${child.id || 'no-id'}` : 'null',
229
+ childText: child?.textContent?.substring(0, 20)
230
+ });
231
+
232
+ if (!parent || !child) return;
233
+
234
+ if (parentId === "root") {
235
+ this.rootId = id;
236
+ }
237
+
238
+ if (beforeId) {
239
+ const before = this.nodes.get(beforeId);
240
+ if (before && before.parentNode === parent) {
241
+ parent.insertBefore(child, before);
242
+ } else if (!parent.contains(child)) {
243
+ parent.appendChild(child);
244
+ }
245
+ } else {
246
+ if (!parent.contains(child)) {
247
+ parent.appendChild(child);
248
+ }
249
+ }
250
+ }
251
+
252
+ /**
253
+ * Move an element within the tree
254
+ */
255
+ private onMove(parentId: string, id: string, beforeId?: string): void {
256
+ this.onInsert(parentId, id, beforeId);
257
+ }
258
+
259
+ /**
260
+ * Remove an element from the tree
261
+ */
262
+ private onRemove(id: string): void {
263
+ const element = this.nodes.get(id);
264
+ if (!element) return;
265
+
266
+ if (element.parentNode) {
267
+ element.parentNode.removeChild(element);
268
+ }
269
+
270
+ this.nodes.delete(id);
271
+
272
+ if (this.rootId === id) {
273
+ this.rootId = null;
274
+ }
275
+ }
276
+
277
+ /**
278
+ * Get an element by ID
279
+ */
280
+ getNode(id: string): HTMLElement | undefined {
281
+ return this.nodes.get(id);
282
+ }
283
+
284
+ /**
285
+ * Clear all nodes
286
+ */
287
+ clear(): void {
288
+ this.container.innerHTML = "";
289
+ this.nodes.clear();
290
+ this.rootId = null;
291
+ }
292
+
293
+ /**
294
+ * Get the component registry (for registering custom components)
295
+ */
296
+ getComponentRegistry(): ComponentRegistry {
297
+ return this.components;
298
+ }
299
+
300
+ /**
301
+ * Get the applicator registry (for registering custom applicators)
302
+ */
303
+ getApplicatorRegistry(): ApplicatorRegistry {
304
+ return this.applicators;
305
+ }
306
+
307
+ /**
308
+ * Enable or configure debug mode
309
+ */
310
+ setDebugConfig(config: Partial<DebugConfig>): void {
311
+ this.debugTracker.setConfig(config);
312
+ }
313
+
314
+ /**
315
+ * Reset debug tracking for all elements
316
+ */
317
+ resetDebugTracking(): void {
318
+ this.debugTracker.resetAll();
319
+ }
320
+
321
+ /**
322
+ * Get debug statistics
323
+ */
324
+ getDebugStats(): { totalRerenders: number; elementCount: number; avgRerenders: number } {
325
+ return this.debugTracker.getStats();
326
+ }
327
+ }
package/src/index.ts ADDED
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @hypen/web - Hypen Web Renderers
3
+ *
4
+ * Browser-only package providing DOM and Canvas rendering for Hypen applications.
5
+ * Requires @hypen/core for the engine and state management.
6
+ *
7
+ * ## Quick Start
8
+ *
9
+ * ```typescript
10
+ * import { Engine, app } from "@hypen/core";
11
+ * import { DOMRenderer } from "@hypen/web";
12
+ *
13
+ * // Initialize engine
14
+ * const engine = new Engine();
15
+ * await engine.init({ wasmPath: "/hypen_engine_bg.wasm" });
16
+ *
17
+ * // Create renderer
18
+ * const container = document.getElementById("app")!;
19
+ * const renderer = new DOMRenderer(container, engine);
20
+ *
21
+ * // Set up patch callback
22
+ * engine.setRenderCallback((patches) => {
23
+ * renderer.applyPatches(patches);
24
+ * });
25
+ *
26
+ * // Render your app
27
+ * engine.renderSource(`Column { Text("Hello Hypen!") }`);
28
+ * ```
29
+ */
30
+
31
+ // ============================================================================
32
+ // DOM RENDERER
33
+ // ============================================================================
34
+
35
+ export { DOMRenderer } from "./dom/renderer.js";
36
+ export { ComponentRegistry } from "./dom/components/index.js";
37
+ export { ApplicatorRegistry } from "./dom/applicators/index.js";
38
+ export { EventManager } from "./dom/events.js";
39
+ export { RerenderTracker, type DebugConfig, defaultDebugConfig } from "./dom/debug.js";
40
+
41
+ // ============================================================================
42
+ // CANVAS RENDERER
43
+ // ============================================================================
44
+
45
+ export { CanvasRenderer } from "./canvas/renderer.js";
46
+ export { canvasHandler, canvasApplicators } from "./dom/canvas/index.js";
47
+
48
+ // Re-export core types that web users commonly need
49
+ export type {
50
+ Patch,
51
+ Action,
52
+ Renderer,
53
+ RouterContext,
54
+ HypenModuleInstance,
55
+ HypenGlobalContext,
56
+ } from "@hypen/core";