web-platform-dx / web-features

Exploring how to present Web platform features adoptability
Apache License 2.0
305 stars 49 forks source link

Cataloging ECMAScript #579

Open Elchi3 opened 4 months ago

Elchi3 commented 4 months ago

I think if we want to catalog the web platform it requires a Birds Eye view down to the individual features. So I thought it'd be a good exercise to do that with everything defined in ECMAScript as it doesn't really interfere with the other technologies (unlike HTML, CSS which have API reflections etc.). I removed Temporal and Intl out of the discussion for now and then this exercise is about how to sort 901 features present in the javascript.* BCD tree. I would love to hear what others think about how to catalog ECMAScript.

I'm building on the idea of snapshots and capabilities in https://github.com/web-platform-dx/web-features/issues/558#issuecomment-1921544581 and I'm using BCD's tags. A branch with tags applied to BCD can be found here: https://github.com/mdn/browser-compat-data/compare/main...Elchi3:browser-compat-data:ecmascript-tags


First, I came up with snapshots tags (in BCD I tagged them as "web-features:ecmascript-1" etc. but we could also make clear these are snapshots by using a prefix or so: "web-features-snapshot:ecmascript-1"). I went through the specs and categorized ~750/901 features by their snapshot (rest TBD):

ECMAScript 1 (194 features)

- javascript.builtins.Array - javascript.builtins.Array.Array - javascript.builtins.Array.join - javascript.builtins.Array.length - javascript.builtins.Array.reverse - javascript.builtins.Array.sort - javascript.builtins.Array.toString - javascript.builtins.Boolean - javascript.builtins.Boolean.Boolean - javascript.builtins.Boolean.toString - javascript.builtins.Boolean.valueOf - javascript.builtins.Date - javascript.builtins.Date.Date - javascript.builtins.Date.UTC - javascript.builtins.Date.getDate - javascript.builtins.Date.getDay - javascript.builtins.Date.getFullYear - javascript.builtins.Date.getHours - javascript.builtins.Date.getMilliseconds - javascript.builtins.Date.getMinutes - javascript.builtins.Date.getMonth - javascript.builtins.Date.getSeconds - javascript.builtins.Date.getTime - javascript.builtins.Date.getTimezoneOffset - javascript.builtins.Date.getUTCDate - javascript.builtins.Date.getUTCDay - javascript.builtins.Date.getUTCFullYear - javascript.builtins.Date.getUTCHours - javascript.builtins.Date.getUTCMilliseconds - javascript.builtins.Date.getUTCMinutes - javascript.builtins.Date.getUTCMonth - javascript.builtins.Date.getUTCSeconds - javascript.builtins.Date.getYear - javascript.builtins.Date.parse - javascript.builtins.Date.setDate - javascript.builtins.Date.setFullYear - javascript.builtins.Date.setHours - javascript.builtins.Date.setMilliseconds - javascript.builtins.Date.setMinutes - javascript.builtins.Date.setMonth - javascript.builtins.Date.setSeconds - javascript.builtins.Date.setTime - javascript.builtins.Date.setUTCDate - javascript.builtins.Date.setUTCFullYear - javascript.builtins.Date.setUTCHours - javascript.builtins.Date.setUTCMilliseconds - javascript.builtins.Date.setUTCMinutes - javascript.builtins.Date.setUTCMonth - javascript.builtins.Date.setUTCSeconds - javascript.builtins.Date.setYear - javascript.builtins.Date.toGMTString - javascript.builtins.Date.toLocaleString - javascript.builtins.Date.toString - javascript.builtins.Date.toUTCString - javascript.builtins.Date.valueOf - javascript.builtins.Function - javascript.builtins.Function.Function - javascript.builtins.Function.length - javascript.builtins.Function.toString - javascript.builtins.Math - javascript.builtins.Math.E - javascript.builtins.Math.LN10 - javascript.builtins.Math.LN2 - javascript.builtins.Math.LOG10E - javascript.builtins.Math.LOG2E - javascript.builtins.Math.PI - javascript.builtins.Math.SQRT1_2 - javascript.builtins.Math.SQRT2 - javascript.builtins.Math.abs - javascript.builtins.Math.acos - javascript.builtins.Math.asin - javascript.builtins.Math.atan - javascript.builtins.Math.atan2 - javascript.builtins.Math.ceil - javascript.builtins.Math.cos - javascript.builtins.Math.exp - javascript.builtins.Math.floor - javascript.builtins.Math.log - javascript.builtins.Math.max - javascript.builtins.Math.min - javascript.builtins.Math.pow - javascript.builtins.Math.random - javascript.builtins.Math.round - javascript.builtins.Math.sin - javascript.builtins.Math.sqrt - javascript.builtins.Math.tan - javascript.builtins.Number - javascript.builtins.Number.MAX_VALUE - javascript.builtins.Number.MIN_VALUE - javascript.builtins.Number.NaN - javascript.builtins.Number.NEGATIVE_INFINITY - javascript.builtins.Number.Number - javascript.builtins.Number.POSITIVE_INFINITY - javascript.builtins.Number.toString - javascript.builtins.Number.valueOf - javascript.builtins.Object - javascript.builtins.Object.Object - javascript.builtins.Object.toString - javascript.builtins.Object.valueOf - javascript.builtins.String - javascript.builtins.String.String - javascript.builtins.String.charAt - javascript.builtins.String.charCodeAt - javascript.builtins.String.fromCharCode - javascript.builtins.String.indexOf - javascript.builtins.String.lastIndexOf - javascript.builtins.String.length - javascript.builtins.String.split - javascript.builtins.String.substring - javascript.builtins.String.toLowerCase - javascript.builtins.String.toString - javascript.builtins.String.toUpperCase - javascript.builtins.String.valueOf - javascript.builtins.Infinity - javascript.builtins.NaN - javascript.builtins.escape - javascript.builtins.eval - javascript.builtins.isFinite - javascript.builtins.isNaN - javascript.builtins.parseFloat - javascript.builtins.parseInt - javascript.builtins.undefined - javascript.builtins.unescape - javascript.functions - javascript.functions.arguments - javascript.functions.arguments.callee - javascript.functions.arguments.length - javascript.grammar.boolean_literals - javascript.grammar.decimal_numeric_literals - javascript.grammar.hexadecimal_numeric_literals - javascript.grammar.null_literal - javascript.grammar.string_literals - javascript.grammar.unicode_escape_sequences - javascript.operators.addition - javascript.operators.addition_assignment - javascript.operators.assignment - javascript.operators.bitwise_and - javascript.operators.bitwise_and_assignment - javascript.operators.bitwise_not - javascript.operators.bitwise_or - javascript.operators.bitwise_or_assignment - javascript.operators.bitwise_xor - javascript.operators.bitwise_xor_assignment - javascript.operators.comma - javascript.operators.conditional - javascript.operators.decrement - javascript.operators.delete - javascript.operators.division - javascript.operators.division_assignment - javascript.operators.equality - javascript.operators.function - javascript.operators.greater_than - javascript.operators.greater_than_or_equal - javascript.operators.grouping - javascript.operators.in - javascript.operators.increment - javascript.operators.inequality - javascript.operators.left_shift - javascript.operators.left_shift_assignment - javascript.operators.less_than - javascript.operators.less_than_or_equal - javascript.operators.logical_and - javascript.operators.logical_not - javascript.operators.logical_or - javascript.operators.multiplication - javascript.operators.multiplication_assignment - javascript.operators.new - javascript.operators.null - javascript.operators.property_accessors - javascript.operators.remainder - javascript.operators.remainder_assignment - javascript.operators.right_shift - javascript.operators.right_shift_assignment - javascript.operators.subtraction - javascript.operators.subtraction_assignment - javascript.operators.this - javascript.operators.typeof - javascript.operators.unary_negation - javascript.operators.unary_plus - javascript.operators.unsigned_right_shift - javascript.operators.unsigned_right_shift_assignment - javascript.operators.void - javascript.statements.block - javascript.statements.break - javascript.statements.continue - javascript.statements.empty - javascript.statements.for - javascript.statements.for_in - javascript.statements.function - javascript.statements.if_else - javascript.statements.return - javascript.statements.var - javascript.statements.while - javascript.statements.with

