Drop ESM support (#2366)

* Drop ESM support

* Add `"unpkg"` field
This commit is contained in:
Isiah Meadows 2019-05-29 09:24:10 -04:00 committed by GitHub
parent 9b38e41fd6
commit b17b00e9eb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 7 additions and 2248 deletions

View file

@ -3,8 +3,5 @@ coverage/
docs/lib/
examples/
/mithril.js
/mithril.mjs
/mithril.min.js
/mithril.min.mjs
/stream/stream.mjs
node_modules/

2
.gitattributes vendored
View file

@ -1,7 +1,5 @@
* text=auto
/mithril.js binary
/mithril.min.js binary
/mithril.mjs binary
/mithril.min.mjs binary
/package-lock.json binary
/yarn.lock binary

View file

@ -21,8 +21,6 @@ before_script:
- npm run build-browser
# Pass -save so it'll update the readme as well
- npm run build-min -- -save
# must run after build-min in order to generate min.mjs
- npm run build-esm
# Run tests, lint, and then check for perf regressions
script:
@ -85,8 +83,6 @@ deploy:
file:
- "mithril.js"
- "mithril.min.js"
- "mithril.mjs"
- "mithril.min.mjs"
skip_cleanup: true
draft: true
on:

View file

@ -77,6 +77,10 @@
- request: don't modify params, call `extract`/`serialize`/`deserialize` with correct `this` value ([#2288](https://github.com/MithrilJS/mithril.js/pull/2288))
- render: simplify component removal ([#2214](https://github.com/MithrilJS/mithril.js/pull/2214))
- render: remove some redundancy within the component initialization code ([#2213](https://github.com/MithrilJS/mithril.js/pull/2213))
- API: `mithril` loads `mithril/index.js`, not the bundle, so users of `mithril/hyperscript`, `mithril/render`, and similar see the same Mithril instance as those just using `mithril` itself.
- `https://unpkg.com/mithril` is configured to receive the *minified* bundle, not the development bundle.
- The raw bundle itself remains accessible at `mithril.js`, and is *not* browser-wrapped.
- Note: this *will* increase overhead with bundlers like Webpack, Rollup, and Browserify.
---

67
esm.js
View file

@ -1,67 +0,0 @@
"use strict"
/*
This script will create esm compatible scripts
from the already compiled versions of:
- mithril.js > mithril.mjs
- mithril.min.js > mithril.min.mjs
- /stream/stream.js > stream.mjs
*/
var fs = require("fs")
var namedExports = [
"m",
"trust",
"fragment",
"mount",
"route",
"render",
"redraw",
"request",
"jsonp",
"parseQueryString",
"buildQueryString",
"version",
"vnode",
"PromisePolyfill"
]
var mithril = fs.readFileSync("mithril.js", "utf8")
fs.writeFileSync("mithril.mjs",
mithril.slice(
mithril.indexOf("\"use strict\"") + 13,
mithril.lastIndexOf("if (typeof module")
)
+ "\nexport default m"
// The exports are declared with prefixed underscores to avoid overwriting previously
// declared variables with the same name
+ "\nvar " + namedExports.map(function(n) { return "_" + n + " = m." + n }).join(",")
+ "\nexport {" + namedExports.map(function(n) { return "_" + n + " as " + n }).join(",") + "}"
)
var mithrilMin = fs.readFileSync("mithril.min.js", "utf8")
var mName = mithrilMin.match(/window\.m=([a-z])}/)[1]
fs.writeFileSync("mithril.min.mjs",
mithrilMin.slice(
12,
mithrilMin.lastIndexOf("\"undefined\"!==typeof module")
)
+ "export default " + mName + ";"
// The exports are declared with prefixed underscores to avoid overwriting previously
// declared variables with the same name
+ "var " + namedExports.map(function(n) { return "_" + n + "=m." + n }).join(",") + ";"
+ "export {" + namedExports.map(function(n) { return "_" + n + " as " + n }).join(",") + "};"
)
var stream = fs.readFileSync("stream/stream.js", "utf8")
fs.writeFileSync("stream/stream.mjs",
stream.slice(
stream.indexOf("\"use strict\"") + 13,
stream.lastIndexOf("if (typeof module")
)
+ "\nexport default Stream"
)

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -1,19 +0,0 @@
"use strict"
/*
This script will create an esm compatible script
from the already compiled version of:
- ospec.js > ospec.mjs
*/
var fs = require("fs")
var ospec = fs.readFileSync("ospec.js", "utf8")
fs.writeFileSync("ospec.mjs",
"export default "
+ ospec.slice(ospec.indexOf("})") + 2)
+ "()"
)

View file

@ -1,386 +0,0 @@
export default (function init(name) {
var spec = {}, subjects = [], results, only = [], ctx = spec, start, stack = 0, nextTickish, hasProcess = typeof process === "object", hasOwn = ({}).hasOwnProperty
var ospecFileName = getStackName(ensureStackTrace(new Error), /[\/\\](.*?):\d+:\d+/), timeoutStackName
var globalTimeout = noTimeoutRightNow
var currentTestError = null
if (name != null) spec[name] = ctx = {}
try {throw new Error} catch (e) {
var ospecFileName = e.stack && (/[\/\\](.*?):\d+:\d+/).test(e.stack) ? e.stack.match(/[\/\\](.*?):\d+:\d+/)[1] : null
}
function o(subject, predicate) {
if (predicate === undefined) {
if (!isRunning()) throw new Error("Assertions should not occur outside test definitions")
return new Assert(subject)
} else {
if (isRunning()) throw new Error("Test definitions and hooks shouldn't be nested. To group tests use `o.spec()`")
subject = String(subject)
if (subject.charCodeAt(0) === 1) throw new Error("test names starting with '\\x01' are reserved for internal use")
ctx[unique(subject)] = new Task(predicate, ensureStackTrace(new Error))
}
}
o.before = hook("\x01before")
o.after = hook("\x01after")
o.beforeEach = hook("\x01beforeEach")
o.afterEach = hook("\x01afterEach")
o.specTimeout = function (t) {
if (isRunning()) throw new Error("o.specTimeout() can only be called before o.run()")
if (hasOwn.call(ctx, "\x01specTimeout")) throw new Error("A default timeout has already been defined in this context")
if (typeof t !== "number") throw new Error("o.specTimeout() expects a number as argument")
ctx["\x01specTimeout"] = t
}
o.new = init
o.spec = function(subject, predicate) {
var parent = ctx
ctx = ctx[unique(subject)] = {}
predicate()
ctx = parent
}
o.only = function(subject, predicate, silent) {
if (!silent) console.log(
highlight("/!\\ WARNING /!\\ o.only() mode") + "\n" + o.cleanStackTrace(ensureStackTrace(new Error)) + "\n",
cStyle("red"), ""
)
only.push(predicate)
o(subject, predicate)
}
o.spy = function(fn) {
var spy = function() {
spy.this = this
spy.args = [].slice.call(arguments)
spy.calls.push({this: this, args: spy.args})
spy.callCount++
if (fn) return fn.apply(this, arguments)
}
if (fn)
Object.defineProperties(spy, {
length: {value: fn.length},
name: {value: fn.name}
})
spy.args = []
spy.calls = []
spy.callCount = 0
return spy
}
o.cleanStackTrace = function(error) {
// For IE 10+ in quirks mode, and IE 9- in any mode, errors don't have a stack
if (error.stack == null) return ""
var i = 0, header = error.message ? error.name + ": " + error.message : error.name, stack
// some environments add the name and message to the stack trace
if (error.stack.indexOf(header) === 0) {
stack = error.stack.slice(header.length).split(/\r?\n/)
stack.shift() // drop the initial empty string
} else {
stack = error.stack.split(/\r?\n/)
}
if (ospecFileName == null) return stack.join("\n")
// skip ospec-related entries on the stack
while (stack[i] != null && stack[i].indexOf(ospecFileName) !== -1) i++
// now we're in user code (or past the stack end)
return stack[i]
}
o.timeout = function(n) {
globalTimeout(n)
}
o.run = function(reporter) {
results = []
start = new Date
test(spec, [], [], new Task(function() {
setTimeout(function () {
timeoutStackName = getStackName({stack: o.cleanStackTrace(ensureStackTrace(new Error))}, /([\w \.]+?:\d+:\d+)/)
if (typeof reporter === "function") reporter(results)
else {
var errCount = o.report(results)
if (hasProcess && errCount !== 0) process.exit(1) // eslint-disable-line no-process-exit
}
})
}, null), 200 /*default timeout delay*/)
function test(spec, pre, post, finalize, defaultDelay) {
if (hasOwn.call(spec, "\x01specTimeout")) defaultDelay = spec["\x01specTimeout"]
pre = [].concat(pre, spec["\x01beforeEach"] || [])
post = [].concat(spec["\x01afterEach"] || [], post)
series([].concat(spec["\x01before"] || [], Object.keys(spec).reduce(function(tasks, key) {
if (key.charCodeAt(0) !== 1 && (only.length === 0 || only.indexOf(spec[key].fn) !== -1 || !(spec[key] instanceof Task))) {
tasks.push(new Task(function(done) {
o.timeout(Infinity)
subjects.push(key)
var pop = new Task(function pop() {subjects.pop(), done()}, null)
if (spec[key] instanceof Task) series([].concat(pre, spec[key], post, pop), defaultDelay)
else test(spec[key], pre, post, pop, defaultDelay)
}, null))
}
return tasks
}, []), spec["\x01after"] || [], finalize), defaultDelay)
}
function series(tasks, defaultDelay) {
var cursor = 0
next()
function next() {
if (cursor === tasks.length) return
var task = tasks[cursor++]
var fn = task.fn
currentTestError = task.err
var timeout = 0, delay = defaultDelay, s = new Date
var current = cursor
var arg
globalTimeout = setDelay
var isDone = false
// public API, may only be called once from use code (or after returned Promise resolution)
function done(err) {
if (!isDone) isDone = true
else throw new Error("`" + arg + "()` should only be called once")
if (timeout === undefined) console.warn("# elapsed: " + Math.round(new Date - s) + "ms, expected under " + delay + "ms\n" + o.cleanStackTrace(task.err))
finalizeAsync(err)
}
// for internal use only
function finalizeAsync(err) {
if (err == null) {
if (task.err != null) succeed(new Assert)
} else {
if (err instanceof Error) fail(new Assert, err.message, err)
else fail(new Assert, String(err), null)
}
if (timeout !== undefined) timeout = clearTimeout(timeout)
if (current === cursor) next()
}
function startTimer() {
timeout = setTimeout(function() {
timeout = undefined
finalizeAsync("async test timed out after " + delay + "ms")
}, Math.min(delay, 2147483647))
}
function setDelay (t) {
if (typeof t !== "number") throw new Error("timeout() and o.timeout() expect a number as argument")
delay = t
}
if (fn.length > 0) {
var body = fn.toString()
arg = (body.match(/^(.+?)(?:\s|\/\*[\s\S]*?\*\/|\/\/.*?\n)*=>/) || body.match(/\((?:\s|\/\*[\s\S]*?\*\/|\/\/.*?\n)*(.+?)(?:\s|\/\*[\s\S]*?\*\/|\/\/.*?\n)*[,\)]/) || []).pop()
if (body.indexOf(arg) === body.lastIndexOf(arg)) {
var e = new Error
e.stack = "`" + arg + "()` should be called at least once\n" + o.cleanStackTrace(task.err)
throw e
}
try {
fn(done, setDelay)
}
catch (e) {
if (task.err != null) finalizeAsync(e)
// The errors of internal tasks (which don't have an Err) are ospec bugs and must be rethrown.
else throw e
}
if (timeout === 0) {
startTimer()
}
} else {
try{
var p = fn()
if (p && p.then) {
startTimer()
p.then(function() { done() }, done)
} else {
nextTickish(next)
}
} catch (e) {
if (task.err != null) finalizeAsync(e)
// The errors of internal tasks (which don't have an Err) are ospec bugs and must be rethrown.
else throw e
}
}
globalTimeout = noTimeoutRightNow
}
}
}
function unique(subject) {
if (hasOwn.call(ctx, subject)) {
console.warn("A test or a spec named `" + subject + "` was already defined")
while (hasOwn.call(ctx, subject)) subject += "*"
}
return subject
}
function hook(name) {
return function(predicate) {
if (ctx[name]) throw new Error("This hook should be defined outside of a loop or inside a nested test group:\n" + predicate)
ctx[name] = new Task(predicate, ensureStackTrace(new Error))
}
}
define("equals", "should equal", function(a, b) {return a === b})
define("notEquals", "should not equal", function(a, b) {return a !== b})
define("deepEquals", "should deep equal", deepEqual)
define("notDeepEquals", "should not deep equal", function(a, b) {return !deepEqual(a, b)})
define("throws", "should throw a", throws)
define("notThrows", "should not throw a", function(a, b) {return !throws(a, b)})
function isArguments(a) {
if ("callee" in a) {
for (var i in a) if (i === "callee") return false
return true
}
}
function deepEqual(a, b) {
if (a === b) return true
if (a === null ^ b === null || a === undefined ^ b === undefined) return false // eslint-disable-line no-bitwise
if (typeof a === "object" && typeof b === "object") {
var aIsArgs = isArguments(a), bIsArgs = isArguments(b)
if (a.constructor === Object && b.constructor === Object && !aIsArgs && !bIsArgs) {
for (var i in a) {
if ((!(i in b)) || !deepEqual(a[i], b[i])) return false
}
for (var i in b) {
if (!(i in a)) return false
}
return true
}
if (a.length === b.length && (a instanceof Array && b instanceof Array || aIsArgs && bIsArgs)) {
var aKeys = Object.getOwnPropertyNames(a), bKeys = Object.getOwnPropertyNames(b)
if (aKeys.length !== bKeys.length) return false
for (var i = 0; i < aKeys.length; i++) {
if (!hasOwn.call(b, aKeys[i]) || !deepEqual(a[aKeys[i]], b[aKeys[i]])) return false
}
return true
}
if (a instanceof Date && b instanceof Date) return a.getTime() === b.getTime()
if (typeof Buffer === "function" && a instanceof Buffer && b instanceof Buffer) {
for (var i = 0; i < a.length; i++) {
if (a[i] !== b[i]) return false
}
return true
}
if (a.valueOf() === b.valueOf()) return true
}
return false
}
function throws(a, b){
try{
a()
}catch(e){
if(typeof b === "string"){
return (e.message === b)
}else{
return (e instanceof b)
}
}
return false
}
function isRunning() {return results != null}
function Assert(value) {
this.value = value
this.i = results.length
results.push({pass: null, context: "", message: "Incomplete assertion in the test definition starting at...", error: currentTestError, testError: currentTestError})
}
function Task(fn, err) {
this.fn = fn
this.err = err
}
function define(name, verb, compare) {
Assert.prototype[name] = function assert(value) {
var self = this
var message = serialize(self.value) + "\n " + verb + "\n" + serialize(value)
if (compare(self.value, value)){
succeed(self, message)
return function(message) {
if (!self.pass) self.message = message + "\n\n" + self.message
}
}else fail(self, message)
}
}
function succeed(assertion, message) {
results[assertion.i].pass = true
results[assertion.i].context = subjects.join(" > ")
results[assertion.i].message = message
}
function fail(assertion, message, error) {
results[assertion.i].pass = false
results[assertion.i].context = subjects.join(" > ")
results[assertion.i].message = message
results[assertion.i].error = error != null ? error : ensureStackTrace(new Error)
}
function serialize(value) {
if (hasProcess) return require("util").inspect(value) // eslint-disable-line global-require
if (value === null || (typeof value === "object" && !(value instanceof Array)) || typeof value === "number") return String(value)
else if (typeof value === "function") return value.name || "<anonymous function>"
try {return JSON.stringify(value)} catch (e) {return String(value)}
}
function noTimeoutRightNow() {
throw new Error("o.timeout must be called snchronously from within a test definition or a hook")
}
var colorCodes = {
red: "31m",
red2: "31;1m",
green: "32;1m"
}
function highlight(message, color) {
var code = colorCodes[color] || colorCodes.red;
return hasProcess ? (process.stdout.isTTY ? "\x1b[" + code + message + "\x1b[0m" : message) : "%c" + message + "%c "
}
function cStyle(color, bold) {
return hasProcess||!color ? "" : "color:"+color+(bold ? ";font-weight:bold" : "")
}
function ensureStackTrace(error) {
// mandatory to get a stack in IE 10 and 11 (and maybe other envs?)
if (error.stack === undefined) try { throw error } catch(e) {return e}
else return error
}
function getStackName(e, exp) {
return e.stack && exp.test(e.stack) ? e.stack.match(exp)[1] : null
}
o.report = function (results) {
var errCount = 0
for (var i = 0, r; r = results[i]; i++) {
if (r.pass == null) {
r.testError.stack = r.message + "\n" + o.cleanStackTrace(r.testError)
r.testError.message = r.message
throw r.testError
}
if (!r.pass) {
var stackTrace = o.cleanStackTrace(r.error)
var couldHaveABetterStackTrace = !stackTrace || timeoutStackName != null && stackTrace.indexOf(timeoutStackName) !== -1
if (couldHaveABetterStackTrace) stackTrace = r.testError != null ? o.cleanStackTrace(r.testError) : r.error.stack || ""
console.error(
(hasProcess ? "\n" : "") +
highlight(r.context + ":", "red2") + "\n" +
highlight(r.message, "red") +
(stackTrace ? "\n" + stackTrace + "\n" : ""),
cStyle("black", true), "", // reset to default
cStyle("red"), cStyle("black")
)
errCount++
}
}
var pl = results.length === 1 ? "" : "s"
var resultSummary = (errCount === 0) ?
highlight((pl ? "All " : "The ") + results.length + " assertion" + pl + " passed", "green"):
highlight(errCount + " out of " + results.length + " assertion" + pl + " failed", "red2")
var runningTime = " in " + Math.round(Date.now() - start) + "ms"
console.log(
(hasProcess ? "\n" : "") +
(name ? name + ": " : "") + resultSummary + runningTime,
cStyle((errCount === 0 ? "green" : "red"), true), ""
)
return errCount
}
if (hasProcess) {
nextTickish = process.nextTick
} else {
nextTickish = function fakeFastNextTick(next) {
if (stack++ < 5000) next()
else setTimeout(next, stack = 0)
}
}
return o
})
()

View file

@ -3,7 +3,6 @@
"version": "3.1.0",
"description": "Noiseless testing framework",
"main": "ospec.js",
"module": "ospec.mjs",
"directories": {
"test": "tests"
},
@ -13,9 +12,6 @@
"bin": {
"ospec": "./bin/ospec"
},
"scripts": {
"prepublishOnly": "node esm.js"
},
"repository": "MithrilJS/mithril.js",
"dependencies": {
"glob": "^7.1.3"

View file

@ -4,15 +4,13 @@
"description": "A framework for building brilliant applications",
"author": "Leo Horie",
"license": "MIT",
"main": "mithril.js",
"module": "mithril.mjs",
"unpkg": "mithril.min.js",
"repository": "MithrilJS/mithril.js",
"scripts": {
"dev": "node bundler/cli browser.js -output mithril.js -watch",
"build": "npm run build-browser & npm run build-min && npm run build-esm",
"build": "npm run build-browser & npm run build-min",
"build-browser": "node bundler/cli browser.js -output mithril.js",
"build-min": "node bundler/cli browser.js -output mithril.min.js -minify",
"build-esm": "node esm.js",
"precommit": "lint-staged",
"lintdocs": "node docs/lint",
"gendocs": "node docs/generate",
@ -24,7 +22,7 @@
"cover": "istanbul cover --print both ospec/bin/ospec",
"release": "npm version -m 'v%s'",
"preversion": "npm run test",
"version": "npm run build && git add mithril.js mithril.min.js mithril.mjs mithril.min.mjs stream/stream.mjs",
"version": "npm run build && git add mithril.js mithril.min.js",
"postversion": "git push --follow-tags"
},
"devDependencies": {

View file

@ -3,7 +3,6 @@
"version": "2.0.0",
"description": "Streaming data, mithril-style",
"main": "stream.js",
"module": "stream.mjs",
"directories": {
"test": "tests"
},

View file

@ -1,172 +0,0 @@
/* eslint-enable */
Stream.SKIP = {}
Stream.lift = lift
Stream.scan = scan
Stream.merge = merge
Stream.combine = combine
Stream.scanMerge = scanMerge
Stream["fantasy-land/of"] = Stream
var warnedHalt = false
Object.defineProperty(Stream, "HALT", {
get: function() {
warnedHalt || console.log("HALT is deprecated and has been renamed to SKIP");
warnedHalt = true
return Stream.SKIP
}
})
function Stream(value) {
var dependentStreams = []
var dependentFns = []
function stream(v) {
if (arguments.length && v !== Stream.SKIP) {
value = v
if (open(stream)) {
stream.changing()
stream.state = "active"
dependentStreams.forEach(function(s, i) { s(dependentFns[i](value)) })
}
}
return value
}
stream.constructor = Stream
stream.state = arguments.length && value !== Stream.SKIP ? "active" : "pending"
stream.parents = []
stream.changing = function() {
open(stream) && (stream.state = "changing")
dependentStreams.forEach(function(s) {
s.changing()
})
}
stream.map = function(fn, ignoreInitial) {
var target = stream.state === "active" && ignoreInitial !== Stream.SKIP
? Stream(fn(value))
: Stream()
target.parents.push(stream)
dependentStreams.push(target)
dependentFns.push(fn)
return target
}
var end
function createEnd() {
end = Stream()
end.map(function(value) {
if (value === true) {
stream.parents.forEach(function (p) {p.unregisterChild(stream)})
stream.state = "ended"
stream.parents.length = dependentStreams.length = dependentFns.length = 0
}
return value
})
return end
}
stream.toJSON = function() { return value != null && typeof value.toJSON === "function" ? value.toJSON() : value }
stream["fantasy-land/map"] = stream.map
stream["fantasy-land/ap"] = function(x) { return combine(function(s1, s2) { return s1()(s2()) }, [x, stream]) }
stream.unregisterChild = function(child) {
var childIndex = dependentStreams.indexOf(child)
if (childIndex !== -1) {
dependentStreams.splice(childIndex, 1)
dependentFns.splice(childIndex, 1)
}
}
Object.defineProperty(stream, "end", {
get: function() { return end || createEnd() }
})
return stream
}
function combine(fn, streams) {
var ready = streams.every(function(s) {
if (s.constructor !== Stream)
throw new Error("Ensure that each item passed to stream.combine/stream.merge/lift is a stream")
return s.state === "active"
})
var stream = ready
? Stream(fn.apply(null, streams.concat([streams])))
: Stream()
var changed = []
var mappers = streams.map(function(s) {
return s.map(function(value) {
changed.push(s)
if (ready || streams.every(function(s) { return s.state !== "pending" })) {
ready = true
stream(fn.apply(null, streams.concat([changed])))
changed = []
}
return value
}, Stream.SKIP)
})
var endStream = stream.end.map(function(value) {
if (value === true) {
mappers.forEach(function(mapper) { mapper.end(true) })
endStream.end(true)
}
return undefined
})
return stream
}
function merge(streams) {
return combine(function() { return streams.map(function(s) { return s() }) }, streams)
}
function scan(fn, acc, origin) {
var stream = origin.map(function(v) {
var next = fn(acc, v)
if (next !== Stream.SKIP) acc = next
return next
})
stream(acc)
return stream
}
function scanMerge(tuples, seed) {
var streams = tuples.map(function(tuple) { return tuple[0] })
var stream = combine(function() {
var changed = arguments[arguments.length - 1]
streams.forEach(function(stream, i) {
if (changed.indexOf(stream) > -1)
seed = tuples[i][1](seed, stream())
})
return seed
}, streams)
stream(seed)
return stream
}
function lift() {
var fn = arguments[0]
var streams = Array.prototype.slice.call(arguments, 1)
return merge(streams).map(function(streams) {
return fn.apply(undefined, streams)
})
}
function open(s) {
return s.state === "pending" || s.state === "active" || s.state === "changing"
}
export default Stream