-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
115 lines (95 loc) · 3.31 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// -------------------------------------------
// Loads resources from the /resources folder
// -------------------------------------------
// TODO: rename loader
module.exports = function loader(ripple, {
dir = '.'
, watch = isNonProd()
, pattern = '/**/!(*test).{css,js}'
, autoload = 'resources'
, autolink = '/resources/components/**/!(*test).{css,js}'
, aliases = {}
} = {}){
log('creating', { watch })
glob(autolink, { root: dir })
.map(path => ripple.link(rel(dir, path), rtype(ripple, path).shortname(path)))
const { r = '', resdirs = r } = require('minimist')(process.argv.slice(2))
, load = register(ripple, dir)
, folders = resdirs
.split(',')
.concat(resolve(dir, autoload))
.filter(Boolean)
.map(d => resolve(d))
.map(append(pattern))
ripple.watcher = chokidar.watch(folders, { ignored: /\b_/ })
.on('error', err)
.on('add', load)
.on('change', load)
.on('ready', async () => {
if (!watch) ripple.watcher.close()
await Promise.all(values(ripple.resources)
.map(res => res.headers.loading))
.catch(err)
def(ripple, 'ready', true)
ripple.emit('ready')
})
ripple.load = (name, alias) => {
if (ripple.resources[name])
return ripple.resources[name]
const path = bresolve(ripple.aliases.dst[name] || name, resolve(dir, 'foo'))
, canonical = rel(dir, path)
if (alias) {
ripple.link(canonical, alias)
} else if (!ripple.aliases.dst[name] && name != canonical) {
ripple.link(name, canonical)
}
return load(path)
}
// TODO: move back to core as chainable
ripple.resource = (name, body, headers) => {
// is.str(body)
// ? ripple.load(body, name)
ripple(name, body, headers)
return ripple
}
return ripple
}
const register = (ripple, dir) => path => {
const type = rtype(ripple, path)
if (!exists(path))
throw new Error(`no such resource at ${path}`)
if (!type)
throw new Error(`could not understand how to load resource at ${path}`)
// TODO: should probably let loaders do this
delete require.cache[path]
return type.load({
name: rel(dir, path)
, headers: { path }
})
}
const rtype = (ripple, path) => values(ripple.types)
.filter(d => d.ext)
.sort(za('ext.length'))
.find(({ ext }) => minimatch(basename(path), ext))
const rel = (dir, path) => './' + relative(dir, path).replace(/\\/g, '/')
const bresolve = (module, parent) => require('browser-resolve').sync(module, { filename: parent })
function isNonProd(){
return lo(process.env.NODE_ENV) != 'prod' && lo(process.env.NODE_ENV) != 'production'
}
const { resolve, relative, basename } = require('path')
, exists = require('fs').existsSync
, glob = require('glob').sync
, chokidar = require('chokidar')
, append = require('utilise/append')
, values = require('utilise/values')
, keys = require('utilise/keys')
, def = require('utilise/def')
, key = require('utilise/key')
, is = require('utilise/is')
, lo = require('utilise/lo')
, by = require('utilise/by')
, za = require('utilise/za')
, log = require('utilise/log')('[ri/resdir]')
, err = require('utilise/err')('[ri/resdir]')
, minimatch = require('minimatch')
, extname = path => [''].concat(path.split('.').slice(1)).join('.')