Level / community

Discussion, support and common information for projects in the community.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Maintenance round: drop legacy features & runtime environments

vweevers opened this issue · comments

Across the board, drop legacy range options (#86), node 6, node 8, IE11, stock Android browser, Safari 9-11. Use latest buffer, standard, sinon and nyc. Require support of Promise, queue-microtask, const, let, Object.assign, arrow functions and async generators.

Tasks:

@ralphtheninja @juliangruber I tested and looked up some more ES6+ features. We can now use many goodies: Symbol, destructuring, rest parameters, block scoped let/const, Map, Set, String.prototype.startsWith, Array.from(), etc.

If we drop support of Safari < 11.1 (2018-04-12, 0.43% global share) and Safari iOS < 11.3 (2018-03-29, 0.69%) then we can also use Rest/Spread Properties and Spread in object literals. That alone is not worth it, but...

If we drop support of Safari < 12 (2018-09-17, 0.5%) and Safari iOS < 12 (2018-09-17, 0.78%) then we can use async generators with for await...of ✨. See Level/abstract-leveldown#338 for an example. I previously planned to only support that on node.

React with thumbs up to drop those versions. I'm for.

Tests (click to expand)
// Temporary test for browsers
test('language features', function (t) {
  // Destructuring
  const { foo } = { foo: 1 }
  t.is(foo, 1)

  // Rest/Spread Properties. Not on Safari < 11.1 (2018-04-12, 0.43%), Safari iOS < 11.3 (2018-03-29, 0.69%)
  // https://github.com/tc39/proposal-object-rest-spread
  const { a, ...rest } = { a: 1, b: 2, c: 3 }
  t.is(a, 1)
  t.same(Object.keys(rest), ['b', 'c'])

  // Spread in object literals
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#spread_in_object_literals
  t.same({ ...rest, c: 100 }, { b: 2, c: 100 }) // Not on Safari iOS < 11.3 (2018-03-29, 0.69%)

  // Rest parameters
  ;((...rest) => t.same(rest, [1, 2, 3]))(1, 2, 3)

  // Block scope
  const x = 9
  for (const x of [10]) t.is(x, 10)
  { const x = 11; t.is(x, 11) }
  t.is(x, 9)

  t.is(`foo ${88}`, 'foo 88')

  // Random stuff
  class Test {}
  t.is(typeof Test, 'function')
  t.is(typeof global.Map, 'function', 'map')
  t.is(typeof global.Set, 'function', 'set')
  t.is(typeof String.prototype.startsWith, 'function', 'String#startsWith')
  t.is(typeof String.prototype.includes, 'function', 'String#includes')
  t.is(typeof Array.from, 'function', 'Array.from()')
  t.is(typeof Number.isInteger, 'function', 'Number.isInteger')

  // Symbol
  const kA = Symbol('a')
  const kB = Symbol('b')
  const obj = { [kA]: true, [kB]: false }
  t.is(obj[kA], true)
  t.is(obj[kB], false)
  t.is(typeof Symbol.for, 'function', 'global symbol registry')

  new Promise((resolve) => resolve(123)).then((res) => {
    t.is(res, 123)
    t.end()
  })
})

// Not on Safari < 12 (0.5%, 2018-09-17) and Safari iOS < 12 (0.78%, 2018-09-17)
test('async generator', async function (t) {
  let ended = false

  async function * generator () {
    try {
      yield 1
      yield 2
      yield 3
    } finally {
      ended = true
    }
  }

  const res = []

  for await (const x of generator()) {
    res.push(x)
  }

  t.same(res, [1, 2, 3])
  t.is(ended, true)
})