[{"data":1,"prerenderedAt":356},["ShallowReactive",2],{"content-ca-\u002Fsdk\u002Farchitecture":3},{"id":4,"title":5,"author":6,"body":7,"date":6,"description":348,"extension":349,"meta":350,"navigation":351,"path":352,"seo":353,"stem":354,"tags":6,"__hash__":355},"content_ca\u002Fca\u002Fsdk\u002Farchitecture.md","Arquitectura del SDK",null,{"type":8,"value":9,"toc":327},"minimark",[10,14,19,30,34,39,43,47,50,56,60,63,80,83,87,90,96,100,103,120,124,128,134,138,144,148,152,158,162,168,172,321],[11,12,5],"h1",{"id":13},"arquitectura-del-sdk",[15,16,18],"h2",{"id":17},"diagrama-del-sistema","Diagrama del Sistema",[20,21,26],"pre",{"className":22,"code":24,"language":25},[23],"language-text","                    ┌─────────────────────────────────────────────────────┐\n                    │              Platform Layer (pwa\u002Fmain.ts)           │\n                    │  PwaPlayer: wires all packages together            │\n                    │  Wake Lock, Screenshot, SW registration            │\n                    └──────────────────────┬──────────────────────────────┘\n                                           │\n    ┌──────────────────────────────────────┼──────────────────────────────────┐\n    │                                      │                                  │\n┌───┴────────────┐  ┌─────────┴─────────┐  ┌──┴──────────────┐  ┌───────────────┐\n│  PlayerCore    │  │  RendererLite     │  │  Service Worker  │  │  XmrWrapper   │\n│  Orchestration │  │  XLF rendering   │  │  Chunk streaming │  │  WebSocket     │\n│  Collection    │  │  Element reuse   │  │  Range requests  │  │  13 commands   │\n│  Offline cache │  │  Transitions     │  │  IC interception │  │  Reconnect     │\n│  Commands      │  │  Touch\u002Fkeyboard  │  │  Cache-first     │  │               │\n└───────┬────────┘  └──────────────────┘  └───────────────────┘  └───────────────┘\n        │\n        ├───────────────────────┬───────────────────────┬──────────────────┐\n        │                       │                       │                  │\n┌───────┴──────────┐  ┌────────┴────────┐  ┌──────────┴──────┐  ┌────────┴───────┐\n│  XmdsClient      │  │ ScheduleManager │  │  CacheManager   │  │ StatsCollector  │\n│  + RestClient    │  │ + Interrupts    │  │  + CacheProxy   │  │ + LogReporter   │\n│  SOAP + REST     │  │ + Overlays      │  │  + DlManager    │  │ Proof-of-play   │\n│  ETag caching    │  │ Dayparting      │  │  Parallel chunks│  │ Fault reporting  │\n└──────────────────┘  └─────────────────┘  └─────────────────┘  └────────┬────────┘\n                                                                         │\n                                                                ┌────────┴────────┐\n                                                                │  SyncManager    │\n                                                                │  Lider\u002Fseguidor │\n                                                                │  BC + WebSocket │\n                                                                │  Aillament grups│\n                                                                │  Deleg. estad.  │\n                                                                └─────────────────┘\n","text",[27,28,24],"code",{"__ignoreMap":29},"",[15,31,33],{"id":32},"patrons-de-disseny-clau","Patrons de Disseny Clau",[35,36,38],"h3",{"id":37},"_1-nucli-independent-de-plataforma","1. Nucli Independent de Plataforma",[40,41,42],"p",{},"PlayerCore conté tota la lògica de negoci sense assumpcions de plataforma. La capa de plataforma (PWA, Electron, Android) connecta els paquets i proporciona implementacions específiques de la plataforma (Wake Lock, captura de pantalla, registre del Service Worker).",[35,44,46],{"id":45},"_2-comunicació-per-eventemitter","2. Comunicació per EventEmitter",[40,48,49],{},"Tots els mòduls es comuniquen mitjançant events, no crides directes a mètodes:",[20,51,54],{"className":52,"code":53,"language":25},[23],"PlayerCore emits:     schedule-updated, collection-complete, purge-request\nRendererLite emits:   layoutStart, layoutEnd, widgetStart, widgetEnd\nStatsCollector:       listens to layout\u002Fwidget events for proof-of-play\nLogReporter:          listens for errors from IC, renderer, collection\n",[27,55,53],{"__ignoreMap":29},[35,57,59],{"id":58},"_3-transport-dual","3. Transport Dual",[40,61,62],{},"El paquet XMDS proporciona dues implementacions de transport amb superfícies d'API idèntiques:",[64,65,66,74],"ul",{},[67,68,69,73],"li",{},[70,71,72],"strong",{},"XmdsClient"," (SOAP\u002FXML) — protocol tradicional, totes les versions del CMS",[67,75,76,79],{},[70,77,78],{},"RestClient"," (REST\u002FJSON) — càrregues 30% més petites, cau ETag 304",[40,81,82],{},"PlayerCore no sap quin transport està actiu.",[35,84,86],{"id":85},"_4-reutilització-delements","4. Reutilització d'Elements",[40,88,89],{},"RendererLite pre-crea TOTS els elements DOM dels widgets en carregar el disseny, els emmagatzema en un Map, i alterna la visibilitat:",[20,91,94],{"className":92,"code":93,"language":25},[23],"Layout load:    Pre-create all elements → widgetElements.set(widgetId, element)\nWidget switch:  Hide current → Show next (visibility toggle, no DOM create\u002Fdestroy)\nLayout replay:  Detect isSameLayout → Reuse elements → Restart videos\nLayout change:  Revoke blob URLs → Destroy elements → Create new set\n",[27,95,93],{"__ignoreMap":29},[35,97,99],{"id":98},"_5-service-worker-com-a-servidor-de-mitjans","5. Service Worker com a Servidor de Mitjans",[40,101,102],{},"En lloc d'un servidor HTTP local, la PWA utilitza el seu Service Worker per interceptar les peticions fetch i servir els mitjans des del cau:",[64,104,105,108,111,114,117],{},[67,106,107],{},"Streaming per blocs amb suport de peticions Range",[67,109,110],{},"Intercepció IC (rutes de Control Interactiu)",[67,112,113],{},"Reescriptura d'URLs de CSS de fonts",[67,115,116],{},"Cau primer amb fallback a xarxa",[67,118,119],{},"Funcionament offline",[15,121,123],{"id":122},"flux-de-dades","Flux de Dades",[35,125,127],{"id":126},"cicle-de-collecció","Cicle de Col·lecció",[20,129,132],{"className":130,"code":131,"language":25},[23],"1. RegisterDisplay()      → CMS settings, commands, XMR address\n2. CRC32 comparison       → Skip if unchanged\n3. RequiredFiles()        → File list with MD5 hashes\n4. Download missing files → 4 parallel chunks, MD5 verify\n5. Schedule()             → Layout schedule XML\n6. Parse schedule         → Layouts, overlays, actions, commands\n7. MediaInventory()       → Report cached file inventory\n8. NotifyStatus()         → Report status (disk, timezone, layout)\n9. SubmitStats()          → Proof-of-play records\n10. SubmitLog()           → Queued log entries\n11. SubmitScreenShot()    → If captured\n",[27,133,131],{"__ignoreMap":29},[35,135,137],{"id":136},"mode-offline","Mode Offline",[20,139,142],{"className":140,"code":141,"language":25},[23],"Network down:\n  → XMDS calls fail → Use IndexedDB-cached schedule\u002Fsettings\n  → Media requests → Service Worker serves from Cache API\n  → Stats\u002Flogs → Queued in IndexedDB, submitted when network returns\n  → Player continues rendering with last known schedule\n",[27,143,141],{"__ignoreMap":29},[15,145,147],{"id":146},"arquitectura-demmagatzematge","Arquitectura d'Emmagatzematge",[35,149,151],{"id":150},"cache-api-fitxers-binaris","Cache API (Fitxers Binaris)",[20,153,156],{"className":154,"code":155,"language":25},[23],"Cache: xibo-media\n├── \u002Fmedia\u002F{id}           → Images, videos, audio\n├── \u002Fwidget\u002F{widgetId}    → Widget HTML (getWidgetHtml)\n├── \u002Ffont\u002F{fontFile}      → Font files\n└── \u002Fstatic\u002F{path}        → Static player assets\n",[27,157,155],{"__ignoreMap":29},[35,159,161],{"id":160},"indexeddb-dades-estructurades","IndexedDB (Dades Estructurades)",[20,163,166],{"className":164,"code":165,"language":25},[23],"Database: xibo-player\n├── files         → File metadata (id, type, md5, size)\n├── stats         → Proof-of-play (pending submission)\n├── logs          → Log entries (pending submission)\n├── schedule      → Last known schedule (offline fallback)\n├── settings      → Last known CMS settings\n└── requiredFiles → Last known required files\n",[27,167,165],{"__ignoreMap":29},[15,169,171],{"id":170},"pila-tecnològica","Pila Tecnològica",[173,174,175,191],"table",{},[176,177,178],"thead",{},[179,180,181,185,188],"tr",{},[182,183,184],"th",{},"Capa",[182,186,187],{},"Tecnologia",[182,189,190],{},"Justificació",[192,193,194,206,220,233,244,255,266,277,288,299,310],"tbody",{},[179,195,196,200,203],{},[197,198,199],"td",{},"Llenguatge",[197,201,202],{},"JavaScript (ES2020+)",[197,204,205],{},"Multiplataforma, sense transpilació",[179,207,208,211,217],{},[197,209,210],{},"Client HTTP",[197,212,213,216],{},[27,214,215],{},"fetch()"," + fetchWithRetry",[197,218,219],{},"Integrat, reintent configurable",[179,221,222,225,230],{},[197,223,224],{},"Anàlisi XML",[197,226,227],{},[27,228,229],{},"DOMParser",[197,231,232],{},"Integrat, conscient de namespaces",[179,234,235,238,241],{},[197,236,237],{},"Emmagatzematge",[197,239,240],{},"Cache API + IndexedDB",[197,242,243],{},"APIs PWA integrades",[179,245,246,249,252],{},[197,247,248],{},"Offline",[197,250,251],{},"Service Worker",[197,253,254],{},"Intercepta totes les peticions fetch",[179,256,257,260,263],{},[197,258,259],{},"Hash MD5",[197,261,262],{},"spark-md5",[197,264,265],{},"4KB, suport ArrayBuffer",[179,267,268,271,274],{},[197,269,270],{},"PDF",[197,272,273],{},"PDF.js (càrrega diferida)",[197,275,276],{},"Estàndard de la indústria",[179,278,279,282,285],{},[197,280,281],{},"HLS",[197,283,284],{},"hls.js (càrrega diferida)",[197,286,287],{},"Polyfill per a navegadors que no són Safari",[179,289,290,293,296],{},[197,291,292],{},"Animacions",[197,294,295],{},"Web Animations API",[197,297,298],{},"Integrat, accelerat per GPU",[179,300,301,304,307],{},[197,302,303],{},"Compilació",[197,305,306],{},"Vite",[197,308,309],{},"Tree-shaking, minificació",[179,311,312,315,318],{},[197,313,314],{},"Paquets",[197,316,317],{},"pnpm workspaces",[197,319,320],{},"Gestió de workspace",[40,322,323,326],{},[70,324,325],{},"Dependències en temps d'execució:"," spark-md5 (4KB), hls.js (diferit), PDF.js (diferit), xibo-communication-framework",{"title":29,"searchDepth":328,"depth":328,"links":329},3,[330,332,339,343,347],{"id":17,"depth":331,"text":18},2,{"id":32,"depth":331,"text":33,"children":333},[334,335,336,337,338],{"id":37,"depth":328,"text":38},{"id":45,"depth":328,"text":46},{"id":58,"depth":328,"text":59},{"id":85,"depth":328,"text":86},{"id":98,"depth":328,"text":99},{"id":122,"depth":331,"text":123,"children":340},[341,342],{"id":126,"depth":328,"text":127},{"id":136,"depth":328,"text":137},{"id":146,"depth":331,"text":147,"children":344},[345,346],{"id":150,"depth":328,"text":151},{"id":160,"depth":328,"text":161},{"id":170,"depth":331,"text":171},"Arquitectura tècnica del XiboPlayer SDK — diagrama del sistema, patrons de disseny i flux de dades.","md",{},true,"\u002Fca\u002Fsdk\u002Farchitecture",{"title":5,"description":348},"ca\u002Fsdk\u002Farchitecture","j9q6C5S3vOLaTDnOO6jMgu1wP4Yottc8eOlT9NPCpkU",1775148105253]