frontend-hamroun 1.2.85 → 1.2.89

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 (96) hide show
  1. package/dist/batch.d.ts +4 -0
  2. package/dist/batch.d.ts.map +1 -0
  3. package/dist/batch.js +22 -0
  4. package/dist/client-router.d.ts +61 -0
  5. package/dist/client-router.d.ts.map +1 -0
  6. package/dist/client-router.js +209 -0
  7. package/dist/component.d.ts +15 -0
  8. package/dist/component.d.ts.map +1 -0
  9. package/dist/component.js +84 -0
  10. package/dist/components/Counter.d.ts +1 -0
  11. package/dist/components/Counter.d.ts.map +1 -0
  12. package/dist/components/Counter.js +2 -0
  13. package/dist/context.d.ts +5 -0
  14. package/dist/context.d.ts.map +1 -0
  15. package/dist/context.js +23 -0
  16. package/dist/event-bus.d.ts +24 -0
  17. package/dist/event-bus.d.ts.map +1 -0
  18. package/dist/event-bus.js +74 -0
  19. package/dist/forms.d.ts +41 -0
  20. package/dist/forms.d.ts.map +1 -0
  21. package/dist/forms.js +147 -0
  22. package/dist/hooks.d.ts +12 -0
  23. package/dist/hooks.d.ts.map +1 -0
  24. package/dist/hooks.js +142 -0
  25. package/dist/index.cjs +1231 -1
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.client.d.ts +13 -0
  28. package/dist/index.client.d.ts.map +1 -0
  29. package/dist/index.client.js +12 -25
  30. package/dist/index.d.ts +68 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +1153 -265
  33. package/dist/index.js.map +1 -1
  34. package/dist/jsx-dev-runtime.cjs +102 -0
  35. package/dist/jsx-dev-runtime.cjs.map +1 -0
  36. package/dist/jsx-dev-runtime.d.ts +3 -0
  37. package/dist/jsx-dev-runtime.d.ts.map +1 -0
  38. package/dist/jsx-dev-runtime.js +96 -0
  39. package/dist/jsx-dev-runtime.js.map +1 -0
  40. package/dist/jsx-runtime/jsx-runtime.d.ts +5 -0
  41. package/dist/jsx-runtime/jsx-runtime.d.ts.map +1 -0
  42. package/dist/jsx-runtime/jsx-runtime.js +40 -0
  43. package/dist/jsx-runtime.cjs +112 -1
  44. package/dist/jsx-runtime.cjs.map +1 -1
  45. package/dist/jsx-runtime.d.ts +18 -0
  46. package/dist/jsx-runtime.d.ts.map +1 -0
  47. package/dist/jsx-runtime.js +90 -79
  48. package/dist/jsx-runtime.js.map +1 -1
  49. package/dist/lifecycle-events.d.ts +109 -0
  50. package/dist/lifecycle-events.d.ts.map +1 -0
  51. package/dist/lifecycle-events.js +176 -0
  52. package/dist/renderComponent.d.ts +14 -0
  53. package/dist/renderComponent.d.ts.map +1 -0
  54. package/dist/renderComponent.js +29 -0
  55. package/dist/renderer.d.ts +4 -0
  56. package/dist/renderer.d.ts.map +1 -0
  57. package/dist/renderer.js +49 -0
  58. package/dist/router.d.ts +56 -0
  59. package/dist/router.d.ts.map +1 -0
  60. package/dist/router.js +165 -0
  61. package/dist/server-renderer.d.ts +2 -0
  62. package/dist/server-renderer.d.ts.map +1 -0
  63. package/dist/server-renderer.js +111 -5
  64. package/dist/server-types.d.ts +43 -0
  65. package/dist/server-types.d.ts.map +1 -0
  66. package/dist/server-types.js +5 -0
  67. package/dist/store.d.ts +42 -0
  68. package/dist/store.d.ts.map +1 -0
  69. package/dist/store.js +98 -0
  70. package/dist/types.d.ts +272 -0
  71. package/dist/types.d.ts.map +1 -0
  72. package/dist/types.js +2 -0
  73. package/dist/utils.d.ts +47 -0
  74. package/dist/utils.d.ts.map +1 -0
  75. package/dist/utils.js +143 -0
  76. package/dist/vdom.d.ts +9 -0
  77. package/dist/vdom.d.ts.map +1 -0
  78. package/dist/vdom.js +21 -0
  79. package/dist/wasm.d.ts +37 -0
  80. package/dist/wasm.d.ts.map +1 -0
  81. package/dist/wasm.js +158 -0
  82. package/package.json +54 -83
  83. package/dist/index.client.cjs +0 -2
  84. package/dist/index.client.cjs.map +0 -1
  85. package/dist/index.client.js.map +0 -1
  86. package/dist/renderer-DaVfBeVi.cjs +0 -2
  87. package/dist/renderer-DaVfBeVi.cjs.map +0 -1
  88. package/dist/renderer-nfT7XSpo.js +0 -61
  89. package/dist/renderer-nfT7XSpo.js.map +0 -1
  90. package/dist/server-renderer-B5b0Q0ck.cjs +0 -2
  91. package/dist/server-renderer-B5b0Q0ck.cjs.map +0 -1
  92. package/dist/server-renderer-C4MB-jAp.js +0 -248
  93. package/dist/server-renderer-C4MB-jAp.js.map +0 -1
  94. package/dist/server-renderer.cjs +0 -2
  95. package/dist/server-renderer.cjs.map +0 -1
  96. package/dist/server-renderer.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,282 +1,1170 @@
