feat: play packages from the library pack's parts, not the whole bundle

Merged
AL
1d ago
+71-43

/h5p handed startEmbed() the whole libraries.h5p (librariesPack). So the first package a visitor opened that lacked a library downloaded all of it. Since pack 1.1.0, which came in with #10, that is 15.5 MB, and 1.8 MB of it is libraries an H5P site's upload check wants, which the player never reads.

This passes startEmbed() the pack export of @missing-elements/h5p-libraries, one part per library, as sites written by h5p-embed have done since 0.8.

What changes

  • Downloads: a package downloads only the parts it needs. Each part is checked against the pack's SHA-256 and kept for every package that uses it. The library-less sample quiz now fetches a handful of parts instead of 15.5 MB.
  • Build output: /build already reads these same parts, so dist/ drops libraries.h5p and is 23 MB in all.
  • Newer library versions (behaviour change): a package that carries older libraries now plays the pack's newer versions (player 0.10, h5p-embed's default for pack). The website already says the player does this.
    • The sample quiz plays 8 of its libraries newer, for example Question Set 1.20.31 → 1.21.14.
    • &refresh-libraries=off on the address plays them as exported.
    • No learner state is affected, because this page never turns on resume.
  • Report: for such a package, the report's libraryBundle is now { url, origin, fromCache, refreshed } instead of null.
  • Type shim: src/h5p-embed.d.ts is removed. h5p-embed ships its own declarations since 1.1.0, and only those know the pack option.

Testing

  • pnpm typecheck and pnpm build pass.
  • pnpm e2e: 10 passed. The changed tests check:
    • the element's libraries is pack;
    • a library-less package fetches only its parts, all from this origin;
    • nothing is fetched from jsDelivr or the H5P hub, and never the whole bundle;
    • the framing page's report carries refreshed and an empty downgradedLibraries.
  • The website's e2e suite: 9 passed against this build (VITE_PLAYER_URL).

Order

Merge embed-my/website#6 first. Its preview reads refreshed. Without it, the live site would describe every package that carries older libraries as "exported without its libraries".

šŸ¤– Generated with Claude Code


Summary by cubic

/h5p now passes startEmbed() the library pack's parts, one per library, instead of the whole libraries.h5p bundle, so a package exported without its libraries downloads only the parts it needs — a handful instead of 15.5 MB.

What changes

  • Each part is checked against the pack's SHA-256 and kept in the browser for every package that uses it; the build page reads the same parts, and dist/ drops libraries.h5p (23 MB in all).
  • A package that carries older libraries plays the pack's newer versions (player 0.10); &refresh-libraries=off plays them as exported, and the report's libraryBundle is now { url, origin, fromCache, refreshed } instead of null.
  • The e2e tests now listen on the browser context, not the page, so they also catch requests the Service Worker makes.
  • src/h5p-embed.d.ts is removed; h5p-embed ships its own declarations since 1.1.0.
  • Merge embed-my/website#6 first: its preview reads refreshed; without it, the live site would describe every such package as "exported without its libraries".