ECMAScript 3 (79 features)

javascript.builtins.Array.concat javascript.builtins.Array.pop javascript.builtins.Array.push javascript.builtins.Array.shift javascript.builtins.Array.slice javascript.builtins.Array.toLocaleString javascript.builtins.Array.unshift javascript.builtins.Date.toDateString javascript.builtins.Date.toLocaleDateString javascript.builtins.Date.toLocaleTimeString javascript.builtins.Date.toTimeString javascript.builtins.Error javascript.builtins.Error.Error javascript.builtins.Error.message javascript.builtins.Error.name javascript.builtins.Error.toString javascript.builtins.EvalError javascript.builtins.EvalError.EvalError javascript.builtins.Function.apply javascript.builtins.Function.call javascript.builtins.Number.toExponential javascript.builtins.Number.toFixed javascript.builtins.Number.toLocaleString javascript.builtins.Number.toPrecision javascript.builtins.Object.hasOwnProperty javascript.builtins.Object.isPrototypeOf javascript.builtins.Object.propertyIsEnumerable javascript.builtins.Object.toLocaleString javascript.builtins.RangeError javascript.builtins.RangeError.RangeError javascript.builtins.ReferenceError javascript.builtins.ReferenceError.ReferenceError javascript.builtins.RegExp javascript.builtins.RegExp.RegExp javascript.builtins.RegExp.exec javascript.builtins.RegExp.global javascript.builtins.RegExp.ignoreCase javascript.builtins.RegExp.lastIndex javascript.builtins.RegExp.multiline javascript.builtins.RegExp.source javascript.builtins.RegExp.test javascript.builtins.RegExp.toString javascript.builtins.String.concat javascript.builtins.String.localeCompare javascript.builtins.String.match javascript.builtins.String.replace javascript.builtins.String.search javascript.builtins.String.slice javascript.builtins.String.substr javascript.builtins.String.toLocaleLowerCase javascript.builtins.String.toLocaleUpperCase javascript.builtins.SyntaxError javascript.builtins.SyntaxError.SyntaxError javascript.builtins.TypeError javascript.builtins.TypeError.TypeError javascript.builtins.URIError javascript.builtins.URIError.URIError javascript.builtins.decodeURI javascript.builtins.decodeURIComponent javascript.builtins.encodeURI javascript.builtins.encodeURIComponent javascript.grammar.regular_expression_literals javascript.regular_expressions.backreference javascript.regular_expressions.capturing_group javascript.regular_expressions.character_class javascript.regular_expressions.character_class_escape javascript.regular_expressions.character_escape javascript.regular_expressions.disjunction javascript.regular_expressions.input_boundary_assertion javascript.regular_expressions.literal_character javascript.regular_expressions.lookahead_assertion javascript.regular_expressions.non_capturing_group javascript.regular_expressions.quantifier javascript.regular_expressions.wildcard javascript.regular_expressions.word_boundary_assertion javascript.statements.do_while javascript.statements.label javascript.statements.throw javascript.statements.try_catch

ECMAScript 5 (35 features)

- javascript.builtins.Array.every - javascript.builtins.Array.filter - javascript.builtins.Array.forEach - javascript.builtins.Array.indexOf - javascript.builtins.Array.isArray - javascript.builtins.Array.lastIndexOf - javascript.builtins.Array.map - javascript.builtins.Array.reduce - javascript.builtins.Array.reduceRight - javascript.builtins.Array.some - javascript.builtins.Date.now - javascript.builtins.Date.parse.iso_8601 - javascript.builtins.Date.toISOString - javascript.builtins.Date.toJSON - javascript.builtins.Function.apply.generic_arrays_as_arguments - javascript.builtins.Function.bind - javascript.builtins.JSON - javascript.builtins.JSON.parse - javascript.builtins.JSON.stringify - javascript.builtins.Object.create - javascript.builtins.Object.defineProperties - javascript.builtins.Object.defineProperty - javascript.builtins.Object.freeze - javascript.builtins.Object.getOwnPropertyDescriptor - javascript.builtins.Object.getOwnPropertyNames - javascript.builtins.Object.getPrototypeOf - javascript.builtins.Object.isExtensible - javascript.builtins.Object.isFrozen - javascript.builtins.Object.isSealed - javascript.builtins.Object.keys - javascript.builtins.Object.preventExtensions - javascript.builtins.Object.seal - javascript.builtins.String.trim - javascript.functions.get - javascript.functions.set

ECMAScript 2015 (355 features)

