hightjs 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/.idea/HightJS.iml +9 -0
  2. package/.idea/copilot.data.migration.agent.xml +6 -0
  3. package/.idea/copilot.data.migration.ask.xml +6 -0
  4. package/.idea/copilot.data.migration.ask2agent.xml +6 -0
  5. package/.idea/copilot.data.migration.edit.xml +6 -0
  6. package/.idea/inspectionProfiles/Project_Default.xml +13 -0
  7. package/.idea/libraries/test_package.xml +9 -0
  8. package/.idea/libraries/ts_commonjs_default_export.xml +9 -0
  9. package/.idea/misc.xml +7 -0
  10. package/.idea/modules.xml +8 -0
  11. package/.idea/vcs.xml +6 -0
  12. package/LICENSE +13 -0
  13. package/README.md +508 -0
  14. package/dist/adapters/express.d.ts +7 -0
  15. package/dist/adapters/express.js +63 -0
  16. package/dist/adapters/factory.d.ts +23 -0
  17. package/dist/adapters/factory.js +122 -0
  18. package/dist/adapters/fastify.d.ts +25 -0
  19. package/dist/adapters/fastify.js +61 -0
  20. package/dist/adapters/native.d.ts +8 -0
  21. package/dist/adapters/native.js +203 -0
  22. package/dist/adapters/starters/express.d.ts +0 -0
  23. package/dist/adapters/starters/express.js +1 -0
  24. package/dist/adapters/starters/factory.d.ts +0 -0
  25. package/dist/adapters/starters/factory.js +1 -0
  26. package/dist/adapters/starters/fastify.d.ts +0 -0
  27. package/dist/adapters/starters/fastify.js +1 -0
  28. package/dist/adapters/starters/index.d.ts +0 -0
  29. package/dist/adapters/starters/index.js +1 -0
  30. package/dist/adapters/starters/native.d.ts +0 -0
  31. package/dist/adapters/starters/native.js +1 -0
  32. package/dist/api/console.d.ts +92 -0
  33. package/dist/api/console.js +276 -0
  34. package/dist/api/http.d.ts +180 -0
  35. package/dist/api/http.js +467 -0
  36. package/dist/auth/client.d.ts +14 -0
  37. package/dist/auth/client.js +68 -0
  38. package/dist/auth/components.d.ts +29 -0
  39. package/dist/auth/components.js +84 -0
  40. package/dist/auth/core.d.ts +38 -0
  41. package/dist/auth/core.js +124 -0
  42. package/dist/auth/index.d.ts +7 -0
  43. package/dist/auth/index.js +27 -0
  44. package/dist/auth/jwt.d.ts +41 -0
  45. package/dist/auth/jwt.js +169 -0
  46. package/dist/auth/providers.d.ts +5 -0
  47. package/dist/auth/providers.js +14 -0
  48. package/dist/auth/react/index.d.ts +6 -0
  49. package/dist/auth/react/index.js +32 -0
  50. package/dist/auth/react.d.ts +22 -0
  51. package/dist/auth/react.js +175 -0
  52. package/dist/auth/routes.d.ts +16 -0
  53. package/dist/auth/routes.js +104 -0
  54. package/dist/auth/types.d.ts +62 -0
  55. package/dist/auth/types.js +2 -0
  56. package/dist/bin/hightjs.d.ts +2 -0
  57. package/dist/bin/hightjs.js +35 -0
  58. package/dist/builder.d.ts +32 -0
  59. package/dist/builder.js +341 -0
  60. package/dist/client/DefaultNotFound.d.ts +1 -0
  61. package/dist/client/DefaultNotFound.js +53 -0
  62. package/dist/client/ErrorBoundary.d.ts +16 -0
  63. package/dist/client/ErrorBoundary.js +181 -0
  64. package/dist/client/clientRouter.d.ts +58 -0
  65. package/dist/client/clientRouter.js +116 -0
  66. package/dist/client/entry.client.d.ts +1 -0
  67. package/dist/client/entry.client.js +271 -0
  68. package/dist/client/routerContext.d.ts +26 -0
  69. package/dist/client/routerContext.js +62 -0
  70. package/dist/client.d.ts +3 -0
  71. package/dist/client.js +8 -0
  72. package/dist/components/Link.d.ts +7 -0
  73. package/dist/components/Link.js +13 -0
  74. package/dist/eslint/index.d.ts +32 -0
  75. package/dist/eslint/index.js +15 -0
  76. package/dist/eslint/use-client-rule.d.ts +19 -0
  77. package/dist/eslint/use-client-rule.js +99 -0
  78. package/dist/eslintSetup.d.ts +0 -0
  79. package/dist/eslintSetup.js +1 -0
  80. package/dist/example/src/web/routes/index.d.ts +3 -0
  81. package/dist/example/src/web/routes/index.js +15 -0
  82. package/dist/helpers.d.ts +18 -0
  83. package/dist/helpers.js +318 -0
  84. package/dist/hotReload.d.ts +23 -0
  85. package/dist/hotReload.js +292 -0
  86. package/dist/index.d.ts +17 -0
  87. package/dist/index.js +480 -0
  88. package/dist/renderer.d.ts +14 -0
  89. package/dist/renderer.js +106 -0
  90. package/dist/router.d.ts +78 -0
  91. package/dist/router.js +359 -0
  92. package/dist/types/framework.d.ts +37 -0
  93. package/dist/types/framework.js +2 -0
  94. package/dist/types.d.ts +43 -0
  95. package/dist/types.js +2 -0
  96. package/dist/typescript/use-client-plugin.d.ts +5 -0
  97. package/dist/typescript/use-client-plugin.js +113 -0
  98. package/dist/validation.d.ts +0 -0
  99. package/dist/validation.js +1 -0
  100. package/package.json +72 -0
  101. package/src/adapters/express.ts +70 -0
  102. package/src/adapters/factory.ts +96 -0
  103. package/src/adapters/fastify.ts +88 -0
  104. package/src/adapters/native.ts +223 -0
  105. package/src/api/console.ts +285 -0
  106. package/src/api/http.ts +515 -0
  107. package/src/auth/client.ts +74 -0
  108. package/src/auth/components.tsx +109 -0
  109. package/src/auth/core.ts +143 -0
  110. package/src/auth/index.ts +9 -0
  111. package/src/auth/jwt.ts +194 -0
  112. package/src/auth/providers.ts +13 -0
  113. package/src/auth/react/index.ts +9 -0
  114. package/src/auth/react.tsx +209 -0
  115. package/src/auth/routes.ts +133 -0
  116. package/src/auth/types.ts +73 -0
  117. package/src/bin/hightjs.js +40 -0
  118. package/src/builder.js +362 -0
  119. package/src/client/DefaultNotFound.tsx +68 -0
  120. package/src/client/clientRouter.ts +137 -0
  121. package/src/client/entry.client.tsx +302 -0
  122. package/src/client.ts +8 -0
  123. package/src/components/Link.tsx +22 -0
  124. package/src/helpers.ts +316 -0
  125. package/src/hotReload.ts +289 -0
  126. package/src/index.ts +514 -0
  127. package/src/renderer.tsx +122 -0
  128. package/src/router.ts +400 -0
  129. package/src/types/framework.ts +42 -0
  130. package/src/types.ts +54 -0
  131. package/tsconfig.json +17 -0
