{
  "schema_version": 1,
  "diagram_type": "architecture",
  "meta": {
    "title": "Monorepo Infernus y sus paquetes",
    "quality_profile": "showcase"
  },
  "layout": {
    "mode": "grid",
    "origin": [
      20,
      40
    ],
    "cols": 10,
    "gapX": 8,
    "gapY": 34,
    "cellW": 120,
    "cellH": 60
  },
  "components": [
    {
      "id": "create_app",
      "type": "backend",
      "label": "create-app",
      "sublabel": "CLI de creacion",
      "row": 0,
      "col": 0
    },
    {
      "id": "gamemode",
      "type": "frontend",
      "label": "Script de gamemode",
      "sublabel": "gamemode propio",
      "row": 1,
      "col": 0
    },
    {
      "id": "core_pkg",
      "type": "backend",
      "label": "@infernus/core",
      "sublabel": "libreria central",
      "row": 2,
      "col": 0
    },
    {
      "id": "samp_node",
      "type": "cloud",
      "label": "samp-node",
      "sublabel": "runtime de Node",
      "row": 3,
      "col": 0
    },
    {
      "id": "fs_pkg",
      "type": "backend",
      "label": "@infernus/fs",
      "sublabel": "scripts incluidos",
      "row": 0,
      "col": 1
    },
    {
      "id": "types_pkg",
      "type": "backend",
      "label": "@infernus/types",
      "sublabel": "tipos globales",
      "row": 1,
      "col": 1
    },
    {
      "id": "omp_server",
      "type": "cloud",
      "label": "open.mp Server",
      "sublabel": "host del servidor",
      "row": 2,
      "col": 1
    },
    {
      "id": "nodejs",
      "type": "cloud",
      "label": "Node.js 22",
      "sublabel": "runtime de JS",
      "row": 3,
      "col": 1
    },
    {
      "id": "shared_pkg",
      "type": "external",
      "label": "@infernus/shared",
      "sublabel": "codigo de build",
      "row": 3,
      "col": 2
    },
    {
      "id": "raknet",
      "type": "backend",
      "label": "raknet",
      "sublabel": "paquetes de red",
      "row": 0,
      "col": 3
    },
    {
      "id": "nex_ac",
      "type": "security",
      "label": "nex-ac",
      "sublabel": "antitrampas",
      "row": 0,
      "col": 4
    },
    {
      "id": "weapon_config",
      "type": "security",
      "label": "weapon-config",
      "sublabel": "dano de armas",
      "row": 1,
      "col": 3
    },
    {
      "id": "query",
      "type": "backend",
      "label": "query",
      "sublabel": "consulta de estado",
      "row": 1,
      "col": 4
    },
    {
      "id": "streamer",
      "type": "backend",
      "label": "streamer",
      "sublabel": "carga de entidades",
      "row": 0,
      "col": 6
    },
    {
      "id": "colandreas",
      "type": "backend",
      "label": "colandreas",
      "sublabel": "colisiones",
      "row": 0,
      "col": 7
    },
    {
      "id": "mapandreas",
      "type": "backend",
      "label": "mapandreas",
      "sublabel": "alturas terreno",
      "row": 0,
      "col": 8
    },
    {
      "id": "map_loader",
      "type": "backend",
      "label": "map-loader",
      "sublabel": "carga de mapas",
      "row": 1,
      "col": 6
    },
    {
      "id": "mapfix",
      "type": "backend",
      "label": "mapfix",
      "sublabel": "parches de mapa",
      "row": 1,
      "col": 7
    },
    {
      "id": "gps",
      "type": "backend",
      "label": "gps",
      "sublabel": "navegacion",
      "row": 1,
      "col": 8
    },
    {
      "id": "cef",
      "type": "backend",
      "label": "cef",
      "sublabel": "navegador en juego",
      "row": 2,
      "col": 3
    },
    {
      "id": "ompp",
      "type": "backend",
      "label": "ompp",
      "sublabel": "extras open.mp",
      "row": 2,
      "col": 4
    },
    {
      "id": "progress",
      "type": "backend",
      "label": "progress",
      "sublabel": "barras de progreso",
      "row": 2,
      "col": 5
    },
    {
      "id": "qrcode",
      "type": "backend",
      "label": "qrcode",
      "sublabel": "codigos QR",
      "row": 3,
      "col": 3
    },
    {
      "id": "s_art",
      "type": "backend",
      "label": "s-art",
      "sublabel": "render de imagenes",
      "row": 3,
      "col": 4
    },
    {
      "id": "e_selection",
      "type": "backend",
      "label": "e-selection",
      "sublabel": "menu de modelos",
      "row": 3,
      "col": 5
    },
    {
      "id": "fcnpc",
      "type": "backend",
      "label": "fcnpc",
      "sublabel": "NPC y bots",
      "row": 2,
      "col": 7
    },
    {
      "id": "samp_voice",
      "type": "backend",
      "label": "samp-voice",
      "sublabel": "chat de voz",
      "row": 2,
      "col": 8
    },
    {
      "id": "veh_para",
      "type": "backend",
      "label": "veh-para",
      "sublabel": "paracaidas",
      "row": 2,
      "col": 9
    },
    {
      "id": "distance",
      "type": "backend",
      "label": "distance",
      "sublabel": "distancias",
      "row": 3,
      "col": 7
    },
    {
      "id": "drift_detection",
      "type": "backend",
      "label": "drift-detection",
      "sublabel": "deteccion de drift",
      "row": 3,
      "col": 8
    },
    {
      "id": "rec",
      "type": "backend",
      "label": "rec",
      "sublabel": "conversion .rec",
      "row": 3,
      "col": 9
    }
  ],
  "boundaries": [
    {
      "kind": "region",
      "label": "Red y antitrampas",
      "wraps": [
        "raknet",
        "nex_ac",
        "weapon_config",
        "query"
      ]
    },
    {
      "kind": "region",
      "label": "Mundo y navegacion",
      "wraps": [
        "streamer",
        "colandreas",
        "mapandreas",
        "map_loader",
        "mapfix",
        "gps"
      ]
    },
    {
      "kind": "region",
      "label": "Interfaz",
      "wraps": [
        "cef",
        "ompp",
        "progress",
        "qrcode",
        "s_art",
        "e_selection"
      ]
    },
    {
      "kind": "region",
      "label": "Jugadores y juego",
      "wraps": [
        "fcnpc",
        "samp_voice",
        "veh_para",
        "distance",
        "drift_detection",
        "rec"
      ]
    }
  ],
  "connections": [
    {
      "id": "createapp-scaffolds-gamemode",
      "from": "create_app",
      "to": "gamemode",
      "label": "genera esqueleto",
      "labelAt": [
        80,
        114
      ]
    },
    {
      "id": "gamemode-imports-core",
      "from": "gamemode",
      "to": "core_pkg",
      "label": "import core",
      "variant": "emphasis",
      "labelAt": [
        80,
        208
      ]
    },
    {
      "id": "core-calls-native",
      "from": "core_pkg",
      "to": "samp_node",
      "label": "callNative",
      "variant": "emphasis",
      "labelAt": [
        80,
        302
      ]
    }
  ],
  "cards": [
    {
      "dot": "cyan",
      "title": "Tres estilos de implementacion",
      "items": [
        "Envolver un plugin nativo: raknet, streamer, colandreas, cef, ompp y fcnpc exponen sus funciones nativas tipadas",
        "Mejorar el comportamiento de core: nex-ac, weapon-config, veh-para y distance sustituyen llamadas nativas para reescribir dano y posicion",
        "TypeScript puro: mapandreas, rec, query y e-selection no necesitan ningun plugin nativo"
      ]
    },
    {
      "dot": "emerald",
      "title": "Puntos de extension en core",
      "items": [
        "defineEvent declara el evento; los listeners forman una cadena de middleware avanzada con next()",
        "defineHooks(Class) devuelve la instantanea de metodos originales y setHook, para sustituir metodos",
        "GameMode.use() solo encola; la carga ocurre en onInit"
      ]
    },
    {
      "dot": "violet",
      "title": "Limite de compilacion y ejecucion",
      "items": [
        "scripts/build-all.ts compila en serie: streamer, core, raknet y el resto",
        "Cada paquete valida tipos y luego empaqueta bundle.mjs / bundle.js / bundle.d.ts",
        "samp-node lo carga open.mp e inyecta samp global; streamer y types no se publican"
      ]
    }
  ]
}