- javascript.builtins.Array.copyWithin - javascript.builtins.Array.entries - javascript.builtins.Array.fill - javascript.builtins.Array.find - javascript.builtins.Array.findIndex - javascript.builtins.Array.from - javascript.builtins.Array.keys - javascript.builtins.Array.of - javascript.builtins.Array.splice - javascript.builtins.Array.values - javascript.builtins.Array.@@iterator - javascript.builtins.Array.@@species - javascript.builtins.Array.@@unscopables - javascript.builtins.ArrayBuffer - javascript.builtins.ArrayBuffer.ArrayBuffer - javascript.builtins.ArrayBuffer.ArrayBuffer.new_required - javascript.builtins.ArrayBuffer.byteLength - javascript.builtins.ArrayBuffer.isView - javascript.builtins.ArrayBuffer.slice - javascript.builtins.ArrayBuffer.@@species - javascript.builtins.DataView - javascript.builtins.DataView.DataView - javascript.builtins.DataView.DataView.new_required - javascript.builtins.DataView.buffer - javascript.builtins.DataView.byteLength - javascript.builtins.DataView.byteOffset - javascript.builtins.DataView.getFloat32 - javascript.builtins.DataView.getFloat64 - javascript.builtins.DataView.getInt16 - javascript.builtins.DataView.getInt32 - javascript.builtins.DataView.getInt8 - javascript.builtins.DataView.getUint16 - javascript.builtins.DataView.getUint32 - javascript.builtins.DataView.getUint8 - javascript.builtins.DataView.setFloat32 - javascript.builtins.DataView.setFloat64 - javascript.builtins.DataView.setInt16 - javascript.builtins.DataView.setInt32 - javascript.builtins.DataView.setInt8 - javascript.builtins.DataView.setUint16 - javascript.builtins.DataView.setUint32 - javascript.builtins.DataView.setUint8 - javascript.builtins.Date.@@toPrimitive - javascript.builtins.Float32Array - javascript.builtins.Float32Array.Float32Array - javascript.builtins.Float32Array.Float32Array.constructor_without_parameters - javascript.builtins.Float32Array.Float32Array.iterable_allowed - javascript.builtins.Float32Array.Float32Array.new_required - javascript.builtins.Float64Array - javascript.builtins.Float64Array.Float64Array - javascript.builtins.Float64Array.Float64Array.constructor_without_parameters - javascript.builtins.Float64Array.Float64Array.iterable_allowed - javascript.builtins.Float64Array.Float64Array.new_required - javascript.builtins.Function.length.configurable_true - javascript.builtins.Function.name - javascript.builtins.Function.name.configurable_true - javascript.builtins.Function.name.inferred_names - javascript.builtins.Function.@@hasInstance - javascript.builtins.Generator - javascript.builtins.Generator.next - javascript.builtins.Generator.return - javascript.builtins.Generator.throw - javascript.builtins.GeneratorFunction - javascript.builtins.GeneratorFunction.GeneratorFunction - javascript.builtins.Int16Array - javascript.builtins.Int16Array.Int16Array - javascript.builtins.Int16Array.Int16Array.constructor_without_parameters - javascript.builtins.Int16Array.Int16Array.iterable_allowed - javascript.builtins.Int16Array.Int16Array.new_required - javascript.builtins.Int32Array - javascript.builtins.Int32Array.Int32Array - javascript.builtins.Int32Array.Int32Array.constructor_without_parameters - javascript.builtins.Int32Array.Int32Array.iterable_allowed - javascript.builtins.Int32Array.Int32Array.new_required - javascript.builtins.Int8Array - javascript.builtins.Int8Array.Int8Array - javascript.builtins.Int8Array.Int8Array.constructor_without_parameters - javascript.builtins.Int8Array.Int8Array.iterable_allowed - javascript.builtins.Int8Array.Int8Array.new_required - javascript.builtins.Iterator - javascript.builtins.Iterator.@@iterator - javascript.builtins.Map - javascript.builtins.Map.Map - javascript.builtins.Map.Map.iterable_allowed - javascript.builtins.Map.Map.new_required - javascript.builtins.Map.Map.null_allowed - javascript.builtins.Map.clear - javascript.builtins.Map.delete - javascript.builtins.Map.entries - javascript.builtins.Map.forEach - javascript.builtins.Map.get - javascript.builtins.Map.has - javascript.builtins.Map.key_equality_for_zeros - javascript.builtins.Map.keys - javascript.builtins.Map.set - javascript.builtins.Map.size - javascript.builtins.Map.values - javascript.builtins.Map.@@iterator - javascript.builtins.Map.@@species - javascript.builtins.Math.acosh - javascript.builtins.Math.asinh - javascript.builtins.Math.atanh - javascript.builtins.Math.cbrt - javascript.builtins.Math.clz32 - javascript.builtins.Math.cosh - javascript.builtins.Math.expm1 - javascript.builtins.Math.fround - javascript.builtins.Math.hypot - javascript.builtins.Math.imul - javascript.builtins.Math.log10 - javascript.builtins.Math.log1p - javascript.builtins.Math.log2 - javascript.builtins.Math.sign - javascript.builtins.Math.sinh - javascript.builtins.Math.tanh - javascript.builtins.Math.trunc - javascript.builtins.Number.EPSILON - javascript.builtins.Number.MAX_SAFE_INTEGER - javascript.builtins.Number.MIN_SAFE_INTEGER - javascript.builtins.Number.isFinite - javascript.builtins.Number.isInteger - javascript.builtins.Number.isNaN - javascript.builtins.Number.isSafeInteger - javascript.builtins.Number.parseFloat - javascript.builtins.Number.parseInt - javascript.builtins.Object.assign - javascript.builtins.Object.getOwnPropertySymbols - javascript.builtins.Object.is - javascript.builtins.Object.preventExtensions.ES2015_behavior - javascript.builtins.Object.proto - javascript.builtins.Object.setPrototypeOf - javascript.builtins.Promise - javascript.builtins.Promise.Promise - javascript.builtins.Promise.all - javascript.builtins.Promise.catch - javascript.builtins.Promise.race - javascript.builtins.Promise.reject - javascript.builtins.Promise.resolve - javascript.builtins.Promise.then - javascript.builtins.Promise.@@species - javascript.builtins.Proxy - javascript.builtins.Proxy.Proxy - javascript.builtins.Proxy.handler.apply - javascript.builtins.Proxy.handler.construct - javascript.builtins.Proxy.handler.defineProperty - javascript.builtins.Proxy.handler.deleteProperty - javascript.builtins.Proxy.handler.get - javascript.builtins.Proxy.handler.getOwnPropertyDescriptor - javascript.builtins.Proxy.handler.getPrototypeOf - javascript.builtins.Proxy.handler.has - javascript.builtins.Proxy.handler.isExtensible - javascript.builtins.Proxy.handler.ownKeys - javascript.builtins.Proxy.handler.preventExtensions - javascript.builtins.Proxy.handler.set - javascript.builtins.Proxy.handler.setPrototypeOf - javascript.builtins.Proxy.revocable - javascript.builtins.Reflect - javascript.builtins.Reflect.apply - javascript.builtins.Reflect.construct - javascript.builtins.Reflect.defineProperty - javascript.builtins.Reflect.deleteProperty - javascript.builtins.Reflect.get - javascript.builtins.Reflect.getOwnPropertyDescriptor - javascript.builtins.Reflect.getPrototypeOf - javascript.builtins.Reflect.has - javascript.builtins.Reflect.isExtensible - javascript.builtins.Reflect.ownKeys - javascript.builtins.Reflect.preventExtensions - javascript.builtins.Reflect.set - javascript.builtins.Reflect.setPrototypeOf - javascript.builtins.RegExp.compile - javascript.builtins.RegExp.flags - javascript.builtins.RegExp.@@match - javascript.builtins.RegExp.@@replace - javascript.builtins.RegExp.@@search - javascript.builtins.RegExp.@@species - javascript.builtins.RegExp.@@split - javascript.builtins.Set - javascript.builtins.Set.Set - javascript.builtins.Set.Set.iterable_allowed - javascript.builtins.Set.Set.new_required - javascript.builtins.Set.Set.null_allowed - javascript.builtins.Set.add - javascript.builtins.Set.clear - javascript.builtins.Set.delete - javascript.builtins.Set.entries - javascript.builtins.Set.forEach - javascript.builtins.Set.has - javascript.builtins.Set.key_equality_for_zeros - javascript.builtins.Set.keys - javascript.builtins.Set.size - javascript.builtins.Set.values - javascript.builtins.Set.@@iterator - javascript.builtins.Set.@@species - javascript.builtins.String.anchor - javascript.builtins.String.big - javascript.builtins.String.blink - javascript.builtins.String.bold - javascript.builtins.String.codePointAt - javascript.builtins.String.endsWith - javascript.builtins.String.fixed - javascript.builtins.String.fontcolor - javascript.builtins.String.fontsize - javascript.builtins.String.fromCodePoint - javascript.builtins.String.includes - javascript.builtins.String.italics - javascript.builtins.String.link - javascript.builtins.String.normalize - javascript.builtins.String.raw - javascript.builtins.String.repeat - javascript.builtins.String.small - javascript.builtins.String.startsWith - javascript.builtins.String.strike - javascript.builtins.String.sub - javascript.builtins.String.sup - javascript.builtins.String.@@iterator - javascript.builtins.Symbol - javascript.builtins.Symbol.Symbol - javascript.builtins.Symbol.for - javascript.builtins.Symbol.hasInstance - javascript.builtins.Symbol.isConcatSpreadable - javascript.builtins.Symbol.iterator - javascript.builtins.Symbol.keyFor - javascript.builtins.Symbol.match - javascript.builtins.Symbol.replace - javascript.builtins.Symbol.search - javascript.builtins.Symbol.species - javascript.builtins.Symbol.split - javascript.builtins.Symbol.toPrimitive - javascript.builtins.Symbol.toString - javascript.builtins.Symbol.toStringTag - javascript.builtins.Symbol.toStringTag.dom_objects - javascript.builtins.Symbol.unscopables - javascript.builtins.Symbol.valueOf - javascript.builtins.Symbol.@@toPrimitive - javascript.builtins.TypedArray - javascript.builtins.TypedArray.BYTES_PER_ELEMENT - javascript.builtins.TypedArray.buffer - javascript.builtins.TypedArray.byteLength - javascript.builtins.TypedArray.byteOffset - javascript.builtins.TypedArray.constructor_without_parameters - javascript.builtins.TypedArray.copyWithin - javascript.builtins.TypedArray.entries - javascript.builtins.TypedArray.every - javascript.builtins.TypedArray.fill - javascript.builtins.TypedArray.filter - javascript.builtins.TypedArray.find - javascript.builtins.TypedArray.findIndex - javascript.builtins.TypedArray.findLast - javascript.builtins.TypedArray.findLastIndex - javascript.builtins.TypedArray.forEach - javascript.builtins.TypedArray.from - javascript.builtins.TypedArray.includes - javascript.builtins.TypedArray.index_properties_not_consulting_prototype - javascript.builtins.TypedArray.indexOf - javascript.builtins.TypedArray.iterable_in_constructor - javascript.builtins.TypedArray.join - javascript.builtins.TypedArray.keys - javascript.builtins.TypedArray.lastIndexOf - javascript.builtins.TypedArray.length - javascript.builtins.TypedArray.map - javascript.builtins.TypedArray.name - javascript.builtins.TypedArray.named_properties - javascript.builtins.TypedArray.new_required - javascript.builtins.TypedArray.of - javascript.builtins.TypedArray.reduce - javascript.builtins.TypedArray.reduceRight - javascript.builtins.TypedArray.reverse - javascript.builtins.TypedArray.set - javascript.builtins.TypedArray.slice - javascript.builtins.TypedArray.some - javascript.builtins.TypedArray.sort - javascript.builtins.TypedArray.subarray - javascript.builtins.TypedArray.toLocaleString - javascript.builtins.TypedArray.toString - javascript.builtins.TypedArray.values - javascript.builtins.TypedArray.@@iterator - javascript.builtins.TypedArray.@@species - javascript.builtins.Uint16Array - javascript.builtins.Uint16Array.Uint16Array - javascript.builtins.Uint16Array.Uint16Array.constructor_without_parameters - javascript.builtins.Uint16Array.Uint16Array.iterable_allowed - javascript.builtins.Uint16Array.Uint16Array.new_required - javascript.builtins.Uint32Array - javascript.builtins.Uint32Array.Uint32Array - javascript.builtins.Uint32Array.Uint32Array.constructor_without_parameters - javascript.builtins.Uint32Array.Uint32Array.iterable_allowed - javascript.builtins.Uint32Array.Uint32Array.new_required - javascript.builtins.Uint8Array - javascript.builtins.Uint8Array.Uint8Array - javascript.builtins.Uint8Array.Uint8Array.constructor_without_parameters - javascript.builtins.Uint8Array.Uint8Array.iterable_allowed - javascript.builtins.Uint8Array.Uint8Array.new_required - javascript.builtins.Uint8ClampedArray - javascript.builtins.Uint8ClampedArray.Uint8ClampedArray - javascript.builtins.Uint8ClampedArray.Uint8ClampedArray.constructor_without_parameters - javascript.builtins.Uint8ClampedArray.Uint8ClampedArray.iterable_allowed - javascript.builtins.Uint8ClampedArray.Uint8ClampedArray.new_required - javascript.builtins.WeakMap - javascript.builtins.WeakMap.WeakMap - javascript.builtins.WeakMap.WeakMap.iterable_allowed - javascript.builtins.WeakMap.WeakMap.new_required - javascript.builtins.WeakMap.WeakMap.null_allowed - javascript.builtins.WeakMap.delete - javascript.builtins.WeakMap.get - javascript.builtins.WeakMap.has - javascript.builtins.WeakMap.set - javascript.builtins.WeakSet - javascript.builtins.WeakSet.WeakSet - javascript.builtins.WeakSet.WeakSet.iterable_allowed - javascript.builtins.WeakSet.WeakSet.null_allowed - javascript.builtins.WeakSet.add - javascript.builtins.WeakSet.delete - javascript.builtins.WeakSet.has - javascript.classes - javascript.classes.constructor - javascript.classes.extends - javascript.classes.static - javascript.functions.arguments.@@iterator - javascript.functions.arrow_functions - javascript.functions.block_level_functions - javascript.functions.default_parameters - javascript.functions.default_parameters.destructured_parameter_with_default_value_assignment - javascript.functions.default_parameters.parameters_without_defaults_after_default_parameters - javascript.functions.get.computed_property_names - javascript.functions.method_definitions - javascript.functions.rest_parameters - javascript.functions.rest_parameters.destructuring - javascript.functions.set.computed_property_names - javascript.grammar.binary_numeric_literals - javascript.grammar.octal_numeric_literals - javascript.grammar.unicode_point_escapes - javascript.grammar.shorthand_object_literals - javascript.grammar.template_literals - javascript.operators.class - javascript.operators.destructuring - javascript.operators.destructuring.computed_property_names - javascript.operators.destructuring.rest_in_arrays - javascript.operators.destructuring.rest_in_objects - javascript.operators.generator_function - javascript.operators.new_target - javascript.operators.object_initializer.computed_property_names - javascript.operators.object_initializer.shorthand_method_names - javascript.operators.object_initializer.shorthand_property_names - javascript.operators.spread - javascript.operators.spread.spread_in_arrays - javascript.operators.spread.spread_in_function_calls - javascript.operators.super - javascript.operators.yield - javascript.operators.yield_star - javascript.statements.class - javascript.statements.const - javascript.statements.for_of - javascript.statements.generator_function - javascript.statements.let

