# Two versions side by side, lazy loading and the package cache

How an app holds two major versions of one package while it moves
between them, and how Jadpo avoids compiling and checking package code
the app doesn't use.

- **When names carry the version.** Exactly while the project holds two
  versions of one package of the same kind, both installed in
  `packages/<name>/` or both the app's own in `shared/providers/<name>/`:
  then every name written through either carries its version
  (`Postcodes.v3.UkPostcode`, `Postcodes.v3.uk.parse(...)`), and one
  without it is `package.version_needed`, naming both. With one version
  held, a name never carries it, so there is one way to write each name;
  one that does is `package.version_unneeded`, with the edit that drops
  it. An installed package and the app's own of one name stay a clash
  (`package.name_taken`), never two versions. Two versions are two
  packages throughout: their declarations never clash, their failures are
  told apart, and the graph and the interpreter know each version's
  declarations by its own name (`Postcodes.v2.uk.parse` beside
  `Postcodes.v3.uk.parse`). A package's own code still writes its names
  bare. A name the package declares that looks like a version (a library
  called `v2`) is the declaration, not a version.
- **The `use` line.** `use packages/postcodes` names the folder, so it
  brings in every version held there; there is no `use` line per version.
- **The lock and connections.** Each version has its own line, as
  `Postcodes.v2` and `Postcodes.v3`, sorted by name, then major version
  ([Records and manifest](records-and-manifest.md)). A connection names
  one version in `package:`, so two versions of a provider are two
  connections.
- **The commands.** A package's folder or code name (`postcodes`,
  `Postcodes`) names both versions, so `jadpo package show`, `update`,
  `remove` and `unlink` refuse it and ask for the version
  (`cli.package_arguments`). `add` installs a second major version beside
  the first. `remove` refuses a version while the app's code writes a
  name through it (`install.in_use`), not while the `use` line stays for
  the other version. `update`'s review marks an entry `used by the app`
  when the code writes it through that version.
- **Translations side by side.** The app words a library package's
  messages under its folder's name (`postcodes: { }`,
  [Packages' text in an app](packages-text-in-an-app.md)),
  which two versions would share, so while two are held the version
  joins the key (`postcodes_v3: { }`), as it joins the names; with one
  held, the key stays the folder's name.
- **Lazy loading.** A package's index and `provider.jadpo` are always
  read; an installed package's `resources/<resource>.jadpo` is compiled
  only once code outside every package writes `<connection>.<resource>`
  for a connection to it. Its bytes still
  count towards the digest, so a changed resource the app doesn't call is
  still `package.digest_mismatch`. The app's own integrations are its
  code, compiled whole, and so are an installed package's types,
  failures and libraries, which the app's names reach directly. Once
  reached, a resource stays compiled for the life of `jadpo dev`, `test
  --watch` or the language server. `jadpo package show` reads a package
  whole.
- **The package cache.** `jadpo check` keeps an installed package's check
  in `~/.cache/jadpo/packages/<digest>/<compiler>` (under
  `$XDG_CACHE_HOME` when it is set): the paths of the package's source
  files it checked with no problem. A later check skips those files' own
  checks; their declarations are still read for the app's. The compiler
  is its version and the size and modification time of the running
  `jadpo`, so a rebuilt compiler never trusts an older one's check. Only a
  package whose files match its lock line's digest is cached, never a
  link; with no home folder, or a cache that can't be read or written,
  every file is checked. The other commands check every file.
- **Connection names.** A connection, to a package or a
  driver, named like one of the app's domains or libraries is
  `semantic.duplicate_declaration` at the connection in `app.jadpo`,
  under "Connecting in `app.jadpo`". A package's library isn't one of the
  app's, so it never clashes.
