frontend-hamroun 1.2.85 → 1.2.88
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.
- package/dist/batch.d.ts +4 -0
- package/dist/batch.d.ts.map +1 -0
- package/dist/batch.js +22 -0
- package/dist/client-router.d.ts +61 -0
- package/dist/client-router.d.ts.map +1 -0
- package/dist/client-router.js +209 -0
- package/dist/component.d.ts +15 -0
- package/dist/component.d.ts.map +1 -0
- package/dist/component.js +84 -0
- package/dist/components/Counter.d.ts +1 -0
- package/dist/components/Counter.d.ts.map +1 -0
- package/dist/components/Counter.js +2 -0
- package/dist/context.d.ts +5 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +23 -0
- package/dist/event-bus.d.ts +24 -0
- package/dist/event-bus.d.ts.map +1 -0
- package/dist/event-bus.js +74 -0
- package/dist/forms.d.ts +41 -0
- package/dist/forms.d.ts.map +1 -0
- package/dist/forms.js +147 -0
- package/dist/hooks.d.ts +12 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +142 -0
- package/dist/index.cjs +1118 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.client.d.ts +13 -0
- package/dist/index.client.d.ts.map +1 -0
- package/dist/index.client.js +12 -25
- package/dist/index.d.ts +65 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1040 -264
- package/dist/index.js.map +1 -1
- package/dist/jsx-dev-runtime.cjs +102 -0
- package/dist/jsx-dev-runtime.cjs.map +1 -0
- package/dist/jsx-dev-runtime.d.ts +3 -0
- package/dist/jsx-dev-runtime.d.ts.map +1 -0
- package/dist/jsx-dev-runtime.js +96 -0
- package/dist/jsx-dev-runtime.js.map +1 -0
- package/dist/jsx-runtime/jsx-runtime.d.ts +5 -0
- package/dist/jsx-runtime/jsx-runtime.d.ts.map +1 -0
- package/dist/jsx-runtime/jsx-runtime.js +40 -0
- package/dist/jsx-runtime.cjs +112 -1
- package/dist/jsx-runtime.cjs.map +1 -1
- package/dist/jsx-runtime.d.ts +18 -0
- package/dist/jsx-runtime.d.ts.map +1 -0
- package/dist/jsx-runtime.js +90 -79
- package/dist/jsx-runtime.js.map +1 -1
- package/dist/lifecycle-events.d.ts +109 -0
- package/dist/lifecycle-events.d.ts.map +1 -0
- package/dist/lifecycle-events.js +176 -0
- package/dist/renderComponent.d.ts +14 -0
- package/dist/renderComponent.d.ts.map +1 -0
- package/dist/renderComponent.js +29 -0
- package/dist/renderer.d.ts +4 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/renderer.js +49 -0
- package/dist/router.d.ts +56 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +165 -0
- package/dist/server-renderer.d.ts +2 -0
- package/dist/server-renderer.d.ts.map +1 -0
- package/dist/server-renderer.js +111 -5
- package/dist/server-types.d.ts +43 -0
- package/dist/server-types.d.ts.map +1 -0
- package/dist/server-types.js +5 -0
- package/dist/store.d.ts +42 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +98 -0
- package/dist/types.d.ts +272 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/utils.d.ts +47 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +143 -0
- package/dist/vdom.d.ts +9 -0
- package/dist/vdom.d.ts.map +1 -0
- package/dist/vdom.js +21 -0
- package/dist/wasm.d.ts +37 -0
- package/dist/wasm.d.ts.map +1 -0
- package/dist/wasm.js +158 -0
- package/package.json +54 -83
- package/dist/index.client.cjs +0 -2
- package/dist/index.client.cjs.map +0 -1
- package/dist/index.client.js.map +0 -1
- package/dist/renderer-DaVfBeVi.cjs +0 -2
- package/dist/renderer-DaVfBeVi.cjs.map +0 -1
- package/dist/renderer-nfT7XSpo.js +0 -61
- package/dist/renderer-nfT7XSpo.js.map +0 -1
- package/dist/server-renderer-B5b0Q0ck.cjs +0 -2
- package/dist/server-renderer-B5b0Q0ck.cjs.map +0 -1
- package/dist/server-renderer-C4MB-jAp.js +0 -248
- package/dist/server-renderer-C4MB-jAp.js.map +0 -1
- package/dist/server-renderer.cjs +0 -2
- package/dist/server-renderer.cjs.map +0 -1
- package/dist/server-renderer.js.map +0 -1
package/dist/forms.js
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
/**
|
2
|
+
* Form handling utilities for the framework
|
3
|
+
*/
|
4
|
+
import { useState, useEffect } from './hooks.js';
|
5
|
+
export function useForm(options) {
|
6
|
+
const { initialValues, validate, onSubmit } = options;
|
7
|
+
const [values, setValues] = useState(initialValues);
|
8
|
+
const [errors, setErrors] = useState({});
|
9
|
+
const [touched, setTouched] = useState({});
|
10
|
+
const [dirty, setDirty] = useState({});
|
11
|
+
const [isSubmitting, setIsSubmitting] = useState(false);
|
12
|
+
const [submitCount, setSubmitCount] = useState(0);
|
13
|
+
// Track form validity and dirty state
|
14
|
+
const isValid = Object.keys(errors).length === 0;
|
15
|
+
const isDirty = Object.values(dirty).some(Boolean);
|
16
|
+
// Validate form when values or validate function changes
|
17
|
+
useEffect(() => {
|
18
|
+
if (validate) {
|
19
|
+
const validationErrors = validate(values);
|
20
|
+
setErrors(validationErrors || {});
|
21
|
+
}
|
22
|
+
}, [values, validate]);
|
23
|
+
// Handle form input changes
|
24
|
+
const handleChange = (e) => {
|
25
|
+
const { name, value, type, checked } = e.target;
|
26
|
+
const fieldValue = type === 'checkbox' ? checked : value;
|
27
|
+
setValues(prev => ({
|
28
|
+
...prev,
|
29
|
+
[name]: fieldValue
|
30
|
+
}));
|
31
|
+
setDirty(prev => ({
|
32
|
+
...prev,
|
33
|
+
[name]: true
|
34
|
+
}));
|
35
|
+
};
|
36
|
+
// Handle field blur
|
37
|
+
const handleBlur = (e) => {
|
38
|
+
const { name } = e.target;
|
39
|
+
setTouched(prev => ({
|
40
|
+
...prev,
|
41
|
+
[name]: true
|
42
|
+
}));
|
43
|
+
};
|
44
|
+
// Set field value programmatically
|
45
|
+
const setFieldValue = (field, value) => {
|
46
|
+
setValues(prev => ({
|
47
|
+
...prev,
|
48
|
+
[field]: value
|
49
|
+
}));
|
50
|
+
setDirty(prev => ({
|
51
|
+
...prev,
|
52
|
+
[field]: true
|
53
|
+
}));
|
54
|
+
};
|
55
|
+
// Set field error programmatically
|
56
|
+
const setFieldError = (field, error) => {
|
57
|
+
setErrors(prev => ({
|
58
|
+
...prev,
|
59
|
+
[field]: error
|
60
|
+
}));
|
61
|
+
};
|
62
|
+
// Update multiple values at once
|
63
|
+
const updateValues = (newValues) => {
|
64
|
+
setValues(prev => ({
|
65
|
+
...prev,
|
66
|
+
...newValues
|
67
|
+
}));
|
68
|
+
// Mark changed fields as dirty
|
69
|
+
const dirtyFields = {};
|
70
|
+
Object.keys(newValues).forEach(key => {
|
71
|
+
dirtyFields[key] = true;
|
72
|
+
});
|
73
|
+
setDirty(prev => ({
|
74
|
+
...prev,
|
75
|
+
...dirtyFields
|
76
|
+
}));
|
77
|
+
};
|
78
|
+
// Reset form to initial state
|
79
|
+
const resetForm = () => {
|
80
|
+
setValues(initialValues);
|
81
|
+
setErrors({});
|
82
|
+
setTouched({});
|
83
|
+
setDirty({});
|
84
|
+
setIsSubmitting(false);
|
85
|
+
};
|
86
|
+
// Handle form submission
|
87
|
+
const handleSubmit = async (e) => {
|
88
|
+
e.preventDefault();
|
89
|
+
// Mark all fields as touched
|
90
|
+
const allTouched = {};
|
91
|
+
Object.keys(values).forEach(key => {
|
92
|
+
allTouched[key] = true;
|
93
|
+
});
|
94
|
+
setTouched(allTouched);
|
95
|
+
// Validate before submission
|
96
|
+
let validationErrors = {};
|
97
|
+
if (validate) {
|
98
|
+
validationErrors = validate(values);
|
99
|
+
setErrors(validationErrors || {});
|
100
|
+
}
|
101
|
+
// Only proceed if valid
|
102
|
+
if (Object.keys(validationErrors).length === 0 && onSubmit) {
|
103
|
+
setIsSubmitting(true);
|
104
|
+
setSubmitCount(count => count + 1);
|
105
|
+
try {
|
106
|
+
await onSubmit(values, {
|
107
|
+
fields: Object.keys(values).reduce((acc, key) => {
|
108
|
+
acc[key] = {
|
109
|
+
value: values[key],
|
110
|
+
error: errors[key],
|
111
|
+
touched: touched[key] || false,
|
112
|
+
dirty: dirty[key] || false
|
113
|
+
};
|
114
|
+
return acc;
|
115
|
+
}, {}),
|
116
|
+
isValid,
|
117
|
+
isDirty,
|
118
|
+
isSubmitting: true,
|
119
|
+
submitCount: submitCount + 1
|
120
|
+
});
|
121
|
+
}
|
122
|
+
finally {
|
123
|
+
setIsSubmitting(false);
|
124
|
+
}
|
125
|
+
}
|
126
|
+
};
|
127
|
+
return {
|
128
|
+
values,
|
129
|
+
errors,
|
130
|
+
touched,
|
131
|
+
dirty,
|
132
|
+
isValid,
|
133
|
+
isDirty,
|
134
|
+
isSubmitting,
|
135
|
+
submitCount,
|
136
|
+
handleChange,
|
137
|
+
handleBlur,
|
138
|
+
handleSubmit,
|
139
|
+
setFieldValue,
|
140
|
+
setFieldError,
|
141
|
+
setValues: updateValues,
|
142
|
+
resetForm
|
143
|
+
};
|
144
|
+
}
|
145
|
+
export default {
|
146
|
+
useForm
|
147
|
+
};
|
package/dist/hooks.d.ts
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
export declare function setRenderCallback(callback: any, element: any, container: any): void;
|
2
|
+
export declare function prepareRender(component?: any): number;
|
3
|
+
export declare function finishRender(): void;
|
4
|
+
export declare function useState<T>(initial: T): [T, (newValue: T | ((prev: T) => T)) => void];
|
5
|
+
export declare function useEffect(callback: () => void | (() => void), deps?: any[]): void;
|
6
|
+
export declare function useMemo<T>(factory: () => T, deps?: any[]): T;
|
7
|
+
export declare function useRef<T>(initial: T): {
|
8
|
+
current: T;
|
9
|
+
};
|
10
|
+
export declare function useErrorBoundary(): [Error | null, () => void];
|
11
|
+
export { createContext, useContext } from './context.js';
|
12
|
+
//# sourceMappingURL=hooks.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAkBA,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,GAAG,IAAI,CAInF;AAED,wBAAgB,aAAa,CAAC,SAAS,GAAE,GAAU,GAAG,MAAM,CAK3D;AAED,wBAAgB,YAAY,IAAI,IAAI,CAGnC;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,CAoCrF;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI,CAyBjF;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAqB5D;AAED,wBAAgB,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG;IAAE,OAAO,EAAE,CAAC,CAAA;CAAE,CAqBpD;AAsBD,wBAAgB,gBAAgB,IAAI,CAAC,KAAK,GAAG,IAAI,EAAE,MAAM,IAAI,CAAC,CAG7D;AAGD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/hooks.js
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
import { batchUpdates, isBatching } from './batch.js';
|
2
|
+
// Current render ID counter
|
3
|
+
let currentRender = 0;
|
4
|
+
let renderContext = null;
|
5
|
+
// State storage
|
6
|
+
const states = new Map();
|
7
|
+
const stateIndices = new Map();
|
8
|
+
const effects = new Map();
|
9
|
+
const memos = new Map();
|
10
|
+
const refs = new Map();
|
11
|
+
// Rendering callbacks
|
12
|
+
let globalRenderCallback = null;
|
13
|
+
let globalContainer = null;
|
14
|
+
let currentElement = null;
|
15
|
+
export function setRenderCallback(callback, element, container) {
|
16
|
+
globalRenderCallback = callback;
|
17
|
+
globalContainer = container;
|
18
|
+
currentElement = element;
|
19
|
+
}
|
20
|
+
export function prepareRender(component = null) {
|
21
|
+
currentRender++;
|
22
|
+
renderContext = component;
|
23
|
+
stateIndices.set(currentRender, 0);
|
24
|
+
return currentRender;
|
25
|
+
}
|
26
|
+
export function finishRender() {
|
27
|
+
renderContext = null;
|
28
|
+
currentRender = 0;
|
29
|
+
}
|
30
|
+
export function useState(initial) {
|
31
|
+
if (!currentRender) {
|
32
|
+
throw new Error("useState must be called within a render");
|
33
|
+
}
|
34
|
+
if (!states.has(currentRender)) {
|
35
|
+
states.set(currentRender, []);
|
36
|
+
}
|
37
|
+
const componentStates = states.get(currentRender);
|
38
|
+
const index = stateIndices.get(currentRender) || 0;
|
39
|
+
if (index >= componentStates.length) {
|
40
|
+
componentStates.push(initial);
|
41
|
+
}
|
42
|
+
const state = componentStates[index];
|
43
|
+
const setState = (newValue) => {
|
44
|
+
const nextValue = typeof newValue === 'function'
|
45
|
+
? newValue(componentStates[index])
|
46
|
+
: newValue;
|
47
|
+
if (componentStates[index] === nextValue)
|
48
|
+
return;
|
49
|
+
componentStates[index] = nextValue;
|
50
|
+
if (isBatching) {
|
51
|
+
batchUpdates(() => rerender(currentRender));
|
52
|
+
}
|
53
|
+
else {
|
54
|
+
rerender(currentRender);
|
55
|
+
}
|
56
|
+
};
|
57
|
+
stateIndices.set(currentRender, index + 1);
|
58
|
+
return [state, setState];
|
59
|
+
}
|
60
|
+
export function useEffect(callback, deps) {
|
61
|
+
if (!currentRender)
|
62
|
+
throw new Error("useEffect must be called within a render");
|
63
|
+
const effectIndex = stateIndices.get(currentRender) || 0;
|
64
|
+
if (!effects.has(currentRender)) {
|
65
|
+
effects.set(currentRender, []);
|
66
|
+
}
|
67
|
+
const componentEffects = effects.get(currentRender);
|
68
|
+
const prevEffect = componentEffects[effectIndex];
|
69
|
+
if (!prevEffect || !deps || !prevEffect.deps || deps.some((dep, i) => dep !== prevEffect.deps[i])) {
|
70
|
+
if (prevEffect?.cleanup) {
|
71
|
+
prevEffect.cleanup();
|
72
|
+
}
|
73
|
+
// Schedule effect execution after render is complete
|
74
|
+
queueMicrotask(() => {
|
75
|
+
const cleanup = callback() || undefined;
|
76
|
+
componentEffects[effectIndex] = { cleanup, deps: deps || [] };
|
77
|
+
});
|
78
|
+
}
|
79
|
+
stateIndices.set(currentRender, effectIndex + 1);
|
80
|
+
}
|
81
|
+
export function useMemo(factory, deps) {
|
82
|
+
if (!currentRender)
|
83
|
+
throw new Error("useMemo must be called within a render");
|
84
|
+
const memoIndex = stateIndices.get(currentRender) || 0;
|
85
|
+
if (!memos.has(currentRender)) {
|
86
|
+
memos.set(currentRender, []);
|
87
|
+
}
|
88
|
+
const componentMemos = memos.get(currentRender);
|
89
|
+
const prevMemo = componentMemos[memoIndex];
|
90
|
+
if (!prevMemo || (deps && deps.some((dep, i) => !Object.is(dep, prevMemo.deps[i])))) {
|
91
|
+
const value = factory();
|
92
|
+
componentMemos[memoIndex] = { value, deps: deps || [] };
|
93
|
+
stateIndices.set(currentRender, memoIndex + 1);
|
94
|
+
return value;
|
95
|
+
}
|
96
|
+
stateIndices.set(currentRender, memoIndex + 1);
|
97
|
+
return prevMemo.value;
|
98
|
+
}
|
99
|
+
export function useRef(initial) {
|
100
|
+
if (!currentRender)
|
101
|
+
throw new Error("useRef must be called within a render");
|
102
|
+
const refIndex = stateIndices.get(currentRender) || 0;
|
103
|
+
if (!refs.has(currentRender)) {
|
104
|
+
refs.set(currentRender, []);
|
105
|
+
}
|
106
|
+
const componentRefs = refs.get(currentRender);
|
107
|
+
if (refIndex >= componentRefs.length) {
|
108
|
+
const ref = { current: initial };
|
109
|
+
componentRefs.push(ref);
|
110
|
+
stateIndices.set(currentRender, refIndex + 1);
|
111
|
+
return ref;
|
112
|
+
}
|
113
|
+
const ref = componentRefs[refIndex];
|
114
|
+
stateIndices.set(currentRender, refIndex + 1);
|
115
|
+
return ref;
|
116
|
+
}
|
117
|
+
async function rerender(rendererId) {
|
118
|
+
try {
|
119
|
+
// Clean up effects
|
120
|
+
const componentEffects = effects.get(rendererId);
|
121
|
+
if (componentEffects) {
|
122
|
+
componentEffects.forEach(effect => {
|
123
|
+
if (effect.cleanup)
|
124
|
+
effect.cleanup();
|
125
|
+
});
|
126
|
+
effects.set(rendererId, []);
|
127
|
+
}
|
128
|
+
// Trigger re-render
|
129
|
+
if (globalRenderCallback && globalContainer && currentElement) {
|
130
|
+
await globalRenderCallback(currentElement, globalContainer);
|
131
|
+
}
|
132
|
+
}
|
133
|
+
catch (error) {
|
134
|
+
console.error('Error during rerender:', error);
|
135
|
+
}
|
136
|
+
}
|
137
|
+
export function useErrorBoundary() {
|
138
|
+
const [error, setError] = useState(null);
|
139
|
+
return [error, () => setError(null)];
|
140
|
+
}
|
141
|
+
// Re-export from context
|
142
|
+
export { createContext, useContext } from './context.js';
|