qcobjects
Version:
QCObjects is an Open-source framework that empowers full-stack developers to make micro-services and micro-frontends into an N-Tier architecture.
1,213 lines (917 loc) • 116 kB
Markdown

[](https://github.com/QuickCorp/QCObjects/blob/master/LICENSE.txt) [](https://www.jsdelivr.com/package/npm/qcobjects) [](https://marketplace.visualstudio.com/items?itemName=Quickcorp.QCObjects-vscode) [](https://qcobjects.readthedocs.io/?badge=latest) [](https://github.com/QuickCorp/QCObjects/releases/) [](https://github.com/QuickCorp/QCObjects) [](https://badge.fury.io/js/qcobjects)   [](CODE_OF_CONDUCT.md)
[](https://www.patreon.com/join/qcobjects?)
# QCObjects
------------------------------------
Bienvenido a [QCObjects](https://qcobjects.dev). Un framework Open Source que empodera a los full-stack developers para hacer micro-servicios y micro-frontends dentro de una arquitectura N-Tier.
Con QCObjects los desarrolladores están habilitados para programar front-end y back-end en conjunto usando una sintaxis común in pure JavaScript. It is cross-browser, cross-platform and cross-frame.
[QCObjects ha sido presentado por British Herald como el marco más avanzado para el desarrollo de software moderno.](https://britishherald.com/qcobjects-the-first-world-class-tech-framework-made-in-south-america-is-meant-to-make-developers-happier-while-they-code/)
Este documento es la documentacion referencial principal!
Este repositorio y archivo léame está alojado en [https://qcobjects.dev](https://qcobjects.dev)
Echa un vistazo a la página oficial de [QCObjects](https://qcobjects.com) at https://qcobjects.com
Este proyecto se adhiere al Pacto Colaborador[code of conduct](CODE_OF_CONDUCT.md). Al participar, se espera que respete este código. Por favor reportar algún comportamiento inaceptable a info@quickcorp.cl.
**Contributors are welcome!**
Puedes contribuir a [QCObjects](https://qcobjects.dev) siguiendo el conjunto de pautas expresadas en el archivo [CONTRIBUTING.md](CONTRIBUTING.md)
# Video Explicativo de QCObjects
Para todos los que no tengan tiempo de leer esto hoy, aquí hay un pequeño video que explica que es QCObjects y que puedes hacer con el.
[](https://www.youtube.com/watch?v=D0rftABPGvQ "QCObjects Explainer Video")
_________________________
# Tabla de Contenidos
<!-- TOC depthFrom:1 depthTo:3 withLinks:1 updateOnSave:1 orderedList:0 -->
- [QCObjects](#qcobjects)
- [Video Explicativo de QCObjects](#video-explicativo-de-qcobjects)
- [Tabla de Contenidos](#tabla-de-contenidos)
- [Principios](#principios)
- [Características principales](#caracter%C3%ADsticas-principales)
- [Características Adoptadas de Apps Web Progresivas (PWA)](#caracter%C3%ADsticas-adoptadas-de-apps-web-progresivas-pwa)
- [Prevenir recursos Render-blocking](#prevenir-recursos-render-blocking)
- [Carga de recursos On-Demand](#carga-de-recursos-on-demand)
- [Lazy-loading de imágenes y componentes (usar atributo lazy-src en vez de src en tag img )](#lazy-loading-de-im%C3%A1genes-y-componentes-usar-atributo-lazy-src-en-vez-de-src-en-tag-img-)
- [Cross Browser Javascript Framework para patrones MVC](#cross-browser-javascript-framework-para-patrones-mvc)
- [Arquitectura de Componentes Dinámicos](#arquitectura-de-componentes-din%C3%A1micos)
- [Especificación ECMA-262](#especificaci%C3%B3n-ecma-262)
- [Copyright](#copyright)
- [Demo](#demo)
- [PWA Live Demo](#pwa-live-demo)
- [Demo Integrada con Foundation](#demo-integrada-con-foundation)
- [Demo Integrada con Materializecss](#demo-integrada-con-materializecss)
- [Demo Usando Raw CSS](#demo-usando-raw-css)
- [Ejemplo de QCObjects usando y manipulando objetos canvas](#ejemplo-de-qcobjects-usando-y-manipulando-objetos-canvas)
- [DevBlog](#devblog)
- [Fork](#fork)
- [Conviértete en Sponsor](#convi%C3%A9rtete-en-sponsor)
- [Revisa el SDK de QCObjects](#revisa-el-sdk-de-qcobjects)
- [Donar](#donar)
- [Instalar](#instalar)
- [Usando QCObjects con Atom:](#usando-qcobjects-con-atom)
- [Usando QCObjects con Visual Studio Code:](#usando-qcobjects-con-visual-studio-code)
- [Instalando con NPM:](#instalando-con-npm)
- [Instalando el docker playground:](#instalando-el-docker-playground)
- [Script de instalación One-Step para Ubuntu 18.x](#script-de-instalaci%C3%B3n-one-step-para-ubuntu-18x)
- [Script de instalación One-Step for macOS](#script-de-instalaci%C3%B3n-one-step-for-macos)
- [Instalar y probar QCObjects en Sistema Operativo Microsoft Windows](#instalar-y-probar-qcobjects-en-sistema-operativo-microsoft-windows)
- [Instalación QCObjects Multi-Cloud](#instalaci%C3%B3n-qcobjects-multi-cloud)
- [DigitalOcean One-Click Droplet](#digitalocean-one-click-droplet)
- [AWS Amazon Machine Images (AMI)](#aws-amazon-machine-images-ami)
- [Amazon Web Services AWS PIB (Private Amazon Machine Image)](#amazon-web-services-aws-pib-private-amazon-machine-image)
- [Usando el código de la versión de desarrollo directo en HTML5](#usando-el-c%C3%B3digo-de-la-versi%C3%B3n-de-desarrollo-directo-en-html5)
- [Usando la versión minificada de código CDN desde jsDelivr](#usando-la-versi%C3%B3n-minificada-de-c%C3%B3digo-cdn-desde-jsdelivr)
- [Usando la última versión no-minificada desde CDN jsDelivr](#usando-la-%C3%BAltima-versi%C3%B3n-no-minificada-desde-cdn-jsdelivr)
- [Usando CDN UNPKG](#usando-cdn-unpkg)
- [Usando CDNJS](#usando-cdnjs)
- [Referencia](#referencia)
- [QC_Object](#qc_object)
- [ComplexStorageCache](#complexstoragecache)
- [asyncLoad](#asyncload)
- [Class](#class)
- [Método QC_Append, append](#m%C3%A9todo-qc_append-append)
- [El método \_super\_](#el-m%C3%A9todo-%5C_super%5C_)
- [New](#new)
- [InheritClass](#inheritclass)
- [ClassFactory](#classfactory)
- [\_Crypt](#%5C_crypt)
- [GLOBAL](#global)
- [CONFIG](#config)
- [Processor](#processor)
- [waitUntil](#waituntil)
- [Package](#package)
- [Import](#import)
- [Export](#export)
- [Cast](#cast)
- [Tag](#tag)
- [Ready](#ready)
- [Component Class](#component-class)
- [Tag HTML Component](#tag-html-component)
- [Controller](#controller)
- [View](#view)
- [VO](#vo)
- [Service](#service)
- [serviceLoader](#serviceloader)
- [JSONService](#jsonservice)
- [ConfigService](#configservice)
- [SourceJS](#sourcejs)
- [SourceCSS](#sourcecss)
- [Effect](#effect)
- [Timer](#timer)
- [Funciones de lista y matemáticas](#funciones-de-lista-y-matem%C3%A1ticas)
- [ArrayList](#arraylist)
- [ArrayCollection](#arraycollection)
- [[ArrayList or Array].unique](#arraylist-or-arrayunique)
- [[ArrayList or Array].table](#arraylist-or-arraytable)
- [[ArrayList or Array].sort](#arraylist-or-arraysort)
- [[ArrayList or Array].sortBy](#arraylist-or-arraysortby)
- [[ArrayList or Array].matrix](#arraylist-or-arraymatrix)
- [[ArrayList or Array].matrix2d](#arraylist-or-arraymatrix2d)
- [[ArrayList or Array].matrix3d](#arraylist-or-arraymatrix3d)
- [range](#range)
- [Array.sum](#arraysum)
- [Array.avg](#arrayavg)
- [Array.min](#arraymin)
- [Array.max](#arraymax)
- [SDK](#sdk)
- [SDK Components](#sdk-components)
- [SDK Controllers](#sdk-controllers)
- [SDK Effects](#sdk-effects)
- [SDK Misc Tools](#sdk-misc-tools)
- [SDK Views](#sdk-views)
- [SDK i18n messages](#sdk-i18n-messages)
- [The QCObjects HTTP2 Built-In Server](#the-qcobjects-http2-built-in-server)
- [Start serving your files with QCObjects](#start-serving-your-files-with-qcobjects)
- [Principals of an N-Tier or Multitier architecture](#principals-of-an-n-tier-or-multitier-architecture)
- [Micro-services Principals](#micro-services-principals)
- [Backend settings in config.json](#backend-settings-in-configjson)
- [Backend routing](#backend-routing)
- [The QCObjects Microservice Class and Package](#the-qcobjects-microservice-class-and-package)
- [Generating a Self-Signed Certificate with QCObjects](#generating-a-self-signed-certificate-with-qcobjects)
- [Working with a Letsencrypt HTTPS certificate, Certbot and QCObjects](#working-with-a-letsencrypt-https-certificate-certbot-and-qcobjects)
- [Quick Start Guide](#quick-start-guide)
- [Quick Start your PWA (Progressive Web App)](#quick-start-your-pwa-progressive-web-app)
- [Quick Start your AMP (Accelerated Mobile Page)](#quick-start-your-amp-accelerated-mobile-page)
- [Start Coding](#start-coding)
- [Step 1: Start creating a main import file and name it like: cl.quickcorp.js. Put it into packages/js/ file directory](#step-1-start-creating-a-main-import-file-and-name-it-like-clquickcorpjs-put-it-into-packagesjs-file-directory)
- [Step 2: Then create some services inhereting classes into the file js/packages/cl.quickcorp.services.js :](#step-2-then-create-some-services-inhereting-classes-into-the-file-jspackagesclquickcorpservicesjs-)
- [Step 3: Now it's time to create the components (cl.quickcorp.components.js)](#step-3-now-its-time-to-create-the-components-clquickcorpcomponentsjs)
- [Step 4: Once you have done the above components declaration, you will now want to code your controllers (cl.quickcorp.controller.js)](#step-4-once-you-have-done-the-above-components-declaration-you-will-now-want-to-code-your-controllers-clquickcorpcontrollerjs)
- [Step 5: To use into the HTML5 code you only need to do some settings between script tags](#step-5-to-use-into-the-html5-code-you-only-need-to-do-some-settings-between-script-tags)
- [QCObjects CLI Tool](#qcobjects-cli-tool)
- [Usage](#usage)
- [Options](#options)
- [Commands](#commands)
- [Use:](#use)
- [ALPHA RISE Startup](#alpha-rise-startup)
<!-- /TOC -->
# Principios
Aquí están Las directrices con lo que QCObjects fue hecho:
0. Deberá escribir en JavaScript para codificar una aplicación JavaScript.
1. Todo es un objeto.
2. Cada objeto tiene una definición.
3. En la interfaz, cualquier objeto puede ir apilado en el DOM o en el Virtual-DOM sin necesidad de redeclarar sus definiciones.
4. Cada objeto tiene un cuerpo.
5. La clase debería ser la definición principal de un objeto.
6. La clase debería ser fácilmente escrita como un objeto.
7. Tu Código debería estar fácilmente organizado en paquetes.
8. Debería ser posible escalar sus aplicaciones a una arquitectura limpia.
9. Un componente es una entidad que tiene un objeto como representación. El contenido de un componente debería ser posible rellenarlo remotamente como localmente. Como objeto el componente tiene cuerpo También y el cuerpo del componente es normalmente una instancia apilada del DOM element.
10. Un componente puede ser adjunto al DOM o separado del el sin afectar a su funcionalidad.
11. Un servicio de llamada puede ser extendido a escalar su funcionalidad.
12. Deberías ser capaz de importar un paquete remotamente.
13. Deberías poder escalar tu código y también controlar tus cambios en el servidor sin hacer llamadas innecesarias a fuentes remotas. No deberías necesitar codificar estos tipos de controles usted mismo.
14. Deberías ser capaz de codificar tu aplicación N-Tier en un solo lenguaje o sintaxis.
15. Deberías ser capaz de aplicar cualquier plantilla que quieras a un componente, no importa la sintaxis o el idioma en el que esta escrito.
16. Si una etiqueta HTML esta ya representada por una instancia de objeto DOM, no deberías necesitar duplicar la defunción de la instancia para representar su contenido.
17. Tu pagina principal HTML debería estar limpia, pero deberías poder enlazar lo que controla el comportamiento de la etiqueta sin afectar la sintaxis del HTML.
18. El orden de ejecución de tu código debe ser fácil de entender y leer desde el codigo y el proceso de renderizado de cada componente debería tener y ejecutar control en cuantas capas necesites.
19.Un patrón en capas(como el MVC o MVCC) debería estar presente para cada componente. No importa si defines cada capa o no.
20. El comportamiento de un componente no debe estar determinado por su proceso de renderizado
21. Es necesario que la pila de componentes se divida en el DOM hacia un árbol subyacente de elementos adjuntos.Entonces ahora existe y se llama Pila anidada de componentes de QCObject.
22. Deberías ser capaz de extender una instancia de componente. Pero deberás ser capaz de controlar su comportamiento dinámico sin afectar a la declaración inicial.
23. Deberías ser capaz de aplicar efectos visuales y animaciones simultaneas de una manera facil a una instancia de elemento DOM.
24. Deberías ser capaz de controlar los efectos visuales y animaciones de CSS como JavaScript sin afectar a su desempeño.
25.Deberías ser capaz de controlar el comportamiento de tu código Into-the-box y out-of-the-box y sobrevivir haciéndolo.
# Características principales
- Plantillas Built-In personalizadas para Progressive Web Apps (PWA) y Accelerated Mobile Pages (AMP)
- Efectos UI revolucionarios.
- Backend de micro-servicios avanzados.
- La simplicidad de un maravilloso diseño de layouts.
- Herramientas CLI completamente re-utilizables.
- Arquitectura orientada a componentes y objetos
- Front-end y back-end juntos en un entorno Full-Stack
- Routing recursivo para componentes.
- Administración de componentes anidados Built-In
- Patron MCV completamente integrado (Model, View, Controller)
- Objetos de datos dinamicos
- Conceptos basados en la arquitectura N-Tier
# Características Adoptadas de Apps Web Progresivas (PWA)
## Prevenir recursos Render-blocking
Para prevenir los recursos Render-blocking , QCObjects ha implementado la función de fabrica [paquete](#Package)
## Carga de recursos On-Demand
Con la arquitectura orientada a los componentes dinámicos, QCObjects renderiza cada recurso visual que esta dentro de un componente, solo cuando el componente se esta construyendo y cada componente esta conectado a un árbol llamado global.componentsStack ese es el que realmente esta apuntando a cada instancia de componente y sus a sus sub componentes. Cada vez que un componente es re-hecho, los recursos visuales están dinámicamente recargados bajo demanda de la manera mas eficiente, así que puedes olvidar esos horribles códigos donde necesitabas controlar el proceso de recarga de los recursos con otros frameworks.
## Lazy-loading de imágenes y componentes (usar atributo lazy-src en vez de src en tag img )
Desde la versión 2.1.251, QCObjects te otorga una forma fácil para el Lazy load de imágenes, usando el ultima estándar para los buscadores.
```html
<img src="img/preloader.svg" lazy-src="img/myrealimage.png"/>
```
En lo anterior, una imagen (ligera) precargada, es usada para ser cargada en la primera instancia y un atributo **lazy-src** es usado para cargar la imagen real después del proceso Lazy load. QCObjects cargara todos las **<img>** etiquetas declaradas dentro de un componente en el lazy mode si tiene un atributo lazy-src, después que un componente es rearmado o cargado. También, QCObjects usara [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) (Cuando este disponible) para determinar ya sea si el lazy-src o la imagen src son visualmente útiles para ser mostradas.
El efecto del Lazy loading es altamente visible solo si la primera vez el PWA es cargado. La próxima vez, la velocidad de carga aumentara significativamente haciendo difícil para el ojo humano ver el resultado. Sin embargo esta característica hará mucho la diferencia en términos de experiencia de usuario, si existen problemas de conexión o las imágenes son muy grandes esta característica es parte de las recomendadas por os escritores de PWA por [Mozzila Developers Network](https://developer.mozilla.org/) un articulo sobre Loadig progresivo. Puedes leer el articulo [here](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Loading)
Si no quieres usar lazy loading para las imágenes, siempre puedes mantener la forma usual de carga no añadiendo el atributo **lazy-src** a la etiqueta **<img>** y usando el tradicional **src**.
# Cross Browser Javascript Framework para patrones MVC
----------------------------------------
[QCObjects](https://qcobjects.dev)Es un framework de Javascript diseñado para hacer todo mas fácil sobre la implementación de los MVC patters en el alcance de pure Javascript. No necesitas utilizar un typescript ni ningún transpiler para que corra. [QCObjects](https://qcobjects.dev). Corre directamente en el buscador y usa pure javascrpt sin ninguna dependencia de código extra. Puedes crear tus propios componentes expresados en objetos nativos reales de Javascript o objetos nativos DOM extendidos para usarlos a tu manera. Puedes también usar QCObjects](https://qcobjects.dev) En conjunto con CSS3 frameworks como [Foundation] (https://foundation.zurb.com), [Bootstrap] (https://getbootstrap.com) Y frameworks de mobil javascript como [PhoneGap] (https://phonegap.com) y OnsenUI (https://onsen.io)

# Arquitectura de Componentes Dinámicos

# Especificación ECMA-262
--------------------------
See
[ECMAScript® 2020 Language Specification](https://tc39.github.io/ecma262/#sec-intro) como referencia.
# Copyright
-----------
Copyright (c) Jean Machuca and [QuickCorp](https://quickcorp.org) <info@quickcorp.cl>
# Demo
--------------
## PWA Live Demo
Mira esta demo en vivo de pure QCObjects basado en aplicación web fronted aquí:
[PWA QCObjects](https://newapp.qcobjects.dev/)
## Demo Integrada con Foundation
A continuación, una demostración en vivo usando componentes de Foundation aquí:
[Demo usando Foundation](https://github.com/QuickCorp/quickobjects_sample1foundation)
## Demo Integrada con Materializecss
Revisa la demostración usando MaterializeCSS aquí:
[Demo Using Materializecss](https://qln.link)
## Demo Usando Raw CSS
Revisa esta demo usando raw CSS aquí:
[Demo Using Raw CSS](https://github.com/QuickCorp/qcobjects_profile_browser)
## Ejemplo de QCObjects usando y manipulando objetos canvas
A continuación el código muestra como QCObjects puede manipular un objeto de lienzo directamente y dentro de componentes
```html
<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
<script type="text/javascript" src="https://qcobjects.dev/QCObjects.js"></script>
<script type="text/javascript">
var canvas1,canvas2,canvas3,container;
CONFIG.set('relativeImportPath','src/');
/**
* Main import sentence.
*/
Import('cl.quickcorp',function (){
/**
* Super Container MyOwnBody
*/
Class('MyOwnBody',HTMLBodyElement,{
customAttr:'custom',
body:document.body // breakes default body element and replace with them
});
/**
* Another custom class definition
*/
Class('MyContainer',HTMLElement,{
width:400,
height:400,
customAttr:'custom attr container'
});
/**
* Another custom class definition
*/
Class('canvas',HTMLCanvasElement,{
customAttr:'custom'
});
/**
* Another custom class definition
*/
Class('MyCanvas2',HTMLCanvasElement,{});
body = New(MyOwnBody); // binds to body
body.css({backgroundColor:'#ccc'});
container = Tag('container')[0].Cast(MyContainer); // cast any javascript dom object to QC_Object class
container.css({backgroundColor:'red'}); // access binding in two directions to dom objects
/**
* Instance a new custom canvas
*/
canvas1 = New(canvas,{
width:100,
height:100,
});
canvas2 = New(canvas,{
width:200,
height:100,
});
canvas3 = New(canvas,{
width:300,
height:50,
});
canvas1.css({backgroundColor:'#000000'}); // like jquery and another style access
canvas1.body.style.backgroundColor='#000000'; // standard javascript style access
canvas2.body.style.backgroundColor='#0044AA'; // standard javascript style access
canvas3.body.style.backgroundColor='green'; // standard javascript style access
canvas1.append(); //append canvas1 to body
canvas2.attachIn('container'); // attach or append to specific tag containers
container.append(canvas3); // append canvas3 to custom tag binding
// canvas1.body.remove(); // remove canvas1 from dom
body.append(canvas3); // append canvas3 to body
// using components
var c1 = New(Component,{'templateURI':'templatesample.html',cached:false});
document.body.append(c1); // appends the c1 to the body
});
</script>
</head>
<body>
<container id="contentLoader" ></container>
</body>
</html>
```
# DevBlog
--------------
el [Official DevBlog of QCObjects](https://devblog.qcobjects.org/) esta alojado en [Hashnode](https://hashnode.com/). El DevBlog esta personalmente escrito por Jean Machuca, el autor de [QCObjects](https://qcobjects.com) Y el esta explicando en detalle como son las mejores practicas y dando los mejores tips y trucos para usar las mas avanzadas características de QCObjects.
# Fork
--------------
Por favor has Fork a este projecto o crea un link a este proyecto en to archivo README.md. Lee el archivo LICENSE.txt antes de usar este código.
# Conviértete en Sponsor
------------------
Si quieres volverte sponsor de este maravilloso proyecto puedes hacerlo [aquí](https://sponsorsignup.qcobjects.dev/)
# Revisa el SDK de QCObjects
----------------------------
Puedes revisar[QCObjects SDK](https://sdk.qcobjects.dev/) y seguir los ejemplos para hacer tus propios componentes destacados.
# Donar
--------------
Si te gustó este código por favor [DONA](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=UUTDBUQHCS4PU&source=url)!
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=UUTDBUQHCS4PU&source=url)
[](https://www.patreon.com/join/qcobjects?)
# Instalar
------------
## Usando QCObjects con Atom:
```shell
> apm install qcobjects-syntax
```
https://atom.io/packages/qcobjects-syntax
## Usando QCObjects con Visual Studio Code:
[](https://marketplace.visualstudio.com/items?itemName=Quickcorp.QCObjects-vscode)
https://marketplace.visualstudio.com/items?itemName=Quickcorp.QCObjects-vscode
## Instalando con NPM:
```shell
> npm install qcobjects-cli -g && npm install qcobjects --save
```

## Instalando el docker playground:
```shell
docker pull -a quickcorp/qcobjects-playground && docker run -it --name qcobjects-playground --rm -it quickcorp/qcobjects-playground
```

## Script de instalación One-Step para Ubuntu 18.x
ATENCIÓN: Haz esto solo en una instalación de Ubuntu 18.x fresca/vacia/actual. No lo haga en un ambiente existente de producción.
Se te pedira permiso sudo grant.
```shell
curl -L https://qcobjects.dev/install_qcobjects_ubuntu18x.sh |sh
```
ATENCIÓN: No somos responsables de el daño en la infraestructura por usar una instalación automatizada de script en una network insegura. Asegúrate de que tus repos y scripts están bajo HTTPS con su certificado valido. Para mejores resultados te recomendamos descargar el script, editarlo para tus necesidades especiales y después ejecútalo en tu maquina local.
## Script de instalación One-Step for macOS
Probado en macOS Catalina 10.15.3
```shell
curl -L https://qcobjects.dev/install_qcobjects_macOS.sh | zsh
```
## Instalar y probar QCObjects en Sistema Operativo Microsoft Windows
1.- Instala la ultima versión de NodeJS para Windows[Aquí](https://nodejs.org/)
2.- Desde el cmd instala qcobjects-cli usando npm
```powershell
npm i qcobjects-cli -g
```
3.- Crea un directorio de para tu proyecto
```powershell
md mynewproject && cd mynewproject
```
4.- Crea una nueva aplicación web progresiva de QCObjects
```powershell
qcobjects create mynewproject --pwa
```

## Instalación QCObjects Multi-Cloud
QCObjects es nativamente soportado por los mas famosos proveedores de nubes. Puedes instalar la mayoría de ellos, preparar y correr todo en un solo paso.
### DigitalOcean One-Click Droplet
Si quieres olvidar apt-get y de configurar la guía, ve directo a desplegar tu proyecto usando una preconfigurada app 1-click incluyendo QCObjects CLI, QCObjects-SDK y QCObjects HTTP2 servidor Built-in. Luego giralo a Droplet VM o a Kubernetes cluster en 60 segundos o menos.
[Crea tu propio Droplet de QCObjects DigitalOcean Aquí](https://marketplace.digitalocean.com/apps/qcobjects)
### AWS Amazon Machine Images (AMI)
Un Amazon Machine Image (AMI) otorga información requerida para lanzar una instancia. Tienes que especificar un AMI cuando quieras lanzar una instancia. Puedes lanzar múltiples instancias para un solo AMI cuando necesites múltiples instancias con la misma configuración. Puedes usar diferentes AMIs para lanzar instancias cuando necesites instancias con diferentes configuraciones.
Un AMI incluye lo siguiente:
- Uno o mas EBS snapshots, o, para instance-store-backed AMIs, una plantilla para la raíz volumen de la instancia(por ejemplo, un sistema operativo, un servidor de aplicaciones y aplicaciones).
- Lanza permisos que controla que cuenta AWS puede usar el AMI para lanzar instancias.
- Un bloqueo de dispositivos mapping que especifica los volúmenes adjuntos a la instancia cuando es lanzada.
[Empieza construyendo QCObjects AMI aquí](https://aws.amazon.com/marketplace/pp/B07YZRH7VB)
### Amazon Web Services AWS PIB (Private Amazon Machine Image)
Imagen privada que te permite construir un nuevo AMI instalando un software AWS Market place en una imagen que tu elijas del AMI disponibles en tu cuenta AWS, esto permite que conocer a mejores especificaciones internas para seguridad, gestiones y cumplimientos. Como con los Marketplace AWS AMIs estándar, cada imagen privada se comprometera a subscripción por el producto instalado y tiene uso de software facturado vía AWS Marketplace.
[Empieza creando tu QCObjects Amazon Private Image aquí](https://aws.amazon.com/marketplace/pp/B07YZRH7VB)
## Usando el código de la versión de desarrollo directo en HTML5
```html
<script type="text/javascript" src="https://qcobjects.dev/QCObjects.js"></script>
```
## Usando la versión minificada de código CDN desde jsDelivr
```html
<script src="https://cdn.jsdelivr.net/npm/qcobjects/QCObjects.min.js"></script>
```
## Usando la última versión no-minificada desde CDN jsDelivr
```html
<script src="https://cdn.jsdelivr.net/npm/qcobjects/QCObjects.js"></script>
```
## Usando CDN UNPKG
```html
<script src="https://unpkg.com/qcobjects@latest/QCObjects.js"></script>
```
## Usando CDNJS
```html
<script src="https://cdnjs.cloudflare.com/ajax/libs/qcobjects/[VERSION]/QCObjects.js"></script>
```
Donde [VERSIÓN] corresponde a la ultima versión usando notaciones numericas, ejemplo: to use version 2.1.420:
```html
<script src="https://cdnjs.cloudflare.com/ajax/libs/qcobjects/2.1.420/QCObjects.js"></script>
```
No necesitas minificar QCObjects, pero si aún quieres usar el codigo minificado puedes hacer esto:
```html
<script src="https://cdnjs.cloudflare.com/ajax/libs/qcobjects/2.1.420/QCObjects.min.js"></script>
```
Otra vez cambia 2.1.420 al numero de la versión que quieras usar.
# Referencia
------------
Aquí están los símbolos y conceptos esenciales de referencia [QCObjects](https://qcobjects.dev)
### QC_Object
Tipos básicos de todos los elementos
### ComplexStorageCache
Con **ComplexStorageCache** puedes manejar el cache de cualquier objeto y subirlo en el storage local.
#### Uso:
```javascript
var cache = new ComplexStorageCache({
index:object.id, // Object Index
load:(cacheController)=>{}, // A function to execute for the first time
alternate: (cacheController)=>{} // The alternate function to execute from the second time the source coude is loaded
});
```
#### Ejemplo:
```javascript
var dataObject = {id:1,
prop1:1,
prop2:2
};
var cache = new ComplexStorageCache({
index: dataObject.id,
load: (cacheController) => {
dataObject = {
id:dataObject.id,
prop1:dataObject.prop1*2, // changing a property value
prop2:dataObject.prop2
};
return dataObject;
},
alternate: (cacheController) => {
dataObject = cacheController.cache.getCached(dataObject.id); // setting dataObject with the cached value
return;
}
});
// Next time you can get the object from the cache
var dataObjectCopyFromCache = cache.getCached(dataObject.id);
console.log(dataObjectCopyFromCache); // will show the very same object value than dataObject
```
### asyncLoad
La función **asyncLoad** carga el código una vez en el modo asyc. Esto es útil para asegurar que el proceso inicial no replica la ejecución y no es recargado después de un código sensible.
#### Uso:
```javascript
asyncLoad(()=>{
// my code here
},args);
// Where args is an array of arguments, it can be the "arguments" special object
```
#### Ejemplo:
```javascript
let doSomething = (arg1,arg2)=>{
asyncLoad((arg1,arg2)=>{
console.log(arg1);
console.log(arg2);
},arguments);
};
doSomething(1,2); // the code of doSomething will be executed once after the rest of asyncLoad queue of functions and before the execution of Ready event.
```
### Class
Esto NO es una clase de definición de ECMAScript 2015 (mira [clase ECMAScript 2015](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes) for reference).
Clase es una función especias que te ayuda a declarar la clase de una manera mas fácil y compatible. Funciona con cross-browser, y esperamos que ECMA pueda adoptar algo similar en el futuro. Para no dejar al Javascript confuso sobre esto, [QCObjects](https://qcobjects.dev) usa "Class" no "class" (note the Camel Case).
#### Uso:
```javascript
Class('MyClassName',MyClassDefinition);
```
Donde **MyClassDefinition** es un objeto junto a el **prototype** de QCObjects
#### Ejemplo:
```javascript
Class('MyClassName',InheritClass,{
propertyName1:0, // just to declare purpose
propertyName2:'',
classMethod1: function (){
// some code here
// note you can use "this" object
return this.propertyName1;
},
classMethod2: function () {
// some code here
return this.propertyName2;
}
});
var newObject = New(MyClassName,{
propertyName1:1, // this initializes the value in 1
propertyName2:"some value"
});
console.log(newObject.classMethod1()); // this will show number 1
console.log(newObject.classMethod2()); // this will show "some value"
```
### Método QC_Append, append
Este es un método especial que hará tu vida mas fácil cuando quieras manipular el **DOM** dinámicamente. Puedes insertar un componente incluso **Component**, a un objeto **QCObjects** o a el elemento **DOM** dentro de otro **HTMLElement**.
##### Uso:
```javascript
[element].append([object or element]);
```
#### Ejemplo:
```javascript
// This will create a QCObjects class named "canvas" extending a HTMLCanvasElement with a customAttr property that has a "custom" value
Class('canvas',HTMLCanvasElement,{
customAttr:'custom'
});
// This will declare an instance canvas1 from the class canvas
let canvas1 = New(canvas,{
width:100,
height:100,
});
// This will append the canvas1 object to the document body
document.body.append(canvas1);
```
### El método \_super\_
Cuando extiendes una clase QCObject desde otra, puedes usar \_super\_ metodo para tener una instancia desde la definición de la clase central.
#### Uso:
```javascript
_super_('MySuperClass','MySuperMethod').call(this,params)
// where this is the current instance and params are method parameters
```
#### Ejemplo:
```javascript
Class('MySuperiorClass',InheritClass,{
propertyName1:0, // just to declare purpose
propertyName2:'',
classMethod1: function (){
// some code here
// note you can use "this" object
return this.propertyName1;
},
});
Class('MyClassName',MySuperiorClass,{
propertyName1:0, // just to declare purpose
propertyName2:'',
classMethod2: function () {
// The next line will execute classMethod1 from MySuperiorClass
// but using the current instance of MyClassName1
return _super_('MySuperiorClass','classMethod1').call(this);
}
});
var newObject = New(MyClassName,{
propertyName1:1, // this initializes the value in 1
propertyName2:"some value"
});
console.log(newObject.classMethod2()); // this will show the number 1
```
### New
Crea una instancia de objeto de una definición de clase de QCObject.
#### Uso:
```javascript
let objectInstance = New(QCObjectsClassName, properties);
// where properties is a single object with the property values
```
NOTA: En las propiedades del objeto puedes usar un solo valor o un captador también pero, solo se ejecutaran una vez.
#### Ejemplo:
```javascript
Class('MyCustomClass',Object);
let objectInstance = New(MyCustomClass,{
prop1:1,
get randomNumber(){ // this getter will be executed once
return Math.random();
}
});
console.log(objectInstance.randomNumber); // it will show console.log(objectInstance.prop1); // it will show number 1
```
### InheritClass
Una sola definición de clase común QCObjects es utilizada.
### ClassFactory
Usa la **ClassFactory** para tener una declaración de clase de fabrica para la clase,
también puedes usar la clase de fabrica desde un paquete o desde la fila apilada.
Para recuperar la clase de fabrica de la clase fila apilada simplemente usa el nombre de la clase llamándola directamente en el código.
#### Ejemplo:
```javascript
/* When you declare MyClass using Class() it is instantly added to the Class queue stack
* and you can get the factory either using ClassFactory() or calling the name MyClass straight in the code
*/
Class('MyClass',{
a:1
})
console.log(MyClass == ClassFactory('MyClass')) // it will show true
```
```javascript
/* On the other hand, ClassFactory() will be so useful when you define a Class into a Package
*/
Package('org.quickcorp.package1',[
Class('MyClass',{
a:1
})
])
console.log(MyClass == ClassFactory('MyClass')) // it will still show true
// The following line will show true as well
console.log(MyClass == ClassFactory('org.quickcorp.package1.MyClass'))
```
```javascript
/* The interesting thing is when you have declared more than one Class using the
* same name MyClass into different packages but with different property default values
* and even properties
*/
Package('org.quickcorp.package1',[
Class('MyClass',{
a:1
})
])
Package('org.quickcorp.package2',[
Class('MyClass',{
a:2,
b:1
})
])
// The last declaration of MyClass will be the one survival in the Class queue
// so the reference MyClass in the code will point to that one
console.log(MyClass == ClassFactory('MyClass')) // it will still show true
// In this case as the MyClass defined in the org.quickcorp.package1 will not be the same
// as the one in the org.quickcorp.package2, but the MyClass in the package2 is the last one
// The following line will show false
console.log(MyClass == ClassFactory('org.quickcorp.package1.MyClass'))
// The following line will show true
console.log(MyClass == ClassFactory('org.quickcorp.package2.MyClass'))
// The following line will show false
console.log(ClassFactory('org.quickcorp.package1.MyClass') == ClassFactory('org.quickcorp.package2.MyClass'))
```
Los ejemplos anteriores están intencionalmente hechos para explicar y mostrar como el alcance de la definición de clase en QCObjects es protejida, llevada y reflejada en una ClassFactory.
Así que vas a querer usar la ClassFactory cuando necesites completar un control sobre el alcance cuando se extienden las Clases.
**Ejemplo**
```javascript
// When normally you extend a Class using the Class queue you do:
Class('MyExtendedClass',MyInheritClass,{
extendedProp1: 'value of prop',
extendedProp2: 2
})
```
```javascript
/* But to protect the scope from misleading by reference, you can asure that MyInheritClass
is the one you want to extend by declaring it into a package and then extend it
*/
Package('org.quickcorp.mypackage1',[
Class('MyInheritClass',{
sourceProp:1
}),
])
// The following code is a definition of MyExtendedClass into a different package
// org.quickcorp.package2
// extending MyInheritClass using ClassFactory to retreive the Class from the source package
// org.quickcorp.mypackage1
Package('org.quickcorp.mypackage2',[
Class('MyExtendedClass',ClassFactory('org.quickcorp.mypackage1.MyInheritClass'),{
extendedProp1: 'value of prop',
extendedProp2: 2
})
])
// this will show the number 1 (as the inherited default value of sourceProp)
console.log(New(MyExtendedClass).sourceProp)
```
### \_Crypt
Con \_Crypt puedes codificar en serie objetos a passphrase
#### Ejemplo (1):
```javascript
var _string = New(_Crypt,{string:'hello world',key:'some encryption md5 key'});
console.log(_string._encrypt());
console.log(_string._decrypt()); // decodes encrypted string to the source
```
#### Ejemplo (2):
```javascript
_Crypt.encrypt('hola mundo','12345678866');
_Crypt.decrypt('nqCelFSiq6Wcpw==','12345678866');
```
### GLOBAL
**GLOBAL** es una clase especial de QCObject para conseguir alancé global. Tiene un conjunto y consigue un método que te ayude a manejar propiedades internas Globales.
#### Ejemplo:
```javascript
GLOBAL.set('globalProperty1','some value in global scope');
var globalProperty1 = GLOBAL.get('globalProperty1');
```
### CONFIG
CONFIG es una clase inteligente que maneja los ajustes generales de tu aplicación. Puedes tener las propiedades ya sea desde config.json o desde la memoria previamente guardado en la llamada set().
#### Uso desde memoria:
1.- En su código inicial, configura los valores iniciales de CONFIG:
```javascript
CONFIG.set('someSettingProperty','some initial value');
```
2.- Luego puede acceder a él desde cualquier parte de su código utilizando el método get:
```javascript
var someSettingProperty = CONFIG.get('someSettingProperty');
```
#### Uso desde config.json:
1.- Necesitas indicar primero que estas usando el archivo config.jso mediante el ajuste "useConfigService" el valor para la verdad.
```javascript
CONFIG.set('useConfigService',true); // using config.json for custom settings config
```
2.-Una vez peparaste el valor anterior QCObjects lo sabra y mirara el siguiente ajuste dentro del archivo config.json en la carpeta basePath de tu aplicación.
#### Uso desde config.json encriptado:
También existe una forma de usar el archivo encriptado config.json con el fin de proteger tus ajustes, robots que pueden robar tu data no protegida desde la aplicación web (como las llaves de arrastre API)
El archivo encriptado json va en https://config.qcobjects.dev, pon tu configuración dominantes y tu contenido config.json. La herramienta encriptará tu json y podrás copiar el contenido incriptado para insertarlo en tu archivo config.json. QCObjects sabrá si la data esta encriptada y tu proceso para decodificar la data sera mas transparente para ti.
#### Propiedades dinámicas de CONFIG
A veces necesitaras establecer el valor de la fuente que no sea estática, como el ENV vars u otras fuentes personalizadas de data dinámica. Para tener valor usando CONFIG de una fuente dinámica tienes que usar un procesador. Existen procesadores comunes predefinidos como $ENV (solo si esta disponible en CLI, Collab o Node) y $config (disponible en todos los ambientes).
Los procesadores son llamados como una meta de valor ya sea en el config.json o en la Clase CONFIG.
```json
// file: config.json
{
"domain":"localhost",
"env1":"$ENV(ENV1)",
"customSettings":{
"value1":"$config(domain)"
}
}
```
```javascript
let value1 = CONFIG.get("customSettings").value1;
// value1 = "localhost";
let env1 = CONFIG.get("env1");
//env1 = (environment variable ENV1)
```
```javascript
// sets the key "api_key" of the CONFIG settings to a dynamic processor $ENV that recovers the value of API_KEY from the environment variables
CONFIG.set("api_key","$ENV(API_KEY)");
let api_key = CONFIG.get("api_key");
// api_key will contain the value of the system API_KEY environment var
// ($ENV processor returns a valid value only on Node.js , QCObjects CLI and QCObjects Collab engine)
```
### Processor
La clase estatica que usa para establecer el procesador personalizado para CONFIG.
#### Uso:
```javascript
Processor.setProcessor(processor)
```
Donde **processor** es el nombre de la función que recibe el argumento del procesador
#### Ejemplo:
Tienes que usar ese valor en tus ajustes de configuración en el valor **serviceURL** pero también necesitas configurar el **host** y los ajustes de **port** usando el valor analizado de esa url. Para analizar el valor de el ambiente SERVICE_URL la variable bajo demanda y rellenarlo con los ajustes de configuración en tu config.json, tu config.json se vera algo así:
```json
// file: config.json
{
"serviceURL":"$ENV(SERVICE_URL)",
"host":"$SERVICE_HOST(SERVICE_URL)",
"port":"$SERVICE_PORT(SERVICE_URL)"
}
```
El **$SERVICE_HOST** y el **$SERVICE_PORT** procesadores no existen. Para definirlos tienes que usar:
```javascript
// execute the next code in your init.js file or before to load the CONFIG settings
let SERVICE_HOST = function (arg){
var processorHandler = this; // to make this always works, do not use arrow functions to define your
let serviceURL = new URL(processorHandler.processors.ENV(arg));
return serviceURL.host;
}
let SERVICE_PORT = function (arg){
var processorHandler = this; // to make this always works, do not use arrow functions to define your
let serviceURL = new URL(processorHandler.processors.ENV(arg));
return serviceURL.port;
}
Processor.setProcessor(SERVICE_HOST);
Processor.setProcessor(SERVICE_PORT);
```
Entonces solo necesita establecer su variable de entorno SERVICE_URL en su shell
Lo siguiente es para los sistemas operativos de Unix/Linux :
```shell
export SERVICE_URL="https://example.com:443/path-to-a-resource/"
```
Y su configuración se cargará dinámicamente de esta manera:
```json
{
"serviceURL":"https://example.com:443/path-to-a-resource/",
"host":"example.com",
"port":"443"
}
```
Y consigue tus valores correspondientes en **CONFIG.get(value)**
### waitUntil
WaitUntil es un ayudante solo en caso de que estés en problemas tratando de correr el código antes de que la condición sea real. El código dentro del waitUntil sera ejecutado una vez.
NOTA: Esto es útil en algunos casos pero no es recomendado para uso excesivo.
#### Uso:
```javascript
waitUntil(()=>{
// the code that will be executed after the condition is true
},()=>{return condition;});
// where condition is what I want to wait for
```
#### Ejemplo:
```javascript
let someVar = 0;
waitUntil(()=>{
console.log('someVar is present');
},()=>{return typeof someVar != 'undefined';});
// where condition is what I want to wait for
```
### Package
Define el paquete de QCObjects y regrésalo.
#### Uso:
```javascript
Package('packageName',[packageContent]);
```
Donde packageContent es una gama de clases de QCObjects. Si solo pasas el packageName param conseguirás el contenido declarado anteriormente.
#### Ejemplo (1):
```javascript
'use strict';
Package('org.quickcorp.main',[
Class('Main',InheritClass,{
propertyName1:'propertyValue1',
}),
Class('MyCustomClass',InheritClass,{
propertyName2:'propertyValue2',
}),
]);
```
#### Ejemplo (2):
```javascript
let mainPackage = Package('org.quickcorp.main'); // this will return the previously declared content of package 'org.quickcorp.main'
// mainPackage[0] will be the Main class definition.
// This is useful for code introspection
```
La técnica de carga de paquetes presente en QCObjects esta basada en una promesa y orientada al alcance. Puedes preguntar si un paquete fue cargado simplemente llamando la función Packege() pasando el nombre del paquete a un argumento.
### Import
Importa un paquete desde otro archivo JS.
#### Uso:
```javascript
Import (packagename,[ready],[external]);
```
Donde el packagename es el nombre del paquete, listo es una función que podrá ser ejecutada después de que el paquete es cargado y el externo es un valor bolean que indica si el archivo JS esta en el mismo origen o esta desde otro recurso externo.
#### Ejemplo (1):
```javascript
Import('org.quickcorp.main');
```
El código anterior intentara importar un archivo JS llamado 'org.quickcorp.main.js' desde un camino especifico en el valor de ajuste **relativeImportPath** presente en tu **CONFIG**. Dentro del archivo tienes que definir el paquete mediante el uso del paquete ('org.quickcorp.main',[Class1, Class2...])
#### Ejemplo (2):
```javascript
Import('org.quickcorp.main',function (){
console.log('remote import is loaded');
},true);
```
El código anterior esta vez esta tratando de cargar en el mismo paquete usando el camino externo mediante el **remoteImportsPath** ajustes presentes en tu **CONFIG**
NOTA: En los dos ejemplos anteriores no necesitas usar o especificar la extensión ".js". Esto esta usado por defecto y no puede ser cambiado por razones de seguridad.
### Export
Pon un símbolo(barra o función) en el alcance global.
#### Uso:
```javascript
Export('name of symbol');
```
#### Ejemplo:
```javascript
(()=>{
// this is local scope
let someFunction = (someLocalParam)=>{
console.log(someLocalParam);
};
Export(someFunction); // now, someFunction is in the top level scope.
})();
// this is the top level scope
someFunction('this works');
```
### Cast
Usa el método Cast de cualquier elemento DOM para obtener las propiedades de otro tipo de objeto. Esto es útil para trasformar un tipo objeto a otro otorgándole mas flexibilidad a tu código.
#### Uso:
```javascript
let resultObject = [element or QCObjects type].Cast(objectToCastFrom);
```
Donde objectToCastFrom es un objeto para obtener propiedades desde y poner el objeto resultante regresado por el cast.
#### Ejemplo:
```javascript
Class('MyOwnClass',{
prop1:'1',
prop2:2
});
let obj = document.createElement('div').Cast(MyOwnClass);
```
El código anterior creara un objeto DOM y lo emitirá a MyOwnClass. Gracias a que MyOwnClass es un tipo clase de QCObject el objeto ahora tendrá propiedades prop1 y prop2 y ahora sera una instancia de objeto QCObject con una propiedad del cuerpo que es un elemento div.
### Tag
Etiquetar es una función útil para seleccionar cualquier elemento DOM usando selectores. Etiquetar siempre regresa a la lista de elementos que puedas mapear, ordenar y filtrar como cualquier otra lista.
#### Uso:
```javascript
var listOfElements = Tag(selector);
```
Donde el selector es un DOM selector de respuestas.
#### Ejemplo:
```html
<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
<script type="text/javascript" src="https://qcobjects.dev/QCObjects.js"></script>
</head>
<body>
<div class="myselector">
<p>Hello world</p>
</div>
<script>
Ready(()=>{
Tag('.myselector > p').map((element)=>{
element.innerHTML = 'Hello world! How are you?';
});
});
</script>
</body>
</html>
```
En el código anterior el elemento párrafo fue creado dentro de un div con una clase css llamada myselector mediante html y luego es modificada dinámicamente usando la función etiqueta de QCObject. Si estas familiarizado con un framework selector query te encantara este.
### Ready
Asigna una función para correr después de que todo esta hecho mediante QCObject y después del evento window.onload. Úsalo para prevenir un error de objeto DOM 'indefinido'.
#### Uso:
```javascript
Ready(()=>{
// My init code here!
});
```
Tenga en cuenta que si define los componentes dinámicos mediante el uso de una etiqueta "componente" en HTML, el contenido dinámico no activara eventos listos. Para atrapar el código cada vez que se carga un componente dinámico usa un método decontrolado hecho en su lugar.
Usaras implementación lista principalmente cuando quieras implementar QCObjects en conjunto con otro framework que lo necesite.
### Component Class
Un tipo clase de QCObject por componentes.
#### Propiedades
**[Component].domain**
Regresa una cadena con el dominio de tu aplicación. Se establece automáticamente por QCObjects al momento de cargar.
**[Component].basePath**
Regresa una cadena con un camino url base de tu aplicación. Se establece automáticamente por QCObjects al moment