INTEGRACIÓN
Integrar P2LRN con tu plataforma
El Player gestiona el paquete y la reproducción. Tu plataforma conserva usuarios, permisos, progreso, puntuación, recursos protegidos y datos que no deben viajar dentro del curso.
Antes de integrar
Carga el Player mediante la guía de instalación elegida. Esta página parte de un <p2lrn-player> ya disponible y se centra en la comunicación con tu plataforma.
Conectores de IA y LMS
Para conectores MCP de ChatGPT, Claude, Grok y aplicaciones locales, o para la arquitectura LMS y LTI 1.3, consulta la documentación de conectores.
Arquitectura
Host Adapter
Host Adapter es el puente entre el Player y los servicios de tu plataforma. Implementa sólo las funciones que tu integración necesite y mantén autenticación y autorización en el servidor.
loadState(context)Recupera el último snapshot de una actividad o de la progresión para poder reanudar.
saveState(state, context)Guarda el snapshot actual. No debe confundirse con un log analítico.
reportScore(score, context)Entrega puntuaciones normalizadas procedentes de cuestionarios, SCORM o H5P cuando el runtime dispone de ellas.
emitEvent(event, context)Entrega el flujo canónico p2lrn:* en orden para analítica, auditoría o integración.
resolveResourceUrl(request, context)Resuelve recursos protegidos que tu plataforma ya ha autorizado y verificado.
La identidad del alumno y el intento actual pertenecen a tu aplicación. Combínalos en tu backend con packageId, contentRoot y entityId; no introduzcas datos personales dentro del paquete.
const adapter = P2LRN.createHostAdapter({
async loadState(context) { return loadProgress(context); },
async saveState(state, context) { await saveProgress(state, context); },
async reportScore(score, context) { await saveScore(score, context); },
async emitEvent(event, context) { await recordEvent(event, context); },
async resolveResourceUrl(request, context) {
const url = await authorizeResource(request, context);
return url ? {url, verified: true, seekable: request.seekable === true} : null;
},
});
document.querySelector('p2lrn-player').adapter = adapter;P2LRN define el contrato del adaptador, pero no impone nombres de rutas ni una base de datos concreta.
Capacidades en vivo: Capability Broker
Host Adapter continúa siendo la frontera para estado, notas, eventos y recursos. Los servicios en vivo opcionales se conectan mediante Capability Broker, de modo que el paquete declara una necesidad semántica y el host decide qué provider real la satisface.
Declara la capacidad y las operaciones permitidas. No contiene endpoints, tokens, usuarios ni credenciales.
Negocia la capacidad y entrega al renderer un invokeCapability() restringido; el renderer no recibe el broker completo.
Registra providers y autoriza cada invocación. Un mismo contrato puede mapear a HTTP, WebSocket, SSE, un servicio local u otra implementación.
La primera capacidad de colaboración utiliza collaboration.room con join, send, listen, snapshot y leave. Ver la guía completa de colaboración.
const provider = P2LRN.createHttpCollaborationProvider({
endpoint: '/api/p2lrn/collaboration',
getHeaders: () => ({ Authorization: 'Bearer ' + token })
});
player.capabilityBroker = P2LRN.createCapabilityBroker({
providers: [provider],
authorize: ({capabilityId}) =>
capabilityId === 'collaboration.room'
});Offline, reintentos y reconciliación
createOfflineHostAdapter() mantiene Host Adapter v1 y añade estado provisional local más un outbox ordenado para estado, puntuaciones y eventos. Con storageNamespace o createIndexedDbOfflineStore() el host puede persistir una partición explícita por usuario/sesión.
- Los snapshots del mismo contexto se coalescen al último; eventos y puntuaciones mantienen orden.
- La entrega es at-least-once.
offlineDeliveryIdpermite al servidor deduplicar efectos cuando necesita idempotencia. createOfflineSyncController()puede reaccionar aonline/offlinecon backoff acotado. No crea servicios, tareas del sistema ni procesos en segundo plano.- La autoridad de notas, identidad y conflictos multi-dispositivo continúa en el servidor.
const offline = P2LRN.createOfflineHostAdapter({
remote: hostAdapter,
storageNamespace: hostOpaqueSession
});
player.adapter = offline;
const sync = P2LRN.createOfflineSyncController({adapter: offline});Recursos compartidos verificados
Una representación remota reutilizable declara expectedDigest SHA-256. El Player no confía en la URL del paquete: el Host Adapter o un resolver local debe entregar bytes verificados.
createMemorySharedResourceStore()Referencia mínima content-addressed para pruebas/local: un mismo digest conserva un único objeto.
createMemoryResourceLibrary()Biblioteca verificable en memoria.
createCacheStorageResourceLibrary()Persistencia en Cache Storage entre sesiones del navegador, siempre indexada por digest.
createResourceLibraryResolver()Busca primero localmente, verifica SHA-256 antes de insertar un miss y devuelve {verified:true}.
createResourceLibraryCapabilityProvider()Expone sólo metadatos mediante resource.library: search, describe y has; los bytes permanecen detrás del resolver.
Studio puede seleccionar una entrada de biblioteca mediante su propiedad resourceLibrary y materializeSharedResource() añade un fallback embebido al mismo Resource cuando se necesita portabilidad sin red.
Cache verificado del curso
createCacheStoragePackageCache() permite conservar un .p2lrn completo después de que pase las verificaciones normales de manifiesto, grafo e integridad. Se vuelve a verificar al abrirlo.
cachePackageURL() y openCachedPackage() son opt-in; el paquete cacheado no contiene identidad, notas ni outbox. El host controla cuota, retención y borrado.
Host autoritativo de referencia
Para un backend Node, @p2lrn/toolkit/host exporta createReferenceAuthoritativeHost() junto con stores en memoria/JSON. La referencia separa la puntuación reportada de una decisión autoritativa producida por grade(), admite políticas de conflicto de estado y deduplica entregas offline por offlineDeliveryId.
Es una implementación de referencia para integrar la frontera de confianza; la plataforma que lo integre sigue siendo responsable de autenticación, autorización, partición multiusuario y almacenamiento adecuado.
Contenido privado
La identidad del alumno y los secretos no pertenecen al paquete. Tu servidor autentica y autoriza la solicitud y puede entregar una URL temporal o resolver el recurso mediante Host Adapter.
Entornos de ejecución aislados
Si un SCORM o un H5P está dentro del propio .p2lrn, no tienes que publicarlo aparte. El Player abre el paquete anidado, prepara sus archivos en memoria y crea automáticamente un iframe sandbox con origen opaco por defecto, incluso si el Player se sirve desde un CDN.
runtime-base-url no es obligatorio para SCORM ni H5P.El comportamiento normal es automático, también en los lanzamientos HTML locales compatibles. El sandbox interno no recibe allow-same-origin, por lo que el código de la actividad no comparte el origen de tu aplicación.
En H5P, si el archivo incluido no lleva todas sus librerías, el Player resuelve las dependencias desde el catálogo H5P situado junto a su distribución, las carga desde el contexto de la aplicación y las transfiere al sandbox. Esas librerías se ejecutan dentro del mismo entorno opaco que el contenido.
Runtime externo opcional
Configura runtime-base-url sólo cuando quieras utilizar deliberadamente un servicio de runtime administrado en otro dominio, subdominio o puerto. Ese modo sigue disponible para sesiones H5P gestionadas por servidor y despliegues con políticas propias.
<p2lrn-player
src="https://content.example.com/course.p2lrn"
runtime-base-url="https://runtime.example.net/p2lrn/runtime/">
</p2lrn-player>Los lanzamientos HTML locales de cmi5, Tin Can, Common Cartridge e IMS Content Package también disponen de sandbox automático. El adaptador cmi5 ofrece previsualización con identidad sintética y estado separado mediante Host Adapter; no sustituye un LMS/LRS real ni acredita conformidad cmi5 completa. Los scripts que exigen URLs HTTP estables, carga dinámica, marcos con el mismo origen o servicios externos pueden requerir un runtime administrado y recursos adicionales. El navegador no ejecuta PHP, JSP, ASP ni Flash.
Persistencia del progreso y métricas
Cuando el curso utiliza progresión, el Player carga su estado con loadState, lo actualiza a partir de representación, finalización y puntuación y vuelve a guardarlo con saveState. Los estados internos de SCORM, H5P o cuestionarios utilizan el mismo contrato, pero con contextos de actividad diferentes.
Usa saveState para reanudar, reportScore para notas y emitEvent para historial/telemetría. La guía Métricas y analítica muestra el modelo completo y los campos disponibles por tipo de contenido.
Seguridad de Save, Reader e Import: responsabilidad de tu sitio web
P2LRN no sustituye la autenticación ni la autorización de la plataforma que lo integra. El comando p2lrn-studio setup genera los endpoints técnicos, pero no los protege con las cuentas, roles o permisos de tu sitio. Antes de habilitarlos para usuarios reales, tu servidor debe aplicar sus propias comprobaciones a POST /api/p2lrn/studio/save, POST /api/p2lrn/studio/read y POST /api/p2lrn/studio/import.
Verifica la sesión o token en el servidor. Comprueba el rol de profesor/editor o administrador y los permisos sobre el curso y el centro concreto; deniega accesos con 401 o 403. Ocultar botones en Studio no constituye autorización.
Si utilizas cookies de sesión, aplica CSRF y comprobación de origen según tu framework. Mantén una política CORS restrictiva, HTTPS y límites de peticiones y tamaño para documentos, ZIP y paquetes.
La aplicación anfitriona fija la carpeta o almacenamiento autorizado, sus cuotas y aislamiento entre usuarios o centros. No permitas al navegador elegir rutas absolutas o sobrescribir paquetes ajenos. Trata los archivos importados como no confiables.
Los contenidos SCORM/H5P se ejecutan aislados. No reciben cookies, secretos ni acceso directo a la base de datos del sitio. Los resultados enviados por el Player no deben considerarse notas acreditadas sin validación del servidor.
Secuencia correcta: navegador → autenticación y autorización de tu sitio → controles CSRF, tamaño y destino → funciones @p2lrn/studio/server → almacenamiento de tu plataforma. Estos requisitos se aplican igual usando npm o CDN. Si sólo creas, editas y descargas archivos en el navegador sin endpoints de servidor, estas tres rutas no son necesarias.
CORS
Si el paquete o un recurso se encuentra en otro origen, el servidor debe permitir su lectura desde el navegador. CORS no sustituye la autenticación ni la autorización del usuario.
Comprobación final
- PAQUETEEl manifiesto, el grafo y los recursos se verifican correctamente.
- PLAYERLos eventos
readyyrenderedllegan sin error. - ESTADOEl progreso y la puntuación se conservan fuera del paquete.
- PRIVADOEl curso no contiene credenciales ni identidad del alumno.
- RUNTIMESCORM, H5P y HTML local compatible usan aislamiento automático; cualquier runtime externo configurado expresamente es accesible.