How to ´Promise.all´ the values of a JS hash

For doing something like this:

var hash = { key1: value1, key2: promise2, ... };
Promise.all(hash).then(hash => ...);

I wrote this little function:

  function promiseAll(hash) {
    const keys = Object.keys(hash);
    const values = keys.map(key => hash[key]);
    return Promise.all(values).then(resolved_values => {
      const resolved_hash = {};
      keys.forEach((key, index) => {
        resolved_hash[key] = resolved_values[index];
      });
      return resolved_hash;
    });
  }

which allows you to do this:

var hash = { key1: value1, key2: promise2, ... };
promiseAll(hash).then(hash => ...);

How to promise in Chrome extensions

The following setup of Message Passing for communicating JSON data from a content script to a popup script is pretty usual:

  chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
    if (sender.tab) {
      return;
    }
    switch (request) {
    case 'selected_count':
      const count = selected_count();
      console.log('selected_count:', count);
      sendResponse({
        data: count
      });
      break;
    case 'selected_items':
      const items = selected_items();
      console.log('selected_items:', items);
      sendResponse({
        data: items
      });
      break;
    case 'unselect_all':
      unselect_all();
      break;
    }
  });

However, if some ´items´ contain data that you get asynchronously (like an image), then the setup above will fail if those data are not loaded before the handler returns.

Unfortunately, ´Promise´s are the right tool for the job in this case, but you can’t use them right away, because you can’t send a promise back to the popup and let it handle that, because a message can’t contain a promise, because

A message can contain any valid JSON object (null, boolean, number, string, array, or [my annotation: POJO] object).

Fortunately, according to the documentation,

If you want to asynchronously use ´sendResponse´, add ´return true;´ to the ´onMessage´ event handler.

which you can do like I show in the rewrite below, where I use a ´Promise´ object to take care of the asynchronous bits:

  chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
    const KEEP_CHANNEL_OPEN = true;
    const CLOSE_CHANNEL = false;
    var result = CLOSE_CHANNEL;
    if (sender.tab) {
      return result;
    }
    switch (request) {
    case 'selected_count':
      const count = selected_count();
      console.log('selected_count:', count);
      sendResponse({
        data: count
      });
      break;
    case 'selected_items':
      selected_items().then(items => {
        console.log('selected_items:', items);
        sendResponse({
          data: items
        });
      });
      result = KEEP_CHANNEL_OPEN;
      break;
    case 'unselect_all':
      unselect_all();
      break;
    }
    return result;
  });

 

How to use Rake::PackageTask to create a zip file

I found out that the easiest way to build a WordPress plugin is using a rake task. In fact, you can use Rake::PackageTask to create a zip file. However, there is very little documentation about how to do it in practice. Here is my solution.

  1. (destroy and) create a folder to hold just the needed files
  2. copy the (possibly transformed) needed files to that folder
  3. compress the folder

Here is my Rakefile:

require 'rake/packagetask'

namespace :nzymes do
    desc 'Build plugin'
    task build: %w(destroy create package)

    desc 'Destroy dist folder and its contents'
    task :destroy do
      rm_rf 'dist'
    end

    desc 'Create dist folder and its contents'
    task :create do
      mkdir_p 'dist/nzymes/vendor'
      cp_r 'vendor/Ando', 'dist/nzymes/vendor'
      cp_r 'src', 'dist/nzymes'
      cp_r Dir.glob('*.php'), 'dist/nzymes'
      cp_r Dir.glob('*.md'), 'dist/nzymes'
      cp_r 'readme.txt', 'dist/nzymes'
    end

    Rake::PackageTask.new('nzymes', :noversion) do |p|
      p.need_zip = true
      p.package_dir = 'dist'
    end
end

Here are the tasks it creates:

andrea at Lock-and-Stock in ~/dev/wordpress/plugins/nzymes on master [!?$]
$ rake --tasks
rake nzymes:build            # Build plugin
rake nzymes:clobber_package  # Remove package products
rake nzymes:create           # Create dist folder and its contents
rake nzymes:destroy          # Destroy dist folder and its contents
rake nzymes:package          # Build all the packages
rake nzymes:repackage        # Force a rebuild of the package files

Here is how you can use it:

andrea at Lock-and-Stock in ~/dev/wordpress/plugins/nzymes on master [!?$]
$ rake nzymes:build
rm -rf dist
mkdir -p dist/nzymes/vendor
cp -r vendor/Ando dist/nzymes/vendor
cp -r src dist/nzymes
cp -r nzymes.php dist/nzymes
cp -r nzymes-manual.md README.md dist/nzymes
cp -r readme.txt dist/nzymes
cd dist
zip -r nzymes.zip nzymes
  adding: nzymes/ (stored 0%)
  adding: nzymes/nzymes-manual.md (deflated 70%)
  adding: nzymes/nzymes.php (deflated 46%)
  adding: nzymes/README.md (deflated 48%)
  adding: nzymes/readme.txt (deflated 53%)
  adding: nzymes/src/ (stored 0%)
  adding: nzymes/src/Nzymes/ (stored 0%)
  adding: nzymes/src/Nzymes/Capabilities.php (deflated 84%)
  adding: nzymes/src/Nzymes/Engine.php (deflated 80%)
  adding: nzymes/src/Nzymes/Options.php (deflated 73%)
  adding: nzymes/src/Nzymes/Plugin.php (deflated 74%)
  adding: nzymes/src/Nzymes/Stack.php (deflated 70%)
  adding: nzymes/src/Nzymes/Unused.php (deflated 69%)
  adding: nzymes/vendor/ (stored 0%)
  adding: nzymes/vendor/Ando/ (stored 0%)
  adding: nzymes/vendor/Ando/ErrorFactory.php (deflated 79%)
  adding: nzymes/vendor/Ando/Exception.php (deflated 29%)
  adding: nzymes/vendor/Ando/Regex.php (deflated 78%)
  adding: nzymes/vendor/Ando/StarFunc.php (deflated 73%)
cd -

Here is what you get:

andrea at Lock-and-Stock in ~/dev/wordpress/plugins/nzymes on master [$]
$ ls -la dist
total 104
drwxr-xr-x   4 andrea  staff    136 May 25 13:03 .
drwxr-xr-x@ 20 andrea  staff    680 May 25 13:03 ..
drwxr-xr-x   8 andrea  staff    272 May 25 13:03 nzymes
-rw-r--r--   1 andrea  staff  50814 May 25 13:03 nzymes.zip