1
- import { createElement, Fragment, jsx } from "./jsx-runtime.js";
2
- import { c as createContext, u as useContext, h as hydrate, r as render } from "./renderer-nfT7XSpo.js";
3
- import { b as batchUpdates, r as renderToString, u as useErrorBoundary, a as useRef, c as useMemo, d as useEffect, e as useState } from "./server-renderer-C4MB-jAp.js";
1
+ function jsx(type, props) {
2
+ console.log('JSX Transform:', { type, props });
3
+ const processedProps = { ...props };
4
+ // Handle children properly
5
+ if (arguments.length > 2) {
6
+ processedProps.children = Array.prototype.slice.call(arguments, 2);
7
+ }
8
+ return { type, props: processedProps };
9
+ }
10
+ const Fragment = ({ children }) => children;
11
+ async function createElement(vnode) {
12
+ console.log('Creating element from:', vnode);
13
+ // Handle primitives and null
14
+ if (vnode == null) {
15
+ return document.createTextNode('');
16
+ }
17
+ if (typeof vnode === 'boolean') {
18
+ return document.createTextNode('');
19
+ }
20
+ if (typeof vnode === 'number' || typeof vnode === 'string') {
21
+ return document.createTextNode(String(vnode));
22
+ }
23
+ // Handle arrays
24
+ if (Array.isArray(vnode)) {
25
+ const fragment = document.createDocumentFragment();
26
+ for (const child of vnode) {
27
+ const node = await createElement(child);
28
+ fragment.appendChild(node);
29
+ }
30
+ return fragment;
31
+ }
32
+ // Handle VNode
33
+ if ('type' in vnode && vnode.props !== undefined) {
34
+ const { type, props } = vnode;
35
+ // Handle function components
36
+ if (typeof type === 'function') {
37
+ try {
38
+ const result = await type(props || {});
39
+ const node = await createElement(result);
40
+ if (node instanceof Element) {
41
+ node.setAttribute('data-component-id', type.name || type.toString());
42
+ }
43
+ return node;
44
+ }
45
+ catch (error) {
46
+ console.error('Error rendering component:', error);
47
+ return document.createTextNode('');
48
+ }
49
+ }
50
+ // Create DOM element
51
+ const element = document.createElement(type);
52
+ // Handle props
53
+ for (const [key, value] of Object.entries(props || {})) {
54
+ if (key === 'children')
55
+ continue;
56
+ if (key.startsWith('on') && typeof value === 'function') {
57
+ const eventName = key.toLowerCase().slice(2);
58
+ // Remove existing event listener if any
59
+ const existingHandler = element.__events?.[eventName];
60
+ if (existingHandler) {
61
+ element.removeEventListener(eventName, existingHandler);
62
+ }
63
+ // Add new event listener
64
+ element.addEventListener(eventName, value);
65
+ if (!element.__events) {
66
+ element.__events = {};
67
+ }
68
+ element.__events[eventName] = value;
69
+ }
70
+ else if (key === 'style' && typeof value === 'object') {
71
+ Object.assign(element.style, value);
72
+ }
73
+ else if (key === 'className') {
74
+ element.setAttribute('class', String(value));
75
+ }
76
+ else if (key !== 'key' && key !== 'ref') {
77
+ element.setAttribute(key, String(value));
78
+ }
79
+ }
80
+ // Handle children
81
+ const children = props?.children;
82
+ if (children != null) {
83
+ const childArray = Array.isArray(children) ? children.flat() : [children];
84
+ for (const child of childArray) {
85
+ const childNode = await createElement(child);
86
+ element.appendChild(childNode);
87
+ }
88
+ }
89
+ return element;
90
+ }
91
+ // Handle other objects by converting to string
92
+ return document.createTextNode(String(vnode));
93
+ }
94
+
95
+ let isBatching = false;
96
+ const queue = [];
97
+ function batchUpdates(fn) {
98
+ if (isBatching) {
99
+ queue.push(fn);
100
+ return;
101
+ }
102
+ isBatching = true;
103
+ try {
104
+ fn();
105
+ while (queue.length > 0) {
106
+ const nextFn = queue.shift();
107
+ nextFn?.();
108
+ }
109
+ }
110
+ finally {
111
+ isBatching = false;
112
+ }
113
+ }
114
+
115
+ const contexts = new Map();
116
+ function createContext(defaultValue) {
117
+ const contextId = Symbol('context');
118
+ const Provider = ({ value, children }) => {
119
+ contexts.set(contextId, value);
120
+ return children;
121
+ };
122
+ const Consumer = ({ children }) => {
123
+ const value = contexts.get(contextId) ?? defaultValue;
124
+ return children(value);
125
+ };
126
+ const context = {
127
+ Provider,
128
+ Consumer,
129
+ displayName: 'Context'
130
+ };
131
+ return context;
132
+ }
133
+ function useContext(context) {
134
+ // In a real implementation, this would access the context value from the component tree
135
+ // For now, returning a default value to satisfy TypeScript
136
+ return {};
137
+ }
138
+
139
+ // Current render ID counter
140
+ let currentRender = 0;
141
+ // State storage
142
+ const states = new Map();
143
+ const stateIndices = new Map();
144
+ const effects = new Map();
145
+ const memos = new Map();
146
+ const refs = new Map();
147
+ // Rendering callbacks
148
+ let globalRenderCallback = null;
149
+ let globalContainer = null;
150
+ let currentElement = null;
151
+ function setRenderCallback(callback, element, container) {
152
+ globalRenderCallback = callback;
153
+ globalContainer = container;
154
+ currentElement = element;
155
+ }
156
+ function prepareRender(component = null) {
157
+ currentRender++;
158
+ stateIndices.set(currentRender, 0);
159
+ return currentRender;
160
+ }
161
+ function finishRender() {
162
+ currentRender = 0;
163
+ }
164
+ function useState(initial) {
165
+ if (!currentRender) {
166
+ throw new Error("useState must be called within a render");
167
+ }
168
+ if (!states.has(currentRender)) {
169
+ states.set(currentRender, []);
170
+ }
171
+ const componentStates = states.get(currentRender);
172
+ const index = stateIndices.get(currentRender) || 0;
173
+ if (index >= componentStates.length) {
174
+ componentStates.push(initial);
175
+ }
176
+ const state = componentStates[index];
177
+ const setState = (newValue) => {
178
+ const nextValue = typeof newValue === 'function'
179
+ ? newValue(componentStates[index])
180
+ : newValue;
181
+ if (componentStates[index] === nextValue)
182
+ return;
183
+ componentStates[index] = nextValue;
184
+ if (isBatching) {
185
+ batchUpdates(() => rerender(currentRender));
186
+ }
187
+ else {
188
+ rerender(currentRender);
189
+ }
190
+ };
191
+ stateIndices.set(currentRender, index + 1);
192
+ return [state, setState];
193
+ }
194
+ function useEffect(callback, deps) {
195
+ if (!currentRender)
196
+ throw new Error("useEffect must be called within a render");
197
+ const effectIndex = stateIndices.get(currentRender) || 0;
198
+ if (!effects.has(currentRender)) {
199
+ effects.set(currentRender, []);
200
+ }
201
+ const componentEffects = effects.get(currentRender);
202
+ const prevEffect = componentEffects[effectIndex];
203
+ if (!prevEffect || !deps || !prevEffect.deps || deps.some((dep, i) => dep !== prevEffect.deps[i])) {
204
+ if (prevEffect?.cleanup) {
205
+ prevEffect.cleanup();
206
+ }
207
+ // Schedule effect execution after render is complete
208
+ queueMicrotask(() => {
209
+ const cleanup = callback() || undefined;
210
+ componentEffects[effectIndex] = { cleanup, deps: deps || [] };
211
+ });
212
+ }
213
+ stateIndices.set(currentRender, effectIndex + 1);
214
+ }
215
+ function useMemo(factory, deps) {
216
+ if (!currentRender)
217
+ throw new Error("useMemo must be called within a render");
218
+ const memoIndex = stateIndices.get(currentRender) || 0;
219
+ if (!memos.has(currentRender)) {
220
+ memos.set(currentRender, []);
221
+ }
222
+ const componentMemos = memos.get(currentRender);
223
+ const prevMemo = componentMemos[memoIndex];
224
+ if (!prevMemo || (deps && deps.some((dep, i) => !Object.is(dep, prevMemo.deps[i])))) {
225
+ const value = factory();
226
+ componentMemos[memoIndex] = { value, deps: deps || [] };
227
+ stateIndices.set(currentRender, memoIndex + 1);
228
+ return value;
229
+ }
230
+ stateIndices.set(currentRender, memoIndex + 1);
231
+ return prevMemo.value;
232
+ }
233
+ function useRef(initial) {
234
+ if (!currentRender)
235
+ throw new Error("useRef must be called within a render");
236
+ const refIndex = stateIndices.get(currentRender) || 0;
237
+ if (!refs.has(currentRender)) {
238
+ refs.set(currentRender, []);
239
+ }
240
+ const componentRefs = refs.get(currentRender);
241
+ if (refIndex >= componentRefs.length) {
242
+ const ref = { current: initial };
243
+ componentRefs.push(ref);
244
+ stateIndices.set(currentRender, refIndex + 1);
245
+ return ref;
246
+ }
247
+ const ref = componentRefs[refIndex];
248
+ stateIndices.set(currentRender, refIndex + 1);
249
+ return ref;
250
+ }
251
+ async function rerender(rendererId) {
252
+ try {
253
+ // Clean up effects
254
+ const componentEffects = effects.get(rendererId);
255
+ if (componentEffects) {
256
+ componentEffects.forEach(effect => {
257
+ if (effect.cleanup)
258
+ effect.cleanup();
259
+ });
260
+ effects.set(rendererId, []);
261
+ }
262
+ // Trigger re-render
263
+ if (globalRenderCallback && globalContainer && currentElement) {
264
+ await globalRenderCallback(currentElement, globalContainer);
265
+ }
266
+ }
267
+ catch (error) {
268
+ console.error('Error during rerender:', error);
269
+ }
270
+ }
271
+ function useErrorBoundary() {
272
+ const [error, setError] = useState(null);
273
+ return [error, () => setError(null)];
274
+ }
275
+
276
+ // Render function for client-side rendering
277
+ async function render(element, container) {
278
+ try {
279
+ // Set up render callback for state updates
280
+ setRenderCallback(render, element, container);
281
+ // Prepare render context
282
+ const renderId = prepareRender(element);
283
+ // Create DOM nodes from virtual elements
284
+ const domNode = await createElement(element);
285
+ // Clear container and append new content
286
+ // Handle both Element and DocumentFragment cases
287
+ if (container instanceof Element) {
288
+ container.innerHTML = '';
289
+ }
290
+ else {
291
+ // For DocumentFragment, clear all children
292
+ while (container.firstChild) {
293
+ container.removeChild(container.firstChild);
294
+ }
295
+ }
296
+ container.appendChild(domNode);
297
+ // Finish render
298
+ finishRender();
299
+ console.log('Render completed successfully');
300
+ }
301
+ catch (error) {
302
+ console.error('Error during render:', error);
303
+ // Clean up render context on error
304
+ finishRender();
305
+ throw error;
306
+ }
307
+ }
308
+ // Hydrate function for client-side hydration of SSR content
309
+ async function hydrate(element, container) {
310
+ try {
311
+ console.log('Starting hydration...');
312
+ // For now, hydrate works the same as render
313
+ // In a more advanced implementation, this would preserve existing DOM
314
+ // and only attach event listeners and initialize state
315
+ await render(element, container);
316
+ console.log('Hydration completed successfully');
317
+ }
318
+ catch (error) {
319
+ console.error('Error during hydration:', error);
320
+ throw error;
321
+ }
322
+ }
323
+
324
+ async function renderToString(element) {
325
+ prepareRender(true); // Mark as SSR
326
+ try {
327
+ const html = await renderNodeToString(element);
328
+ return html;
329
+ }
330
+ finally {
331
+ finishRender();
332
+ }
333
+ }
334
+ async function renderNodeToString(node) {
335
+ // Handle null, undefined, boolean
336
+ if (node == null || typeof node === 'boolean') {
337
+ return '';
338
+ }
339
+ // Handle primitives
340
+ if (typeof node === 'string' || typeof node === 'number') {
341
+ return escapeHtml(String(node));
342
+ }
343
+ // Handle arrays
344
+ if (Array.isArray(node)) {
345
+ const results = await Promise.all(node.map(child => renderNodeToString(child)));
346
+ return results.join('');
347
+ }
348
+ // Handle objects with type and props (React-like elements)
349
+ if (node && typeof node === 'object' && 'type' in node) {
350
+ const { type, props = {} } = node;
351
+ // Handle function components
352
+ if (typeof type === 'function') {
353
+ try {
354
+ const result = await type(props);
355
+ return await renderNodeToString(result);
356
+ }
357
+ catch (error) {
358
+ console.error('Error rendering component:', error);
359
+ return `<!-- Error rendering component: ${error.message} -->`;
360
+ }
361
+ }
362
+ // Handle DOM elements
363
+ if (typeof type === 'string') {
364
+ return await renderDOMElement(type, props);
365
+ }
366
+ }
367
+ // Fallback for other objects
368
+ if (typeof node === 'object') {
369
+ return escapeHtml(JSON.stringify(node));
370
+ }
371
+ return escapeHtml(String(node));
372
+ }
373
+ async function renderDOMElement(tagName, props) {
374
+ const { children, ...attrs } = props;
375
+ // Self-closing tags
376
+ const voidElements = new Set([
377
+ 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',
378
+ 'link', 'meta', 'param', 'source', 'track', 'wbr'
379
+ ]);
380
+ // Build attributes string
381
+ const attributeString = Object.entries(attrs)
382
+ .filter(([key, value]) => {
383
+ // Filter out React-specific props and event handlers
384
+ if (key.startsWith('on') || key === 'key' || key === 'ref')
385
+ return false;
386
+ if (value == null || value === false)
387
+ return false;
388
+ return true;
389
+ })
390
+ .map(([key, value]) => {
391
+ // Handle className -> class
392
+ if (key === 'className')
393
+ key = 'class';
394
+ // Handle boolean attributes
395
+ if (value === true)
396
+ return key;
397
+ // Handle style objects
398
+ if (key === 'style' && typeof value === 'object' && value !== null) {
399
+ const styleString = Object.entries(value)
400
+ .map(([prop, val]) => `${kebabCase(prop)}:${val}`)
401
+ .join(';');
402
+ return `style="${escapeHtml(styleString)}"`;
403
+ }
404
+ return `${key}="${escapeHtml(String(value))}"`;
405
+ })
406
+ .join(' ');
407
+ const openTag = `<${tagName}${attributeString ? ' ' + attributeString : ''}>`;
408
+ // Self-closing elements
409
+ if (voidElements.has(tagName)) {
410
+ return openTag.slice(0, -1) + '/>';
411
+ }
412
+ // Elements with children
413
+ const closeTag = `</${tagName}>`;
414
+ if (children != null) {
415
+ const childrenString = await renderNodeToString(children);
416
+ return openTag + childrenString + closeTag;
417
+ }
418
+ return openTag + closeTag;
419
+ }
420
+ function escapeHtml(text) {
421
+ const htmlEscapes = {
422
+ '&': '&amp;',
423
+ '<': '&lt;',
424
+ '>': '&gt;',
425
+ '"': '&quot;',
426
+ "'": '&#x27;',
427
+ '/': '&#x2F;'
428
+ };
429
+ return text.replace(/[&<>"'/]/g, (match) => htmlEscapes[match]);
430
+ }
431
+ function kebabCase(str) {
432
+ return str.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
433
+ }
434
+
4
435
  function arePropsEqual(oldProps, newProps) {
5
- const oldKeys = Object.keys(oldProps).filter((k) => k !== "children");
6
- const newKeys = Object.keys(newProps).filter((k) => k !== "children");
7
- if (oldKeys.length !== newKeys.length) return false;
8
- return oldKeys.every((key) => oldProps[key] === newProps[key]);
436
+ const oldKeys = Object.keys(oldProps).filter(k => k !== 'children');
437
+ const newKeys = Object.keys(newProps).filter(k => k !== 'children');
438
+ if (oldKeys.length !== newKeys.length)
439
+ return false;
440
+ return oldKeys.every(key => oldProps[key] === newProps[key]);
9
441
  }
10
442
  function diff(oldNode, newNode) {
11
- if (oldNode == null || newNode == null) return oldNode !== newNode;
12
- if (typeof oldNode !== typeof newNode) return true;
13
- if (typeof newNode === "string" || typeof newNode === "number")
14
- return oldNode !== newNode;
15
- if (newNode.type !== oldNode.type) return true;
16
- return !arePropsEqual(oldNode.props, newNode.props);
443
+ if (oldNode == null || newNode == null)
444
+ return oldNode !== newNode;
445
+ if (typeof oldNode !== typeof newNode)
446
+ return true;
447
+ if (typeof newNode === 'string' || typeof newNode === 'number')
448
+ return oldNode !== newNode;
449
+ if (newNode.type !== oldNode.type)
450
+ return true;
451
+ return !arePropsEqual(oldNode.props, newNode.props);
17
452
  }
18
453
  function shouldComponentUpdate(oldProps, newProps) {
19
- return !arePropsEqual(oldProps, newProps);
454
+ return !arePropsEqual(oldProps, newProps);
20
455
  }
456
+
21
457
  class Component {
22
- constructor(props = {}) {
23
- this.state = {};
24
- this.element = null;
25
- this._mounted = false;
26
- this.props = props;
27
- }
28
- componentDidMount() {
29
- }
30
- async setState(newState) {
31
- const prevState = { ...this.state };
32
- this.state = { ...prevState, ...newState };
33
- console.log(`${this.constructor.name} state updated:`, {
34
- prev: prevState,
35
- next: this.state
36
- });
37
- await Promise.resolve();
38
- if (this._mounted) {
39
- await this.update();
40
- } else {
41
- await this.update();
42
- }
43
- }
44
- _replayEvents(oldElement, newElement) {
45
- const oldEvents = oldElement.__events || {};
46
- Object.entries(oldEvents).forEach(([event, handler]) => {
47
- newElement.addEventListener(event, handler);
48
- });
49
- newElement.__events = oldEvents;
50
- }
51
- _deepCloneWithEvents(node) {
52
- const clone = node.cloneNode(false);
53
- const events = node.__events || {};
54
- clone.__events = events;
55
- Object.entries(events).forEach(([event, handler]) => {
56
- clone.addEventListener(event, handler);
458
+ constructor(props = {}) {
459
+ this.state = {};
460
+ this.element = null;
461
+ this._mounted = false;
462
+ this.props = props;
463
+ }
464
+ componentDidMount() {
465
+ // Hook for after component is mounted
466
+ }
467
+ async setState(newState) {
468
+ const prevState = { ...this.state };
469
+ this.state = { ...prevState, ...newState };
470
+ console.log(`${this.constructor.name} state updated:`, {
471
+ prev: prevState,
472
+ next: this.state
473
+ });
474
+ await Promise.resolve(); // Ensure state is updated before re-render
475
+ if (this._mounted) {
476
+ await this.update();
477
+ }
478
+ else {
479
+ await this.update();
480
+ }
481
+ }
482
+ _replayEvents(oldElement, newElement) {
483
+ const oldEvents = oldElement.__events || {};
484
+ Object.entries(oldEvents).forEach(([event, handler]) => {
485
+ newElement.addEventListener(event, handler);
486
+ });
487
+ newElement.__events = oldEvents;
488
+ }
489
+ _deepCloneWithEvents(node) {
490
+ const clone = node.cloneNode(false);
491
+ // Copy events from original element
492
+ const events = node.__events || {};
493
+ clone.__events = events;
494
+ Object.entries(events).forEach(([event, handler]) => {
495
+ clone.addEventListener(event, handler);
496
+ });
497
+ // Clone children
498
+ Array.from(node.childNodes).forEach(child => {
499
+ if (child instanceof HTMLElement) {
500
+ clone.appendChild(this._deepCloneWithEvents(child));
501
+ }
502
+ else {
503
+ clone.appendChild(child.cloneNode(true));
504
+ }
505
+ });
506
+ return clone;
507
+ }
508
+ async update() {
509
+ const vdom = this.render();
510
+ if (!vdom)
511
+ return document.createTextNode('');
512
+ const rendered = await createElement(vdom);
513
+ if (rendered instanceof HTMLElement) {
514
+ return this._updateElement(rendered);
515
+ }
516
+ const wrapper = document.createElement('div');
517
+ wrapper.appendChild(rendered);
518
+ return this._updateElement(wrapper);
519
+ }
520
+ async _updateElement(rendered) {
521
+ const newElement = this._deepCloneWithEvents(rendered);
522
+ newElement.__instance = this;
523
+ if (!this.element) {
524
+ this.element = newElement;
525
+ if (!this._mounted) {
526
+ this._mounted = true;
527
+ queueMicrotask(() => this.componentDidMount());
528
+ }
529
+ }
530
+ else if (this.element.parentNode) {
531
+ this.element.parentNode.replaceChild(newElement, this.element);
532
+ this.element = newElement;
533
+ }
534
+ return this.element;
535
+ }
536
+ render() {
537
+ throw new Error('Component must implement render() method');
538
+ }
539
+ }
540
+
541
+ /**
542
+ * Client-side router for single-page applications
543
+ */
544
+ // Create context for router
545
+ const RouterContext = createContext({
546
+ location: {
547
+ pathname: '/',
548
+ search: '',
549
+ hash: ''
550
+ },
551
+ params: {},
552
+ navigate: () => { },
553
+ match: () => false
554
+ });
555
+ // Parse path pattern into regex
556
+ function parsePath(path) {
557
+ // Convert :param syntax to capture groups
558
+ const pattern = path
559
+ .replace(/\/+$/, '') // Remove trailing slashes
560
+ .replace(/^\/+/, '/') // Ensure leading slash
561
+ .replace(/\/:([^/]+)/g, '/([^/]+)');
562
+ // Get param names
563
+ const paramNames = [];
564
+ path.replace(/\/:([^/]+)/g, (_, paramName) => {
565
+ paramNames.push(paramName);
566
+ return '';
57
567
  });
58
- Array.from(node.childNodes).forEach((child) => {
59
- if (child instanceof HTMLElement) {
60
- clone.appendChild(this._deepCloneWithEvents(child));
61
- } else {
62
- clone.appendChild(child.cloneNode(true));
63
- }
568
+ return { pattern, paramNames };
569
+ }
570
+ // Match a path against a pattern
571
+ function matchPath(pathname, route) {
572
+ const { path, exact = false } = route;
573
+ const { pattern, paramNames } = parsePath(path);
574
+ // Create regex with or without exact matching
575
+ const regex = new RegExp(`^${pattern}${exact ? '$' : ''}`);
576
+ const match = pathname.match(regex);
577
+ if (!match)
578
+ return null;
579
+ // Extract params
580
+ const params = {};
581
+ paramNames.forEach((name, index) => {
582
+ params[name] = match[index + 1];
64
583
  });
65
- return clone;
66
- }
67
- async update() {
68
- const vdom = this.render();
69
- if (!vdom) return document.createTextNode("");
70
- const rendered = await createElement(vdom);
71
- if (rendered instanceof HTMLElement) {
72
- return this._updateElement(rendered);
73
- }
74
- const wrapper = document.createElement("div");
75
- wrapper.appendChild(rendered);
76
- return this._updateElement(wrapper);
77
- }
78
- async _updateElement(rendered) {
79
- const newElement = this._deepCloneWithEvents(rendered);
80
- newElement.__instance = this;
81
- if (!this.element) {
82
- this.element = newElement;
83
- if (!this._mounted) {
84
- this._mounted = true;
85
- queueMicrotask(() => this.componentDidMount());
86
- }
87
- } else if (this.element.parentNode) {
88
- this.element.parentNode.replaceChild(newElement, this.element);
89
- this.element = newElement;
90
- }
91
- return this.element;
92
- }
93
- render() {
94
- throw new Error("Component must implement render() method");
95
- }
96
- }
97
- const DEFAULT_GO_WASM_PATH = "/wasm_exec.js";
98
- async function loadGoWasm(wasmUrl, options = {}) {
99
- const {
100
- importObject = {},
101
- goWasmPath = DEFAULT_GO_WASM_PATH,
102
- loadGo = true,
103
- onLoad,
104
- debug = false
105
- } = options;
106
- if (typeof window !== "undefined" && loadGo) {
107
- await loadGoRuntime(goWasmPath);
108
- }
109
- try {
110
- const go = typeof Go !== "undefined" ? new Go() : null;
111
- if (debug) console.log(`[WASM] Loading module from ${wasmUrl}`);
112
- const response = await fetch(wasmUrl);
113
- if (!response.ok) {
114
- throw new Error(`Failed to fetch WASM module: ${response.statusText}`);
115
- }
116
- const buffer = await response.arrayBuffer();
117
- const module = await WebAssembly.compile(buffer);
118
- const finalImportObject = go ? {
119
- ...go.importObject,
120
- ...importObject
121
- } : importObject;
122
- const instance = await WebAssembly.instantiate(module, finalImportObject);
123
- if (go) {
124
- go.run(instance);
125
- }
126
- const exports = instance.exports;
127
- const functions = {};
128
- for (const key in exports) {
129
- if (typeof exports[key] === "function") {
130
- const exportedFn = exports[key];
131
- functions[key] = (...args) => exportedFn(...args);
132
- if (debug) {
133
- const originalFn = functions[key];
134
- functions[key] = (...args) => {
135
- console.log(`[WASM] Calling ${key}(${args.join(", ")})`);
136
- const result = originalFn(...args);
137
- console.log(`[WASM] ${key} returned:`, result);
138
- return result;
139
- };
140
- }
141
- }
142
- }
143
- if (typeof window !== "undefined") {
144
- for (const key in window) {
145
- if (key.startsWith("go") && typeof window[key] === "function") {
146
- const globalFn = window[key];
147
- functions[key] = (...args) => globalFn(...args);
148
- if (debug) {
149
- const originalFn = functions[key];
150
- functions[key] = (...args) => {
151
- console.log(`[WASM] Calling global ${key}(${args.join(", ")})`);
152
- const result = originalFn(...args);
153
- console.log(`[WASM] ${key} returned:`, result);
154
- return result;
584
+ return params;
585
+ }
586
+ // Router Provider component
587
+ function RouterProvider({ routes, children }) {
588
+ // Get initial location from window if available
589
+ const getInitialLocation = () => {
590
+ if (typeof window === 'undefined') {
591
+ return { pathname: '/', search: '', hash: '' };
592
+ }
593
+ return {
594
+ pathname: window.location.pathname,
595
+ search: window.location.search,
596
+ hash: window.location.hash
597
+ };
598
+ };
599
+ // Fix: Call the function to get the initial value instead of passing the function itself
600
+ const [location, setLocation] = useState(getInitialLocation());
601
+ const [params, setParams] = useState({});
602
+ // Update params when location changes
603
+ useEffect(() => {
604
+ for (const route of routes) {
605
+ const matchedParams = matchPath(location.pathname, route);
606
+ if (matchedParams) {
607
+ setParams(matchedParams);
608
+ break;
609
+ }
610
+ }
611
+ }, [location, routes]);
612
+ // Listen for popstate events
613
+ useEffect(() => {
614
+ if (typeof window === 'undefined')
615
+ return;
616
+ const handlePopState = () => {
617
+ setLocation({
618
+ pathname: window.location.pathname,
619
+ search: window.location.search,
620
+ hash: window.location.hash
621
+ });
622
+ };
623
+ window.addEventListener('popstate', handlePopState);
624
+ return () => window.removeEventListener('popstate', handlePopState);
625
+ }, []);
626
+ // Navigation function
627
+ const navigate = (to, options = {}) => {
628
+ if (typeof window === 'undefined')
629
+ return;
630
+ const { replace = false, state = null } = options;
631
+ if (replace) {
632
+ window.history.replaceState(state, '', to);
633
+ }
634
+ else {
635
+ window.history.pushState(state, '', to);
636
+ }
637
+ // Update location
638
+ setLocation({
639
+ pathname: window.location.pathname,
640
+ search: window.location.search,
641
+ hash: window.location.hash
642
+ });
643
+ };
644
+ // Match function to test if a path matches the current location
645
+ const match = (path) => {
646
+ const { pattern } = parsePath(path);
647
+ const regex = new RegExp(`^${pattern}`);
648
+ return regex.test(location.pathname);
649
+ };
650
+ // Router context value
651
+ const routerValue = {
652
+ location: {
653
+ pathname: location.pathname,
654
+ search: location.search,
655
+ hash: location.hash
656
+ },
657
+ params,
658
+ navigate,
659
+ match
660
+ };
661
+ return jsx(RouterContext.Provider, { value: routerValue, children });
662
+ }
663
+ // Route component
664
+ function Route({ path, component: Component, props = {} }) {
665
+ const context = useContext();
666
+ const params = context.params;
667
+ const locationPathname = context.location.pathname;
668
+ const routeToMatch = { path, component: Component };
669
+ const match = matchPath(locationPathname, routeToMatch);
670
+ if (!match)
671
+ return null;
672
+ return jsx(Component, { ...props, params });
673
+ }
674
+ // Switch component
675
+ function Switch({ children }) {
676
+ const context = useContext();
677
+ const locationPathname = context.location.pathname;
678
+ // Find the first matching route
679
+ const child = Array.isArray(children)
680
+ ? children.find(child => {
681
+ if (!child || typeof child.type !== 'function' || !child.props.path)
682
+ return false;
683
+ const routeObj = {
684
+ path: child.props.path,
685
+ component: child.type,
686
+ exact: child.props.exact || false
155
687
  };
156
- }
688
+ return matchPath(locationPathname, routeObj);
689
+ })
690
+ : children;
691
+ return child || null;
692
+ }
693
+ // Link component
694
+ function Link({ to, replace = false, state = null, className = '', activeClassName = '', children, ...rest }) {
695
+ const context = useContext();
696
+ const navigate = context.navigate;
697
+ const match = context.match;
698
+ const handleClick = (e) => {
699
+ e.preventDefault();
700
+ navigate(to, { replace, state });
701
+ };
702
+ const isActive = match(to);
703
+ const classes = [
704
+ className,
705
+ isActive ? activeClassName : ''
706
+ ].filter(Boolean).join(' ');
707
+ return jsx('a', {
708
+ href: to,
709
+ className: classes || undefined,
710
+ onClick: handleClick,
711
+ ...rest,
712
+ children
713
+ });
714
+ }
715
+ // Redirect component
716
+ function Redirect({ to, replace = true }) {
717
+ const context = useContext();
718
+ const navigate = context.navigate;
719
+ useEffect(() => {
720
+ navigate(to, { replace });
721
+ }, [to]);
722
+ return null;
723
+ }
724
+ // Hooks
725
+ function useLocation() {
726
+ const context = useContext();
727
+ return context.location;
728
+ }
729
+ function useParams() {
730
+ const context = useContext();
731
+ return context.params;
732
+ }
733
+ function useNavigate() {
734
+ const context = useContext();
735
+ return context.navigate;
736
+ }
737
+
738
+ /**
739
+ * Form handling utilities for the framework
740
+ */
741
+ function useForm(options) {
742
+ const { initialValues, validate, onSubmit } = options;
743
+ const [values, setValues] = useState(initialValues);
744
+ const [errors, setErrors] = useState({});
745
+ const [touched, setTouched] = useState({});
746
+ const [dirty, setDirty] = useState({});
747
+ const [isSubmitting, setIsSubmitting] = useState(false);
748
+ const [submitCount, setSubmitCount] = useState(0);
749
+ // Track form validity and dirty state
750
+ const isValid = Object.keys(errors).length === 0;
751
+ const isDirty = Object.values(dirty).some(Boolean);
752
+ // Validate form when values or validate function changes
753
+ useEffect(() => {
754
+ if (validate) {
755
+ const validationErrors = validate(values);
756
+ setErrors(validationErrors || {});
757
+ }
758
+ }, [values, validate]);
759
+ // Handle form input changes
760
+ const handleChange = (e) => {
761
+ const { name, value, type, checked } = e.target;
762
+ const fieldValue = type === 'checkbox' ? checked : value;
763
+ setValues(prev => ({
764
+ ...prev,
765
+ [name]: fieldValue
766
+ }));
767
+ setDirty(prev => ({
768
+ ...prev,
769
+ [name]: true
770
+ }));
771
+ };
772
+ // Handle field blur
773
+ const handleBlur = (e) => {
774
+ const { name } = e.target;
775
+ setTouched(prev => ({
776
+ ...prev,
777
+ [name]: true
778
+ }));
779
+ };
780
+ // Set field value programmatically
781
+ const setFieldValue = (field, value) => {
782
+ setValues(prev => ({
783
+ ...prev,
784
+ [field]: value
785
+ }));
786
+ setDirty(prev => ({
787
+ ...prev,
788
+ [field]: true
789
+ }));
790
+ };
791
+ // Set field error programmatically
792
+ const setFieldError = (field, error) => {
793
+ setErrors(prev => ({
794
+ ...prev,
795
+ [field]: error
796
+ }));
797
+ };
798
+ // Update multiple values at once
799
+ const updateValues = (newValues) => {
800
+ setValues(prev => ({
801
+ ...prev,
802
+ ...newValues
803
+ }));
804
+ // Mark changed fields as dirty
805
+ const dirtyFields = {};
806
+ Object.keys(newValues).forEach(key => {
807
+ dirtyFields[key] = true;
808
+ });
809
+ setDirty(prev => ({
810
+ ...prev,
811
+ ...dirtyFields
812
+ }));
813
+ };
814
+ // Reset form to initial state
815
+ const resetForm = () => {
816
+ setValues(initialValues);
817
+ setErrors({});
818
+ setTouched({});
819
+ setDirty({});
820
+ setIsSubmitting(false);
821
+ };
822
+ // Handle form submission
823
+ const handleSubmit = async (e) => {
824
+ e.preventDefault();
825
+ // Mark all fields as touched
826
+ const allTouched = {};
827
+ Object.keys(values).forEach(key => {
828
+ allTouched[key] = true;
829
+ });
830
+ setTouched(allTouched);
831
+ // Validate before submission
832
+ let validationErrors = {};
833
+ if (validate) {
834
+ validationErrors = validate(values);
835
+ setErrors(validationErrors || {});
836
+ }
837
+ // Only proceed if valid
838
+ if (Object.keys(validationErrors).length === 0 && onSubmit) {
839
+ setIsSubmitting(true);
840
+ setSubmitCount(count => count + 1);
841
+ try {
842
+ await onSubmit(values, {
843
+ fields: Object.keys(values).reduce((acc, key) => {
844
+ acc[key] = {
845
+ value: values[key],
846
+ error: errors[key],
847
+ touched: touched[key] || false,
848
+ dirty: dirty[key] || false
849
+ };
850
+ return acc;
851
+ }, {}),
852
+ isValid,
853
+ isDirty,
854
+ isSubmitting: true,
855
+ submitCount: submitCount + 1
856
+ });
857
+ }
858
+ finally {
859
+ setIsSubmitting(false);
860
+ }
861
+ }
862
+ };
863
+ return {
864
+ values,
865
+ errors,
866
+ touched,
867
+ dirty,
868
+ isValid,
869
+ isDirty,
870
+ isSubmitting,
871
+ submitCount,
872
+ handleChange,
873
+ handleBlur,
874
+ handleSubmit,
875
+ setFieldValue,
876
+ setFieldError,
877
+ setValues: updateValues,
878
+ resetForm
879
+ };
880
+ }
881
+
882
+ function createEventBus() {
883
+ const events = new Map();
884
+ const onceHandlers = new WeakMap();
885
+ const on = (event, handler) => {
886
+ if (!events.has(event)) {
887
+ events.set(event, new Set());
888
+ }
889
+ events.get(event).add(handler);
890
+ // Return a function to remove this handler
891
+ return () => off(event, handler);
892
+ };
893
+ const once = (event, handler) => {
894
+ // Create a wrapper that will call the handler and remove itself
895
+ const onceWrapper = (...args) => {
896
+ off(event, onceWrapper);
897
+ handler(...args);
898
+ };
899
+ // Store the mapping between the original handler and the wrapper
900
+ onceHandlers.set(handler, onceWrapper);
901
+ // Register the wrapper
902
+ return on(event, onceWrapper);
903
+ };
904
+ const off = (event, handler) => {
905
+ // If no handler is provided, remove all handlers for the event
906
+ if (!handler) {
907
+ events.delete(event);
908
+ return;
157
909
  }
158
- }
910
+ // Check if it's a once handler wrapper
911
+ const wrappedHandler = onceHandlers.get(handler);
912
+ const handlerToRemove = wrappedHandler || handler;
913
+ if (events.has(event)) {
914
+ events.get(event).delete(handlerToRemove);
915
+ // Clean up empty event sets
916
+ if (events.get(event).size === 0) {
917
+ events.delete(event);
918
+ }
919
+ }
920
+ };
921
+ const emit = (event, ...args) => {
922
+ if (!events.has(event)) {
923
+ return;
924
+ }
925
+ // Create a copy of the handlers to avoid issues if handlers modify the set
926
+ const handlers = Array.from(events.get(event));
927
+ // Call each handler with the arguments
928
+ for (const handler of handlers) {
929
+ handler(...args);
930
+ }
931
+ };
932
+ const clear = (event) => {
933
+ if (event) {
934
+ events.delete(event);
935
+ }
936
+ else {
937
+ events.clear();
938
+ }
939
+ };
940
+ return { on, once, off, emit, clear };
941
+ }
942
+ // Create a global event bus instance
943
+ const globalEventBus = createEventBus();
944
+ // Hook to use the event bus in components
945
+ function useEvent(event, handler, options = {}) {
946
+ return options.once
947
+ ? globalEventBus.once(event, handler)
948
+ : globalEventBus.on(event, handler);
949
+ }
950
+
951
+ /**
952
+ * Global state management solution similar to Redux
953
+ */
954
+ function createStore(reducer, initialState, middlewares = []) {
955
+ let state = initialState;
956
+ let listeners = [];
957
+ // Apply middlewares
958
+ let dispatch = (action) => {
959
+ state = reducer(state, action);
960
+ listeners.forEach(listener => listener());
961
+ return action;
962
+ };
963
+ // Chain middlewares
964
+ if (middlewares.length > 0) {
965
+ const middlewareAPI = {
966
+ getState: () => state,
967
+ dispatch: (action) => dispatch(action),
968
+ subscribe: (listener) => subscribe(listener)
969
+ };
970
+ const chain = middlewares.map(middleware => middleware(middlewareAPI));
971
+ dispatch = chain.reduce((a, b) => (next) => a(b(next)))(dispatch);
159
972
  }
160
- const wasmInstance = {
161
- instance,
162
- module,
163
- exports,
164
- functions
973
+ // Subscribe to store changes
974
+ function subscribe(listener) {
975
+ listeners.push(listener);
976
+ return function unsubscribe() {
977
+ listeners = listeners.filter(l => l !== listener);
978
+ };
979
+ }
980
+ // Initialize store with default state
981
+ dispatch({ type: '@@INIT' });
982
+ return {
983
+ getState: () => state,
984
+ dispatch,
985
+ subscribe
165
986
  };
166
- if (onLoad) {
167
- onLoad(wasmInstance);
168
- }
169
- return wasmInstance;
170
- } catch (error) {
171
- console.error("[WASM] Failed to load Go WASM module:", error);
172
- throw error;
173
- }
174
- }
175
- async function loadGoRuntime(path = DEFAULT_GO_WASM_PATH) {
176
- if (typeof window === "undefined") return;
177
- if (typeof window.Go !== "undefined") {
178
- return;
179
- }
180
- return new Promise((resolve, reject) => {
181
- const script = document.createElement("script");
182
- script.src = path;
183
- script.onload = () => resolve();
184
- script.onerror = () => reject(new Error(`Failed to load Go WASM runtime from ${path}`));
185
- document.head.appendChild(script);
186
- });
187
- }
188
- function createTypedWasmFunction(instance, functionName) {
189
- if (!instance.functions[functionName]) {
190
- throw new Error(`WASM function "${functionName}" not found`);
191
- }
192
- return instance.functions[functionName];
193
- }
194
- const goValues = {
195
- // Convert JS string to Go string (returns memory pointer)
196
- stringToGo: (instance, str) => {
197
- if (!instance.functions.__stringToGo) {
198
- throw new Error("__stringToGo function not found in WASM module");
199
- }
200
- return instance.functions.__stringToGo(str);
201
- },
202
- // Convert Go string (memory pointer) to JS string
203
- stringFromGo: (instance, ptr) => {
204
- if (!instance.functions.__stringFromGo) {
205
- throw new Error("__stringFromGo function not found in WASM module");
206
- }
207
- return instance.functions.__stringFromGo(ptr);
208
- },
209
- // Convert JS object to Go (returns memory pointer)
210
- objectToGo: (instance, obj) => {
211
- if (!instance.functions.__objectToGo) {
212
- throw new Error("__objectToGo function not found in WASM module");
213
- }
214
- return instance.functions.__objectToGo(JSON.stringify(obj));
215
- },
216
- // Convert Go object (memory pointer) to JS object
217
- objectFromGo: (instance, ptr) => {
218
- if (!instance.functions.__objectFromGo) {
219
- throw new Error("__objectFromGo function not found in WASM module");
220
- }
221
- const str = instance.functions.__objectFromGo(ptr);
222
- return JSON.parse(str);
223
- }
987
+ }
988
+ const StoreContext = createContext({
989
+ store: {
990
+ getState: () => ({}),
991
+ dispatch: () => { },
992
+ subscribe: () => () => { }
993
+ },
994
+ state: {}
995
+ });
996
+ function StoreProvider({ store, children }) {
997
+ const [state, setState] = useState(store.getState());
998
+ useEffect(() => {
999
+ const unsubscribe = store.subscribe(() => {
1000
+ setState(store.getState());
1001
+ });
1002
+ return unsubscribe;
1003
+ }, [store]);
1004
+ return jsx(StoreContext.Provider, {
1005
+ value: { store, state },
1006
+ children
1007
+ });
1008
+ }
1009
+ function useSelector(selector) {
1010
+ const context = useContext();
1011
+ return selector(context.state);
1012
+ }
1013
+ function useDispatch() {
1014
+ const context = useContext();
1015
+ return context.store.dispatch;
1016
+ }
1017
+ function useStore() {
1018
+ const context = useContext();
1019
+ return context.store;
1020
+ }
1021
+ // Common middlewares
1022
+ const logger = (store) => (next) => (action) => {
1023
+ console.group(action.type);
1024
+ console.log('Previous state:', store.getState());
1025
+ console.log('Action:', action);
1026
+ const result = next(action);
1027
+ console.log('Next state:', store.getState());
1028
+ console.groupEnd();
1029
+ return result;
224
1030
  };
225
- const frontendHamroun = {
226
- // JSX
227
- jsx,
228
- jsxs: jsx,
229
- jsxDEV: jsx,
230
- Fragment,
231
- createElement,
232
- // Rendering
233
- render,
234
- hydrate,
235
- // Hooks
236
- useState,
237
- useEffect,
238
- useMemo,
239
- useRef,
240
- useContext,
241
- useErrorBoundary,
242
- // Context
243
- createContext,
244
- // Server rendering
245
- renderToString,
246
- // Utilities
247
- batchUpdates,
248
- diff,
249
- shouldComponentUpdate,
250
- // Component class
251
- Component,
252
- // WASM
253
- loadGoWasm,
254
- createTypedWasmFunction,
255
- goValues
1031
+ const thunk = (store) => (next) => (action) => {
1032
+ if (typeof action === 'function') {
1033
+ return action(store.dispatch, store.getState);
1034
+ }
1035
+ return next(action);
256
1036
  };
257
- export {
258
- Component,
259
- Fragment,
260
- batchUpdates,
261
- createContext,
262
- createElement,
263
- createTypedWasmFunction,
264
- frontendHamroun as default,
265
- diff,
266
- goValues,
267
- hydrate,
268
- jsx,
269
- jsx as jsxDEV,
270
- jsx as jsxs,
271
- loadGoWasm,
272
- render,
273
- renderToString,
274
- shouldComponentUpdate,
275
- useContext,
276
- useEffect,
277
- useErrorBoundary,
278
- useMemo,
279
- useRef,
280
- useState
1037
+
1038
+ /**
1039
+ * Lifecycle events for components and application
1040
+ */
1041
+ var LifecycleEvents;
1042
+ (function (LifecycleEvents) {
1043
+ LifecycleEvents["APP_INIT"] = "app:init";
1044
+ LifecycleEvents["APP_MOUNTED"] = "app:mounted";
1045
+ LifecycleEvents["APP_UPDATED"] = "app:updated";
1046
+ LifecycleEvents["APP_ERROR"] = "app:error";
1047
+ LifecycleEvents["APP_DESTROYED"] = "app:destroyed";
1048
+ LifecycleEvents["COMPONENT_CREATED"] = "component:created";
1049
+ LifecycleEvents["COMPONENT_MOUNTED"] = "component:mounted";
1050
+ LifecycleEvents["COMPONENT_UPDATED"] = "component:updated";
1051
+ LifecycleEvents["COMPONENT_ERROR"] = "component:error";
1052
+ LifecycleEvents["COMPONENT_UNMOUNTED"] = "component:unmounted";
1053
+ LifecycleEvents["ROUTER_BEFORE_CHANGE"] = "router:before-change";
1054
+ LifecycleEvents["ROUTER_AFTER_CHANGE"] = "router:after-change";
1055
+ LifecycleEvents["ROUTER_ERROR"] = "router:error";
1056
+ LifecycleEvents["STORE_INITIALIZED"] = "store:initialized";
1057
+ LifecycleEvents["STORE_BEFORE_ACTION"] = "store:before-action";
1058
+ LifecycleEvents["STORE_AFTER_ACTION"] = "store:after-action";
1059
+ LifecycleEvents["STORE_ERROR"] = "store:error";
1060
+ })(LifecycleEvents || (LifecycleEvents = {}));
1061
+ // Event emitters
1062
+ function emitAppInit(data) {
1063
+ globalEventBus.emit(LifecycleEvents.APP_INIT, data);
1064
+ }
1065
+ function emitAppMounted(rootElement) {
1066
+ globalEventBus.emit(LifecycleEvents.APP_MOUNTED, rootElement);
1067
+ }
1068
+ function emitAppUpdated() {
1069
+ globalEventBus.emit(LifecycleEvents.APP_UPDATED);
1070
+ }
1071
+ function emitAppError(error) {
1072
+ globalEventBus.emit(LifecycleEvents.APP_ERROR, error);
1073
+ }
1074
+ function emitAppDestroyed() {
1075
+ globalEventBus.emit(LifecycleEvents.APP_DESTROYED);
1076
+ }
1077
+ function emitComponentCreated(info) {
1078
+ globalEventBus.emit(LifecycleEvents.COMPONENT_CREATED, info);
1079
+ }
1080
+ function emitComponentMounted(info, element) {
1081
+ globalEventBus.emit(LifecycleEvents.COMPONENT_MOUNTED, info, element);
1082
+ }
1083
+ function emitComponentUpdated(info, prevProps, newProps) {
1084
+ globalEventBus.emit(LifecycleEvents.COMPONENT_UPDATED, info, prevProps, newProps);
1085
+ }
1086
+ function emitComponentError(info, error) {
1087
+ globalEventBus.emit(LifecycleEvents.COMPONENT_ERROR, info, error);
1088
+ }
1089
+ function emitComponentUnmounted(info) {
1090
+ globalEventBus.emit(LifecycleEvents.COMPONENT_UNMOUNTED, info);
1091
+ }
1092
+ // Event listeners
1093
+ function onAppInit(handler) {
1094
+ return globalEventBus.on(LifecycleEvents.APP_INIT, handler);
1095
+ }
1096
+ function onAppMounted(handler) {
1097
+ return globalEventBus.on(LifecycleEvents.APP_MOUNTED, handler);
1098
+ }
1099
+ function onAppUpdated(handler) {
1100
+ return globalEventBus.on(LifecycleEvents.APP_UPDATED, handler);
1101
+ }
1102
+ function onAppError(handler) {
1103
+ return globalEventBus.on(LifecycleEvents.APP_ERROR, handler);
1104
+ }
1105
+ function onAppDestroyed(handler) {
1106
+ return globalEventBus.on(LifecycleEvents.APP_DESTROYED, handler);
1107
+ }
1108
+ function onComponentCreated(handler) {
1109
+ return globalEventBus.on(LifecycleEvents.COMPONENT_CREATED, handler);
1110
+ }
1111
+ function onComponentMounted(handler) {
1112
+ return globalEventBus.on(LifecycleEvents.COMPONENT_MOUNTED, handler);
1113
+ }
1114
+ function onComponentUpdated(handler) {
1115
+ return globalEventBus.on(LifecycleEvents.COMPONENT_UPDATED, handler);
1116
+ }
1117
+ function onComponentError(handler) {
1118
+ return globalEventBus.on(LifecycleEvents.COMPONENT_ERROR, handler);
1119
+ }
1120
+ function onComponentUnmounted(handler) {
1121
+ return globalEventBus.on(LifecycleEvents.COMPONENT_UNMOUNTED, handler);
1122
+ }
1123
+
1124
+ // Core JSX and rendering functions
1125
+ // Default export object for compatibility
1126
+ const frontendHamroun = {
1127
+ // JSX
1128
+ jsx,
1129
+ jsxs: jsx,
1130
+ jsxDEV: jsx,
1131
+ Fragment,
1132
+ createElement,
1133
+ // Rendering
1134
+ render,
1135
+ hydrate,
1136
+ renderToString,
1137
+ // Hooks
1138
+ useState,
1139
+ useEffect,
1140
+ useMemo,
1141
+ useRef,
1142
+ useContext,
1143
+ useErrorBoundary,
1144
+ // Context
1145
+ createContext,
1146
+ // Utilities
1147
+ batchUpdates,
1148
+ diff,
1149
+ shouldComponentUpdate,
1150
+ // Component class
1151
+ Component,
1152
+ // Router
1153
+ RouterProvider,
1154
+ Route,
1155
+ Switch,
1156
+ Link,
1157
+ Redirect,
1158
+ useLocation,
1159
+ useParams,
1160
+ useNavigate,
1161
+ // Forms
1162
+ useForm,
1163
+ // Event bus
1164
+ createEventBus,
1165
+ useEvent,
1166
+ eventBus: globalEventBus
281
1167
  };
1168
+
1169
+ export { Component, Fragment, LifecycleEvents, Link, Redirect, Route, RouterProvider, StoreProvider, Switch, batchUpdates, createContext, createElement, createEventBus, createStore, frontendHamroun as default, diff, emitAppDestroyed, emitAppError, emitAppInit, emitAppMounted, emitAppUpdated, emitComponentCreated, emitComponentError, emitComponentMounted, emitComponentUnmounted, emitComponentUpdated, globalEventBus as eventBus, hydrate, jsx, jsx as jsxDEV, jsx as jsxs, logger, onAppDestroyed, onAppError, onAppInit, onAppMounted, onAppUpdated, onComponentCreated, onComponentError, onComponentMounted, onComponentUnmounted, onComponentUpdated, render, renderToString, shouldComponentUpdate, thunk, useContext, useDispatch, useEffect, useErrorBoundary, useEvent, useForm, useLocation, useMemo, useNavigate, useParams, useRef, useSelector, useState, useStore };
282
1170
  //# sourceMappingURL=index.js.map