Packages

Bundle functions, a face, and their files into a package another program imports

A package is a folder with a kaya.json that names it. It holds Kaya modules and any other files they use: a face's HTML, images, data. Another package or a program imports the folder, and the functions it gets still find their package's own files.

Packages compose. A general package can sit under a specialized one, and a program can sit on top:

storytelling/        tells a story scene by scene in a player face
  kaya.json
  main.kaya
  player.html
pickleworths/        a show: its cast, their portraits and its own player;
  kaya.json          imports storytelling
  main.kaya
  player.html
  portraits/
    barnaby.png
episode-3/
  main.kaya          the story itself; imports pickleworths

The story-episode example runs this project in your browser, portraits and all.

kaya.json

{
  "name": "storytelling",
  "version": "1.0.0",
  "main": "main.kaya",
  "description": "Tell a story scene by scene in a player face."
}
  • name: lowercase letters, digits and hyphens, starting with a letter.
  • version: letters, digits, ., - and +.
  • main: the module an import of the folder brings in. It defaults to main.kaya.
  • description is optional. Any other key is refused, so a misspelled field fails instead of being ignored.

Importing a package

Import the folder. The reference ends in /:

import tellStory from "../storytelling/"

The names you import are functions defined in the package's main module. Importing a package runs none of its code and mounts nothing. Its functions run when you call them.

A package's modules may import one another, as ./scenes.kaya, and other packages, as ../storytelling/. A path that leaves the package is refused before the program runs.

A package's own files

A package declares the files it uses with resource, and its code reaches them with asset(path:). The path is resolved beside the module whose code calls asset(), so it finds the package's file wherever the caller lives:

// storytelling/main.kaya
resource "player.html"

function tellStory(title: string, scenes: json, face?: file): string {
  let ownPlayer = asset(path: "player.html")
  let player = face ?? ownPlayer
  mount(component: "story-player", face: player, reads: ["story.scene"], sends: {"story.next": {zodTypeName: "Object", shape: {}}})
  // ...
}

Each package keeps its files apart. In the session they live under .packages/<name>@<version>/, so storytelling and pickleworths can both ship a player.html. A package's resources keep their own paths: as, in, from and resources are for programs, not packages.

Specializing a package

A show changes what it needs by passing its own values. Here the show passes its own player face to the storytelling driver:

// pickleworths/main.kaya
import tellStory from "../storytelling/"

resource "player.html"

function playEpisode(title: string, scenes: json): string {
  return tellStory(title: "The Pickleworths: {{title}}", scenes: scenes, face: asset(path: "player.html"))
}
// episode-3/main.kaya
import playEpisode from "../pickleworths/"

let scenes = []
scenes.push(value: { speaker: "Barnaby", line: "Has anyone seen the garden gnome?" })
let ending = playEpisode(title: "Episode 3", scenes: scenes)
"{{ending}}"

A face a package supplies is a face the program writes: the viewer asks before it runs it the first time. A package's images reach its face as pinned files: asset() returns each one with its size and digest, and the face shows it with kaya.media().

Identity and copies

A package is identified by its name and version, not by its folder. Moving a package's folder changes nothing for the program that imports it. One program may use one copy of a package version: importing storytelling@1.0.0 from two different folders is refused.

When a run first imports a package, it copies the package's files, and those of every package it depends on, into the session. A paused session that resumes later uses those copies, even if the folder has changed or moved.

Not yet

  • Importing a package from a URL.
  • Skills inside a package.