xonecode 0.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.
Files changed (187) hide show
  1. package/README.md +167 -0
  2. package/dist/agent/authEnDisco.js +56 -0
  3. package/dist/agent/authEnDisco.js.map +1 -0
  4. package/dist/agent/configEnDisco.js +109 -0
  5. package/dist/agent/configEnDisco.js.map +1 -0
  6. package/dist/agent/crearProyecto.js +34 -0
  7. package/dist/agent/crearProyecto.js.map +1 -0
  8. package/dist/agent/entorno.js +124 -0
  9. package/dist/agent/entorno.js.map +1 -0
  10. package/dist/agent/guionizado.js +53 -0
  11. package/dist/agent/guionizado.js.map +1 -0
  12. package/dist/agent/instantanea.js +129 -0
  13. package/dist/agent/instantanea.js.map +1 -0
  14. package/dist/agent/interrupts.js +83 -0
  15. package/dist/agent/interrupts.js.map +1 -0
  16. package/dist/agent/mensajes.js +24 -0
  17. package/dist/agent/mensajes.js.map +1 -0
  18. package/dist/agent/modelos.js +42 -0
  19. package/dist/agent/modelos.js.map +1 -0
  20. package/dist/agent/normalizar.js +20 -0
  21. package/dist/agent/normalizar.js.map +1 -0
  22. package/dist/agent/perfiles.js +103 -0
  23. package/dist/agent/perfiles.js.map +1 -0
  24. package/dist/agent/proyecto.js +107 -0
  25. package/dist/agent/proyecto.js.map +1 -0
  26. package/dist/agent/puente.js +142 -0
  27. package/dist/agent/puente.js.map +1 -0
  28. package/dist/agent/resumenDeTool.js +48 -0
  29. package/dist/agent/resumenDeTool.js.map +1 -0
  30. package/dist/agent/skills.js +65 -0
  31. package/dist/agent/skills.js.map +1 -0
  32. package/dist/agent/textoDeTool.js +113 -0
  33. package/dist/agent/textoDeTool.js.map +1 -0
  34. package/dist/agent/turnoReal.js +173 -0
  35. package/dist/agent/turnoReal.js.map +1 -0
  36. package/dist/agent/verificador.js +65 -0
  37. package/dist/agent/verificador.js.map +1 -0
  38. package/dist/agent/xoneAgent.js +106 -0
  39. package/dist/agent/xoneAgent.js.map +1 -0
  40. package/dist/bin.js +9 -0
  41. package/dist/bin.js.map +1 -0
  42. package/dist/cli/aprobar.js +82 -0
  43. package/dist/cli/aprobar.js.map +1 -0
  44. package/dist/cli/config.js +133 -0
  45. package/dist/cli/config.js.map +1 -0
  46. package/dist/cli/consola.js +346 -0
  47. package/dist/cli/consola.js.map +1 -0
  48. package/dist/cli/describe.js +53 -0
  49. package/dist/cli/describe.js.map +1 -0
  50. package/dist/cli/doctor.js +45 -0
  51. package/dist/cli/doctor.js.map +1 -0
  52. package/dist/cli/main.js +520 -0
  53. package/dist/cli/main.js.map +1 -0
  54. package/dist/cli/markdown.js +90 -0
  55. package/dist/cli/markdown.js.map +1 -0
  56. package/dist/cli/run.js +164 -0
  57. package/dist/cli/run.js.map +1 -0
  58. package/dist/cli/spinner.js +89 -0
  59. package/dist/cli/spinner.js.map +1 -0
  60. package/dist/cli/stdio.js +193 -0
  61. package/dist/cli/stdio.js.map +1 -0
  62. package/dist/cli/tema.js +40 -0
  63. package/dist/cli/tema.js.map +1 -0
  64. package/dist/cli/verify.js +62 -0
  65. package/dist/cli/verify.js.map +1 -0
  66. package/dist/core/bitacora.js +30 -0
  67. package/dist/core/bitacora.js.map +1 -0
  68. package/dist/core/config.js +236 -0
  69. package/dist/core/config.js.map +1 -0
  70. package/dist/core/contextos.js +56 -0
  71. package/dist/core/contextos.js.map +1 -0
  72. package/dist/core/deps.js +51 -0
  73. package/dist/core/deps.js.map +1 -0
  74. package/dist/core/diff.js +79 -0
  75. package/dist/core/diff.js.map +1 -0
  76. package/dist/core/esqueleto.js +366 -0
  77. package/dist/core/esqueleto.js.map +1 -0
  78. package/dist/core/events.js +2 -0
  79. package/dist/core/events.js.map +1 -0
  80. package/dist/core/modelos.js +85 -0
  81. package/dist/core/modelos.js.map +1 -0
  82. package/dist/core/notify.js +106 -0
  83. package/dist/core/notify.js.map +1 -0
  84. package/dist/core/ports.js +114 -0
  85. package/dist/core/ports.js.map +1 -0
  86. package/dist/core/turno.js +127 -0
  87. package/dist/core/turno.js.map +1 -0
  88. package/dist/vendor/hitl.js +103 -0
  89. package/dist/vendor/hitl.js.map +1 -0
  90. package/dist/vendor/skillLoaders/catalog.js +74 -0
  91. package/dist/vendor/skillLoaders/catalog.js.map +1 -0
  92. package/dist/vendor/tokenTracking.js +58 -0
  93. package/dist/vendor/tokenTracking.js.map +1 -0
  94. package/package.json +41 -0
  95. package/skills/xone-debugging/SKILL.md +52 -0
  96. package/skills/xone-debugging/references/faq.md +561 -0
  97. package/skills/xone-debugging/references/troubleshooting-y-glosario.md +429 -0
  98. package/skills/xone-development/SKILL.md +105 -0
  99. package/skills/xone-development/references/anti-patrones.md +94 -0
  100. package/skills/xone-development/references/css/atributos-por-categoria.md +509 -0
  101. package/skills/xone-development/references/css/buenas-practicas-y-parser.md +419 -0
  102. package/skills/xone-development/references/css/dinamicos-cascada-y-componentes.md +550 -0
  103. package/skills/xone-development/references/css/patrones-material-y-temas.md +1140 -0
  104. package/skills/xone-development/references/css/propiedades-y-herencia.md +885 -0
  105. package/skills/xone-development/references/css/selectores-unidades-colores.md +840 -0
  106. package/skills/xone-development/references/datos/appdata-referencia-ampliada.md +457 -0
  107. package/skills/xone-development/references/datos/appdata.md +611 -0
  108. package/skills/xone-development/references/datos/http-sqlmanager-y-crypto.md +720 -0
  109. package/skills/xone-development/references/datos/http.md +366 -0
  110. package/skills/xone-development/references/datos/oauth2-y-replica.md +156 -0
  111. package/skills/xone-development/references/device/biometria-imagedrawing-y-otros.md +544 -0
  112. package/skills/xone-development/references/device/objetos-de-dispositivo.md +583 -0
  113. package/skills/xone-development/references/device/systemsettings-referencia-ampliada.md +396 -0
  114. package/skills/xone-development/references/device/systemsettings-y-permisos.md +342 -0
  115. package/skills/xone-development/references/fundamentos/conceptos-clave.md +695 -0
  116. package/skills/xone-development/references/fundamentos/configuracion-app-xml-ini-mappings.md +668 -0
  117. package/skills/xone-development/references/fundamentos/errores-comunes.md +312 -0
  118. package/skills/xone-development/references/fundamentos/navegacion-convenciones-y-primer-proyecto.md +576 -0
  119. package/skills/xone-development/references/fundamentos/plataforma-y-anatomia-de-proyecto.md +387 -0
  120. package/skills/xone-development/references/indice-completo.md +77 -0
  121. package/skills/xone-development/references/javascript/coleccion-error-y-usuario.md +260 -0
  122. package/skills/xone-development/references/javascript/debugging-y-best-practices.md +245 -0
  123. package/skills/xone-development/references/javascript/metodos-de-los-controles.md +556 -0
  124. package/skills/xone-development/references/javascript/metodos-nativos-de-la-vista.md +114 -0
  125. package/skills/xone-development/references/javascript/motor-js-y-contexto-de-ejecucion.md +319 -0
  126. package/skills/xone-development/references/javascript/objeto-ai-llm-en-dispositivo.md +358 -0
  127. package/skills/xone-development/references/javascript/objetos-creables-a-m.md +527 -0
  128. package/skills/xone-development/references/javascript/objetos-creables-n-z.md +385 -0
  129. package/skills/xone-development/references/javascript/patrones-criticos-seguridad-y-rendimiento.md +595 -0
  130. package/skills/xone-development/references/javascript/patrones-de-navegacion-datos-y-codigo.md +751 -0
  131. package/skills/xone-development/references/javascript/patrones-de-ui-voz-integracion-y-seguridad.md +701 -0
  132. package/skills/xone-development/references/javascript/plantillas-y-funciones-utilitarias.md +647 -0
  133. package/skills/xone-development/references/javascript/self-y-dataobject.md +449 -0
  134. package/skills/xone-development/references/javascript/singletons-globales.md +361 -0
  135. package/skills/xone-development/references/javascript/ui-catalogo-de-metodos.md +464 -0
  136. package/skills/xone-development/references/javascript/ui-gps-camara-y-multimedia.md +506 -0
  137. package/skills/xone-development/references/javascript/ui-navegacion-mensajes-y-vista.md +422 -0
  138. package/skills/xone-development/references/resumen-js-datos-dispositivo.md +80 -0
  139. package/skills/xone-development/references/resumen-xml-y-css.md +74 -0
  140. package/skills/xone-development/references/tipos-de-prop.md +28 -0
  141. package/skills/xone-development/references/xml-ui/asfilter-visibilidad-eventos-y-macros.md +576 -0
  142. package/skills/xone-development/references/xml-ui/atributos-coll-group-frame.md +235 -0
  143. package/skills/xone-development/references/xml-ui/atributos-method-macro-script-event-app.md +244 -0
  144. package/skills/xone-development/references/xml-ui/atributos-prop.md +439 -0
  145. package/skills/xone-development/references/xml-ui/contents-y-macros.md +392 -0
  146. package/skills/xone-development/references/xml-ui/errores-comunes-xml.md +245 -0
  147. package/skills/xone-development/references/xml-ui/estructura-y-nodo-coll.md +326 -0
  148. package/skills/xone-development/references/xml-ui/eventos-ciclo-de-vida-e-interaccion.md +704 -0
  149. package/skills/xone-development/references/xml-ui/eventos-sistema-login-y-personalizados.md +944 -0
  150. package/skills/xone-development/references/xml-ui/layouts-herencia-y-buenas-practicas.md +618 -0
  151. package/skills/xone-development/references/xml-ui/mapas.md +685 -0
  152. package/skills/xone-development/references/xml-ui/mappings-y-colecciones-separadas.md +148 -0
  153. package/skills/xone-development/references/xml-ui/nodos-group-y-frame.md +666 -0
  154. package/skills/xone-development/references/xml-ui/patrones-de-pantalla.md +643 -0
  155. package/skills/xone-development/references/xml-ui/prop-atributos-y-condiciones.md +298 -0
  156. package/skills/xone-development/references/xml-ui/prop-tipos-basicos.md +493 -0
  157. package/skills/xone-development/references/xml-ui/prop-tipos-combos-y-controles.md +664 -0
  158. package/skills/xone-development/references/xml-ui/prop-tipos-listas-y-mapas.md +412 -0
  159. package/skills/xone-plan-builder/SKILL.md +183 -0
  160. package/skills/xone-plan-builder/agents/openai.yaml +5 -0
  161. package/skills/xone-plan-builder/references/TASKS-FORMAT.md +132 -0
  162. package/skills/xone-project-generator/SKILL.md +111 -0
  163. package/skills/xone-project-generator/references/canonical-sizes.md +292 -0
  164. package/skills/xone-project-generator/references/colecciones-base.md +16 -0
  165. package/skills/xone-project-generator/references/convenciones-de-nombres.md +16 -0
  166. package/skills/xone-project-generator/references/ejemplos-por-sector-y-prohibiciones.md +140 -0
  167. package/skills/xone-project-generator/references/fase-3-estilos-css.md +597 -0
  168. package/skills/xone-project-generator/references/fase-6-colecciones.md +762 -0
  169. package/skills/xone-project-generator/references/fase-7-asfilter-e-integraciones.md +142 -0
  170. package/skills/xone-project-generator/references/fase-7-entidades-y-estructura-de-pantalla.md +494 -0
  171. package/skills/xone-project-generator/references/fase-7-plantilla-consola.md +477 -0
  172. package/skills/xone-project-generator/references/fase-7-plantillas-de-pantalla.md +302 -0
  173. package/skills/xone-project-generator/references/fase-7-viewmodes-graficos-y-listas.md +681 -0
  174. package/skills/xone-project-generator/references/fase-7-viewmodes-mapa-y-calendario.md +479 -0
  175. package/skills/xone-project-generator/references/fases-0-2-analisis-y-modelo-de-datos.md +350 -0
  176. package/skills/xone-project-generator/references/fases-10-12-readmes-y-validacion.md +194 -0
  177. package/skills/xone-project-generator/references/fases-4-5-estructura-y-configuracion.md +587 -0
  178. package/skills/xone-project-generator/references/fases-8-9-eventos-y-javascript.md +861 -0
  179. package/skills/xone-project-generator/references/flujo-de-generacion.md +67 -0
  180. package/skills/xone-project-generator/references/plantillas-estandar.md +98 -0
  181. package/skills/xone-project-generator/references/tamanos-canonicos.md +49 -0
  182. package/skills/xone-review/SKILL.md +189 -0
  183. package/skills/xone-spec-builder/SKILL.md +235 -0
  184. package/skills/xone-spec-builder/agents/openai.yaml +5 -0
  185. package/skills/xone-spec-builder/references/ADR-FORMAT.md +55 -0
  186. package/skills/xone-spec-builder/references/CONTEXT-FORMAT.md +42 -0
  187. package/skills/xone-spec-builder/references/PLAN-FORMAT.md +120 -0
