const fs = require('fs')
const path = require('path')
const del = require('del')
const babel = require('babel-core')
const buble = require('buble')
const rollup = require('rollup')
const resolvePlugin = require('rollup-plugin-node-resolve')
const babelPlugin = require('rollup-plugin-babel')
const externalsPlugin = require('rollup-plugin-auto-external')

const bundles = [
  {
    input: {
      input: path.resolve('src/index.js'),
      plugins: [
        babelPlugin({
          exclude: 'node_modules/**'
        }),
        resolvePlugin(),
        externalsPlugin({ dependencies: true, peerDependecies: true })
      ]
    },
    output: {
      format: 'es'
    }
  },
  {
    input: {
      input: path.resolve('src/index.js'),
      plugins: [
        babelPlugin({
          exclude: 'node_modules/**'
        }),
        resolvePlugin(),
        externalsPlugin({ dependencies: true, peerDependecies: true })
      ]
    },
    output: {
      format: 'cjs'
    }
  },
  {
    input: {
      input: path.resolve('src/index.js'),
      plugins: [
        babelPlugin({
          exclude: 'node_modules/**'
        }),
        resolvePlugin(),
        externalsPlugin({ dependencies: false, peerDependecies: true })
      ]
    },
    output: {
      format: 'umd',
      name: 'observer'
    }
  }
]

async function build () {
  // Clean up the output directory
  await del(path.resolve('dist'))
  fs.mkdirSync(path.resolve('dist'))

  // Compile source code into a distributable format with Babel and Rollup
  for (const config of bundles) {
    const es6Path = path.resolve('dist', `${config.output.format}.es6.js`)
    const bundle = await rollup.rollup(config.input)
    const { code: es6Code } = await bundle.generate(config.output)
    fs.writeFileSync(es6Path, es6Code, 'utf-8')

    const es6MinPath = path.resolve(
      'dist',
      `${config.output.format}.es6.min.js`
    )
    const { code: es6MinCode } = babel.transform(es6Code, {
      presets: ['minify']
    })
    fs.writeFileSync(es6MinPath, es6MinCode, 'utf-8')

    const es5Path = path.resolve('dist', `${config.output.format}.es5.js`)
    const { code: es5Code } = buble.transform(es6Code, {
      transforms: {
        dangerousForOf: true,
        modules: false
      }
    })
    fs.writeFileSync(es5Path, es5Code, 'utf-8')

    const es5MinPath = path.resolve(
      'dist',
      `${config.output.format}.es5.min.js`
    )
    const { code: es5MinCode } = babel.transform(es5Code, {
      presets: ['minify']
    })
    fs.writeFileSync(es5MinPath, es5MinCode, 'utf-8')
  }
}

build()

@@ -1943,32 +1943,171 @@
 form(es6Code, %7B%0A
+      // dead code elimination breaks the delete trap%0A      // by moving the hadKey part after the deletion, which always results in false%0A
       presets: %5B
@@ -2097,32 +2097,33 @@
 %0A      presets: 
+%5B
 %5B'minify'%5D%0A    %7D
@@ -2107,32 +2107,54 @@
 sets: %5B%5B'minify'
+, %7B deadcode: false %7D%5D
 %5D%0A    %7D)%0A    fs.
@@ -2645,16 +2645,17 @@
 resets: 
+%5B
 %5B'minify
@@ -2655,16 +2655,38 @@
 'minify'
+, %7B deadcode: false %7D%5D
 %5D%0A    %7D)

fix the minified build