encrypt = (data, key) => {
  if (!key) {
    return /** @type {PromiseLike<Uint8Array>} */ (promise.resolve(data));
  }
  const iv = crypto.getRandomValues(new Uint8Array(12));
  return crypto.subtle
    .encrypt(
      {
        name: "AES-GCM",
        iv,
      },
      key,
      data
    )
    .then((cipher) => {
      const encryptedDataEncoder = encoding.createEncoder();
      encoding.writeVarString(encryptedDataEncoder, "AES-GCM");
      encoding.writeVarUint8Array(encryptedDataEncoder, iv);
      encoding.writeVarUint8Array(encryptedDataEncoder, new Uint8Array(cipher));
      return encoding.toUint8Array(encryptedDataEncoder);
    });
}
@param {Uint8Array} data data to be encrypted
@param {CryptoKey?} key
@return {PromiseLike<Uint8Array>} encrypted, base64 encoded message