nyte 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- export {};
1
+ export declare function DevIndicator(): import("react/jsx-runtime").JSX.Element | null;
@@ -33,6 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.DevIndicator = DevIndicator;
36
37
  const jsx_runtime_1 = require("react/jsx-runtime");
37
38
  /*
38
39
  * This file is part of the Nyte.js Project.
@@ -214,184 +215,72 @@ function App({ componentMap, routes, initialComponentPath, initialParams, layout
214
215
  // Adiciona o indicador de dev se não for produção
215
216
  return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [content, process.env.NODE_ENV !== 'production' && (0, jsx_runtime_1.jsx)(DevIndicator, {})] }));
216
217
  }
217
- // --- Constantes de Configuração ---
218
- const DEV_INDICATOR_SIZE = 48;
219
- const DEV_INDICATOR_CORNERS = [
220
- { top: 16, left: 16 }, // 0: topo-esquerda
221
- { top: 16, right: 16 }, // 1: topo-direita
222
- { bottom: 16, left: 16 }, // 2: baixo-esquerda
223
- { bottom: 16, right: 16 }, // 3: baixo-direita
224
- ];
225
218
  function DevIndicator() {
226
- const [corner, setCorner] = (0, react_1.useState)(3); // Canto atual (0-3)
227
- const [isDragging, setIsDragging] = (0, react_1.useState)(false); // Estado de arrastar
228
- const [isBuilding, setIsBuilding] = (0, react_1.useState)(false); // Estado de build
229
- // Posição visual do indicador durante o arraste
230
- const [position, setPosition] = (0, react_1.useState)({ top: 0, left: 0 });
231
- const indicatorRef = (0, react_1.useRef)(null);
232
- const dragStartRef = (0, react_1.useRef)(null);
233
- // Escuta eventos de hot reload para mostrar estado de build
234
- (0, react_1.useEffect)(() => {
235
- if (typeof window === 'undefined')
236
- return;
237
- const handleHotReloadMessage = (event) => {
238
- try {
239
- const message = JSON.parse(event.data);
240
- // Quando detecta mudança em arquivo, ativa loading
241
- if (message.type === 'frontend-reload' ||
242
- message.type === 'backend-api-reload' ||
243
- message.type === 'src-reload') {
244
- setIsBuilding(true);
245
- }
246
- // Quando o build termina ou servidor fica pronto, desativa loading
247
- if (message.type === 'server-ready' || message.type === 'build-complete') {
248
- setIsBuilding(false);
249
- }
250
- }
251
- catch (e) {
252
- // Ignora mensagens que não são JSON
253
- }
254
- };
255
- // Intercepta mensagens WebSocket
256
- const originalWebSocket = window.WebSocket;
257
- window.WebSocket = class extends originalWebSocket {
258
- constructor(url, protocols) {
259
- super(url, protocols);
260
- this.addEventListener('message', (event) => {
261
- if (url.toString().includes('hweb-hotreload')) {
262
- handleHotReloadMessage(event);
263
- }
264
- });
265
- }
266
- };
267
- return () => {
268
- window.WebSocket = originalWebSocket;
269
- };
270
- }, []);
271
- // --- Estilos Dinâmicos ---
272
- const getIndicatorStyle = () => {
273
- const baseStyle = {
274
- position: 'fixed',
275
- zIndex: 9999,
276
- width: DEV_INDICATOR_SIZE,
277
- height: DEV_INDICATOR_SIZE,
278
- borderRadius: '50%',
279
- background: isBuilding
280
- ? 'linear-gradient(135deg, #f093fb, #f5576c)' // Gradiente Rosa/Vermelho quando building
281
- : 'linear-gradient(135deg, #8e2de2, #4a00e0)', // Gradiente Roxo normal
282
- color: 'white',
283
- fontWeight: 'bold',
284
- fontSize: 28,
285
- boxShadow: isBuilding
286
- ? '0 4px 25px rgba(245, 87, 108, 0.6)' // Shadow mais forte quando building
287
- : '0 4px 15px rgba(0,0,0,0.2)',
288
- display: 'flex',
289
- alignItems: 'center',
290
- justifyContent: 'center',
291
- cursor: isDragging ? 'grabbing' : 'grab',
292
- userSelect: 'none',
293
- transition: isDragging ? 'none' : 'all 0.3s ease-out',
294
- animation: isBuilding ? 'hweb-pulse 1.5s ease-in-out infinite' : 'none',
295
- };
296
- if (isDragging) {
297
- return {
298
- ...baseStyle,
299
- top: position.top,
300
- left: position.left,
301
- };
302
- }
303
- return { ...baseStyle, ...DEV_INDICATOR_CORNERS[corner] };
304
- };
305
- const getMenuPositionStyle = () => {
306
- // Posiciona o menu dependendo do canto
307
- switch (corner) {
308
- case 0: return { top: '110%', left: '0' }; // Top-Left
309
- case 1: return { top: '110%', right: '0' }; // Top-Right
310
- case 2: return { bottom: '110%', left: '0' }; // Bottom-Left
311
- case 3: return { bottom: '110%', right: '0' }; // Bottom-Right
312
- default: return {};
313
- }
314
- };
315
- // --- Lógica de Eventos ---
316
- const handleMouseDown = (e) => {
317
- e.preventDefault();
318
- dragStartRef.current = { x: e.clientX, y: e.clientY, moved: false };
319
- if (indicatorRef.current) {
320
- const rect = indicatorRef.current.getBoundingClientRect();
321
- setPosition({ top: rect.top, left: rect.left });
322
- }
323
- setIsDragging(true);
324
- };
325
- const handleMouseMove = (0, react_1.useCallback)((e) => {
326
- if (!isDragging || !dragStartRef.current)
327
- return;
328
- const deltaX = e.clientX - dragStartRef.current.x;
329
- const deltaY = e.clientY - dragStartRef.current.y;
330
- // Diferencia clique de arrastar (threshold de 5px)
331
- if (!dragStartRef.current.moved && Math.hypot(deltaX, deltaY) > 5) {
332
- dragStartRef.current.moved = true;
333
- }
334
- if (dragStartRef.current.moved) {
335
- setPosition(prevPos => ({
336
- top: prevPos.top + deltaY,
337
- left: prevPos.left + deltaX,
338
- }));
339
- // Atualiza a referência para o próximo movimento
340
- dragStartRef.current.x = e.clientX;
341
- dragStartRef.current.y = e.clientY;
342
- }
343
- }, [isDragging]);
344
- const handleMouseUp = (0, react_1.useCallback)((e) => {
345
- if (!isDragging)
346
- return;
347
- setIsDragging(false);
348
- // Se moveu, calcula o canto mais próximo
349
- if (dragStartRef.current?.moved) {
350
- const { clientX, clientY } = e;
351
- const w = window.innerWidth;
352
- const h = window.innerHeight;
353
- const dists = [
354
- Math.hypot(clientX, clientY), // TL
355
- Math.hypot(w - clientX, clientY), // TR
356
- Math.hypot(clientX, h - clientY), // BL
357
- Math.hypot(w - clientX, h - clientY), // BR
358
- ];
359
- setCorner(dists.indexOf(Math.min(...dists)));
360
- }
361
- dragStartRef.current = null;
362
- }, [isDragging]);
363
- // Adiciona e remove listeners globais
364
- (0, react_1.useEffect)(() => {
365
- if (isDragging) {
366
- window.addEventListener('mousemove', handleMouseMove);
367
- window.addEventListener('mouseup', handleMouseUp);
368
- }
369
- return () => {
370
- window.removeEventListener('mousemove', handleMouseMove);
371
- window.removeEventListener('mouseup', handleMouseUp);
372
- };
373
- }, [isDragging, handleMouseMove, handleMouseUp]);
219
+ const [isVisible, setIsVisible] = (0, react_1.useState)(true);
220
+ if (!isVisible)
221
+ return null;
374
222
  return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("style", { children: `
375
- @keyframes hweb-pulse {
376
- 0%, 100% {
377
- transform: scale(1);
378
- opacity: 1;
379
- }
380
- 50% {
381
- transform: scale(1.1);
382
- opacity: 0.8;
383
- }
384
- }
385
-
386
- @keyframes hweb-spin {
387
- from {
388
- transform: rotate(0deg);
389
- }
390
- to {
391
- transform: rotate(360deg);
392
- }
393
- }
394
- ` }), (0, jsx_runtime_1.jsx)("div", { ref: indicatorRef, style: getIndicatorStyle(), onMouseDown: handleMouseDown, title: isBuilding ? "Building..." : "Modo Dev Nyte.js", children: isBuilding ? ((0, jsx_runtime_1.jsx)("span", { style: { animation: 'hweb-spin 1s linear infinite' }, children: "\u27F3" })) : ('H') })] }));
223
+ @keyframes nyte-pulse {
224
+ 0% { opacity: 0.4; }
225
+ 50% { opacity: 1; }
226
+ 100% { opacity: 0.4; }
227
+ }
228
+ .nyte-dev-badge {
229
+ position: fixed;
230
+ bottom: 20px;
231
+ right: 20px;
232
+ z-index: 999999;
233
+ display: flex;
234
+ align-items: center;
235
+ gap: 12px;
236
+ padding: 8px 14px;
237
+ background: rgba(15, 15, 20, 0.8);
238
+ backdrop-filter: blur(12px);
239
+ -webkit-backdrop-filter: blur(12px);
240
+
241
+ border-radius: 10px;
242
+ color: #fff;
243
+ font-family: 'Inter', ui-monospace, SFMono-Regular, Menlo, monospace;
244
+ font-size: 12px;
245
+ font-weight: 600;
246
+ letter-spacing: 0.05em;
247
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
248
+ transition: all 0.2s ease;
249
+ cursor: default;
250
+ user-select: none;
251
+ }
252
+ .nyte-dev-badge:hover {
253
+ border-color: rgba(142, 45, 226, 0.5);
254
+ transform: translateY(-2px);
255
+ }
256
+ .nyte-status-dot {
257
+ width: 8px;
258
+ height: 8px;
259
+ background: #10b981; /* Verde esmeralda */
260
+ border-radius: 50%;
261
+ box-shadow: 0 0 10px #10b981;
262
+ animation: nyte-pulse 2s infinite ease-in-out;
263
+ }
264
+ .nyte-label {
265
+ color: rgba(255, 255, 255, 0.5);
266
+ text-transform: uppercase;
267
+ font-size: 10px;
268
+ }
269
+ .nyte-logo {
270
+ background: linear-gradient(135deg, #00a3a3, #808080);
271
+ -webkit-background-clip: text;
272
+ -webkit-text-fill-color: transparent;
273
+ font-weight: 800;
274
+ }
275
+ ` }), (0, jsx_runtime_1.jsxs)("div", { className: "nyte-dev-badge", children: [(0, jsx_runtime_1.jsx)("div", { className: "nyte-status-dot" }), (0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)("span", { className: "nyte-logo", children: "NYTE.JS" }) }), (0, jsx_runtime_1.jsx)("button", { onClick: () => setIsVisible(false), style: {
276
+ background: 'none',
277
+ border: 'none',
278
+ color: 'rgba(255,255,255,0.3)',
279
+ cursor: 'pointer',
280
+ fontSize: '14px',
281
+ padding: '0 0 0 4px',
282
+ marginLeft: '4px'
283
+ }, title: "Fechar", children: "\u00D7" })] })] }));
395
284
  }
396
285
  // --- Inicialização do Cliente (CSR - Client-Side Rendering) ---
397
286
  function deobfuscateData(obfuscated) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nyte",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "Nyte.js is a high-level framework for building web applications with ease and speed. It provides a robust set of tools and features to streamline development and enhance productivity.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -223,221 +223,92 @@ function App({ componentMap, routes, initialComponentPath, initialParams, layout
223
223
 
224
224
 
225
225
 
226
- // --- Constantes de Configuração ---
227
- const DEV_INDICATOR_SIZE = 48;
228
- const DEV_INDICATOR_CORNERS = [
229
- { top: 16, left: 16 }, // 0: topo-esquerda
230
- { top: 16, right: 16 }, // 1: topo-direita
231
- { bottom: 16, left: 16 }, // 2: baixo-esquerda
232
- { bottom: 16, right: 16 },// 3: baixo-direita
233
- ];
234
-
235
- function DevIndicator() {
236
- const [corner, setCorner] = useState(3); // Canto atual (0-3)
237
- const [isDragging, setIsDragging] = useState(false); // Estado de arrastar
238
- const [isBuilding, setIsBuilding] = useState(false); // Estado de build
239
-
240
- // Posição visual do indicador durante o arraste
241
- const [position, setPosition] = useState<{ top: number; left: number }>({ top: 0, left: 0 });
242
-
243
- const indicatorRef = useRef<HTMLDivElement>(null);
244
- const dragStartRef = useRef<{ x: number; y: number; moved: boolean } | null>(null);
245
-
246
- // Escuta eventos de hot reload para mostrar estado de build
247
- useEffect(() => {
248
- if (typeof window === 'undefined') return;
249
-
250
- const handleHotReloadMessage = (event: MessageEvent) => {
251
- try {
252
- const message = JSON.parse(event.data);
253
-
254
- // Quando detecta mudança em arquivo, ativa loading
255
- if (message.type === 'frontend-reload' ||
256
- message.type === 'backend-api-reload' ||
257
- message.type === 'src-reload') {
258
- setIsBuilding(true);
259
- }
260
-
261
- // Quando o build termina ou servidor fica pronto, desativa loading
262
- if (message.type === 'server-ready' || message.type === 'build-complete') {
263
- setIsBuilding(false);
264
- }
265
- } catch (e) {
266
- // Ignora mensagens que não são JSON
267
- }
268
- };
269
-
270
- // Intercepta mensagens WebSocket
271
- const originalWebSocket = window.WebSocket;
272
- window.WebSocket = class extends originalWebSocket {
273
- constructor(url: string | URL, protocols?: string | string[]) {
274
- super(url, protocols);
275
-
276
- this.addEventListener('message', (event) => {
277
- if (url.toString().includes('hweb-hotreload')) {
278
- handleHotReloadMessage(event);
279
- }
280
- });
281
- }
282
- } as any;
283
-
284
- return () => {
285
- window.WebSocket = originalWebSocket;
286
- };
287
- }, []);
288
-
289
- // --- Estilos Dinâmicos ---
290
- const getIndicatorStyle = (): React.CSSProperties => {
291
- const baseStyle: React.CSSProperties = {
292
- position: 'fixed',
293
- zIndex: 9999,
294
- width: DEV_INDICATOR_SIZE,
295
- height: DEV_INDICATOR_SIZE,
296
- borderRadius: '50%',
297
- background: isBuilding
298
- ? 'linear-gradient(135deg, #f093fb, #f5576c)' // Gradiente Rosa/Vermelho quando building
299
- : 'linear-gradient(135deg, #8e2de2, #4a00e0)', // Gradiente Roxo normal
300
- color: 'white',
301
- fontWeight: 'bold',
302
- fontSize: 28,
303
- boxShadow: isBuilding
304
- ? '0 4px 25px rgba(245, 87, 108, 0.6)' // Shadow mais forte quando building
305
- : '0 4px 15px rgba(0,0,0,0.2)',
306
- display: 'flex',
307
- alignItems: 'center',
308
- justifyContent: 'center',
309
- cursor: isDragging ? 'grabbing' : 'grab',
310
- userSelect: 'none',
311
- transition: isDragging ? 'none' : 'all 0.3s ease-out',
312
- animation: isBuilding ? 'hweb-pulse 1.5s ease-in-out infinite' : 'none',
313
- };
314
226
 
315
- if (isDragging) {
316
- return {
317
- ...baseStyle,
318
- top: position.top,
319
- left: position.left,
320
- };
321
- }
322
-
323
- return { ...baseStyle, ...DEV_INDICATOR_CORNERS[corner] };
324
- };
325
-
326
- const getMenuPositionStyle = (): React.CSSProperties => {
327
- // Posiciona o menu dependendo do canto
328
- switch (corner) {
329
- case 0: return { top: '110%', left: '0' }; // Top-Left
330
- case 1: return { top: '110%', right: '0' }; // Top-Right
331
- case 2: return { bottom: '110%', left: '0' }; // Bottom-Left
332
- case 3: return { bottom: '110%', right: '0' }; // Bottom-Right
333
- default: return {};
334
- }
335
- };
336
-
337
- // --- Lógica de Eventos ---
338
- const handleMouseDown = (e: React.MouseEvent<HTMLDivElement>) => {
339
- e.preventDefault();
340
- dragStartRef.current = { x: e.clientX, y: e.clientY, moved: false };
341
- if (indicatorRef.current) {
342
- const rect = indicatorRef.current.getBoundingClientRect();
343
- setPosition({ top: rect.top, left: rect.left });
344
- }
345
- setIsDragging(true);
346
- };
347
-
348
- const handleMouseMove = useCallback((e: MouseEvent) => {
349
- if (!isDragging || !dragStartRef.current) return;
350
227
 
351
- const deltaX = e.clientX - dragStartRef.current.x;
352
- const deltaY = e.clientY - dragStartRef.current.y;
353
-
354
- // Diferencia clique de arrastar (threshold de 5px)
355
- if (!dragStartRef.current.moved && Math.hypot(deltaX, deltaY) > 5) {
356
- dragStartRef.current.moved = true;
357
- }
358
-
359
- if (dragStartRef.current.moved) {
360
- setPosition(prevPos => ({
361
- top: prevPos.top + deltaY,
362
- left: prevPos.left + deltaX,
363
- }));
364
- // Atualiza a referência para o próximo movimento
365
- dragStartRef.current.x = e.clientX;
366
- dragStartRef.current.y = e.clientY;
367
- }
368
- }, [isDragging]);
369
-
370
- const handleMouseUp = useCallback((e: MouseEvent) => {
371
- if (!isDragging) return;
372
- setIsDragging(false);
373
-
374
- // Se moveu, calcula o canto mais próximo
375
- if (dragStartRef.current?.moved) {
376
- const { clientX, clientY } = e;
377
- const w = window.innerWidth;
378
- const h = window.innerHeight;
379
-
380
- const dists = [
381
- Math.hypot(clientX, clientY), // TL
382
- Math.hypot(w - clientX, clientY), // TR
383
- Math.hypot(clientX, h - clientY), // BL
384
- Math.hypot(w - clientX, h - clientY), // BR
385
- ];
386
- setCorner(dists.indexOf(Math.min(...dists)));
387
- }
388
-
389
- dragStartRef.current = null;
390
- }, [isDragging]);
391
-
392
- // Adiciona e remove listeners globais
393
- useEffect(() => {
394
- if (isDragging) {
395
- window.addEventListener('mousemove', handleMouseMove);
396
- window.addEventListener('mouseup', handleMouseUp);
397
- }
398
- return () => {
399
- window.removeEventListener('mousemove', handleMouseMove);
400
- window.removeEventListener('mouseup', handleMouseUp);
401
- };
402
- }, [isDragging, handleMouseMove, handleMouseUp]);
228
+ export function DevIndicator() {
229
+ const [isVisible, setIsVisible] = useState(true);
403
230
 
231
+ if (!isVisible) return null;
404
232
 
405
233
  return (
406
234
  <>
407
235
  <style>
408
236
  {`
409
- @keyframes hweb-pulse {
410
- 0%, 100% {
411
- transform: scale(1);
412
- opacity: 1;
413
- }
414
- 50% {
415
- transform: scale(1.1);
416
- opacity: 0.8;
417
- }
418
- }
419
-
420
- @keyframes hweb-spin {
421
- from {
422
- transform: rotate(0deg);
423
- }
424
- to {
425
- transform: rotate(360deg);
426
- }
427
- }
428
- `}
237
+ @keyframes nyte-pulse {
238
+ 0% { opacity: 0.4; }
239
+ 50% { opacity: 1; }
240
+ 100% { opacity: 0.4; }
241
+ }
242
+ .nyte-dev-badge {
243
+ position: fixed;
244
+ bottom: 20px;
245
+ right: 20px;
246
+ z-index: 999999;
247
+ display: flex;
248
+ align-items: center;
249
+ gap: 12px;
250
+ padding: 8px 14px;
251
+ background: rgba(15, 15, 20, 0.8);
252
+ backdrop-filter: blur(12px);
253
+ -webkit-backdrop-filter: blur(12px);
254
+
255
+ border-radius: 10px;
256
+ color: #fff;
257
+ font-family: 'Inter', ui-monospace, SFMono-Regular, Menlo, monospace;
258
+ font-size: 12px;
259
+ font-weight: 600;
260
+ letter-spacing: 0.05em;
261
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
262
+ transition: all 0.2s ease;
263
+ cursor: default;
264
+ user-select: none;
265
+ }
266
+ .nyte-dev-badge:hover {
267
+ border-color: rgba(142, 45, 226, 0.5);
268
+ transform: translateY(-2px);
269
+ }
270
+ .nyte-status-dot {
271
+ width: 8px;
272
+ height: 8px;
273
+ background: #10b981; /* Verde esmeralda */
274
+ border-radius: 50%;
275
+ box-shadow: 0 0 10px #10b981;
276
+ animation: nyte-pulse 2s infinite ease-in-out;
277
+ }
278
+ .nyte-label {
279
+ color: rgba(255, 255, 255, 0.5);
280
+ text-transform: uppercase;
281
+ font-size: 10px;
282
+ }
283
+ .nyte-logo {
284
+ background: linear-gradient(135deg, #00a3a3, #808080);
285
+ -webkit-background-clip: text;
286
+ -webkit-text-fill-color: transparent;
287
+ font-weight: 800;
288
+ }
289
+ `}
429
290
  </style>
430
- <div
431
- ref={indicatorRef}
432
- style={getIndicatorStyle()}
433
- onMouseDown={handleMouseDown}
434
- title={isBuilding ? "Building..." : "Modo Dev Nyte.js"}
435
- >
436
- {isBuilding ? (
437
- <span style={{ animation: 'hweb-spin 1s linear infinite' }}>⟳</span>
438
- ) : (
439
- 'H'
440
- )}
291
+
292
+ <div className="nyte-dev-badge">
293
+ <div className="nyte-status-dot" />
294
+ <div>
295
+ <span className="nyte-logo">NYTE.JS</span>
296
+ </div>
297
+ <button
298
+ onClick={() => setIsVisible(false)}
299
+ style={{
300
+ background: 'none',
301
+ border: 'none',
302
+ color: 'rgba(255,255,255,0.3)',
303
+ cursor: 'pointer',
304
+ fontSize: '14px',
305
+ padding: '0 0 0 4px',
306
+ marginLeft: '4px'
307
+ }}
308
+ title="Fechar"
309
+ >
310
+ ×
311
+ </button>
441
312
  </div>
442
313
  </>
443
314
  );