Apps are bundled in packages. When a new version of a package is released, users are going to update the package, and with it all apps in the package. It may be necessary to apply changes to all instances of those apps, for example, when an attribute named foo is to be renamed to bar.

The .Update method is for this purpose: to update all affected files. (All files that are instances of apps of the updated package.)


Let’s assume you are the vendor of the package example.com, and you have a gallery app at example.com/gallery-1. Your app uses a string attribute foo that you want to rename to bar.

  • As this is a data change, you will have to create a new app and update (migrate) the old app’s instances.
  • Create a new file /gallery-2 to hold the new version of the app.
  • Set its type to app-1.
  • Create the file /gallery-1/.Update.
  • Set the .Update file’s link property to path /gallery-2. (This documents that the /gallery-2 app supersedes the /gallery-1 app. Required to do updates one version at a time.)
  • Set the .Update file’s type to sjs-4 or any interpreter of your choice, and write the code that will do the transformation:
    • f will point to the instance being transformed (migrated).
    • Remember that f may have a longer typeChain to your app. It is guaranteed that the files on the typeChain of f will be updated after f itself. Thus, the typeChain of f ends in /gallery-1.
    • Rename the string attribute foo to bar. (Create a new attribute, remove the old one.)
    • Do NOT change the type of the file f to point to /gallery-2, it will be done automatically. In fact, it may not need to be updated, if there is a longer typeChain. (!)
  • Implement the new version of the app. You may want to move or copy the relevant files from /gallery-1/* to /gallery-2/*.
  • To update local instances of the app eg. for testing, see the sjs-4 os.updateInstances() method.

Updating an entire package runs in a single transaction.

Important note

In the above example, never ever remove the file /gallery-1. It makes sure that restoring an old version of a website will continue to just work.

Caveat emptor

  • Changing the .ContentSecurityPolicy rules of a website during an update is not currently supported. Get in touch if you need it implemented. Note that the website owner will have to approve .ContentSecurityPolicy changes every single time.

Design considerations

  • Updating shall be idempotent. Run as often as you want, and always end up with the same result.
  • Updating shall not require access to previous versions of a package.
  • Updating any historical version of a package to the current state shall yield the same result. This is a common scenario due to having version control.
  • Support longer type chains, hide this complexity from developers.