ECMAScript 2016 (5 features)

- javascript.builtins.Array.includes - javascript.operators.exponentiation - javascript.operators.exponentiation_assignment - javascript.statements.generator_function.IteratorResult_object - javascript.statements.generator_function.not_constructable_with_new

ECMAScript 2017 (35 features)

- javascript.builtins.AsyncFunction - javascript.builtins.AsyncFunction.AsyncFunction - javascript.builtins.AsyncGenerator - javascript.builtins.AsyncGenerator.next - javascript.builtins.AsyncGenerator.return - javascript.builtins.AsyncGenerator.throw - javascript.builtins.AsyncGeneratorFunction - javascript.builtins.AsyncGeneratorFunction.AsyncGeneratorFunction - javascript.builtins.Atomics - javascript.builtins.Atomics.add - javascript.builtins.Atomics.and - javascript.builtins.Atomics.compareExchange - javascript.builtins.Atomics.exchange - javascript.builtins.Atomics.isLockFree - javascript.builtins.Atomics.load - javascript.builtins.Atomics.notify - javascript.builtins.Atomics.or - javascript.builtins.Atomics.store - javascript.builtins.Atomics.sub - javascript.builtins.Atomics.wait - javascript.builtins.Atomics.xor - javascript.builtins.DataView.DataView.sharedarraybuffer_support - javascript.builtins.DataView.buffer.sharedarraybuffer_support - javascript.builtins.Date.UTC.optional_monthIndex - javascript.builtins.Object.entries - javascript.builtins.Object.getOwnPropertyDescriptors - javascript.builtins.Object.values - javascript.builtins.SharedArrayBuffer - javascript.builtins.SharedArrayBuffer.SharedArrayBuffer - javascript.builtins.SharedArrayBuffer.byteLength - javascript.builtins.SharedArrayBuffer.slice - javascript.builtins.SharedArrayBuffer.@@species - javascript.builtins.String.padEnd - javascript.builtins.String.padStart - javascript.functions.arrow_functions.trailing_comma

ECMAScript 2018 (8 features)

- javascript.builtins.AsyncIterator - javascript.builtins.AsyncIterator.@@asyncIterator - javascript.builtins.Promise.finally - javascript.builtins.RegExp.dotAll - javascript.builtins.Symbol.asyncIterator - javascript.grammar.template_literals.template_literal_revision - javascript.statements.for_await_of - javascript.statements.for_of.async_iterators

ECMAScript 2019 (10 features)

- javascript.builtins.Array.flat - javascript.builtins.Array.flatMap - javascript.builtins.Array.sort.stable_sorting - javascript.builtins.Function.toString.toString_revision - javascript.builtins.JSON.json_superset - javascript.builtins.JSON.stringify.well_formed_stringify - javascript.builtins.Object.fromEntries - javascript.builtins.String.trimEnd - javascript.builtins.String.trimStart - javascript.builtins.Symbol.description

ECMAScript 2020 (22 features)