@@ -0,0 +1,695 @@
1
+ # XOne — Conceptos clave
2
+
3
+ > Fuente: `xone/v2/xone-help-docs/topics/01-xone-fundamentals.md` §6. Referencia de la skill; el índice está en [../../SKILL.md](../../SKILL.md).
4
+
5
+ Contenido: §6 colecciones, DataObject, props, prefijo ##PREF##, macros del sistema, códigos de error y sintaxis JavaScript soportada por el motor
6
+
7
+ ---
8
+
9
+ ## 6. Conceptos Clave
10
+
11
+ ### 6.1 Colecciones
12
+
13
+ Una **coleccion** en XOne es el concepto más fundamental. Combina tres roles que en desarrollo web suelen estar separados:
14
+
15
+ 1. **Tabla de base de datos**: Define la estructura de datos (campos, tipos)
16
+ 2. **Pantalla/Vista**: Define como se presenta la información al usuario
17
+ 3. **Formulario**: Define como el usuario interactua con los datos
18
+
19
+ #### Tipos de Colecciones
20
+
21
+ | Tipo | Tiene tabla en BD? | Uso típico | Ejemplo |
22
+ |------|-------------------|------------|---------|
23
+ | **Con datos** (SQL) | Si | Almacenar registros persistentes | `Tareas`, `Clientes`, `Productos` |
24
+ | **Especial** (sin tabla) | No | Pantallas de menu, entrada, login | `EntradaApp`, `MenuPrincipal` |
25
+ | **Dependiente** | Depende del padre | Datos hijos de otra coleccion | `LineasPedido` (dentro de `Pedidos`) |
26
+
27
+ #### Coleccion con datos (persistente)
28
+
29
+ Se identifica porque tiene los atributos `sql` y `objname`:
30
+
31
+ ```xml
32
+ <coll name="Clientes"
33
+ sql="SELECT * FROM ##PREF##Clientes"
34
+ objname="Clientes"
35
+ updateobj="Clientes"
36
+ loadall="true">
37
+ <!-- Esta coleccion TIENE tabla en la BD: gen_clientes -->
38
+ </coll>
39
+ ```
40
+
41
+ El atributo `objname` es la clave: le dice a XOne que esta coleccion necesita una tabla en la base de datos. Sin `objname`, la coleccion solo existe en memoria.
42
+
43
+ #### Coleccion especial (sin tabla)
44
+
45
+ Se identifica porque tiene `special="true"` y NO tiene `objname`:
46
+
47
+ ```xml
48
+ <coll name="EntradaApp" title="Bienvenido"
49
+ special="true" notab="true" show-toolbar="false">
50
+ <!-- Esta coleccion NO tiene tabla, es solo una pantalla -->
51
+ </coll>
52
+ ```
53
+
54
+ #### Colecciones base vs colecciones adicionales
55
+
56
+ | Aspecto | Colecciones Base | Colecciones Adicionales |
57
+ |---------|-----------------|----------------------|
58
+ | **Cuales son** | `Empresas`, `Usuarios` | Todas las demas |
59
+ | **Donde se definen** | `mappings.xne` | Archivos `.xne` separados |
60
+ | **Son obligatorias?** | Si, siempre | Solo las que necesite el proyecto |
61
+ | **Campos obligatorios** | Si (ver sección 4.3) | Los que defina el desarrollador |
62
+
63
+ #### Herencia entre colecciones (`inherits`)
64
+
65
+ Una coleccion puede heredar la estructura (grupos, frames, props y eventos) de otra usando el atributo `inherits` en el nodo `<coll>`. La hija sobrescribe los elementos del padre que tengan el mismo `name`, y conserva el resto.
66
+
67
+ ```xml
68
+ <coll name="groupsFixed" special="true">
69
+ <!-- Header y footer comunes... -->
70
+ </coll>
71
+
72
+ <coll name="PantallaX" inherits="groupsFixed" special="true">
73
+ <!-- Hereda todo de groupsFixed y añade lo propio -->
74
+ </coll>
75
+ ```
76
+
77
+ Uso típico: scaffolding visual compartido (header/footer/navegación) definido una sola vez en una coll `special="true"` y reutilizado por todas las pantallas que lo necesiten. Soporta cadenas (A → B → C) pero NO herencia multiple. Para la referencia completa y `<include-layout>`, ver topics/02d-xml-layouts-herencia.md, sección 10.
78
+
79
+ ### 6.2 Objetos de Datos (DataObject)
80
+
81
+ Un **DataObject** (u "objeto de datos") es una instancia individual de una coleccion. Si la coleccion es una tabla, el DataObject es una fila.
82
+
83
+ #### Acceso al objeto actual: `self`
84
+
85
+ Dentro de cualquier script de una coleccion, `self` referencia al DataObject actual:
86
+
87
+ ```javascript
88
+ // Leer un campo del objeto actual
89
+ let nombre = self.NOMBRE;
90
+ let codigo = self.CODIGO;
91
+
92
+ // Escribir un campo
93
+ self.NOMBRE = "Nuevo nombre";
94
+ self.ESTADO = "COMPLETADO";
95
+
96
+ // Ambas sintaxis son validas:
97
+ let valor1 = self.MAP_CAMPO; // Notacion punto
98
+ let valor2 = self["MAP_CAMPO"]; // Notacion corchetes (util con nombres dinamicos)
99
+ ```
100
+
101
+ #### Métodos disponibles del DataObject
102
+
103
+ ```javascript
104
+ // Guardar cambios en la BD
105
+ self.save();
106
+
107
+ // Obtener la coleccion propietaria
108
+ let coll = self.getOwnerCollection();
109
+ let nombreColl = coll.getName();
110
+
111
+ // Obtener contenidos embebidos (colecciones hijas)
112
+ let comentarios = self.getContents("@Comentarios");
113
+
114
+ // Cargar datos desde JSON
115
+ self.loadFromJson('{"NOMBRE": "Test", "CODIGO": 1}');
116
+
117
+ // Exportar a JSON
118
+ let jsonObj = self.toJson();
119
+ let jsonStr = self.toJsonString();
120
+ ```
121
+
122
+ #### Concepto de Campos MAP_
123
+
124
+ El prefijo `MAP_` es una **señal al framework** que indica: *"este prop NO es una columna de la tabla BD, no intentes persistirlo"*. Cuando el framework lee un `<prop>` cuyo `name` empieza por `MAP_`, lo excluye de los `INSERT` y `UPDATE` que se generan contra la tabla apuntada por `objname`. Por eso **`MAP_loquesea` no existe ni debe existir como columna en la base de datos**.
125
+
126
+ **Regla de oro:** Si el valor del prop NO proviene de una columna de la tabla de `objname`, su `name` **debe empezar por `MAP_`**.
127
+
128
+ ##### Los tres casos en los que se usa MAP_
129
+
130
+ **Caso 1 — Campos que vienen de un JOIN en el SQL de la coll**
131
+
132
+ Cuando la coleccion hace un `LEFT JOIN` a otra tabla para mostrar una descripción, el alias del campo enlazado debe empezar por `MAP_`:
133
+
134
+ ```xml
135
+ <coll name="Pedidos"
136
+ sql="SELECT t1.*,
137
+ c.NOMBRE AS MAP_NOMBRECLIENTE,
138
+ c.TELEFONO AS MAP_TELEFONOCLIENTE
139
+ FROM ##PREF##Pedidos t1
140
+ LEFT OUTER JOIN ##PREF##Clientes c ON t1.IDCLIENTE=c.ID"
141
+ objname="pedidos"
142
+ updateobj="pedidos"
143
+ progid="ASData.CASBasicDataObj">
144
+
145
+ <group name="General" id="1">
146
+ <!-- FK normal: SI es columna de la tabla Pedidos -->
147
+ <prop name="IDCLIENTE" type="N" visible="7" mapcol="Clientes" mapfld="ID" />
148
+
149
+ <!-- Campos del JOIN: NO son columnas de Pedidos, llevan MAP_ -->
150
+ <prop name="MAP_NOMBRECLIENTE" type="T" visible="7" locked="true" fieldsize="150" />
151
+ <prop name="MAP_TELEFONOCLIENTE" type="T" visible="7" locked="true" fieldsize="20" />
152
+ </group>
153
+ </coll>
154
+ ```
155
+
156
+ **Caso 2 — Campos enlazados via `linkedto` (combos/lookups)**
157
+
158
+ El patron combo en XOne usa dos props: uno oculto que guarda el ID (es columna BD, sin `MAP_`) y otro visible que muestra la descripción obtenida del lookup (no es columna BD, lleva `MAP_`):
159
+
160
+ ```xml
161
+ <!-- Prop oculto: guarda el ID del tipo. SI es columna de la tabla -->
162
+ <prop name="IDTIPO" type="N" visible="0"
163
+ mapcol="TiposProducto" mapfld="ID" />
164
+
165
+ <!-- Prop visible: muestra la descripción obtenida del lookup. NO es columna -->
166
+ <prop name="MAP_TIPO_DESC" type="T" visible="1"
167
+ title="Tipo de producto"
168
+ linkedto="IDTIPO"
169
+ linkedfield="DESCRIPCION"
170
+ showinline="true" />
171
+ ```
172
+
173
+ **Caso 3 — Props puramente visuales (sin origen de datos)**
174
+
175
+ Cualquier prop que no representa un dato guardable también debe llevar `MAP_`: etiquetas, botones, valores calculados en runtime, estados de UI, buscadores temporales, imágenes decorativas, etc.
176
+
177
+ | Uso | Ejemplo | Tipo típico |
178
+ |-----|---------|-------------|
179
+ | Etiquetas / títulos | `MAP_TITULO`, `MAP_SUBTITULO` | `L` (alias legacy: `TL`) |
180
+ | Botones | `MAP_BTN_GUARDAR`, `MAP_BTN_CANCELAR` | `B` |
181
+ | Valores calculados | `MAP_TOTAL`, `MAP_SUBTOTAL_IVA` | `N2`, `F` |
182
+ | Estados de UI | `MAP_TAB`, `MAP_MODO`, `MAP_SELECCIONADO` | `T`, `N`, `NC` |
183
+ | Buscadores / filtros | `MAP_BUSQUEDA`, `MAP_FILTRO` | `T` |
184
+ | Imágenes decorativas | `MAP_LOGO` | `IMG` |
185
+ | Callbacks / objetos JS | `MAP_CALLBACK` | `O` |
186
+
187
+ ```xml
188
+ <!-- Etiqueta (no se guarda) -->
189
+ <prop name="MAP_TITULO" type="L" title="Gestion de Pedidos" class="textoTitulo" />
190
+
191
+ <!-- Botón (no se guarda) -->
192
+ <prop name="MAP_BTN_GUARDAR" type="B" visible="1" title="Guardar"
193
+ method="executenode(guardar)" />
194
+
195
+ <!-- Total calculado en runtime (no se guarda) -->
196
+ <prop name="MAP_TOTAL" type="N2" visible="1" locked="true" title="Total" />
197
+
198
+ <!-- Buscador temporal (no se guarda) -->
199
+ <prop name="MAP_BUSQUEDA" type="T" visible="1" title="Buscar" onchange="Refresh" />
200
+ ```
201
+
202
+ ##### Mecanismo interno y consecuencias
203
+
204
+ - El framework **excluye** los `MAP_*` de los `INSERT` y `UPDATE` contra `objname`.
205
+ - El valor vive **solo en memoria** dentro del DataObject (`self`), durante la vida de la pantalla.
206
+ - Se lee y escribe normalmente desde JavaScript: `self.MAP_CAMPO`, `self["MAP_CAMPO"]` o `self.getValue("MAP_CAMPO")`.
207
+ - Se puede referenciar en `disablevisible`, en macros de CSS/XML (`##FLD_MAP_xxx##`), y como destino de `ui.refresh("MAP_xxx")`.
208
+ - Los `MAP_` **no son de solo lectura**: se les puede asignar valor desde JS, desde `<action name="setval">`, desde un `linkedto`, etc. El `locked="true"` de los ejemplos es una decisión de UI, no una consecuencia de ser MAP_.
209
+
210
+ ##### Comparativa: con y sin MAP_
211
+
212
+ ```xml
213
+ <!-- Este campo SI se guarda en BD (es columna de la tabla) -->
214
+ <prop name="NOMBRE" type="T" visible="7" fieldsize="100" />
215
+
216
+ <!-- Este campo NO se guarda en BD (prefijo MAP_ -> el framework lo excluye) -->
217
+ <prop name="MAP_BTN_EDITAR" type="B" visible="7" title="Editar" />
218
+ ```
219
+
220
+ ##### Anti-patrones (errores típicos)
221
+
222
+ | Error | Consecuencia |
223
+ |-------|--------------|
224
+ | Poner `MAP_` a un campo que SI esta en la tabla BD | El framework no lo persiste: el dato se pierde al guardar |
225
+ | Omitir `MAP_` en un alias de JOIN | El framework intenta hacer UPDATE de esa columna: error SQL porque no existe |
226
+ | Omitir `MAP_` en el prop visible de un combo con `linkedto` | El framework intenta guardar la descripción como columna: error SQL |
227
+ | Poner `MAP_` a una etiqueta `L`/`TL` que se conecta a un campo BD | La etiqueta no refleja el dato persistido correctamente |
228
+ | Declarar una columna `MAP_LOQUESEA` en la tabla SQL | No se usa nunca: el framework nunca escribe en ella |
229
+
230
+ ### 6.3 Propiedades (Props)
231
+
232
+ Las propiedades (`<prop>`) son el elemento fundamental de XOne. Tienen un **rol dual**:
233
+
234
+ 1. **Campo de datos**: Define un dato (nombre, tipo, tamaño)
235
+ 2. **Elemento visual**: Define como se ve y se interactua con ese dato
236
+
237
+ #### Sistema de Tipos
238
+
239
+ Cada propiedad tiene un `type` que determina tanto el tipo de dato como el control visual:
240
+
241
+ | Type | Nombre | Dato | Control Visual | Ejemplo |
242
+ |------|--------|------|---------------|---------|
243
+ | `T` | Texto | String | Campo de texto editable | Nombres, descripciones |
244
+ | `L` | Texto Label | String | Texto de solo lectura — forma preferida. Sin `title`, muestra el valor del campo | Títulos, etiquetas |
245
+ | `TL` | Texto Label (alias legacy) | String | Alias legacy de `L`: mismo control. | Equivalente a `L` |
246
+ | `N` | Numérico | Integer | Campo numérico | IDs, cantidades |
247
+ | `N2` | Numérico 2 dec | Real (2 decimales) | Campo decimal | Precios, porcentajes |
248
+ | `N6` | Numérico 6 dec | Real (6 decimales) | Campo decimal preciso | Coordenadas GPS |
249
+ | `B` | Botón | No persiste | Botón de acción | Guardar, Cancelar |
250
+ | `IMG` | Imagen | Ruta (String) | Visor/captura de imagen | Fotos, logos |
251
+ | `NC` | Checkbox | Integer (0/1) | Toggle/checkbox | Activo si/no |
252
+ | `D` | Fecha | String (fecha) | Selector de fecha | Fecha nacimiento |
253
+ | `DT` | Fecha/Hora | String (datetime) | Selector fecha + hora | Timestamps |
254
+ | `X` | Password | String | Campo enmascarado | Contrasenas |
255
+ | `Z` | Zona/Content | No persiste | Lista embebida | Listas dentro de pantalla |
256
+ | `DR` | Firma/Dibujo | Ruta (String) | Canvas de firma o dibujo libre | Firma digital |
257
+
258
+ > Para la tabla completa de tipos y sus variantes, consulta 02 - Estructura XML y Colecciones.
259
+
260
+ #### Bitmask de Visibilidad
261
+
262
+ El atributo `visible` usa un **mapa de bits** para controlar donde se muestra cada propiedad:
263
+
264
+ | Valor | Significado | Cuando se usa |
265
+ |-------|-------------|---------------|
266
+ | `0` | Oculto | Campos internos, IDs, ROWIDs |
267
+ | `1` | Solo en modo edición | Campos que solo se ven al editar un registro |
268
+ | `2` | Solo en modo lista | Campos que solo se ven en el listado |
269
+ | `4` | Solo en contents | Campos visibles dentro de listas embebidas |
270
+ | `7` | Visible en todos los modos | Campos que siempre deben mostrarse (1+2+4=7) |
271
+
272
+ **Ejemplo práctico:**
273
+
274
+ ```xml
275
+ <!-- Oculto: el usuario nunca lo ve, pero se usa internamente -->
276
+
277
+ <!-- Solo visible al editar un registro individual -->
278
+ <prop name="DESCRIPCION_DETALLADA" type="T" visible="1" />
279
+
280
+ <!-- Solo visible en la lista de registros -->
281
+ <prop name="RESUMEN" type="L" visible="2" />
282
+
283
+ <!-- Visible en todos los contextos -->
284
+ <prop name="NOMBRE" type="T" visible="7" />
285
+ ```
286
+
287
+ #### Visibilidad Condicional
288
+
289
+ Además del bitmask estático, se puede controlar la visibilidad de forma dinámica con `disablevisible`:
290
+
291
+ ```xml
292
+ <!-- Se oculta si MAP_TIPO es igual a 0 -->
293
+ <prop name="MAP_CAMPO_EXTRA" type="T"
294
+ disablevisible="MAP_TIPO=0" />
295
+
296
+ <!-- Se oculta si MAP_MODO es vacio -->
297
+ <frame name="frmAvanzado"
298
+ disablevisible="MAP_MODO=''" >
299
+ <!-- Contenido avanzado -->
300
+ </frame>
301
+ ```
302
+
303
+ ### 6.4 Prefix PREF
304
+
305
+ El **prefijo** es un concepto fundamental en XOne que conecta las colecciones con las tablas de la base de datos.
306
+
307
+ #### Que es?
308
+
309
+ El prefijo (configurado en `app.xml` con el atributo `prefix`) se antepone al nombre de cada tabla en la base de datos. Por defecto, el prefijo es `"gen"`.
310
+
311
+ #### Como funciona?
312
+
313
+ ```
314
+ prefix = "gen"
315
+ +
316
+ objname = "Tareas"
317
+ =
318
+ Tabla en BD: gen_tareas
319
+ ```
320
+
321
+ #### La macro ##PREF##
322
+
323
+ En las consultas SQL de las colecciones, se usa la macro `##PREF##` para que el sistema inserte automáticamente el prefijo con el guion bajo:
324
+
325
+ ```xml
326
+ <!-- Esto: -->
327
+ <coll name="Tareas" sql="SELECT * FROM ##PREF##Tareas" ...>
328
+
329
+ <!-- Se convierte en tiempo de ejecución en: -->
330
+ <!-- SELECT * FROM gen_tareas -->
331
+ ```
332
+
333
+ #### Por que usar ##PREF## en vez de escribir "gen_" directamente?
334
+
335
+ Porque el prefijo puede cambiar entre proyectos. Si un cliente tiene prefijo `"inv"`, la misma consulta generara:
336
+
337
+ ```
338
+ SELECT * FROM inv_Tareas
339
+ ```
340
+
341
+ Sin necesidad de modificar ningun archivo `.xne`.
342
+
343
+ > **Error común:** Olvidar `##PREF##` en las consultas SQL. Si escribes `SELECT * FROM Tareas`, la consulta fallara porque la tabla real se llama `gen_tareas`.
344
+
345
+ ### 6.5 Macros del Sistema
346
+
347
+ XOne proporciona macros que se resuelven en tiempo de ejecución. Se identifican por estar entre dobles `##`:
348
+
349
+ #### Macros de Base de Datos
350
+
351
+ | Macro | Descripción | Ejemplo de uso |
352
+ |-------|-------------|----------------|
353
+ | `##PREF##` | Prefijo de tablas + guion bajo | `sql="SELECT * FROM ##PREF##Tareas"` |
354
+ | `##ENTID##` | ID de la empresa actual | `filter="IDEMPRESA=##ENTID##"` |
355
+ | `##USERID##` | ID del usuario logueado | `filter="ID_USUARIO=##USERID##"` |
356
+
357
+ #### Macros de Aplicación
358
+
359
+ | Macro | Descripción | Ejemplo de uso |
360
+ |-------|-------------|----------------|
361
+ | `##VERSION##` | Versión de la app (definida en `<app versión="...">`) | `title="Versión ##VERSION##"` |
362
+ | `##FRAME_VERSION##` | Versión del framework XOne | `title="Framework ##FRAME_VERSION##"` |
363
+ | `##APP##` | Ruta de la carpeta de la aplicación en el dispositivo | `path="##APP##\icons\imagen.png"` |
364
+ | `##LOGIN_LASTUSER##` | Último usuario que hizo login | Pre-rellenar campo de login |
365
+
366
+ #### Macros de Dispositivo
367
+
368
+ | Macro | Descripción | Ejemplo de uso |
369
+ |-------|-------------|----------------|
370
+ | `##DEVICEID##` | Identificador único del dispositivo | `filter="DEVICE=##DEVICEID##"` |
371
+ | `##DEVICE_MODEL##` | Modelo del dispositivo | `title="Modelo: ##DEVICE_MODEL##"` |
372
+ | `##DEVICE_OS##` | Sistema operativo del dispositivo (`"android"` o `"ios"`) | `value="MyApp_##DEVICE_OS##"` |
373
+
374
+ Las macros de dispositivo se pueden leer también desde JavaScript:
375
+
376
+ ```javascript
377
+ var so = appData.getGlobalMacro("##DEVICE_OS##");
378
+ var deviceId = appData.getGlobalMacro("##DEVICEID##");
379
+ var modelo = appData.getGlobalMacro("##DEVICE_MODEL##");
380
+ ```
381
+
382
+ #### Cerrar pantalla / cerrar aplicación
383
+
384
+ Formas correctas desde JavaScript:
385
+
386
+ ```javascript
387
+ // Cerrar la pantalla actual y volver a la anterior
388
+ ui.getView(self).exit();
389
+
390
+ // Cerrar completamente la aplicación
391
+ appData.exit();
392
+ ```
393
+
394
+ **Nota sobre código heredado:** En proyectos antiguos puede aparecer el patrón `appData.failWithMessage(-11888, "##EXIT##")` (con la macro `##EXIT##` y el código `-11888`) para cerrar la pantalla. Sigue funcionando, pero la forma preferida es `ui.getView(self).exit()`.
395
+
396
+ #### Macros de Fecha/Hora
397
+
398
+ | Macro | Descripción | Formato |
399
+ |-------|-------------|---------|
400
+ | `##NOW##` | Fecha y hora actual del sistema | Depende de la configuración |
401
+ | `##NOW_DATE##` | Fecha actual | `dd/MM/yyyy` |
402
+ | `##NOW_TIME##` | Hora actual | `HH:mm:ss` |
403
+
404
+ #### Macros de Campo (`##FLD_CAMPO##`)
405
+
406
+ Las macros `##FLD_CAMPO##` se resuelven al valor actual del campo especificado. Son extremadamente útiles para crear interfaces dinámicas:
407
+
408
+ | Uso | Descripción | Ejemplo |
409
+ |-----|-------------|---------|
410
+ | Filtros de contents | Filtrar datos hijos por campo del padre | `filter="ID_PADRE=##FLD_ID##"` |
411
+ | Colores dinámicos | Cambiar colores según un campo | `bgcolor="##FLD_MAP_COLOR##"` |
412
+ | Textos dinámicos | Mostrar texto variable en atributos | `title="##FLD_MAP_TITULO##"` |
413
+ | Imágenes dinámicas | Cambiar imagen según un campo | `img="##FLD_MAP_ICONO##"` |
414
+
415
+ ```xml
416
+ <!-- Color de fondo dinámico basado en un campo -->
417
+ <prop name="MAP_LABEL" type="L"
418
+ bgcolor="##FLD_MAP_COLOR1##"
419
+ forecolor="##FLD_MAP_COLOR2##" />
420
+
421
+ <!-- Imagen dinámica basada en un campo -->
422
+ <prop name="BTORDENAR" type="B"
423
+ img="##FLD_MAP_BTORDEN##"
424
+ imgsel="##FLD_MAP_BTORDENCLICK##" />
425
+
426
+ <!-- Filtro de contents con campo del padre -->
427
+ <contents name="@Detalles" src="Detalles"
428
+ filter="ID_PADRE=##FLD_ID##" />
429
+
430
+ <!-- Color dinámico en CSS de frame -->
431
+ .frmsuperior {
432
+ bgcolor: ##FLD_MAP_COLORACTIVO##;
433
+ }
434
+ ```
435
+
436
+ #### Ejemplo de uso combinado de macros
437
+
438
+ ```xml
439
+ <!-- Macro en consulta SQL -->
440
+ <coll name="MisTareas"
441
+ sql="SELECT * FROM ##PREF##Tareas WHERE ID_USUARIO = ##USERID##">
442
+
443
+ <!-- Macro en evento create para mostrar version -->
444
+ <create>
445
+ <action name="setval" field="MAP_VERSION"
446
+ value="Versión ##VERSION## - Framework ##FRAME_VERSION##" />
447
+ </create>
448
+
449
+ <!-- Macro de campo para color dinámico -->
450
+ <prop name="MAP_INDICADOR" type="L"
451
+ bgcolor="##FLD_MAP_COLOR_ESTADO##" />
452
+ ```
453
+
454
+ #### Macros de Animación
455
+
456
+ XOne tiene animaciones predefinidas accesibles via macros. Las más comunes:
457
+
458
+ | Macro | Efecto |
459
+ |-------|--------|
460
+ | `##ALPHA_IN##` / `##ALPHA_OUT##` | Aparecer / Desaparecer (fade) |
461
+ | `##ZOOM_IN##` / `##ZOOM_OUT##` | Zoom de entrada / salida |
462
+ | `##LEFT_IN##` / `##LEFT_OUT##` | Entrar / salir desde la izquierda |
463
+ | `##RIGHT_IN##` / `##RIGHT_OUT##` | Entrar / salir desde la derecha |
464
+ | `##TOP_IN##` / `##BOTTOM_IN##` | Entrar desde arriba / abajo |
465
+ | `##PUSH_IN##` / `##PUSH_OUT##` | Empujar hacia arriba / abajo |
466
+ | `##PUSH_DOWN_IN##` / `##PUSH_DOWN_OUT##` | Empujar hacia abajo (entrada / salida) |
467
+ | `##SLIDE_DOWN_IN##` / `##SLIDE_UP_OUT##` | Deslizamiento hacia abajo / arriba |
468
+
469
+ ```javascript
470
+ // Mostrar grupo 2 con animacion fade
471
+ ui.showGroup(2, "##ALPHA_IN##", 200, "##ALPHA_OUT##", 200);
472
+ ```
473
+
474
+ ```xml
475
+ <!-- Animacion en frames -->
476
+ <frame name="frmDetalle"
477
+ animation-in="##RIGHT_IN##"
478
+ animation-out="##LEFT_OUT##"
479
+ animation-in-delay="250"
480
+ animation-out-delay="250" />
481
+
482
+ <!-- Animacion en colecciones especiales -->
483
+ <coll name="EspecialMenu" special="true"
484
+ animation-in="##RIGHT_IN##"
485
+ animation-out="##LEFT_OUT##">
486
+ ```
487
+
488
+ > Para la lista completa de macros de animación y ejemplos avanzados, consulta 05 - Eventos, Patrones y FAQ.
489
+
490
+ ### 6.6 Códigos de Error
491
+
492
+ XOne utiliza códigos de error numéricos especificos para controlar el flujo de la aplicación. Los dos códigos más importantes son:
493
+
494
+ | Código | Significado | Uso |
495
+ |--------|------------|-----|
496
+ | `-8100` | Campos obligatorios faltantes / validación | `appData.failWithMessage(-8100, "mensaje")` |
497
+ | `-11888` | Código heredado para cerrar pantalla con la macro `##EXIT##` (forma preferida hoy: `ui.getView(self).exit()`) | `appData.failWithMessage(-11888, "##EXIT##")` |
498
+
499
+ #### Uso del código -8100 (Validación)
500
+
501
+ El código `-8100` se usa para interrumpir una operación cuando faltan datos obligatorios o una validación no se cumple. Muestra un mensaje al usuario y cancela la acción en curso:
502
+
503
+ ```javascript
504
+ // Validar antes de guardar
505
+ function validarFormulario() {
506
+ if (!self.NOMBRE || self.NOMBRE === "") {
507
+ appData.failWithMessage(-8100, "El campo Nombre es obligatorio");
508
+ return false;
509
+ }
510
+ if (!self.EMAIL || self.EMAIL === "") {
511
+ appData.failWithMessage(-8100, "El campo Email es obligatorio");
512
+ return false;
513
+ }
514
+ return true;
515
+ }
516
+ ```
517
+
518
+ #### Cerrar pantalla / aplicación (control de flujo)
519
+
520
+ Formas correctas desde JavaScript:
521
+
522
+ ```javascript
523
+ // Salir de la pantalla actual (volver atrás)
524
+ ui.getView(self).exit();
525
+
526
+ // Salir completamente de la aplicación
527
+ appData.exit();
528
+ ```
529
+
530
+ **Código heredado:** Algunos proyectos antiguos usan `appData.failWithMessage(-11888, "##EXIT##")` para cerrar la pantalla. Sigue funcionando, pero las formas de arriba son preferidas.
531
+
532
+ #### Verificación de errores después de operaciones
533
+
534
+ Después de operaciones como `save()`, se puede verificar si ocurrio un error:
535
+
536
+ ```javascript
537
+ self.save();
538
+ if (appData.error().getNumber() != 0) {
539
+ ui.showToast("Error: " + appData.error().getDescription());
540
+ appData.error().clear();
541
+ }
542
+ ```
543
+
544
+ | Método | Descripción |
545
+ |--------|-------------|
546
+ | `appData.error().getNumber()` | Devuelve el código numérico del último error (0 = sin error) |
547
+ | `appData.error().getDescription()` | Devuelve la descripción textual del error |
548
+ | `appData.error().clear()` | Limpia el estado de error actual |
549
+
550
+ ### 6.7 Sintaxis JavaScript soportada por el motor
551
+
552
+ El motor JavaScript de XOne está basado en un **fork de Mozilla Rhino** fuertemente parcheado en Java 17, con backports selectivos: soporta **ES5 completo + buena parte de ES6+** (incluyendo `class` y `Promise`). No es ES2015 completo. Conocer qué piezas concretas funcionan evita errores en tiempo de parseo o de ejecución.
553
+
554
+ #### Sintaxis ES6+ SÍ disponible
555
+
556
+ | Característica ES6+ | Notas |
557
+ |---------------------|-------|
558
+ | `let` / `const` | Funcionan con su semántica de *block scope*. |
559
+ | Arrow functions `() => {}` | Funcionan, incluido el binding léxico de `this`. |
560
+ | Destructuring `var {a, b} = obj` y de parámetros `function f({x, y})` | Funciona. |
561
+ | `for...of` | Sobre `String`, `Array` y arrays-like. NO funciona sobre generators del fork (que son estilo legacy SpiderMonkey, ver fila siguiente). |
562
+ | Generadores con `yield` | Funcionan. El parser acepta dos sintaxis: (a) función normal con `yield` en el cuerpo (detección retroactiva, estilo legacy), y (b) la sintaxis explícita `function*` / `*method()` dentro de class. Ambas equivalentes. **Runtime estilo SpiderMonkey legacy**: `gen.next()` devuelve el valor directamente (no `{value, done}`) y lanza `StopIteration` al terminar. `for...of` NO los itera; usar `try { while (true) v = iter.next(); ... } catch (e) {}`. |
563
+ | `Symbol` / `Symbol.iterator` | Iteración estándar sobre nativos. |
564
+ | `class` ES6+ | Declaraciones, expresiones, `extends`, `super`, `static`, getters/setters, computed keys (`[expr]() {}`), **field declarations** (`field = expr;` / `static field = expr;`), **generator methods** (`*method()` / `static *method()`). Implementado vía desugar a `function` + `prototype`. NO soporta: private fields (`#name`), static blocks, `new.target`. Ver sección dedicada en este archivo. |
565
+ | `Promise` (custom, ES2024-compatible) | API completa: constructor, `resolve`, `reject`, `all`, `allSettled`, `race`, `any` (con `AggregateError`-like), `withResolvers`. Instancia: `.then`, `.catch`, `.finally`, `.status`. Implementación custom en el módulo `xonejavascript_lib/objects/promises/Promise`. Limitaciones: no hay microtask scheduling real (callbacks despachan en threads); asimilación de thenables solo para Promise nativos (no objetos genéricos con `.then`). |
566
+ | Métodos modernos de `String` | `padStart`, `padEnd`, `replaceAll`, `matchAll`, `at`, `trimStart`, `trimEnd`, `includes`, `startsWith`, `endsWith`, `repeat`, `normalize`, `codePointAt`, `fromCodePoint`, `String.raw` (forma con objeto manual), `isWellFormed`, `toWellFormed` — todos los del estándar hasta ES2024. |
567
+ | Métodos modernos de `Array` | `map`, `filter`, `reduce`, `forEach`, `find`, `findIndex`, `includes`, `some`, `every` — disponibles desde ES5/ES6. |
568
+ | Typed arrays | `Int8Array`, `Uint8Array`, `Int16Array`, `Uint16Array`, `Int32Array`, `Uint32Array`, `Float32Array`, `Float64Array`, `ArrayBuffer`. |
569
+ | `JSON.parse()` / `JSON.stringify()` | Estándar. |
570
+
571
+ #### Sintaxis ES6+ NO disponible
572
+
573
+ | Característica ES6+ | Por qué falla | Alternativa en XOne |
574
+ |---------------------|--------------|---------------------|
575
+ | **Template literals** `` `${var}` `` | El lexer no reconoce el carácter backtick (`` ` ``) — *illegal character*. | Concatenación `"texto " + var` |
576
+ | `async` / `await` | Palabras reservadas — parse error. | Callbacks o `Promise` custom (sí soportado, ver arriba). |
577
+ | `import` / `export` | No hay sistema de módulos. | `<include>` en `app.xml`, `appData.loadIncludeFile()` |
578
+ | Spread/rest `...args` | No implementado. | Usar `arguments` o `apply(thisArg, argsArray)` |
579
+ | Default parameters `function f(x=1)` | No implementado. | `function f(x){ if (x===undefined) x = 1; ... }` |
580
+ | Computed property names en object literals `{[k]: v}` | El parser no acepta la sintaxis dentro de `{}`. **SÍ** la acepta dentro de cuerpos de clase (`class { [k]() {} }`). | Object literal: crear vacío + asignar `var o = {}; o[k] = v;` |
581
+ | Shorthand props `{a, b}` (sin destructuring) | No implementado en object literals. | `{a: a, b: b}` |
582
+ | Optional chaining `?.` / nullish coalescing `??` | No implementados. | Chequeos manuales: `obj && obj.x`, `x !== undefined ? x : default` |
583
+ | Private fields `#name` en clase | No implementado (necesita runtime con WeakMap-like scoping). | Convención: prefijo `_`, e.g. `this._x`. |
584
+ | Static blocks `static { ... }` en clase | No implementado. | Sentencias `ClassName.x = ...;` justo después de la clase. |
585
+ | `new.target` dentro de constructores | No implementado. | Convención manual (e.g. `if (!(this instanceof Foo)) ...`). |
586
+
587
+ #### Sintaxis ES5 (base, siempre disponible)
588
+
589
+ | Característica | Notas |
590
+ |----------------|-------|
591
+ | `var` | Function scope. |
592
+ | Funciones declarativas `function nombre() {}` | Estándar. |
593
+ | `try / catch / finally` | Estándar. |
594
+ | `Math`, `Date`, `RegExp` | Globales estándar. |
595
+ | `console.{log,info,debug,warn,error,trace,assert,group,groupCollapsed,groupEnd,time,timeLog,timeEnd,count,countReset,dir,dirxml,clear,table}` | API `console` completa (WHATWG-like) con varargs y formato `%s/%d/%i/%f/%o/%O/%j/%%`. |
596
+
597
+ #### Ejemplo comparativo
598
+
599
+ ```javascript
600
+ // INCORRECTO - sintaxis que NO funciona en XOne
601
+ var template = `Hola ${nombre}`; // template literal: parse error
602
+ function saludo(nombre = "anon") { } // default params: parse error
603
+ function f(...rest) { } // rest params: parse error
604
+ var obj = {a, b}; // shorthand props: parse error
605
+ var obj2 = {[k]: 1}; // computed keys en object literal: parse error
606
+ var v = obj?.x; // optional chaining: parse error
607
+
608
+ // CORRECTO - sintaxis válida en XOne
609
+ var template = "Hola " + nombre;
610
+ function saludo(nombre) { if (nombre === undefined) nombre = "anon"; }
611
+ var obj = {a: a, b: b};
612
+ var obj2 = {}; obj2[k] = 1;
613
+ var v = obj && obj.x;
614
+
615
+ // SÍ funciona: let/const, arrow functions, destructuring, class, Promise,
616
+ // generadores, métodos modernos de String y Array
617
+ let saludar = (nombre) => "Hola " + nombre;
618
+ const MAX = 10;
619
+ let items = lista.map(i => i.nombre);
620
+ let [a, b] = [1, 2]; // destructuring
621
+ "5".padStart(3, "0"); // "005"
622
+ "a-b-c".replaceAll("-", "+"); // "a+b+c"
623
+ "abc".at(-1); // "c"
624
+
625
+ class Persona { // class declarations
626
+ edad = 0; // field declaration (instance)
627
+ static contador = 0; // field declaration (static)
628
+ constructor(nombre) {
629
+ this.nombre = nombre;
630
+ Persona.contador++;
631
+ }
632
+ saludar() { return "Hola, soy " + this.nombre; }
633
+ static crear(n) { return new Persona(n); }
634
+ *iterFields() { yield this.nombre; yield this.edad; } // generator method
635
+ }
636
+ class Empleado extends Persona { // extends + super
637
+ constructor(nombre, rol) {
638
+ super(nombre);
639
+ this.rol = rol;
640
+ }
641
+ saludar() { return super.saludar() + " (" + this.rol + ")"; }
642
+ }
643
+ var e = new Empleado("Juan", "dev");
644
+ e.saludar(); // "Hola, soy Juan (dev)"
645
+
646
+ new Promise((resolve, reject) => { // Promise ES2024
647
+ setTimeout(() => resolve(42), 100);
648
+ }).then(v => console.log(v)) // .then funciona
649
+ .catch(err => console.error(err)) // .catch funciona (ya no es .Catch)
650
+ .finally(() => console.log("listo")); // .finally también
651
+
652
+ Promise.all([p1, p2]).then(([a, b]) => {}); // estáticos completos
653
+ Promise.allSettled([p1, p2]);
654
+ Promise.any([p1, p2]);
655
+ const { promise, resolve, reject } = Promise.withResolvers();
656
+ ```
657
+
658
+ #### APIs de navegador NO disponibles
659
+
660
+ XOne no ejecuta JavaScript en un navegador. Las siguientes APIs **no existen**:
661
+
662
+ | API NO disponible | Alternativa XOne |
663
+ |-------------------|-----------------|
664
+ | `document.getElementById()` | `ui.getView(self)` o `getControl("X")` |
665
+ | `window` / `window.location` / `window.history` | `ui.openEditView(...)`, `ui.getView(self).exit()` |
666
+ | `localStorage` / `sessionStorage` | `appData.setGlobalMacro` / `appData.getGlobalMacro` |
667
+ | `XMLHttpRequest()` | `$http.get/post/...` (idiomático) o `fetch(url, init)` (ver tabla siguiente) |
668
+ | `navigator.geolocation` | `ui.startGps({nodeName: "..."})` / `new GpsTools()` |
669
+ | `alert()` / `confirm()` / `prompt()` | `ui.msgBox()` / `ui.showToast()` |
670
+ | `async` / `await` (palabras reservadas, parse error) | Callbacks o `Promise` (sí soportado vía implementación custom — ver tabla siguiente). |
671
+
672
+ #### APIs WHATWG/Node SÍ disponibles (implementación custom XOne)
673
+
674
+ Compatible con la semántica de la spec, registrado en `RhinoJavascriptEngine.addNativeJavascriptObjects`:
675
+
676
+ | API | Notas |
677
+ |-----|-------|
678
+ | `console.{log,info,debug,warn,error,trace,assert,group,groupCollapsed,groupEnd,time,timeLog,timeEnd,count,countReset,dir,dirxml,clear,table}` | Varargs y formato `%s/%d/%i/%f/%o/%O/%j/%%`. |
679
+ | `fetch(input, init?)` | Devuelve `Promise<Response>`. Soporta `method`, `headers`, `body` (string / `URLSearchParams` / `ArrayBuffer` / typed array), `signal`. **NO** soporta `Request` como primer arg, body `FormData`/`Blob`/`ReadableStream`, ni cancelación in-flight real (el `AbortSignal` solo rechaza el Promise; la red sigue en background). Ignora `mode/credentials/cache/redirect/referrer/integrity/keepalive`. |
680
+ | `Response` | `status`, `ok`, `headers`, `url`, `text()`, `json()`, `arrayBuffer()`, `clone()`. |
681
+ | `Headers` | Case-insensitive, multi-valor con `, ` (regla WHATWG). |
682
+ | `AbortController` / `AbortSignal` | `signal.aborted`, `abort(reason)`, hereda de `EventTarget`. |
683
+ | `setTimeout` / `clearTimeout` / `setInterval` / `clearInterval` / `queueMicrotask` | Tiempos en **ms** (semántica spec). El patrón XOne idiomático sigue siendo `ui.executeActionAfterDelay(node, segundos)` para un disparo único integrado con la UI, pero `setTimeout` con `(fn, ms)` también es válido. |
684
+ | `Promise` | ES2024 casi completo. Estáticos: `resolve`, `reject`, `all`, `allSettled`, `race`, `any`, `withResolvers`. Instancia: `.then`, `.catch`, `.finally`, `.status` (`"pending"`/`"fulfilled"`/`"rejected"`). Limitación: no hay microtask scheduling real; asimilación de thenables solo para instancias de `Promise`. |
685
+ | `URL` / `URLSearchParams` | Constructores estilo WHATWG. |
686
+ | `EventTarget` | `addEventListener`, `removeEventListener`, `dispatchEvent`, opción `once`. |
687
+ | `TextEncoder` (UTF-8) / `TextDecoder` (UTF-8/16/Latin-1/ASCII + fallback `Charset.forName`) | |
688
+ | `performance.now()` / `performance.timeOrigin` | |
689
+ | `atob` / `btoa` | WHATWG, Latin-1. |
690
+ | `structuredClone` | Detección de ciclos; soporta Date/RegExp/Array/objeto/ArrayBuffer/typed arrays. |
691
+ | `DOMParser` / `XMLSerializer` | |
692
+ | `globalThis` | Auto-referencia al scope global. |
693
+ | `crypto`, `clipboard`, `deviceInfo`, `systemSettings`, `packageManager`, `biometricsManager`, … | Singletons XOne; ver tópico 06. |
694
+
695
+ > Para más detalles sobre buenas prácticas de JavaScript en XOne, consulta 03 - Guía de API JavaScript.