UNPKG

3.17 kBJavaScriptView Raw
1var path = require('path')
2var util = require('util')
3var Transform = require('stream').Transform
4var multimatch = require('multimatch')
5var objectEach = require('mixy').each
6
7util.inherits(Groups, Transform)
8
9module.exports = Groups
10
11var UNKNOWN = '__UNKNOWN__'
12var noop = function () {}
13
14function Groups(opts) {
15 Transform.call(this, { objectMode: true })
16
17 opts = opts || {}
18 this.basedir = opts.basedir || process.cwd()
19 this._groupFilters = [].concat(opts.groupFilter)
20 .filter(Boolean).map(this.createFilter, this)
21
22 this._groups = Object.create(null)
23 this._bundles = Object.create(null)
24 this._unknown = []
25}
26
27Groups.prototype._transform = function(row, _, next) {
28 var moduleID = row.id
29 this.getGroups(row).forEach(function (group) {
30 this._bundles[group] = true
31 this._addGroup(moduleID, group)
32 }, this)
33
34 // Ensure that `this._groups[moduleID]` is ready
35 this._addGroup(moduleID)
36
37 var groups = Object.keys(this._groups[moduleID])
38 if (!groups.length) {
39 groups.push(UNKNOWN)
40 }
41
42 groups.forEach(function (group) {
43 this.addGroup(row, group)
44 }, this)
45
46 next(null, row)
47}
48
49Groups.prototype._flush = function(next) {
50 var bundles = Object.keys(this._bundles)
51 this._unknown.forEach(function (moduleID) {
52 bundles.forEach(function (bundleID) {
53 this._addGroup(moduleID, bundleID)
54 }, this)
55 }, this)
56
57 var groups = this._groups
58 this.emit('groups', bundles.reduce(function (map, bundleID) {
59 var modules = map[bundleID] = []
60 objectEach(groups, function (bundleMap, moduleID) {
61 if (bundleMap[bundleID]) {
62 modules.push(moduleID)
63 }
64 })
65 return map
66 }, Object.create(null)))
67
68 next()
69}
70
71Groups.prototype._addGroup = function(moduleID, group) {
72 var groups = this._groups[moduleID]
73 if (!groups) {
74 groups = Object.create(null)
75 }
76 if (group) {
77 groups[group] = true
78 }
79 this._groups[moduleID] = groups
80}
81
82Groups.prototype.addGroup = function(row, group) {
83 Object.keys(row.deps || {}).forEach(function (key) {
84 this._addGroup(row.deps[key], group)
85 }, this)
86
87 var moduleID = row.id
88
89 if (this._groups[moduleID][UNKNOWN]) {
90 delete this._groups[moduleID][UNKNOWN]
91 }
92
93 if (group === UNKNOWN) {
94 this._unknown.push(moduleID)
95 }
96}
97
98Groups.prototype.createFilter = function(opts) {
99 if (typeof opts === 'function') {
100 opts = { output: opts }
101 } else if (typeof opts === 'string' || Array.isArray(opts)) {
102 opts = { filter: opts }
103 }
104 if (typeof opts !== 'object') return noop
105 if (typeof opts.output === 'function') return opts.output
106
107 var output = opts.output
108 if (typeof output !== 'string') output = null
109 var filterEntries = opts.filter
110 if (typeof filterEntries !== 'function') {
111 filterEntries = function (file) {
112 if (!opts.filter) return true
113 return multimatch(file, opts.filter).length
114 }
115 }
116 var basedir = opts.basedir || this.basedir
117 return function (file) {
118 if (filterEntries(file)) {
119 return output || path.relative(basedir, file)
120 }
121 }
122}
123
124Groups.prototype.getGroups = function(row) {
125 return this._groupFilters.map(function (filter) {
126 return filter(row.file)
127 }).filter(Boolean)
128}
129