@decido/shell-vscode-core 4.0.1 → 4.0.3

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 (54) hide show
  1. package/dist/index.js +2016 -0
  2. package/dist/index.mjs +1949 -0
  3. package/package.json +18 -14
  4. package/.turbo/turbo-build.log +0 -13
  5. package/CHANGELOG.md +0 -31
  6. package/src/appState.ts +0 -167
  7. package/src/core/AIService.ts +0 -109
  8. package/src/core/ApiService.ts +0 -40
  9. package/src/core/AuthService.ts +0 -85
  10. package/src/core/BaseService.ts +0 -47
  11. package/src/core/CalendarService.ts +0 -44
  12. package/src/core/CommandService.ts +0 -69
  13. package/src/core/DebugPanelService.ts +0 -38
  14. package/src/core/DebugService.ts +0 -181
  15. package/src/core/EventBus.ts +0 -60
  16. package/src/core/EventHandler.ts +0 -97
  17. package/src/core/GamificationService.ts +0 -120
  18. package/src/core/HookService.ts +0 -86
  19. package/src/core/ModalService.ts +0 -97
  20. package/src/core/NotificationService.ts +0 -53
  21. package/src/core/RouterService.ts +0 -68
  22. package/src/core/ServiceContainer.ts +0 -31
  23. package/src/core/ShortcutService.ts +0 -49
  24. package/src/core/StorageService.ts +0 -123
  25. package/src/core/ThemeService.ts +0 -71
  26. package/src/core/WebSocketService.ts +0 -32
  27. package/src/core/api.ts +0 -78
  28. package/src/core/app/ModuleManager.ts +0 -273
  29. package/src/core/app/apiFactory.ts +0 -130
  30. package/src/core/app/commandManager.ts +0 -218
  31. package/src/core/app/moduleLoader.ts +0 -39
  32. package/src/core/app/routeManager.ts +0 -8
  33. package/src/core/index.ts +0 -15
  34. package/src/core/signals.ts +0 -84
  35. package/src/core/uiState.ts +0 -13
  36. package/src/index.ts +0 -18
  37. package/src/lib/local-db.ts +0 -65
  38. package/src/lib/sync-service.ts +0 -44
  39. package/src/platform/ILayoutService.ts +0 -77
  40. package/src/platform/IRenderer.ts +0 -16
  41. package/src/platform/ServiceRegistry.ts +0 -53
  42. package/src/platform/extensionPoints.ts +0 -202
  43. package/src/platform/index.ts +0 -4
  44. package/src/stores/editorStore.ts +0 -6
  45. package/src/stores/gamificationStore.ts +0 -4
  46. package/src/stores/historyStore.ts +0 -14
  47. package/src/stores/workspaceStore.ts +0 -8
  48. package/src/types/app.ts +0 -36
  49. package/src/types/debug.ts +0 -69
  50. package/src/types/index.ts +0 -3
  51. package/src/types/platform.ts +0 -112
  52. package/src/ui/Palette.ts +0 -161
  53. package/src/utils.ts +0 -63
  54. package/tsconfig.json +0 -23