@@ -0,0 +1,137 @@
1
+ // Sistema de roteamento do lado do cliente para hweb-sdk
2
+
3
+ export interface RouterEvents {
4
+ beforeNavigate?: (url: string) => boolean | Promise<boolean>;
5
+ afterNavigate?: (url: string) => void;
6
+ }
7
+
8
+ class Router {
9
+ private events: RouterEvents = {};
10
+ private listeners: Set<() => void> = new Set();
11
+
12
+ /**
13
+ * Navega para uma nova rota
14
+ */
15
+ async push(url: string): Promise<void> {
16
+ // Callback antes de navegar
17
+ if (this.events.beforeNavigate) {
18
+ const shouldProceed = await this.events.beforeNavigate(url);
19
+ if (shouldProceed === false) return;
20
+ }
21
+
22
+ // Atualiza a URL na barra de endereço
23
+ window.history.pushState({ path: url }, '', url);
24
+
25
+ // Dispara evento para o roteador capturar de forma assíncrona
26
+ setTimeout(() => this.triggerNavigation(), 0);
27
+
28
+ // Callback após navegar
29
+ if (this.events.afterNavigate) {
30
+ this.events.afterNavigate(url);
31
+ }
32
+ }
33
+
34
+ /**
35
+ * Substitui a entrada atual do histórico
36
+ */
37
+ async replace(url: string): Promise<void> {
38
+ // Callback antes de navegar
39
+ if (this.events.beforeNavigate) {
40
+ const shouldProceed = await this.events.beforeNavigate(url);
41
+ if (shouldProceed === false) return;
42
+ }
43
+
44
+ // Substitui a URL atual no histórico
45
+ window.history.replaceState({ path: url }, '', url);
46
+
47
+ // Dispara evento para o roteador capturar de forma assíncrona
48
+ setTimeout(() => this.triggerNavigation(), 0);
49
+
50
+ // Callback após navegar
51
+ if (this.events.afterNavigate) {
52
+ this.events.afterNavigate(url);
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Volta uma página no histórico
58
+ */
59
+ back(): void {
60
+ window.history.back();
61
+ }
62
+
63
+ /**
64
+ * Avança uma página no histórico
65
+ */
66
+ forward(): void {
67
+ window.history.forward();
68
+ }
69
+
70
+ /**
71
+ * Recarrega a página atual (re-renderiza o componente)
72
+ */
73
+ refresh(): void {
74
+ setTimeout(() => this.triggerNavigation(), 0);
75
+ }
76
+
77
+ /**
78
+ * Obtém a URL atual
79
+ */
80
+ get pathname(): string {
81
+ return window.location.pathname;
82
+ }
83
+
84
+ /**
85
+ * Obtém os query parameters atuais
86
+ */
87
+ get query(): URLSearchParams {
88
+ return new URLSearchParams(window.location.search);
89
+ }
90
+
91
+ /**
92
+ * Obtém a URL completa atual
93
+ */
94
+ get url(): string {
95
+ return window.location.href;
96
+ }
97
+
98
+ /**
99
+ * Adiciona event listeners para eventos de roteamento
100
+ */
101
+ on(events: RouterEvents): void {
102
+ this.events = { ...this.events, ...events };
103
+ }
104
+
105
+ /**
106
+ * Remove event listeners
107
+ */
108
+ off(): void {
109
+ this.events = {};
110
+ }
111
+
112
+ /**
113
+ * Adiciona um listener para mudanças de rota
114
+ */
115
+ subscribe(listener: () => void): () => void {
116
+ this.listeners.add(listener);
117
+ return () => this.listeners.delete(listener);
118
+ }
119
+
120
+ /**
121
+ * Dispara evento de navegação para todos os listeners
122
+ */
123
+ private triggerNavigation(): void {
124
+ // Dispara o evento nativo para o roteador do hweb capturar
125
+ window.dispatchEvent(new PopStateEvent('popstate'));
126
+
127
+ // Notifica todos os listeners customizados
128
+ this.listeners.forEach(listener => listener());
129
+ }
130
+
131
+ }
132
+
133
+ // Instância singleton do router
134
+ export const router = new Router();
135
+
136
+ // Para compatibilidade, também exporta como default
137
+ export default router;
@@ -0,0 +1,302 @@
1
+ import React, {useState, useEffect, useCallback, useRef} from 'react';
2
+ import { createRoot } from 'react-dom/client';
3
+ import { router } from './clientRouter';
4
+
5
+ // --- O Componente Principal do Cliente (Roteador) ---
6
+
7
+ interface AppProps {
8
+ componentMap: Record<string, any>;
9
+ routes: { pattern: string; componentPath: string }[];
10
+ initialComponentPath: string;
11
+ initialParams: any;
12
+ layoutComponent?: any;
13
+ }
14
+
15
+ function App({ componentMap, routes, initialComponentPath, initialParams, layoutComponent }: AppProps) {
16
+ // Estado que guarda o componente a ser renderizado atualmente
17
+
18
+ const [CurrentPageComponent, setCurrentPageComponent] = useState(() => {
19
+ // Se for a rota especial __404__, não busca no componentMap
20
+ if (initialComponentPath === '__404__') {
21
+ return null;
22
+ }
23
+ return componentMap[initialComponentPath];
24
+ });
25
+ const [params, setParams] = useState(initialParams);
26
+
27
+ const findRouteForPath = useCallback((path: string) => {
28
+ for (const route of routes) {
29
+ const regexPattern = route.pattern.replace(/\[(\w+)\]/g, '(?<$1>[^/]+)');
30
+ const regex = new RegExp(`^${regexPattern}/?$`);
31
+ const match = path.match(regex);
32
+ if (match) {
33
+ return {
34
+ componentPath: route.componentPath,
35
+ params: match.groups || {}
36
+ };
37
+ }
38
+ }
39
+ return null;
40
+ }, [routes]);
41
+
42
+ const updateRoute = useCallback(() => {
43
+ const currentPath = router.pathname;
44
+ const match = findRouteForPath(currentPath);
45
+ if (match) {
46
+ setCurrentPageComponent(() => componentMap[match.componentPath]);
47
+ setParams(match.params);
48
+ } else {
49
+ // Se não encontrou rota, define como null para mostrar 404
50
+ setCurrentPageComponent(null);
51
+ setParams({});
52
+ }
53
+ }, [router.pathname, findRouteForPath, componentMap]);
54
+
55
+ // Ouve os eventos de "voltar" e "avançar" do navegador
56
+ useEffect(() => {
57
+ const handlePopState = () => {
58
+ updateRoute();
59
+ };
60
+
61
+ window.addEventListener('popstate', handlePopState);
62
+
63
+ // Também se inscreve no router para mudanças de rota
64
+ const unsubscribe = router.subscribe(updateRoute);
65
+
66
+ return () => {
67
+ window.removeEventListener('popstate', handlePopState);
68
+ unsubscribe();
69
+ };
70
+ }, [updateRoute]);
71
+
72
+ // Se não há componente ou é a rota __404__, mostra página 404
73
+ if (!CurrentPageComponent || initialComponentPath === '__404__') {
74
+ // Usa o componente 404 personalizado se existir, senão usa o padrão do hweb
75
+ const NotFoundComponent = (window as any).__HWEB_NOT_FOUND__;
76
+
77
+ if (NotFoundComponent) {
78
+ // Usa o notFound.tsx personalizado do usuário
79
+ const NotFoundContent = <NotFoundComponent />;
80
+
81
+ // Aplica o layout se existir
82
+ if (layoutComponent) {
83
+ return React.createElement(layoutComponent, { children: NotFoundContent });
84
+ }
85
+ return NotFoundContent;
86
+ } else {
87
+ // Usa o 404 padrão do hweb que foi incluído no build
88
+ const DefaultNotFound = (window as any).__HWEB_DEFAULT_NOT_FOUND__;
89
+ const NotFoundContent = <DefaultNotFound />;
90
+
91
+ // Aplica o layout se existir
92
+ if (layoutComponent) {
93
+ return React.createElement(layoutComponent, { children: NotFoundContent });
94
+ }
95
+ return NotFoundContent;
96
+ }
97
+ }
98
+
99
+ // Renderiza o componente atual (sem Context, usa o router diretamente)
100
+ const PageContent = <CurrentPageComponent params={params} />;
101
+
102
+ // SEMPRE usa o layout - se não existir, cria um wrapper padrão
103
+ const content = layoutComponent
104
+ ? React.createElement(layoutComponent, { children: PageContent })
105
+ : <div>{PageContent}</div>;
106
+
107
+ // Adiciona o indicador de dev se não for produção
108
+ return (
109
+ <>
110
+ {content}
111
+ {process.env.NODE_ENV !== 'production' && <DevIndicator />}
112
+ </>
113
+ );
114
+ }
115
+
116
+
117
+
118
+ // --- Constantes de Configuração ---
119
+ const DEV_INDICATOR_SIZE = 48;
120
+ const DEV_INDICATOR_CORNERS = [
121
+ { top: 16, left: 16 }, // 0: topo-esquerda
122
+ { top: 16, right: 16 }, // 1: topo-direita
123
+ { bottom: 16, left: 16 }, // 2: baixo-esquerda
124
+ { bottom: 16, right: 16 },// 3: baixo-direita
125
+ ];
126
+
127
+ function DevIndicator() {
128
+ const [corner, setCorner] = useState(3); // Canto atual (0-3)
129
+ const [isDragging, setIsDragging] = useState(false); // Estado de arrastar
130
+
131
+ // Posição visual do indicador durante o arraste
132
+ const [position, setPosition] = useState<{ top: number; left: number }>({ top: 0, left: 0 });
133
+
134
+ const indicatorRef = useRef<HTMLDivElement>(null);
135
+ const dragStartRef = useRef<{ x: number; y: number; moved: boolean } | null>(null);
136
+
137
+ // --- Estilos Dinâmicos ---
138
+ const getIndicatorStyle = (): React.CSSProperties => {
139
+ const baseStyle: React.CSSProperties = {
140
+ position: 'fixed',
141
+ zIndex: 9999,
142
+ width: DEV_INDICATOR_SIZE,
143
+ height: DEV_INDICATOR_SIZE,
144
+ borderRadius: '50%',
145
+ background: 'linear-gradient(135deg, #8e2de2, #4a00e0)', // Gradiente Roxo
146
+ color: 'white',
147
+ fontWeight: 'bold',
148
+ fontSize: 28,
149
+ boxShadow: '0 4px 15px rgba(0,0,0,0.2)',
150
+ display: 'flex',
151
+ alignItems: 'center',
152
+ justifyContent: 'center',
153
+ cursor: isDragging ? 'grabbing' : 'grab',
154
+ userSelect: 'none',
155
+ transition: isDragging ? 'none' : 'all 0.3s ease-out', // Animação suave ao soltar
156
+ };
157
+
158
+ if (isDragging) {
159
+ return {
160
+ ...baseStyle,
161
+ top: position.top,
162
+ left: position.left,
163
+ };
164
+ }
165
+
166
+ return { ...baseStyle, ...DEV_INDICATOR_CORNERS[corner] };
167
+ };
168
+
169
+ const getMenuPositionStyle = (): React.CSSProperties => {
170
+ // Posiciona o menu dependendo do canto
171
+ switch (corner) {
172
+ case 0: return { top: '110%', left: '0' }; // Top-Left
173
+ case 1: return { top: '110%', right: '0' }; // Top-Right
174
+ case 2: return { bottom: '110%', left: '0' }; // Bottom-Left
175
+ case 3: return { bottom: '110%', right: '0' }; // Bottom-Right
176
+ default: return {};
177
+ }
178
+ };
179
+
180
+ // --- Lógica de Eventos ---
181
+ const handleMouseDown = (e: React.MouseEvent<HTMLDivElement>) => {
182
+ e.preventDefault();
183
+ dragStartRef.current = { x: e.clientX, y: e.clientY, moved: false };
184
+ if (indicatorRef.current) {
185
+ const rect = indicatorRef.current.getBoundingClientRect();
186
+ setPosition({ top: rect.top, left: rect.left });
187
+ }
188
+ setIsDragging(true);
189
+ };
190
+
191
+ const handleMouseMove = useCallback((e: MouseEvent) => {
192
+ if (!isDragging || !dragStartRef.current) return;
193
+
194
+ const deltaX = e.clientX - dragStartRef.current.x;
195
+ const deltaY = e.clientY - dragStartRef.current.y;
196
+
197
+ // Diferencia clique de arrastar (threshold de 5px)
198
+ if (!dragStartRef.current.moved && Math.hypot(deltaX, deltaY) > 5) {
199
+ dragStartRef.current.moved = true;
200
+ }
201
+
202
+ if (dragStartRef.current.moved) {
203
+ setPosition(prevPos => ({
204
+ top: prevPos.top + deltaY,
205
+ left: prevPos.left + deltaX,
206
+ }));
207
+ // Atualiza a referência para o próximo movimento
208
+ dragStartRef.current.x = e.clientX;
209
+ dragStartRef.current.y = e.clientY;
210
+ }
211
+ }, [isDragging]);
212
+
213
+ const handleMouseUp = useCallback((e: MouseEvent) => {
214
+ if (!isDragging) return;
215
+ setIsDragging(false);
216
+
217
+ // Se moveu, calcula o canto mais próximo
218
+ if (dragStartRef.current?.moved) {
219
+ const { clientX, clientY } = e;
220
+ const w = window.innerWidth;
221
+ const h = window.innerHeight;
222
+
223
+ const dists = [
224
+ Math.hypot(clientX, clientY), // TL
225
+ Math.hypot(w - clientX, clientY), // TR
226
+ Math.hypot(clientX, h - clientY), // BL
227
+ Math.hypot(w - clientX, h - clientY), // BR
228
+ ];
229
+ setCorner(dists.indexOf(Math.min(...dists)));
230
+ }
231
+
232
+ dragStartRef.current = null;
233
+ }, [isDragging]);
234
+
235
+ // Adiciona e remove listeners globais
236
+ useEffect(() => {
237
+ if (isDragging) {
238
+ window.addEventListener('mousemove', handleMouseMove);
239
+ window.addEventListener('mouseup', handleMouseUp);
240
+ }
241
+ return () => {
242
+ window.removeEventListener('mousemove', handleMouseMove);
243
+ window.removeEventListener('mouseup', handleMouseUp);
244
+ };
245
+ }, [isDragging, handleMouseMove, handleMouseUp]);
246
+
247
+
248
+ return (
249
+ <div ref={indicatorRef} style={getIndicatorStyle()} onMouseDown={handleMouseDown} title="Modo Dev HightJS">
250
+ H
251
+ </div>
252
+ );
253
+ }
254
+
255
+ // --- Inicialização do Cliente (CSR - Client-Side Rendering) ---
256
+
257
+ function initializeClient() {
258
+ const initialData = (window as any).__HWEB_INITIAL_DATA__;
259
+
260
+ if (!initialData) {
261
+ console.error('[hweb] Dados iniciais não encontrados na página.');
262
+ return;
263
+ }
264
+
265
+ // Cria o mapa de componentes dinamicamente a partir dos módulos carregados
266
+ const componentMap: Record<string, any> = {};
267
+
268
+ // Registra todos os componentes que foram importados
269
+ if ((window as any).__HWEB_COMPONENTS__) {
270
+ Object.assign(componentMap, (window as any).__HWEB_COMPONENTS__);
271
+ }
272
+
273
+ const container = document.getElementById('root');
274
+ if (!container) {
275
+ console.error('[hweb] Container #root não encontrado.');
276
+ return;
277
+ }
278
+
279
+ try {
280
+ // Usar createRoot para render inicial (CSR)
281
+ const root = createRoot(container);
282
+
283
+ root.render(
284
+ <App
285
+ componentMap={componentMap}
286
+ routes={initialData.routes}
287
+ initialComponentPath={initialData.initialComponentPath}
288
+ initialParams={initialData.initialParams}
289
+ layoutComponent={(window as any).__HWEB_LAYOUT__}
290
+ />
291
+ );
292
+ } catch (error) {
293
+ console.error('[hweb] Erro ao renderizar aplicação:', error);
294
+ }
295
+ }
296
+
297
+ // Executa quando o DOM estiver pronto
298
+ if (document.readyState === 'loading') {
299
+ document.addEventListener('DOMContentLoaded', initializeClient);
300
+ } else {
301
+ initializeClient();
302
+ }
package/src/client.ts ADDED
@@ -0,0 +1,8 @@
1
+ // Este arquivo exporta apenas código seguro para o cliente (navegador)
2
+ export { Link } from './components/Link';
3
+ export { RouteConfig, Metadata } from "./types";
4
+ export { router } from './client/clientRouter';
5
+
6
+
7
+
8
+
@@ -0,0 +1,22 @@
1
+ import React, { type AnchorHTMLAttributes, type ReactNode } from 'react';
2
+ import { router } from '../client/clientRouter';
3
+
4
+ interface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
5
+ href: string;
6
+ children: ReactNode;
7
+ }
8
+
9
+ export function Link({ href, children, ...props }: LinkProps) {
10
+ const handleClick = async (e: React.MouseEvent<HTMLAnchorElement>) => {
11
+ e.preventDefault();
12
+
13
+ // Usa o novo sistema de router
14
+ await router.push(href);
15
+ };
16
+
17
+ return (
18
+ <a href={href} {...props} onClick={handleClick}>
19
+ {children}
20
+ </a>
21
+ );
22
+ }