- javascript.builtins.BigInt - javascript.builtins.BigInt.BigInt - javascript.builtins.BigInt.asIntN - javascript.builtins.BigInt.asUintN - javascript.builtins.BigInt.toLocaleString - javascript.builtins.BigInt.toString - javascript.builtins.BigInt.valueOf - javascript.builtins.BigInt64Array - javascript.builtins.BigInt64Array.BigInt64Array - javascript.builtins.BigUint64Array - javascript.builtins.BigUint64Array.BigUint64Array - javascript.builtins.DataView.getBigInt64 - javascript.builtins.DataView.getBigUint64 - javascript.builtins.DataView.setBigInt64 - javascript.builtins.DataView.setBigUint64 - javascript.builtins.Promise.allSettled - javascript.builtins.String.matchAll - javascript.builtins.Symbol.matchAll - javascript.builtins.globalThis - javascript.operators.nullish_coalescing - javascript.operators.nullish_coalescing_assignment - javascript.operators.optional_chaining

ECMAScript 2021 (13 features)

- javascript.builtins.AggregateError - javascript.builtins.AggregateError.AggregateError - javascript.builtins.AggregateError.errors - javascript.builtins.Atomics.Atomic_operations_on_non_shared_buffers - javascript.builtins.FinalizationRegistry - javascript.builtins.FinalizationRegistry.FinalizationRegistry - javascript.builtins.FinalizationRegistry.register - javascript.builtins.FinalizationRegistry.unregister - javascript.builtins.Promise.any - javascript.builtins.String.replaceAll - javascript.builtins.WeakRef - javascript.builtins.WeakRef.WeakRef - javascript.builtins.WeakRef.deref

ECMAScript 2022 (7 features)

- javascript.builtins.Array.at - javascript.builtins.Error.Error.options_cause_parameter - javascript.builtins.Error.cause - javascript.builtins.Object.hasOwn - javascript.builtins.RegExp.hasIndices - javascript.builtins.String.at - javascript.builtins.TypedArray.at

ECMAScript 2023 (14 features)

- javascript.builtins.Array.findLast - javascript.builtins.Array.findLastIndex - javascript.builtins.Array.toReversed - javascript.builtins.Array.toSorted - javascript.builtins.Array.toSpliced - javascript.builtins.Array.with - javascript.builtins.FinalizationRegistry.symbol_as_target - javascript.builtins.TypedArray.toReversed - javascript.builtins.TypedArray.toSorted - javascript.builtins.TypedArray.with - javascript.builtins.WeakMap.symbol_as_keys - javascript.builtins.WeakRef.symbol_as_target - javascript.builtins.WeakSet.symbol_as_keys - javascript.grammar.hashbang_comments

ECMAScript 2024 (10 features)

- javascript.builtins.ArrayBuffer.ArrayBuffer.maxByteLength_option - javascript.builtins.ArrayBuffer.maxByteLength - javascript.builtins.ArrayBuffer.resizable - javascript.builtins.ArrayBuffer.resize - javascript.builtins.Atomics.waitAsync - javascript.builtins.SharedArrayBuffer.SharedArrayBuffer.maxByteLength_option - javascript.builtins.SharedArrayBuffer.grow - javascript.builtins.SharedArrayBuffer.growable - javascript.builtins.SharedArrayBuffer.maxByteLength - javascript.builtins.String.toWellFormed


Second, I came up with some capability groups. Here I'm trying to be user-oriented as I believe we want to show what the web can do (and ignore its evolution for a moment). I guess we want to ask: ECMAScript, what do you offer? And here we need to figure out how detailed we want to be. I drafted some high-level capability groups for ECMAScript. Would love to hear thoughts on these.


Third, we probably want to combine the high-level capability groups with the snapshots. One assumption we make is that the older/un-enhanced the capabilities are, the less interesting it is to break them down into sub groups. For example, the Date API has not seen substantial updates since ECMAScript 3 and so it is just the Date API as a whole without any meaningful iterations or new capabilities. For other high-level capabilities, like Arrays, this is very different. Here we probably want to break down what Arrays can do and since when; the snapshots help with that enormously. Compare Arrays and Date API:

Arrays

- web-features:ecmascript-1: javascript.builtins.Array - web-features:ecmascript-1: javascript.builtins.Array.Array - web-features:ecmascript-1: javascript.builtins.Array.join - web-features:ecmascript-1: javascript.builtins.Array.length - web-features:ecmascript-1: javascript.builtins.Array.reverse - web-features:ecmascript-1: javascript.builtins.Array.sort - web-features:ecmascript-1: javascript.builtins.Array.toString - web-features:ecmascript-1: javascript.grammar.array_literals - web-features:ecmascript-3: javascript.builtins.Array.concat - web-features:ecmascript-3: javascript.builtins.Array.pop - web-features:ecmascript-3: javascript.builtins.Array.push - web-features:ecmascript-3: javascript.builtins.Array.shift - web-features:ecmascript-3: javascript.builtins.Array.slice - web-features:ecmascript-3: javascript.builtins.Array.toLocaleString - web-features:ecmascript-3: javascript.builtins.Array.unshift - web-features:ecmascript-5: javascript.builtins.Array.every - web-features:ecmascript-5: javascript.builtins.Array.filter - web-features:ecmascript-5: javascript.builtins.Array.forEach - web-features:ecmascript-5: javascript.builtins.Array.indexOf - web-features:ecmascript-5: javascript.builtins.Array.isArray - web-features:ecmascript-5: javascript.builtins.Array.lastIndexOf - web-features:ecmascript-5: javascript.builtins.Array.map - web-features:ecmascript-5: javascript.builtins.Array.reduce - web-features:ecmascript-5: javascript.builtins.Array.reduceRight - web-features:ecmascript-5: javascript.builtins.Array.some - web-features:ecmascript-2015: javascript.builtins.Array.copyWithin - web-features:ecmascript-2015: javascript.builtins.Array.entries - web-features:ecmascript-2015: javascript.builtins.Array.fill - web-features:ecmascript-2015: javascript.builtins.Array.find - web-features:ecmascript-2015: javascript.builtins.Array.findIndex - web-features:ecmascript-2015: javascript.builtins.Array.from - web-features:ecmascript-2015: javascript.builtins.Array.keys - web-features:ecmascript-2015: javascript.builtins.Array.of - web-features:ecmascript-2015: javascript.builtins.Array.splice - web-features:ecmascript-2015: javascript.builtins.Array.values - web-features:ecmascript-2015: javascript.builtins.Array.@@iterator - web-features:ecmascript-2015: javascript.builtins.Array.@@species - web-features:ecmascript-2015: javascript.builtins.Array.@@unscopables - web-features:ecmascript-2019: javascript.builtins.Array.flat - web-features:ecmascript-2019: javascript.builtins.Array.flatMap - web-features:ecmascript-2020: javascript.builtins.Array.includes - web-features:ecmascript-2022: javascript.builtins.Array.at - web-features:ecmascript-2023: javascript.builtins.Array.findLast - web-features:ecmascript-2023: javascript.builtins.Array.findLastIndex - web-features:ecmascript-2023: javascript.builtins.Array.toReversed - web-features:ecmascript-2023: javascript.builtins.Array.toSorted - web-features:ecmascript-2023: javascript.builtins.Array.toSpliced - web-features:ecmascript-2023: javascript.builtins.Array.with

Date API