@@ -1,53 +0,0 @@
1
- // /src/core/NotificationService.ts (REDISENADO)
2
-
3
- import { html } from "../utils.js";
4
-
5
- export type NotificationType = 'info' | 'success' | 'warning' | 'error' | 'achievement';
6
-
7
- export class NotificationService {
8
- public container: HTMLElement;
9
-
10
- constructor() {
11
- this.container = document.createElement('div');
12
- this.container.id = 'notification-container';
13
- this.container.className = 'fixed top-5 right-5 z-10000 w-96 space-y-3';
14
- document.body.appendChild(this.container);
15
- }
16
-
17
- public show(type: NotificationType, title: string, message: string, duration: number = 4000) {
18
- const id = `notif_${Date.now()}`;
19
- const notificationEl = document.createElement('div');
20
- notificationEl.id = id;
21
-
22
- const typeStyles = {
23
- info: { icon: 'fas fa-info-circle', color: 'border-secondary' },
24
- success: { icon: 'fas fa-check-circle', color: 'border-success' },
25
- warning: { icon: 'fas fa-exclamation-triangle', color: 'border-accent' },
26
- error: { icon: 'fas fa-times-circle', color: 'border-danger' },
27
- achievement: { icon: 'fas fa-trophy', color: 'border-accent' },
28
- };
29
- const styles = typeStyles[type];
30
-
31
- // Usamos la estética glass-card con un borde de color distintivo
32
- notificationEl.innerHTML = html`
33
- <div class="notification-item glass-card animate-slide-in-right border-l-4 ${styles.color}">
34
- <i class="notification-icon ${styles.icon}"></i>
35
- <div class="flex-grow">
36
- <h4 class="notification-title">${title}</h4>
37
- <p class="notification-message">${message}</p>
38
- </div>
39
- <button class="notification-close-btn" data-close-id="${id}">&times;</button>
40
- </div>
41
- `;
42
-
43
- notificationEl.querySelector('.notification-close-btn')?.addEventListener('click', () => {
44
- notificationEl.remove();
45
- });
46
-
47
- this.container.appendChild(notificationEl);
48
-
49
- setTimeout(() => {
50
- document.getElementById(id)?.remove();
51
- }, duration);
52
- }
53
- }
@@ -1,68 +0,0 @@
1
- // src/core/RouterService.ts
2
- import { authService } from './AuthService.js';
3
- import { IPlatformAPI } from './api.js';
4
- import { RouteDefinition } from '../types';
5
-
6
- export class RouterService {
7
- private routes: RouteDefinition[] = [];
8
- private api!: IPlatformAPI;
9
-
10
- public init(api: IPlatformAPI) {
11
- this.api = api;
12
- window.addEventListener('hashchange', this.handleRouteChange);
13
- // window.addEventListener('load', this.handleRouteChange);
14
- }
15
-
16
- public registerRoute(route: RouteDefinition) {
17
- this.routes.push(route);
18
- }
19
-
20
- public navigate(path: string) {
21
- window.location.hash = path;
22
- }
23
-
24
- // Centraliza la lectura del hash en un solo lugar.
25
- private _getCurrentHash(): string {
26
- return window.location.hash.slice(1) || '/';
27
- }
28
-
29
- public handleRouteChange = () => {
30
- const path = this._getCurrentHash();
31
- const route = this.routes.find(r => r.path === path);
32
- const session = authService.session[0](); // Obtenemos el estado actual de la sesión
33
-
34
- if (!route) {
35
- // Ruta no encontrada, podríamos redirigir a una página 404
36
- console.error(`Ruta no encontrada: ${path}`);
37
- this.api.layout.renderComponent('not-found-view');
38
- return;
39
- }
40
-
41
- // --- LÓGICA DE GUARDIÁN DE NAVEGACIÓN ---
42
- const isAuthenticated = session.status === 'authenticated';
43
-
44
- // 1. Si la ruta es protegida y el usuario no está autenticado...
45
- if (route.auth === 'protected' && !isAuthenticated) {
46
- this.navigate('/login'); // ...redirige al login.
47
- return;
48
- }
49
-
50
- // 2. Si la ruta es solo para invitados (como login) y el usuario ya está autenticado...
51
- if (route.auth === 'guestOnly' && isAuthenticated) {
52
- this.navigate('/dashboard'); // ...redirige al dashboard.
53
- return;
54
- }
55
-
56
- // 3. (Futuro) Si la ruta requiere roles específicos...
57
- // if (route.roles && !route.roles.some(role => session.user?.roles.includes(role))) {
58
- // this.navigate('/forbidden'); // ...redirige a "Acceso Denegado".
59
- // return;
60
- // }
61
-
62
- // Si todas las comprobaciones pasan, renderizamos el componente.
63
- if (route.title) document.title = `Decido - ${route.title}`;
64
- this.api.layout.renderComponent(route.componentTag, { isFullscreen: route.isFullscreen });
65
- }
66
- }
67
-
68
- export const routerService = new RouterService();
@@ -1,31 +0,0 @@
1
- import { ServiceKey, ServiceRegistry } from "../platform/ServiceRegistry.js";
2
-
3
- /**
4
- * Un contenedor de inyección de dependencias tipado y genérico.
5
- */
6
- export class ServiceContainer {
7
- private services = new Map<ServiceKey, any>();
8
-
9
- /**
10
- * Registra una instancia de un servicio.
11
- * El tipo es validado contra el `ServiceRegistry`.
12
- */
13
- public register<K extends ServiceKey>(key: K, instance: ServiceRegistry[K]): void {
14
- if (this.services.has(key)) {
15
- console.warn(`[ServiceContainer] El servicio '${key}' ya está registrado. Se sobrescribirá.`);
16
- }
17
- this.services.set(key, instance);
18
- }
19
-
20
- /**
21
- * Obtiene la instancia de un servicio registrado.
22
- * El tipo de retorno es inferido automáticamente a partir de la clave.
23
- */
24
- public get<K extends ServiceKey>(key: K): ServiceRegistry[K] {
25
- const service = this.services.get(key);
26
- if (!service) {
27
- throw new Error(`[ServiceContainer] No se encontró servicio registrado con la clave: ${key}`);
28
- }
29
- return service;
30
- }
31
- }
@@ -1,49 +0,0 @@
1
- // /src/core/ShortcutService.ts
2
-
3
- import { IPlatformAPI } from "./api.js";
4
-
5
- interface Shortcut {
6
- id: string;
7
- keys: string; // Ej: "Control+K", "Shift+N"
8
- commandId: string;
9
- commandArg?: any;
10
- description?: string;
11
- }
12
-
13
- export class ShortcutService {
14
- private api!: IPlatformAPI;
15
- private shortcuts: Map<string, Shortcut> = new Map();
16
-
17
- public init(api: IPlatformAPI) {
18
- this.api = api;
19
- window.addEventListener('keydown', this.handleKeyDown.bind(this));
20
- }
21
-
22
- public register(shortcut: Shortcut) {
23
- // La clave será una combinación normalizada, ej: "control_k"
24
- const key = shortcut.keys.toLowerCase().split('+').sort().join('_');
25
- this.shortcuts.set(key, shortcut);
26
- }
27
-
28
- private handleKeyDown(e: KeyboardEvent) {
29
- const keyParts: string[] = [];
30
- if (e.ctrlKey) keyParts.push('control');
31
- if (e.metaKey) keyParts.push('meta'); // Cmd en Mac
32
- if (e.shiftKey) keyParts.push('shift');
33
- if (e.altKey) keyParts.push('alt');
34
-
35
- // Evitamos que modificadores solos disparen algo
36
- if (!['Control', 'Meta', 'Shift', 'Alt'].includes(e.key)) {
37
- keyParts.push(e.key.toLowerCase());
38
- }
39
-
40
- if (keyParts.length > 1) {
41
- const key = keyParts.sort().join('_');
42
- const shortcut = this.shortcuts.get(key);
43
- if (shortcut) {
44
- e.preventDefault();
45
- this.api.commands.execute(shortcut.commandId, shortcut.commandArg);
46
- }
47
- }
48
- }
49
- }
@@ -1,123 +0,0 @@
1
- // src/core/StorageService.ts
2
- import { DailySnapshot, db, ModuleData, LocalProject } from "../lib/local-db.js";
3
-
4
-
5
-
6
-
7
- export class StorageService {
8
- // --- Métodos para Colecciones de Entidades (Tareas, Metas, etc.) ---
9
-
10
- async getCollection<T>(entityType: string): Promise<T[]> {
11
- const results = await db.moduleData.where({ entityType }).toArray();
12
- return results.map((item: { data: T; }) => item.data as T);
13
- }
14
-
15
- async saveEntity<T extends { id: string | number }>(entityType: string, entity: T): Promise<void> {
16
- const record: ModuleData = {
17
- id: `${entityType}-${entity.id}`,
18
- entityId: entity.id,
19
- moduleId: entityType + 's',
20
- entityType: entityType,
21
- data: entity
22
- };
23
- await db.moduleData.put(record);
24
- }
25
-
26
- async deleteEntity(entityType: string, entityId: string | number): Promise<void> {
27
- await db.moduleData.delete(`${entityType}-${entityId}`);
28
- }
29
-
30
- // --- Métodos para Objetos de Estado Únicos (Journal, Settings, etc.) ---
31
-
32
- async getValue<T>(key: string): Promise<T | undefined> {
33
- const result = await db.moduleData.get(`value-${key}`);
34
- return result ? result.data as T : undefined;
35
- }
36
-
37
- async saveValue<T>(key: string, value: T): Promise<void> {
38
- const record: ModuleData = {
39
- id: `value-${key}`,
40
- entityId: key,
41
- moduleId: 'values',
42
- entityType: 'value',
43
- data: value
44
- };
45
- await db.moduleData.put(record);
46
- }
47
-
48
- /**
49
- * Guarda un snapshot completo del estado de la aplicación para una fecha específica.
50
- * La fecha se guarda en formato 'YYYY-MM-DD'.
51
- * @param date La fecha del snapshot.
52
- * @param state El objeto de estado completo a guardar.
53
- */
54
- async saveDailySnapshot(date: Date, state: any): Promise<void> {
55
- const dateKey = date.toISOString().split('T')[0]; // 'YYYY-MM-DD'
56
- const snapshotRecord: DailySnapshot = {
57
- date: dateKey,
58
- data: state,
59
- timestamp: new Date()
60
- };
61
- // `put` sobreescribirá si ya existe un snapshot para ese día.
62
- await db.dailySnapshots.put(snapshotRecord);
63
- console.log(`📸 Snapshot guardado para la fecha: ${dateKey}`);
64
- }
65
-
66
- /**
67
- * Recupera el snapshot de un día específico.
68
- * @param date La fecha del snapshot a recuperar.
69
- * @returns El estado guardado para esa fecha, o undefined si no existe.
70
- */
71
- async getDailySnapshot(date: Date): Promise<any | undefined> {
72
- const dateKey = date.toISOString().split('T')[0];
73
- const result = await db.dailySnapshots.get(dateKey);
74
- return result ? result.data : undefined;
75
- }
76
-
77
- /**
78
- * Obtiene una lista de todas las fechas para las que existe un snapshot.
79
- * @returns Un array de strings con las fechas en formato 'YYYY-MM-DD'.
80
- */
81
- async getAvailableSnapshotDates(): Promise<string[]> {
82
- return await db.dailySnapshots.toCollection().keys() as string[];
83
- }
84
-
85
- // --- PROYECTOS (Manejo de datos pesados) ---
86
-
87
- async saveProject(id: string, name: string, flowData: any) {
88
- // IndexedDB es asíncrono, no bloquea la UI
89
- await db.projects.put({
90
- id,
91
- name,
92
- data: flowData, // Aquí puedes guardar MBs de nodos sin problema
93
- updatedAt: Date.now()
94
- });
95
- console.log(`💾 Proyecto ${id} guardado en IndexedDB`);
96
- }
97
-
98
- async getProject(id: string): Promise<LocalProject | undefined> {
99
- return await db.projects.get(id);
100
- }
101
-
102
- async getAllProjectsMetadata() {
103
- // Solo traemos ID y Nombre para la lista del sidebar (rápido)
104
- return await db.projects.toArray();
105
- }
106
-
107
- async deleteProject(id: string) {
108
- await db.projects.delete(id);
109
- }
110
-
111
- // --- CONFIGURACIÓN (Settings ligeros) ---
112
-
113
- async setSetting(key: string, value: any) {
114
- await db.settings.put({ key, value });
115
- }
116
-
117
- async getSetting(key: string) {
118
- const item = await db.settings.get(key);
119
- return item?.value;
120
- }
121
- }
122
-
123
- export const storageService = new StorageService();
@@ -1,71 +0,0 @@
1
- // src/core/ThemeService.ts
2
- import { createSignal } from './signals.js';
3
-
4
- export type Theme = 'dark' | 'light';
5
-
6
- // Valores por defecto para los temas
7
- const themes = {
8
- dark: {
9
- '--bg-main': '#070720',
10
- '--bg-content': '#0F0F23',
11
- '--bg-surface': 'rgba(255, 255, 255, 0.03)',
12
- '--text-primary': '#FFFFFF',
13
- '--text-secondary': '#9CA3AF',
14
- },
15
- light: {
16
- '--bg-main': '#f8f9fa',
17
- '--bg-content': '#FFFFFF',
18
- '--bg-surface': 'rgba(0, 0, 0, 0.03)',
19
- '--text-primary': '#212529',
20
- '--text-secondary': '#495057',
21
- }
22
- };
23
-
24
- export class ThemeService {
25
- public activeTheme: ReturnType<typeof createSignal<Theme>>;
26
-
27
- constructor() {
28
- const savedTheme = localStorage.getItem('decido-theme') as Theme || 'dark';
29
- this.activeTheme = createSignal(savedTheme);
30
- this.applyTheme(savedTheme);
31
- }
32
-
33
- public setTheme(themeName: Theme): void {
34
- this.activeTheme[1](themeName); // Actualiza la señal
35
- this.applyTheme(themeName);
36
- localStorage.setItem('decido-theme', themeName);
37
- }
38
-
39
- private applyTheme(themeName: Theme) {
40
- const theme = themes[themeName];
41
- for (const [key, value] of Object.entries(theme)) {
42
- document.documentElement.style.setProperty(key, value);
43
- }
44
- }
45
-
46
- // Permite actualizar un token individual en tiempo real para el panel
47
- public updateToken(tokenName: string, value: string) {
48
- document.documentElement.style.setProperty(tokenName, value);
49
- }
50
-
51
- public applyPalette(palette: Record<string, string>) {
52
- const tokenMap = {
53
- primary: '--color-primary',
54
- secondary: '--color-secondary',
55
- accent: '--color-accent',
56
- bgMain: '--bg-main',
57
- bgContent: '--bg-content',
58
- textPrimary: '--text-primary',
59
- textSecondary: '--text-secondary',
60
- };
61
-
62
- for (const [key, value] of Object.entries(palette)) {
63
- const tokenName = tokenMap[key as keyof typeof tokenMap];
64
- if (tokenName) {
65
- this.updateToken(tokenName, value);
66
- }
67
- }
68
- }
69
- }
70
-
71
- export const themeService = new ThemeService();
@@ -1,32 +0,0 @@
1
- // File: packages/core/src/core/WebSocketService.ts
2
-
3
- import { IPlatformAPI } from './api';
4
-
5
- // Define los estados posibles de la conexión para un control claro.
6
- type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'error';
7
-
8
- /**
9
- * Servicio Mock de WebSocket. Desactivado para la transición a Micro-IDE.
10
- */
11
- export class WebSocketService {
12
- private api!: IPlatformAPI;
13
- private status: ConnectionStatus = 'disconnected';
14
-
15
- /**
16
- * @param api La instancia de la API de la plataforma.
17
- */
18
- public init(api: IPlatformAPI): void {
19
- this.api = api;
20
- console.log("🔌 WebSocketService (Mock) inicializado en modo Offline.");
21
- }
22
-
23
- public connect(): void {
24
- console.log("[WebSocket] Ignorado: Conectando local (Micro-IDE).");
25
- }
26
-
27
- public disconnect(): void { }
28
-
29
- public emit(eventName: string, payload: any): void {
30
- console.log(`[WebSocket Mock] Envío evadido: ${eventName}`, payload);
31
- }
32
- }
package/src/core/api.ts DELETED
@@ -1,78 +0,0 @@
1
- // src/platform/api.ts
2
- import { CommandService } from "./CommandService.js";
3
- import { EventBus } from "./EventBus.js";
4
- import { ILayoutService } from "../platform"
5
- import { ModalService } from "./ModalService.js";
6
- import { NotificationService } from "./NotificationService.js";
7
- import * as state from '../appState.js';
8
- import { GamificationService } from "./GamificationService.js";
9
- import { CalendarService } from "./CalendarService.js";
10
- import { ShortcutService } from "./ShortcutService.js";
11
- import { ModuleManager } from "./app/ModuleManager.js";
12
- import { ThemeService } from "./ThemeService.js";
13
- import { AuthService } from './AuthService.js';
14
- import { RouterService } from "./RouterService.js";
15
- import { StorageService } from "./StorageService.js";
16
- import { SyncService } from "../lib/sync-service.js";
17
- import { ServiceKey, ServiceRegistry } from '../platform/ServiceRegistry.js';
18
- import { ServiceContainer } from "./ServiceContainer.js";
19
- import { HookService } from "./index.js";
20
- import { DebugService } from "./DebugService.js";
21
- import { WebSocketService } from "./WebSocketService.js";
22
-
23
-
24
- /**
25
- * La API de la Plataforma que se expone a cada módulo.
26
- * Actúa como un contrato bien definido entre el núcleo de la app y sus extensiones.
27
- */
28
- export interface IPlatformAPI {
29
- debug?: DebugService;
30
- events: EventBus;
31
- commands: CommandService;
32
- layout: ILayoutService;
33
- modals: ModalService;
34
- notifications: NotificationService;
35
- gamification: GamificationService;
36
- calendar: CalendarService;
37
- shortcuts: ShortcutService;
38
- state: typeof state;
39
- theme: ThemeService;
40
- storage: StorageService;
41
- sync: SyncService;
42
- router?: RouterService;
43
-
44
- moduleManager: ModuleManager | null;
45
- container: ServiceContainer;
46
- readonly hooks: HookService;
47
- websocket: WebSocketService;
48
-
49
- // --- Acceso a la API del Backend ---
50
- readonly modules: {
51
- rateModule(id: any, rating: number, review: string): unknown;
52
- getModuleById(moduleId: string): unknown;
53
- getCategories(): any[] | PromiseLike<any[]>;
54
- getModules: () => Promise<any[]>;
55
- getInstalledModules: () => Promise<any[]>;
56
- uploadModule: (formData: FormData) => Promise<any>;
57
- installModule: (moduleId: string) => Promise<any>;
58
- getProfile: () => Promise<any>;
59
- updateProfile: (profileData: any) => Promise<any>;
60
- };
61
- readonly timetravel: {
62
- revertToDate: (date: String) => Promise<any>;
63
- getSnapshotDates(): Promise<any>;
64
- getPreviousActivityDate: (date: String) => Promise<any>;
65
- getNextActivityDate: (date: String) => Promise<any>;
66
- };
67
- readonly auth: AuthService;
68
- readonly ai: {
69
- generateTheme: (prompt: string) => Promise<any>;
70
- // ... otros métodos de IA
71
- };
72
-
73
- // El API de servicios ahora es una fachada para el contenedor
74
- readonly services: {
75
- register<K extends keyof ServiceRegistry>(key: K, instance: ServiceRegistry[K]): void;
76
- get<K extends keyof ServiceRegistry>(key: K): Promise<ServiceRegistry[K]>;
77
- };
78
- }