What a version number of these packages promises, what it does not, and how a breaking change reaches you.
The packages follow semantic versioning. From 1.0.0, a change that breaks anything under What is covered comes only in a major release; a minor adds without breaking; a patch fixes. Before 1.0.0, a minor may break what is covered and a patch does not.
Two kinds of fix ship in any release, a patch included:
- Security. A fix that refuses something hostile, even when it refuses a package that played before. Which releases receive one is in SECURITY.md.
- Conformance. A fix that brings what a package sends or writes into line with the standard it implements — xAPI, cmi5, the zip format — even when a system downstream accepted the old form.
Each release's notes, on GitHub, list a breaking change, or a fix of either kind, first, with what to do about it.
- The element.
<h5p-player>, and every attribute, property, method and event in the element's API, with the values anddetailshapes given there. A new errorcodeorprogressphase can come in a minor: treat one you do not know as the general case. - The files. The package's exports —
., the element, and./sw,mountH5P— and the four files a host without a build step copies by name:h5p-player.js,h5p-sw.js,h5p-sw-mount.jsandh5p-jobs.js. - The worker's path. The player's routes are
h5p/besideh5p-sw.js, the scope the element registers, orh5p/in the scope of a host's own worker that mounts them. Every other request is left to the network, or to the host's own handlers. - What statements carry.
context.platformish5p-offline-player <version>, andcontext.revisionissha256:<hex>, followed by; librariesand the fingerprint of what supplied libraries, a bundle's or the pack's archives' (Which build a learner completed). The recipe behind the hash does not change within a major, and a major that changes it gives the new value a prefix of its own, so an audit can always tell which recipe to recompute with. - What names a package.
activity-iddefaults to the package URL, and the statements' object ids are built on it; a package'spkgIdcomes from its URL and the host's validator, or from the picked file's name, size and date, and saved state is kept under it. Neither recipe changes within a major. - What counts as the result. The rule behind
finished, as the API page states it, since an LMS records completion by it. - What is kept on the device. Saved state (
resume="device") survives every release, a major included, unless the release's notes say otherwise. Cached packages survive minors and patches; a major starts the cache afresh, and each package is downloaded once more. - Versions side by side. Within a major, an element plays with a Service Worker from an older
release: it updates its own worker before the first load, and logs a warning where it cannot —
a stale copy of
h5p-sw.json the host, or a host's worker with the routes mounted. A worker serves an element from an older release too. Upgrading says what a host does about it.
- The
runtimeexport a bundled host hands the element, anddist/, which a host usingassets-baseserves whole. - Its pairing with the player. The player's peer dependency names the runtime versions it plays with, and any pairing in that range plays. The boot configuration and the messages between the frame and the element are a contract between the two packages, not an API: a runtime that needs more of it than older players write is a breaking release of the runtime, and goes out with a player that moves its range.
- The H5P core inside is updated in minor releases, the version it carries named in the
notes and in
dist/NOTICE.txt. The core's own strings, refreshed weekly from Moodle's language packs, change in patches.
libraries="pack" plays against the pack version a player release pins, so one player version
always plays a package against the same libraries. The pin moves in a minor release, never in a
patch: with pack, a library a package carries plays at the pack's newer version, so a new pack
changes what packages that carry their libraries play, and their revision, and a learner's state
saved against the build before starts over. Libraries move to newer minors, and content written
for an older minor is brought up by the libraries' own upgrade steps. Content written for a newer
minor than any source has plays at the newest older one unless downgrade-libraries="off", and
plays at the newer one once a pack has it. A pack that drops a content type or a library major the
one before carried comes only with a player major.
What is covered of the pack itself: the pack export, parts/ with its index.json and one
<folder>.h5p per library, and libraries.h5p, the whole pack as one file. Since 1.1.0 the
index marks the libraries carried for an H5P site's upload check installOnly, and gives each
library's editorDependencies and dynamicDependencies beside its preloadedDependencies; the
pack export leaves the marked ones out, and the ./install export has them.
- The command's options, and the files it writes for each kind of host.
- The page's interface: its query parameters and the messages it posts, as its
README
lists them: what a snippet, or a page that reads
report, is built on. buildSite(), the command as a function, andstartEmbed(), the page as one, with their options and their types; andresizer.js, which speaks H5P's own resizer protocol.- The SCORM package
--scormwrites, andbuildScorm(), with its options and types: SCORM 1.2, the elements its page sets (cmi.core.score.raw,.minand.max,cmi.core.lesson_status,cmi.core.session_time,cmi.core.exit, and since 1.5 each question'scmi.interactions.n), and what it keeps incmi.suspend_data, which a zip written by a later version reads back unless the libraries it carries from the pack have changed: 1.5 writes it compressed and still reads what 1.4 wrote plain. Since 1.6, the options: SCORM 2004 4th Edition with the same elements under 2004's names (cmi.completion_statusandcmi.success_statusapart,cmi.score.scaledbesides), a pass mark, and completion as 100; a zip written with none is the 1.2 zip above. - The SCORM page,
scorm.htmlon a written site, andplanScormInPage(),buildScormInPage()andstartScormPage(), with their options and types: the same zip asbuildScorm()'s, built in the browser.
A written site is a folder of copies and changes only when it is written again: upgrading is running the new version of the command and deploying the folder. A SCORM zip likewise, replaced in the LMS.
startCmi5(), isCmi5Launch() and createCmi5Client(), with the options and the session's and
client's methods its README
lists, and their types. The statements it sends are cmi5's, so a fix that brings one into line
with the specification is a conformance fix.
The command's options, and normalizeArchive(), formatBytes() and archiveFingerprint(), with
their types, and crc32() from @missing-elements/h5p-normalize/crc32, which embed and h5p-author
take through a range. The content of a package it rewrites never changes. How it lays out the zip may change in a minor, as
long as the player streams the result at least as well.
The command's options, its exit codes — 0 plays, 1 does not, 2 could not run; with --preview,
0 when the preview ends and 2 when it could not start — report.json, to
which fields may be added, and verifyPackage() and summarize(), with their types: VerifyReport
is report.json's shape, and gains fields the same way. The verifier is a step in other
people's pipelines, so a check that turns a pass into a fail comes in a minor, never a patch; a new
warning can come in any release.
- The routes inside
h5p/, the messages between the element, the workers and the frame, and how the database and the caches are laid out. They may change in any release, within what Versions side by side promises. - The frame's document and its policy, beyond what
allow-originsanduntrustedpromise. - Content types. The libraries are H5P's and their authors', and how one looks or behaves changes with the pack.
- Exports and files this page does not name: a package's other exports, the rest of the
player's
dist/, the files inside the runtime's. Nor anything reached by a path a package does not export. Among them the player's./plan, its library rules for the packages of this repository that write what it plays, h5p-author and the embed command, which depend on an exact version of the player for that reason. - The demo site, including
/app/and/embedthere, and this repository's scripts and workflows.
A renamed attribute, value or option keeps working through the rest of its major and goes only in a major. None is in that state now.
The player needs a secure context — https, or localhost — with Service Workers, the Cache API,
IndexedDB, Web Locks and DecompressionStream for deflate-raw. Its browser suite runs on every
change in Chromium, Firefox and WebKit, Playwright's builds of their current releases; Safari on
macOS and iOS is checked by hand. No version floor is published: a package that plays in a current
browser and not in another that has those features is a bug, and worth reporting. Dropping an engine
is a major change.
The commands — h5p-normalize, h5p-verify, h5p-embed — and the functions behind them
declare the Node versions they run on in engines. That floor rises in a minor when a Node line
reaches its end of life, never in a patch.
The player, the runtime and the embed site are released together whenever the contract between them
changes: the player names the runtime versions it plays with, and the embed site the player, runtime
and library pack it writes a site from. The library pack has a version of its own, and each release
of it is followed by a player release that pins it, since pack plays only the version the player
names. cmi5, the normalizer and the verifier are versioned on their own.