# Package actions and recipes

This is the detail behind a package's actions, in
[What package code may do](what-package-code-may-do.md), and its
[Recipes](what-package-code-may-do.md#recipes): what a package action may call, how the app calls
one, and how `jadpo package recipe` copies a recipe into your app.

- **Calling its own API.** In a package's action, `<resource>.<operation>(input)`
  calls one of its package's operations, public or not, by its bare names;
  a function or a test of the package calling one is
  `effect.function_persistence`. The operation's failures are the
  package's own, so they pass on to the action's `fails` with `attempt`
  as a library function's do, or are handled with `match`. At run time
  the call goes through the connection the app called the action
  through, with its credential, host, timeout and fake.
- **No other action.** A package's action calling another action, its
  package's or any other, is `package.action_invalid`. A package action
  calls only its own package's operations and pure functions.
- **No setting and no sign-in.** A `config.<name>` read anywhere in a
  package's code but its tests, a key given to a `crypto` call's `key:`
  included, is `package.action_invalid`: a package reads none of the
  app's settings, so it can neither send one to its API nor sign or
  decrypt with the app's keys; what its provider needs reaches it
  through the connection's `credential:`. So is a call of `sessions.*`,
  `magic_links.*` or `test_passkeys.*` in a package's code: who is
  signed in is the app's own.
- **The app's call.** `connection.<action>(...)` calls a `public` action
  of the connection's package, from an action of a domain its
  `domains:` lists (`connection.domain_not_listed` otherwise), with the
  action's parameters as written; one without `public` is
  `package.not_public`. Its package failures are mapped at the call by
  their codes, as an operation's are (`failure.attempt_required` when
  nothing maps them), and one no arm maps is a fault; its `attempt` may
  not map `timed_out:`, since its calls are several, or may be. An
  unknown name through the connection lists its public operations and
  actions.
- **Steps.** A package action's changing calls count as the calling
  action's on its longest way through, and the keys the runtime derives
  carry on the caller's step numbering, so a second package action, or
  the app's own call after one, continues it. A package action over 8 is
  `step.too_many` where it is declared, which `jadpo package check`'s
  `compiles` row shows, so it can't be published.
- **Emitting.** `emit` in a `public` package action is
  `package.action_invalid`; one without `public`, which only the
  package's subscribers run, emits the package's own events ("Package
  subscribers and recipes in `sample/`").
- **A resource and an action of one name** is `package.action_invalid`
  at the action.
- **The surface.** Each `public` action is an entry after the
  operations, `action <name>` with its file, its `signature` and a `fails`
  line per failure, compared between versions as a function's is.
- **Fakes.** A test's `fakes:` may script any of the package's
  operations, public or not, when the package has actions, since those
  reach the ones it keeps to itself; a package action runs its real code
  in a test, as every package's code does. The provider plan holds every
  operation of a connection's package.
- **`jadpo package recipe <package> <recipe> --into <domain>`** finds the
  package as `jadpo package show` does and copies every file under its
  `recipes/<recipe>/`, hidden ones left out, to the same path under
  `domains/<domain>/`, which must be one of the app's domains. It copies
  all or nothing: a file the domain already has is never written over,
  and naming one refuses the copy with `cli.package_arguments`. The files
  are copied as they are; `jadpo check` then shows what to fit to the app.
  The screen lists each file written, the footer counts them, and the
  hint is `jadpo check`, designed with the CLI design language:

```text
Copied recipe track_parcels into domains/shipping
    domains/shipping/actions/track_parcel.jadpo
    domains/shipping/schedules/track_nightly.jadpo

recipe copied: Couriers.v1, track_parcels, 2 files

next: jadpo check  shows what to fit to the app
```