- web-features:ecmascript-1: javascript.builtins.Date - web-features:ecmascript-1: javascript.builtins.Date.Date - web-features:ecmascript-1: javascript.builtins.Date.UTC - web-features:ecmascript-1: javascript.builtins.Date.getDate - web-features:ecmascript-1: javascript.builtins.Date.getDay - web-features:ecmascript-1: javascript.builtins.Date.getFullYear - web-features:ecmascript-1: javascript.builtins.Date.getHours - web-features:ecmascript-1: javascript.builtins.Date.getMilliseconds - web-features:ecmascript-1: javascript.builtins.Date.getMinutes - web-features:ecmascript-1: javascript.builtins.Date.getMonth - web-features:ecmascript-1: javascript.builtins.Date.getSeconds - web-features:ecmascript-1: javascript.builtins.Date.getTime - web-features:ecmascript-1: javascript.builtins.Date.getTimezoneOffset - web-features:ecmascript-1: javascript.builtins.Date.getUTCDate - web-features:ecmascript-1: javascript.builtins.Date.getUTCDay - web-features:ecmascript-1: javascript.builtins.Date.getUTCFullYear - web-features:ecmascript-1: javascript.builtins.Date.getUTCHours - web-features:ecmascript-1: javascript.builtins.Date.getUTCMilliseconds - web-features:ecmascript-1: javascript.builtins.Date.getUTCMinutes - web-features:ecmascript-1: javascript.builtins.Date.getUTCMonth - web-features:ecmascript-1: javascript.builtins.Date.getUTCSeconds - web-features:ecmascript-1: javascript.builtins.Date.getYear - web-features:ecmascript-1: javascript.builtins.Date.parse - web-features:ecmascript-1: javascript.builtins.Date.setDate - web-features:ecmascript-1: javascript.builtins.Date.setFullYear - web-features:ecmascript-1: javascript.builtins.Date.setHours - web-features:ecmascript-1: javascript.builtins.Date.setMilliseconds - web-features:ecmascript-1: javascript.builtins.Date.setMinutes - web-features:ecmascript-1: javascript.builtins.Date.setMonth - web-features:ecmascript-1: javascript.builtins.Date.setSeconds - web-features:ecmascript-1: javascript.builtins.Date.setTime - web-features:ecmascript-1: javascript.builtins.Date.setUTCDate - web-features:ecmascript-1: javascript.builtins.Date.setUTCFullYear - web-features:ecmascript-1: javascript.builtins.Date.setUTCHours - web-features:ecmascript-1: javascript.builtins.Date.setUTCMilliseconds - web-features:ecmascript-1: javascript.builtins.Date.setUTCMinutes - web-features:ecmascript-1: javascript.builtins.Date.setUTCMonth - web-features:ecmascript-1: javascript.builtins.Date.setUTCSeconds - web-features:ecmascript-1: javascript.builtins.Date.setYear - web-features:ecmascript-1: javascript.builtins.Date.toGMTString - web-features:ecmascript-1: javascript.builtins.Date.toLocaleString - web-features:ecmascript-1: javascript.builtins.Date.toString - web-features:ecmascript-1: javascript.builtins.Date.toUTCString - web-features:ecmascript-1: javascript.builtins.Date.valueOf - web-features:ecmascript-3: javascript.builtins.Date.toDateString - web-features:ecmascript-3: javascript.builtins.Date.toLocaleDateString - web-features:ecmascript-3: javascript.builtins.Date.toLocaleTimeString - web-features:ecmascript-3: javascript.builtins.Date.toTimeString - web-features:ecmascript-5: javascript.builtins.Date.now - web-features:ecmascript-5: javascript.builtins.Date.toISOString - web-features:ecmascript-5: javascript.builtins.Date.toJSON - web-features:ecmascript-2015: javascript.builtins.Date.@@toPrimitive - web-features:ecmascript-2017: javascript.builtins.Date.UTC.optional_monthIndex

(As you can see, I have just exercised this for Array and Date for the moment and not for all high-level capabilities listed above, but I can do that if y'all think this is useful for cataloging ECMAScript in web-features.)

One thing to say here is that the snapshot tags are useful, but maybe they aren't as meaningful as we want them to be. Instead of using the ECMAScript versions/years, we could also tag them with smaller capability groups and break Array down into some sub groups like these. This is a lot harder and more work, though. Example for Array:


Okay, that was a lot. Thanks for reading this far! Now: How would you group/catalog 901 ECMAScript features?

foolip commented 4 months ago

@Elchi3 thank you so much, I thought that would be a massive undertaking, and maybe it was, but you sure did it quickly!

Looking at this tells me that "Why not have both" from https://github.com/web-platform-dx/web-features/issues/558 is the right path here. We already have an entry for Flattening Arrays, and that's part of ECMAScript 2019 apparently.

My main question at this point is whether we should map at the level of BCD or in web-features. In other words, should we record that BCD's javascript.builtins.Array.flat + javascript.builtins.Array.flatMap are part of ECMAScript 2019, or the array-flat web-features entry?

When we have a high level feature that fits in a group like ECMAScript 2019, why not just associate those? But if there are ever cases where a feature straddles ECMAScript releases, and developers nonetheless think of it as one feature, then we'll need to deal with it some other way.

Building on https://github.com/web-platform-dx/web-features/issues/217#issuecomment-1918839788, I'm inclined to suggest something like this. First, the tree of groups we'd define

web-features
├─ javascript
│  ├─ ecmascript-1
│  ├─ ecmascript-3
│  ├─ ecmascript-5
│  ├─ ecmascript-2015
│  ├─ ecmascript-...
│  ├─ ecmascript-2024

Then, the array-flat feature would have group: ecmascript-2019 in its YAML definition.

When needed, BCD could also use the tag "web-features:group:ecmascript-2019" to put individual BCD entries into a group.

@Elchi3 WDYT? Is it messy to split this across web-features and BCD like this?

foolip commented 4 months ago

If we go with groups as distinct from features, we need to decide whether groups are a namespace or not. In other words, should consumers of web-features have to use "group:ecmascript-2019" or similar to point to a group? It comes down to whether it's good that it's obvious at the "call site" that it's a group and not a concrete feature, and I think it probably is.

Elchi3 commented 4 months ago

@Elchi3 thank you so much, I thought that would be a massive undertaking, and maybe it was, but you sure did it quickly!

Yes, as always, 90% is easy and then the remaining 100 or so data points aren't as easy to sort. I ignored all non-standard features in the end as well. Still some more things to sort. Can be seen in this branch https://github.com/mdn/browser-compat-data/compare/main...Elchi3:browser-compat-data:ecmascript-tags (I forgot the link in my initial comment above, added now and also updated the data above with the latest cataloging for ECMAScript version snapshots).

My main question at this point is whether we should map at the level of BCD or in web-features

I think, given BCD is a moving target and the source of all this cataloging, I find all this easier to do with BCD tags. The synchronization between the two will be work otherwise. But I could be convinced to do it in web-features. I think we are still at the phase where we explore what data model we need to have (more below).

When we have a high level feature that fits in a group like ECMAScript 2019, why not just associate those? But if there are ever cases where a feature straddles ECMAScript releases, and developers nonetheless think of it as one feature, then we'll need to deal with it some other way.

To me, so far, it was really useful to associate an ECMAScript snapshot version with individual BCD data points. See Array above. Just by looking at that, you can see how Array evolved and you can determine Array features from there (like I did in my step 3 above). And, yes, there are features that straddle ECMAScript releases, and so the snapshot tag is optional but useful in case we have it.

If we go with groups as distinct from features, we need to decide whether groups are a namespace or not. In other words, should consumers of web-features have to use "group:ecmascript-2019" or similar to point to a group?

To me, snapshots are different to groups. In fact, I think I found it useful to think about three things as my data model in my cataloging exercise:.

1) "web-features-snapshot:<snapshot>"

I played with this in BCD and it looks like this: Array constructor:

"tags":[
  "web-features-snapshot:ecmascript-1",
  "web-features-group:arrays",
  "web-features-feature:basic-arrays"
],

Array.at:

"tags":[
  "web-features-snapshot:ecmascript-2022",
  "web-features-group:arrays",
  "web-features-feature:array-at"
],

Commit: https://github.com/mdn/browser-compat-data/commit/89722af6543cc393c97b02961fca7c5edcb36be5

Now you can do interesting queries against BCD:

npm run traverse -- -t web-features-snapshot:ecmascript-2023 (same as above but this branch has tags applied to smaller dataset)

- javascript.builtins.Array.findLast - javascript.builtins.Array.findLastIndex - javascript.builtins.Array.toReversed - javascript.builtins.Array.toSorted - javascript.builtins.Array.toSpliced - javascript.builtins.Array.with - javascript.builtins.TypedArray.findLast - javascript.builtins.TypedArray.findLastIndex - javascript.builtins.TypedArray.toReversed - javascript.builtins.TypedArray.toSorted - javascript.builtins.TypedArray.with

