FiveLenguaje AI Fusion
SpaceFive · la demo oficial de Five

Un lenguaje.
Un binario.
Toda la web.

SpaceFive es un framework web escrito solo en Five y con todo incluido. HTTP, WebSocket, PostgreSQL, bcrypt, AES, idiomas: el propio runtime se encarga de todo. Sin Node, sin FFI, sin servidor ORM. Un único binario estático que habla directamente con Postgres, con tres aplicaciones reales funcionando encima ahora mismo.

—
activos registrados
—
valor total
—
personas en nómina
1
binario estático
01 — DEMOS EN VIVO

Tres aplicaciones, un mismo framework,
una misma estética.

Cada clic lo atiende un handler de Five: actualizaciones parciales hipermedia, formularios renderizados en el servidor, exportación a CSV, subida de fotos y eventos en tiempo real.

02 — SI VIENES DE xBASE O HARBOUR

Este lenguaje ya lo sabes.
Solo ha cambiado la pantalla.

Si has programado en Clipper, FoxPro o Harbour, una página de SpaceFive se lee como un diálogo que has escrito cien veces. Todos los ejemplos de abajo son reales: el widget de la derecha lo acaba de dibujar el código de la izquierda, en esta misma petición.

Un menú — MENU … ENDMENU
MENU hMenu MENUBAR
   MENUITEM "Assets"      ACTION "/assets"
   MENUITEM "People"      ACTION "/people"
   MENUITEM "+ New asset" ACTION "/assets/new" GOLD
ENDMENU
cHtml := MENU_HTML( hMenu )
generado en esta petición

La sintaxis de FiveWin, tal cual. MENU_HTML() devuelve el marcado; el aspecto lo decide el skin.

Cifras clave — DASHBOARD … STAT
hStat := DB_ONE( cAssetStats, {} )

DASHBOARD hDash
   STAT "Total assets"   VALUE hStat[ "n" ] GOLD
   STAT "Total value"    VALUE Money( hStat[ "total" ], "USD" ) GOLD
   STAT "Active"         VALUE hStat[ "active" ] OK
   STAT "In maintenance" VALUE hStat[ "maint" ] WARN
ENDDASHBOARD
cHtml := DASH_HTML( hDash )
generado en esta petición

Una consulta y cuatro líneas STAT. GOLD, OK y WARN son los colores; las cifras llegan en vivo desde PostgreSQL.

Total assets
14
Total value
$66,745
Active
12
In maintenance
1
Un browse — TABLE … COLUMN
aRows := DB_QUERY( cFirstEmployees, {} )

TABLE hList OF aRows LINK "/people/:id"
   COLUMN "name"       HEADER "Employee" THUMB "photo" SUB "emp_no"
   COLUMN "position"   HEADER "Position"
   COLUMN "status"     HEADER "Status" BADGE
   COLUMN "salary"     HEADER "Salary" MONEY CURRENCY "currency" RIGHT
ENDTABLE
cHtml := TABLE_HTML( hList )
generado en esta petición

Un TBrowse para la web: una COLUMN por campo, THUMB, BADGE, MONEY y RIGHT dicen cómo mostrarla, y con LINK cada fila se vuelve clicable.

EmployeePositionStatusSalary
Tarjetas con foto — GALLERY … CARD
GALLERY hCards OF aRows LINK "/people/:id"
   CARD PHOTO "photo"  INITIALS "name"
   CARD BADGE "status"
   CARD TAG   "position"
   CARD TITLE "name"
   CARD META  "department"
   CARD VALUE "salary" CURRENCY "currency"
ENDGALLERY
cHtml := GALLERY_HTML( hCards )
generado en esta petición

CARD coloca cada campo en su sitio de la tarjeta: foto, badge, etiqueta, título, nota, importe. La tarjeta en sí es un único archivo HTML dentro del skin.

Un formulario — FORM … GET … COMBO
FORM hForm ACTION "/people" OF hReq
   GET   "emp_no" LABEL "Employee no." VALUE "E-2001"
   GET   "name"   LABEL "Name"
   COMBO "status" LABEL "Status" VALUE "active" ITEMS aStatuses
   GET   "salary" LABEL "Salary (annual)" VALUE 90000
   BUTTON "Save" GOLD
   LINK   "Cancel" ACTION "/"
