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.
- 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 +1231 -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 +68 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1153 -265
- 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
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,GAAG,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,aAAa,kDAKxB,CAAC;AAEH,wBAAgB,SAAS,IAAI,kBAAkB,CAE9C;AAED,wBAAgB,WAAW;;;;;EAQ1B;AAED,wBAAgB,SAAS,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,KAAK,CAAC,CAGlE;AAED,wBAAgB,WAAW,WAnCR,MAAM,KAAK,IAAI,CAsCjC;AAED,wBAAgB,cAAc,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,GAAG,CAAA;CAAE,GAAG,GAAG,CA2DnE;AAED,wBAAgB,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,KAAK,EAAE,CAAA;CAAE,OAYrD;AAwCD,wBAAgB,IAAI,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,GAAG,GAAG,CAetG;AAED,wBAAgB,KAAK,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,GAAG,CAAA;CAAE,QAG1E;AAED,wBAAgB,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,GAAG,CAAA;CAAE,OAkBrD;;;;;;;;;;;;AAED,wBAUE"}
|
package/dist/router.js
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
/**
|
2
|
+
* Router implementation for client and server navigation
|
3
|
+
*/
|
4
|
+
import { useState, useEffect } from './hooks.js';
|
5
|
+
import { createContext, useContext } from './context.js';
|
6
|
+
import { jsx } from './jsx-runtime.js';
|
7
|
+
export const RouterContext = createContext({
|
8
|
+
currentPath: '/',
|
9
|
+
navigate: () => { },
|
10
|
+
params: {},
|
11
|
+
query: {}
|
12
|
+
});
|
13
|
+
export function useRouter() {
|
14
|
+
return useContext(RouterContext);
|
15
|
+
}
|
16
|
+
export function useLocation() {
|
17
|
+
const router = useContext(RouterContext);
|
18
|
+
return {
|
19
|
+
pathname: router.currentPath,
|
20
|
+
search: '', // TODO: Implement search parsing
|
21
|
+
hash: '', // TODO: Implement hash parsing
|
22
|
+
state: {} // TODO: Implement history state
|
23
|
+
};
|
24
|
+
}
|
25
|
+
export function useParams() {
|
26
|
+
const router = useContext(RouterContext);
|
27
|
+
return router.params;
|
28
|
+
}
|
29
|
+
export function useNavigate() {
|
30
|
+
const router = useContext(RouterContext);
|
31
|
+
return router.navigate;
|
32
|
+
}
|
33
|
+
export function RouterProvider({ children }) {
|
34
|
+
// Initial path should be window.location.pathname on client, or passed from server context
|
35
|
+
const [currentPath, setCurrentPath] = useState(typeof window !== 'undefined' ? window.location.pathname : '/');
|
36
|
+
const [params, setParams] = useState({});
|
37
|
+
const [query, setQuery] = useState({});
|
38
|
+
// Update path when URL changes
|
39
|
+
useEffect(() => {
|
40
|
+
if (typeof window === 'undefined')
|
41
|
+
return;
|
42
|
+
const handlePopState = () => {
|
43
|
+
setCurrentPath(window.location.pathname);
|
44
|
+
parseQuery(window.location.search);
|
45
|
+
};
|
46
|
+
window.addEventListener('popstate', handlePopState);
|
47
|
+
// Parse initial query
|
48
|
+
parseQuery(window.location.search);
|
49
|
+
return () => {
|
50
|
+
window.removeEventListener('popstate', handlePopState);
|
51
|
+
};
|
52
|
+
}, []);
|
53
|
+
// Parse query string into object
|
54
|
+
const parseQuery = (queryString) => {
|
55
|
+
const queryObj = {};
|
56
|
+
if (queryString.startsWith('?')) {
|
57
|
+
queryString = queryString.substring(1);
|
58
|
+
}
|
59
|
+
queryString.split('&').forEach(pair => {
|
60
|
+
if (!pair)
|
61
|
+
return;
|
62
|
+
const [key, value] = pair.split('=');
|
63
|
+
queryObj[decodeURIComponent(key)] = decodeURIComponent(value || '');
|
64
|
+
});
|
65
|
+
setQuery(queryObj);
|
66
|
+
};
|
67
|
+
// Navigate programmatically
|
68
|
+
const navigate = (path) => {
|
69
|
+
if (typeof window === 'undefined')
|
70
|
+
return;
|
71
|
+
window.history.pushState(null, '', path);
|
72
|
+
setCurrentPath(path);
|
73
|
+
parseQuery(window.location.search);
|
74
|
+
};
|
75
|
+
return jsx(RouterContext.Provider, {
|
76
|
+
value: { currentPath, navigate, params, query },
|
77
|
+
children
|
78
|
+
});
|
79
|
+
}
|
80
|
+
export function Router({ routes }) {
|
81
|
+
const router = useRouter();
|
82
|
+
const currentPath = router.currentPath;
|
83
|
+
// Find matching route
|
84
|
+
const matchedRoute = findMatchingRoute(routes, currentPath);
|
85
|
+
if (!matchedRoute) {
|
86
|
+
return jsx('div', { children: '404 - Page Not Found' });
|
87
|
+
}
|
88
|
+
return matchedRoute.component({ children: matchedRoute.children });
|
89
|
+
}
|
90
|
+
function findMatchingRoute(routes, path) {
|
91
|
+
for (const route of routes) {
|
92
|
+
const match = matchPath(path, route);
|
93
|
+
if (match) {
|
94
|
+
return {
|
95
|
+
...route,
|
96
|
+
params: match.params
|
97
|
+
};
|
98
|
+
}
|
99
|
+
}
|
100
|
+
return null;
|
101
|
+
}
|
102
|
+
function matchPath(pathname, route) {
|
103
|
+
const { path, exact = true } = route;
|
104
|
+
// Convert route pattern to regex
|
105
|
+
const pattern = path.replace(/:[a-zA-Z0-9_]+/g, '([^/]+)');
|
106
|
+
const regex = new RegExp(`^${pattern}${exact ? '$' : ''}`);
|
107
|
+
const match = pathname.match(regex);
|
108
|
+
if (!match) {
|
109
|
+
return null;
|
110
|
+
}
|
111
|
+
// Extract params
|
112
|
+
const params = {};
|
113
|
+
const paramNames = path.match(/:[a-zA-Z0-9_]+/g) || [];
|
114
|
+
paramNames.forEach((paramName, index) => {
|
115
|
+
params[paramName.substring(1)] = match[index + 1];
|
116
|
+
});
|
117
|
+
return { params };
|
118
|
+
}
|
119
|
+
export function Link({ to, children, ...rest }) {
|
120
|
+
const router = useRouter();
|
121
|
+
const navigate = router.navigate;
|
122
|
+
const handleClick = (e) => {
|
123
|
+
e.preventDefault();
|
124
|
+
navigate(to);
|
125
|
+
};
|
126
|
+
return jsx('a', {
|
127
|
+
href: to,
|
128
|
+
onClick: handleClick,
|
129
|
+
...rest,
|
130
|
+
children
|
131
|
+
});
|
132
|
+
}
|
133
|
+
export function Route({ path, component }) {
|
134
|
+
// This is a configuration component, not actually rendered
|
135
|
+
return null;
|
136
|
+
}
|
137
|
+
export function Switch({ children }) {
|
138
|
+
const router = useRouter();
|
139
|
+
const currentPath = router.currentPath;
|
140
|
+
// Find the first matching route
|
141
|
+
const child = Array.isArray(children)
|
142
|
+
? children.find(child => {
|
143
|
+
if (!child || !child.props)
|
144
|
+
return false;
|
145
|
+
const routeObj = {
|
146
|
+
path: child.props.path,
|
147
|
+
component: child.props.component,
|
148
|
+
exact: child.props.exact
|
149
|
+
};
|
150
|
+
return matchPath(currentPath, routeObj);
|
151
|
+
})
|
152
|
+
: children;
|
153
|
+
return child || null;
|
154
|
+
}
|
155
|
+
export default {
|
156
|
+
RouterProvider,
|
157
|
+
Router,
|
158
|
+
Link,
|
159
|
+
Route,
|
160
|
+
Switch,
|
161
|
+
useRouter,
|
162
|
+
useParams,
|
163
|
+
useNavigate,
|
164
|
+
useLocation
|
165
|
+
};
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"server-renderer.d.ts","sourceRoot":"","sources":["../src/server-renderer.ts"],"names":[],"mappings":"AAGA,wBAAsB,cAAc,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CASlE"}
|
package/dist/server-renderer.js
CHANGED
@@ -1,5 +1,111 @@
|
|
1
|
-
import {
|
2
|
-
export {
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
import { prepareRender, finishRender } from './hooks.js';
|
2
|
+
export async function renderToString(element) {
|
3
|
+
const renderId = prepareRender(true); // Mark as SSR
|
4
|
+
try {
|
5
|
+
const html = await renderNodeToString(element);
|
6
|
+
return html;
|
7
|
+
}
|
8
|
+
finally {
|
9
|
+
finishRender();
|
10
|
+
}
|
11
|
+
}
|
12
|
+
async function renderNodeToString(node) {
|
13
|
+
// Handle null, undefined, boolean
|
14
|
+
if (node == null || typeof node === 'boolean') {
|
15
|
+
return '';
|
16
|
+
}
|
17
|
+
// Handle primitives
|
18
|
+
if (typeof node === 'string' || typeof node === 'number') {
|
19
|
+
return escapeHtml(String(node));
|
20
|
+
}
|
21
|
+
// Handle arrays
|
22
|
+
if (Array.isArray(node)) {
|
23
|
+
const results = await Promise.all(node.map(child => renderNodeToString(child)));
|
24
|
+
return results.join('');
|
25
|
+
}
|
26
|
+
// Handle objects with type and props (React-like elements)
|
27
|
+
if (node && typeof node === 'object' && 'type' in node) {
|
28
|
+
const { type, props = {} } = node;
|
29
|
+
// Handle function components
|
30
|
+
if (typeof type === 'function') {
|
31
|
+
try {
|
32
|
+
const result = await type(props);
|
33
|
+
return await renderNodeToString(result);
|
34
|
+
}
|
35
|
+
catch (error) {
|
36
|
+
console.error('Error rendering component:', error);
|
37
|
+
return `<!-- Error rendering component: ${error.message} -->`;
|
38
|
+
}
|
39
|
+
}
|
40
|
+
// Handle DOM elements
|
41
|
+
if (typeof type === 'string') {
|
42
|
+
return await renderDOMElement(type, props);
|
43
|
+
}
|
44
|
+
}
|
45
|
+
// Fallback for other objects
|
46
|
+
if (typeof node === 'object') {
|
47
|
+
return escapeHtml(JSON.stringify(node));
|
48
|
+
}
|
49
|
+
return escapeHtml(String(node));
|
50
|
+
}
|
51
|
+
async function renderDOMElement(tagName, props) {
|
52
|
+
const { children, ...attrs } = props;
|
53
|
+
// Self-closing tags
|
54
|
+
const voidElements = new Set([
|
55
|
+
'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',
|
56
|
+
'link', 'meta', 'param', 'source', 'track', 'wbr'
|
57
|
+
]);
|
58
|
+
// Build attributes string
|
59
|
+
const attributeString = Object.entries(attrs)
|
60
|
+
.filter(([key, value]) => {
|
61
|
+
// Filter out React-specific props and event handlers
|
62
|
+
if (key.startsWith('on') || key === 'key' || key === 'ref')
|
63
|
+
return false;
|
64
|
+
if (value == null || value === false)
|
65
|
+
return false;
|
66
|
+
return true;
|
67
|
+
})
|
68
|
+
.map(([key, value]) => {
|
69
|
+
// Handle className -> class
|
70
|
+
if (key === 'className')
|
71
|
+
key = 'class';
|
72
|
+
// Handle boolean attributes
|
73
|
+
if (value === true)
|
74
|
+
return key;
|
75
|
+
// Handle style objects
|
76
|
+
if (key === 'style' && typeof value === 'object' && value !== null) {
|
77
|
+
const styleString = Object.entries(value)
|
78
|
+
.map(([prop, val]) => `${kebabCase(prop)}:${val}`)
|
79
|
+
.join(';');
|
80
|
+
return `style="${escapeHtml(styleString)}"`;
|
81
|
+
}
|
82
|
+
return `${key}="${escapeHtml(String(value))}"`;
|
83
|
+
})
|
84
|
+
.join(' ');
|
85
|
+
const openTag = `<${tagName}${attributeString ? ' ' + attributeString : ''}>`;
|
86
|
+
// Self-closing elements
|
87
|
+
if (voidElements.has(tagName)) {
|
88
|
+
return openTag.slice(0, -1) + '/>';
|
89
|
+
}
|
90
|
+
// Elements with children
|
91
|
+
const closeTag = `</${tagName}>`;
|
92
|
+
if (children != null) {
|
93
|
+
const childrenString = await renderNodeToString(children);
|
94
|
+
return openTag + childrenString + closeTag;
|
95
|
+
}
|
96
|
+
return openTag + closeTag;
|
97
|
+
}
|
98
|
+
function escapeHtml(text) {
|
99
|
+
const htmlEscapes = {
|
100
|
+
'&': '&',
|
101
|
+
'<': '<',
|
102
|
+
'>': '>',
|
103
|
+
'"': '"',
|
104
|
+
"'": ''',
|
105
|
+
'/': '/'
|
106
|
+
};
|
107
|
+
return text.replace(/[&<>"'/]/g, (match) => htmlEscapes[match]);
|
108
|
+
}
|
109
|
+
function kebabCase(str) {
|
110
|
+
return str.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
|
111
|
+
}
|
@@ -0,0 +1,43 @@
|
|
1
|
+
/**
|
2
|
+
* Public type definitions for server functionality
|
3
|
+
* These types are safe to import in any environment
|
4
|
+
*/
|
5
|
+
export interface ServerConfig {
|
6
|
+
port?: number;
|
7
|
+
apiDir?: string;
|
8
|
+
pagesDir?: string;
|
9
|
+
staticDir?: string;
|
10
|
+
enableCors?: boolean;
|
11
|
+
corsOptions?: any;
|
12
|
+
db?: {
|
13
|
+
url: string;
|
14
|
+
type: 'mongodb' | 'mysql' | 'postgres';
|
15
|
+
};
|
16
|
+
auth?: {
|
17
|
+
secret: string;
|
18
|
+
expiresIn?: string;
|
19
|
+
};
|
20
|
+
}
|
21
|
+
export interface Server {
|
22
|
+
start(): Promise<void>;
|
23
|
+
stop(): Promise<void>;
|
24
|
+
getExpressApp(): any;
|
25
|
+
getDatabase(): any;
|
26
|
+
getAuth(): any;
|
27
|
+
}
|
28
|
+
export interface User {
|
29
|
+
id: string | number;
|
30
|
+
username: string;
|
31
|
+
password?: string;
|
32
|
+
email?: string;
|
33
|
+
roles?: string[];
|
34
|
+
[key: string]: any;
|
35
|
+
}
|
36
|
+
export interface DbConfig {
|
37
|
+
url: string;
|
38
|
+
type: 'mongodb' | 'mysql' | 'postgres';
|
39
|
+
}
|
40
|
+
export interface MiddlewareFunction {
|
41
|
+
(req: any, res: any, next: any): void | Promise<void>;
|
42
|
+
}
|
43
|
+
//# sourceMappingURL=server-types.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"server-types.d.ts","sourceRoot":"","sources":["../src/server-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,EAAE,CAAC,EAAE;QACH,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,UAAU,CAAC;KACxC,CAAC;IACF,IAAI,CAAC,EAAE;QACL,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED,MAAM,WAAW,MAAM;IACrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,aAAa,IAAI,GAAG,CAAC;IACrB,WAAW,IAAI,GAAG,CAAC;IACnB,OAAO,IAAI,GAAG,CAAC;CAChB;AAED,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,UAAU,CAAC;CACxC;AAED,MAAM,WAAW,kBAAkB;IACjC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvD"}
|
package/dist/store.d.ts
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
export interface Action {
|
2
|
+
type: string;
|
3
|
+
payload?: any;
|
4
|
+
}
|
5
|
+
export type Reducer<S> = (state: S, action: Action) => S;
|
6
|
+
export type Selector<S, R> = (state: S) => R;
|
7
|
+
export type Dispatch = (action: Action) => void;
|
8
|
+
export type Middleware<S> = (store: Store<S>) => (next: Dispatch) => (action: Action) => void;
|
9
|
+
export interface Store<S> {
|
10
|
+
getState: () => S;
|
11
|
+
dispatch: Dispatch;
|
12
|
+
subscribe: (listener: () => void) => () => void;
|
13
|
+
}
|
14
|
+
export interface AsyncAction {
|
15
|
+
(dispatch: Dispatch, getState: () => any): Promise<void> | void;
|
16
|
+
}
|
17
|
+
export declare function createStore<S>(reducer: Reducer<S>, initialState: S, middlewares?: Middleware<S>[]): Store<S>;
|
18
|
+
export interface StoreContextType {
|
19
|
+
store: Store<any>;
|
20
|
+
state: any;
|
21
|
+
}
|
22
|
+
export declare const StoreContext: import("./types.js").Context<StoreContextType>;
|
23
|
+
export declare function StoreProvider<S>({ store, children }: {
|
24
|
+
store: Store<S>;
|
25
|
+
children: any;
|
26
|
+
}): any;
|
27
|
+
export declare function useSelector<S, R>(selector: Selector<S, R>): R;
|
28
|
+
export declare function useDispatch<S>(): Dispatch;
|
29
|
+
export declare function useStore<S>(): Store<S>;
|
30
|
+
export declare const logger: Middleware<any>;
|
31
|
+
export declare const thunk: Middleware<any>;
|
32
|
+
declare const _default: {
|
33
|
+
createStore: typeof createStore;
|
34
|
+
StoreProvider: typeof StoreProvider;
|
35
|
+
useSelector: typeof useSelector;
|
36
|
+
useDispatch: typeof useDispatch;
|
37
|
+
useStore: typeof useStore;
|
38
|
+
logger: Middleware<any>;
|
39
|
+
thunk: Middleware<any>;
|
40
|
+
};
|
41
|
+
export default _default;
|
42
|
+
//# sourceMappingURL=store.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,GAAG,CAAC;CACf;AAED,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC,CAAC;AAEzD,MAAM,MAAM,QAAQ,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC;AAE7C,MAAM,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;AAEhD,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,KAAK,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;AAE9F,MAAM,WAAW,KAAK,CAAC,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;CACjD;AAGD,MAAM,WAAW,WAAW;IAC1B,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACjE;AAED,wBAAgB,WAAW,CAAC,CAAC,EAC3B,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,YAAY,EAAE,CAAC,EACf,WAAW,GAAE,UAAU,CAAC,CAAC,CAAC,EAAO,GAChC,KAAK,CAAC,CAAC,CAAC,CAwCV;AAGD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,KAAK,EAAE,GAAG,CAAC;CACZ;AAED,eAAO,MAAM,YAAY,gDAOvB,CAAC;AAEH,wBAAgB,aAAa,CAAC,CAAC,EAAE,EAC/B,KAAK,EACL,QAAQ,EACT,EAAE;IACD,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAChB,QAAQ,EAAE,GAAG,CAAC;CACf,GAAG,GAAG,CAeN;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAG7D;AAED,wBAAgB,WAAW,CAAC,CAAC,KAAK,QAAQ,CAGzC;AAED,wBAAgB,QAAQ,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAGtC;AAGD,eAAO,MAAM,MAAM,EAAE,UAAU,CAAC,GAAG,CAQlC,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,UAAU,CAAC,GAAG,CAKjC,CAAC;;;;;;;;;;AAEF,wBAQE"}
|
package/dist/store.js
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
/**
|
2
|
+
* Global state management solution similar to Redux
|
3
|
+
*/
|
4
|
+
import { useState, useEffect } from './hooks.js';
|
5
|
+
import { createContext, useContext } from './context.js';
|
6
|
+
import { jsx } from './jsx-runtime.js';
|
7
|
+
export function createStore(reducer, initialState, middlewares = []) {
|
8
|
+
let state = initialState;
|
9
|
+
let listeners = [];
|
10
|
+
// Apply middlewares
|
11
|
+
let dispatch = (action) => {
|
12
|
+
state = reducer(state, action);
|
13
|
+
listeners.forEach(listener => listener());
|
14
|
+
return action;
|
15
|
+
};
|
16
|
+
// Chain middlewares
|
17
|
+
if (middlewares.length > 0) {
|
18
|
+
const middlewareAPI = {
|
19
|
+
getState: () => state,
|
20
|
+
dispatch: (action) => dispatch(action),
|
21
|
+
subscribe: (listener) => subscribe(listener)
|
22
|
+
};
|
23
|
+
const chain = middlewares.map(middleware => middleware(middlewareAPI));
|
24
|
+
dispatch = chain.reduce((a, b) => (next) => a(b(next)))(dispatch);
|
25
|
+
}
|
26
|
+
// Subscribe to store changes
|
27
|
+
function subscribe(listener) {
|
28
|
+
listeners.push(listener);
|
29
|
+
return function unsubscribe() {
|
30
|
+
listeners = listeners.filter(l => l !== listener);
|
31
|
+
};
|
32
|
+
}
|
33
|
+
// Initialize store with default state
|
34
|
+
dispatch({ type: '@@INIT' });
|
35
|
+
return {
|
36
|
+
getState: () => state,
|
37
|
+
dispatch,
|
38
|
+
subscribe
|
39
|
+
};
|
40
|
+
}
|
41
|
+
export const StoreContext = createContext({
|
42
|
+
store: {
|
43
|
+
getState: () => ({}),
|
44
|
+
dispatch: () => { },
|
45
|
+
subscribe: () => () => { }
|
46
|
+
},
|
47
|
+
state: {}
|
48
|
+
});
|
49
|
+
export function StoreProvider({ store, children }) {
|
50
|
+
const [state, setState] = useState(store.getState());
|
51
|
+
useEffect(() => {
|
52
|
+
const unsubscribe = store.subscribe(() => {
|
53
|
+
setState(store.getState());
|
54
|
+
});
|
55
|
+
return unsubscribe;
|
56
|
+
}, [store]);
|
57
|
+
return jsx(StoreContext.Provider, {
|
58
|
+
value: { store, state },
|
59
|
+
children
|
60
|
+
});
|
61
|
+
}
|
62
|
+
export function useSelector(selector) {
|
63
|
+
const context = useContext(StoreContext);
|
64
|
+
return selector(context.state);
|
65
|
+
}
|
66
|
+
export function useDispatch() {
|
67
|
+
const context = useContext(StoreContext);
|
68
|
+
return context.store.dispatch;
|
69
|
+
}
|
70
|
+
export function useStore() {
|
71
|
+
const context = useContext(StoreContext);
|
72
|
+
return context.store;
|
73
|
+
}
|
74
|
+
// Common middlewares
|
75
|
+
export const logger = (store) => (next) => (action) => {
|
76
|
+
console.group(action.type);
|
77
|
+
console.log('Previous state:', store.getState());
|
78
|
+
console.log('Action:', action);
|
79
|
+
const result = next(action);
|
80
|
+
console.log('Next state:', store.getState());
|
81
|
+
console.groupEnd();
|
82
|
+
return result;
|
83
|
+
};
|
84
|
+
export const thunk = (store) => (next) => (action) => {
|
85
|
+
if (typeof action === 'function') {
|
86
|
+
return action(store.dispatch, store.getState);
|
87
|
+
}
|
88
|
+
return next(action);
|
89
|
+
};
|
90
|
+
export default {
|
91
|
+
createStore,
|
92
|
+
StoreProvider,
|
93
|
+
useSelector,
|
94
|
+
useDispatch,
|
95
|
+
useStore,
|
96
|
+
logger,
|
97
|
+
thunk
|
98
|
+
};
|