npm run traverse -- -t web-features-group:arrays (All Array features)

- javascript.builtins.Array - javascript.builtins.Array.Array - javascript.builtins.Array.at - javascript.builtins.Array.concat - javascript.builtins.Array.copyWithin - javascript.builtins.Array.entries - javascript.builtins.Array.every - javascript.builtins.Array.fill - javascript.builtins.Array.filter - javascript.builtins.Array.find - javascript.builtins.Array.findIndex - javascript.builtins.Array.findLast - javascript.builtins.Array.findLastIndex - javascript.builtins.Array.flat - javascript.builtins.Array.flatMap - javascript.builtins.Array.forEach - javascript.builtins.Array.from - javascript.builtins.Array.fromAsync - javascript.builtins.Array.includes - javascript.builtins.Array.indexOf - javascript.builtins.Array.isArray - javascript.builtins.Array.join - javascript.builtins.Array.keys - javascript.builtins.Array.lastIndexOf - javascript.builtins.Array.length - javascript.builtins.Array.map - javascript.builtins.Array.of - javascript.builtins.Array.pop - javascript.builtins.Array.push - javascript.builtins.Array.reduce - javascript.builtins.Array.reduceRight - javascript.builtins.Array.reverse - javascript.builtins.Array.shift - javascript.builtins.Array.slice - javascript.builtins.Array.some - javascript.builtins.Array.sort - javascript.builtins.Array.sort.stable_sorting - javascript.builtins.Array.splice - javascript.builtins.Array.toLocaleString - javascript.builtins.Array.toReversed - javascript.builtins.Array.toSorted - javascript.builtins.Array.toSpliced - javascript.builtins.Array.toString - javascript.builtins.Array.unshift - javascript.builtins.Array.values - javascript.builtins.Array.with - javascript.builtins.Array.@@iterator - javascript.builtins.Array.@@species - javascript.builtins.Array.@@unscopables - javascript.grammar.array_literals

npm run traverse -- -t web-features-group:typed-arrays (All Typed Array features)

- javascript.builtins.Float32Array - javascript.builtins.Float32Array.Float32Array - javascript.builtins.Float32Array.Float32Array.constructor_without_parameters - javascript.builtins.Float32Array.Float32Array.iterable_allowed - javascript.builtins.Float32Array.Float32Array.new_required - javascript.builtins.Float64Array - javascript.builtins.Float64Array.Float64Array - javascript.builtins.Float64Array.Float64Array.constructor_without_parameters - javascript.builtins.Float64Array.Float64Array.iterable_allowed - javascript.builtins.Float64Array.Float64Array.new_required - javascript.builtins.Int16Array - javascript.builtins.Int16Array.Int16Array - javascript.builtins.Int16Array.Int16Array.constructor_without_parameters - javascript.builtins.Int16Array.Int16Array.new_required - javascript.builtins.Int32Array - javascript.builtins.Int32Array.Int32Array - javascript.builtins.Int32Array.Int32Array.constructor_without_parameters - javascript.builtins.Int32Array.Int32Array.iterable_allowed - javascript.builtins.Int32Array.Int32Array.new_required - javascript.builtins.Int8Array - javascript.builtins.Int8Array.Int8Array - javascript.builtins.Int8Array.Int8Array.constructor_without_parameters - javascript.builtins.Int8Array.Int8Array.iterable_allowed - javascript.builtins.Int8Array.Int8Array.new_required - javascript.builtins.TypedArray - javascript.builtins.TypedArray.BYTES_PER_ELEMENT - javascript.builtins.TypedArray.at - javascript.builtins.TypedArray.buffer - javascript.builtins.TypedArray.byteLength - javascript.builtins.TypedArray.byteOffset - javascript.builtins.TypedArray.constructor_without_parameters - javascript.builtins.TypedArray.copyWithin - javascript.builtins.TypedArray.entries - javascript.builtins.TypedArray.every - javascript.builtins.TypedArray.fill - javascript.builtins.TypedArray.filter - javascript.builtins.TypedArray.find - javascript.builtins.TypedArray.findIndex - javascript.builtins.TypedArray.findLast - javascript.builtins.TypedArray.findLastIndex - javascript.builtins.TypedArray.forEach - javascript.builtins.TypedArray.from - javascript.builtins.TypedArray.includes - javascript.builtins.TypedArray.indexOf - javascript.builtins.TypedArray.join - javascript.builtins.TypedArray.keys - javascript.builtins.TypedArray.lastIndexOf - javascript.builtins.TypedArray.length - javascript.builtins.TypedArray.map - javascript.builtins.TypedArray.name - javascript.builtins.TypedArray.named_properties - javascript.builtins.TypedArray.new_required - javascript.builtins.TypedArray.of - javascript.builtins.TypedArray.reduce - javascript.builtins.TypedArray.reduceRight - javascript.builtins.TypedArray.reverse - javascript.builtins.TypedArray.set - javascript.builtins.TypedArray.slice - javascript.builtins.TypedArray.some - javascript.builtins.TypedArray.sort - javascript.builtins.TypedArray.subarray - javascript.builtins.TypedArray.toLocaleString - javascript.builtins.TypedArray.toReversed - javascript.builtins.TypedArray.toSorted - javascript.builtins.TypedArray.toString - javascript.builtins.TypedArray.values - javascript.builtins.TypedArray.with - javascript.builtins.TypedArray.@@iterator - javascript.builtins.TypedArray.@@species - javascript.builtins.Uint16Array - javascript.builtins.Uint16Array.Uint16Array - javascript.builtins.Uint16Array.Uint16Array.constructor_without_parameters - javascript.builtins.Uint16Array.Uint16Array.iterable_allowed - javascript.builtins.Uint16Array.Uint16Array.new_required - javascript.builtins.Uint8Array - javascript.builtins.Uint8Array.Uint8Array - javascript.builtins.Uint8Array.Uint8Array.constructor_without_parameters - javascript.builtins.Uint8Array.Uint8Array.iterable_allowed - javascript.builtins.Uint8Array.Uint8Array.new_required - javascript.builtins.Uint8ClampedArray - javascript.builtins.Uint8ClampedArray.Uint8ClampedArray - javascript.builtins.Uint8ClampedArray.Uint8ClampedArray.iterable_allowed - javascript.builtins.Uint8ClampedArray.Uint8ClampedArray.new_required

npm run traverse -- -t web-features-feature:array-by-copy (Array By Copy feature that impacts Arrays and Typed Arrays)

- javascript.builtins.Array.toReversed - javascript.builtins.Array.toSorted - javascript.builtins.Array.toSpliced - javascript.builtins.Array.with - javascript.builtins.TypedArray.toReversed - javascript.builtins.TypedArray.toSorted - javascript.builtins.TypedArray.with