ENDFORM
cHtml := FORM_HTML( hForm )
generado en esta petición

El @ SAY … GET de toda la vida, en el navegador. El token CSRF viaja dentro del formulario y, al pulsar Save, se crea un empleado de verdad.

Cancel

De la pantalla DOS al navegador

Antes escribíasAhora escribesQué hace
@ 10, 5 SAY "Name" GET cNameGET "name" LABEL "Name" VALUE cNameUn campo de texto con su etiqueta.
MENU oMenu … MENUITEM … ENDMENUMENU hMenu MENUBAR … MENUITEM … ENDMENUBotones de cabecera, chips laterales y pestañas con una sola sintaxis.
TBrowse / dbEdit()TABLE hList OF aRows … COLUMN … ENDTABLEUna lista clicable con miniaturas, badges y columnas de importes.
USE customers INDEX ON nameaRows := DB_QUERY( cSql, { cName } )PostgreSQL con parámetros ligados, sin servidor ORM de por medio.
SET COLOR TO W+/Bpublic/skins/<skin>/skin.cssEl aspecto es cosa del skin: CSS y pequeñas plantillas HTML que un diseñador puede tocar.
ACTIVATE WINDOW oWndFV_SERVE( nPort, "public", {| hReq | APP_DISPATCH( hReq ) } )El servidor web entero cabe en una línea de main.prg.
03 — CÓMO FUNCIONA

Runtime nativo, sin pegamento.

Cada capa es una llamada a la librería del runtime de Five. Aparte de PostgreSQL, no hay nada que instalar.

FV_SERVE

HTTP de principio a fin

Entran cabeceras y cookies; salen el estado y el set-cookie. Cada petición corre en su propio hilo de la VM.

WsServe · WsSend

Tiempo real

Un servidor WebSocket sin dependencias. El feed al pie de esta página lo está escuchando.

PG_OPEN · PG_QUERY

PostgreSQL, sin intermediarios

Consultas con parámetros ligados sobre pgx. Las migraciones se ejecutan al arrancar y son idempotentes.

PWHASH · ENCRYPT · SECEQ

Seguro por defecto

Contraseñas con bcrypt, sesiones AES-256-GCM, comparaciones en tiempo constante y CSRF double-submit.

T()

Idiomas de serie

Traducciones por catálogo con el idioma decidido en cada petición. Esta misma página se sirve en seis idiomas desde locales/*.json.

hx.js

UI hipermedia

Un shim de 54 líneas al estilo HTMX: swaps parciales y cabeceras CSRF, sin paso de build ni framework.

04 — EL CÓDIGO

La petición es un hash. La respuesta, otro.
El handler es un bloque.

La tabla de rutas y un handler reales de la aplicación que está en marcha.

routes/routes.prg
// asset manager — gallery, list, detail, CRUD, export
ROUTE( "GET",  "/assets",            {| hReq | ASSET_DASHBOARD( hReq ) } )
ROUTE( "GET",  "/assets/cards",      {| hReq | ASSET_CARDS( hReq ) } )
ROUTE( "POST", "/assets",            {| hReq | ASSET_CREATE( hReq ) } )
ROUTE( "GET",  "/assets/export.csv", {| hReq | ASSET_EXPORT( hReq ) } )

// main.prg — the whole server
FV_SERVE( hCfg[ "port" ], "public", {| hReq | APP_DISPATCH( hReq ) } )

// a handler: query → hash → JSON. The result lives in a variable; RETURN returns it.
FUNCTION ASSET_LIST( hReq )
   LOCAL aRows := Rows( hReq, 1000, 0 )
   LOCAL hRes  := RES_JSON( { "ok" => .T., "assets" => aRows, "count" => Len( aRows ) } )

RETURN hRes
 wss · /wsconectando
Feed en tiempo real de RT_BROADCAST. Crea un registro en otra pestaña y míralo aparecer aquí: Nuevo activo · Nuevo empleado