npm run traverse -- -t web-features-feature:array-find (Array Find that impacts Arrays and Typed Arrays

- javascript.builtins.Array.find - javascript.builtins.Array.findIndex - javascript.builtins.TypedArray.find - javascript.builtins.TypedArray.findIndex

I didn't implement additional data querying, but I guess with this you could ask BCD for:

But sure, you could also record this data differently and say that there are parent-child relationships instead of "groups" and "features" like I did here. And maybe the snapshot data is just really useful data that helps to find specific features within a lot of data. 🤷

So, the data model consisting of "web-features-snapshot", "web-features-group", and "web-features-feature" is just a first idea. I'd love hear more and maybe others have a different mental model about these things. I think it would be good to sort this out, before trying to catalog all of ECMAScript which I'm setting as my personal goal here.

foolip commented 4 months ago

I see, it does make sense to think of spec snapshots differently from groups. For example the HTML5 snapshot would certainly span multiple groups like "workers", "form controls", "media elements", and so on.

I wonder if web-specs might make more sense than web-features as the source of truth on snapshots. Have you checked if older spec snapshots are recorded there, or is it only current specs?

I also wonder about consumers, do you think BCD consumers would make use of snapshot data?

Elchi3 commented 4 months ago

I wonder if web-specs might make more sense than web-features as the source of truth on snapshots. Have you checked if older spec snapshots are recorded there, or is it only current specs?

From what I can tell, it doesn't record snapshots. It would be an idea to get the list of allowable snapshots from web-specs indeed. I don't think we want to make up our own snapshots (I think indexed-db-1 and indexed-db-2 are real levels observed from the specs, and e.g. CSS4 is also officially defined as a kind of snapshot). So, yes, maybe we could propose this for web-specs and use it for validation for the web-features-snapshot tags.

I also wonder about consumers, do you think BCD consumers would make use of snapshot data?

Yes, I think tags are powerful to any BCD consumer because currently you only get lists of BCD features by tree (e.g. javascript.builtins.array.*). If we had the three tags that I described, you could already get much more nuanced feature lists as described in my comment above and without having to go through other data sources like web-features.

captainbrosset commented 4 months ago

We discussed the feature vs. group vs. snapshot idea at yesterday's WebDX meeting: https://docs.google.com/document/d/1ree75ImLZjf60lTZ3BhCaLHygxgywr7SBXp-q0xPs8A/edit#heading=h.tm9h5efbalpr

A few highlights from the discussion:

foolip commented 4 months ago

When web features get implemented in browsers, they ship as little bundles or related things. Not just one method or property. These bundles that get implemented at the same time seem to correspond to what we call features here.

A lot of complexity comes different browsers shipping things in different order and bundles. I'm sure that all of the following happen for two granular APIs A and B that seem like they form a reasonable group at first:

And so on.

A problem is that if we base groups on bundles of shipping, then when another browser ships only part of it, we need to split that feature group. Some amount of updating to match reality is reasonable, but I think trying to determine how and when to split manually and picking good names for the feature groups is going to be overwhelming.

Rather I think we'll need to find a way to handle small amounts of "skew" in a way that doesn't require minting new features for every unique combination of "initial support" versions.

This kind of thing has already been a problem with at least Clipboard API, custom elements, the input event, and scrollbar-* properties.

ddbeck commented 4 months ago

I got to have lunch with @Elchi3 today and we had a very wide-ranging discussion, but we talked a lot about this issue specifically. I will not attempt to recap everything, but I thought I would share some things that I learned:

Terminology: We had a hard time talking about this because the terms are unclear. Specifically, "feature" is overloaded: everything's a feature, at different resolutions. For the purposes of our conversation, we settled on

Bundling: Talking to Florian, I finally understood what he meant by "combin[ing] the high-level capability groups with the snapshots." Florian is concerned (rightly) that if we start authoring bundles we might very well compose groups that are ungrounded (e.g., "Daniel's favorite Array methods") or motivated (e.g., seeking specific Baseline statuses or mapping to browser engineering's incremental steps toward a genuine feature), instead of descriptive.

I originally misunderstood, thinking that Florian was suggesting (for example) "Array x ES2024" is a group that must exist, given the plausibility of the other two groups. Instead, the intersection might help us author the most meaningful bundles we might find in that intersection. This seems like a great way to unblock certain discussions about whether a feature is or is not in a given feature (e.g., whether to omit a given BCD key or to override a Baseline status and so on). This might help guide us in deciding whether to (as @foolip says above) skew or split a bundle.

Scaling: This struck me as especially important in the absence of developer salience. The bundles needed for the most visible features and proposals will be pretty transparent to developers (e.g. developers themselves will have a good sense of what is and is not "subgrid"). But when it comes to cataloguing the whole of the platform, drawing boxes around features becomes much more difficult: do we really expect developers to make clear distinctions between older cohorts of features? Using the intersection of snapshots and capabilities can give us a starting point other than vibes or recapitulating dubious legacies (e.g., wiki-era MDN information architecture choices).


  1. The emphasis here is on "point in time" not "specification." I suspect there are other possible origins of snapshots (e.g., implementation year), but they're all final. Some features get in or they don't and that's that.
  2. Credit to James for using this term in yesterday's WebDX meeting.
tidoust commented 4 months ago

@Elchi3 The terminology shared by @ddbeck above mentions three levels (on top of the BCD key level of course). In the draft pull request you prepared, I see 4 types of tags:

  1. web-features-snapshot:xxx
  2. web-features-group:xxx
  3. web-features-bundle:xxx
  4. and a more generic web-features:xxx type of tag

What does the 4th type represent? Or is a leftover, to be replaced by web-features-bundle?

Elchi3 commented 4 months ago

Or is a leftover, to be replaced by web-features-bundle?

Yeah, leftover. I didn't touch the generic web-features:xxx tags because I don't know if the terminology we are talking about here will be adapted. These would be bundles indeed, if adapted.

foolip commented 4 months ago

Does someone have more context on bundles? If we adopt that terminology, would web-features not have anything called a "feature" any longer? Or are only some features bundles? (We have some entries which correspond to zero or one BCD key.)

Elchi3 commented 4 months ago

I don't have a good definition yet and I'm not sure bundle is a good name for it but calling these things bundles was easier in this discussion because "feature" is already overloaded. We could also say web-features-feature:xxx or something else, too.

I guess the core of the problem is not really the name but missing guidelines about what goes into a bundle/feature-set and what doesn't.

To me, a bundle consists of one or more BCD keys that we can reason about as a logical/evolutional extension to the web platform. I think it would be good to agree on some rules what "logical/evolutional" means.

To me,

I'd love to hear how others approach bundling things together. Would definitely help me to catalog/bundle all of ECMAScript.

captainbrosset commented 4 months ago

Agreed that the name isn't the issue here. In fact, if we manage to land on a clear definition for this, I'd love for this lower level to just be called "feature" again. Even if it's overloaded, as long as we define it clearly in the repo.

To me, a bundle consists of one or more BCD keys that we can reason about as a logical/evolutional extension to the web platform. I think it would be good to agree on some rules what "logical/evolutional" means.

We need to think from a user's perspective which, I think, Can I Use does pretty well. For example, if "Can I use CSS Anchor Positioning yet?" is a question that a web developer is likely to ask themselves in an attempt to accomplish a particular task, then CSS Anchor Positioning is probably a feature/bundle. It's definitely a feature/bundle if CSS Anchor Positioning can't itself be broken down further into smaller features/bundles which we could ask similar questions about.

For example, "Can i use colors on the web?" is a valid developer question. Does that mean Colors is a feature/bundle? No, because you can break it down further into "Can I use relative color syntax?". This question makes sense from a web developer's perspective. They've heard of relative colors, have a need for it to accomplish a given task, and want to know if they can use it. Can relative color be broken down further? Perhaps (the syntax is so complex that BCD might have multiple keys for it), but my hunch is that it's unlikely for a dev to ask "Can I use this specific way of writing relative colors?".

ddbeck commented 3 months ago

To me, a bundle consists of one or more BCD keys that we can reason about as a logical/evolutional extension to the web platform. I think it would be good to agree on some rules what "logical/evolutional" means.

I'm not sure I agree with this. I think bundles ought to be descriptive of web developers' view of the platform. I think it's very likely that most bundles are logical or evolutionary—and that's probably a safe default in the absence of other information about web developers' perspective—but I think it's possible for them to be arbitrary.

Imagine it's 2007 and some web developers are thinking about AJAX. Such a bundle would probably have something like XMLHttpRequest (and some methods), document.getElementById(), and Element.innerHTML. That looks pretty arbitrary, viewed from the bottom up. But it would be a bundle that would be very relevant to developers at the time.

It's not hard to imagine descriptive groups having meaning in 2024. For instance, we might want to map to historic caniuse features (approximately, "Alexis's best judgment at the time he created the feature on caniuse") or a blogger might coin a term relating to a development pattern that catches on (probably not me, but I bet there are certain versions of "<developer>'s favorite Array methods" that could matter).