-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
151 lines (132 loc) · 4.46 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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
'use strict';
var path = require('path');
var utils = require('./lib/utils');
var indexer = require('./lib/indexer');
/**
* Sarge object used to register [indexers](#indexers) and execute the [collect](#collect) and [index](#index)
* methods on indexers.
*
* ```js
* var sarge = new Sarge();
* ```
* @param {Object} `options` Options to control defaults.
* @param {String} `options.indexer` Set a default indexer to use when one isn't specified in [.collect](#collect) or [.index](#index). Defaults to "default".
* @param {Object} `options.indexers` Optionally set an object of indexers when creating the new instance.
* @returns {Object} Instance of Sarge
* @api public
*/
function Sarge(options) {
if (!(this instanceof Sarge)) {
return new Sarge(options);
}
utils.define(this, 'options', utils.extend({}, options));
utils.define(this, 'indexers', {});
utils.define(this, 'files', {});
this.indexer('default', indexer());
if (this.options.indexers) {
utils.own(this.options.indexers, function(val, key) {
this.indexer(key, val);
}, this);
}
}
/**
* Get or set an indexer by name. This throws an error if only name is passed and the indexer is not found.
*
* ```js
* // set
* sarge.indexer('foo', foo);
* // get
* var foo = sarge.indexer('foo');
* ```
* @param {String} `name` Name of indexer to get or set.
* @param {Object} `indexer` Instance of an indexer. See [indexers](#indexers) for more information.
* @return {Object} Sarge instance when setting, indexer instance when getting.
* @api public
*/
Sarge.prototype.indexer = function(name, indexer) {
if (typeof name !== 'string') {
throw new TypeError('expected "name" to be a string');
}
if (typeof indexer === 'undefined') {
if (this.indexers[name]) {
return this.indexers[name];
}
throw new Error('Unable to find indexer "' + name + '"');
}
this.indexers[name] = indexer;
return this;
};
/**
* Creates a through stream that will execute `.collect` method on specified indexer
* for each file passing through the stream. The `.collect` method passes an object
* to the callback that will be collected and then indexed when `.index` is called.
*
* ```js
* app.src('*.md')
* // use default set on instance or "default" indexer
* .pipe(sarge.collect())
* // or specify a registred indexer to use
* .pipe(sarge.collect({indexer: 'foo'}));
* ```
* @param {Object} `options` Options used to specify the indexer to use.
* @return {Stream} Through stream that's used to collect files to index.
* @api public
*/
Sarge.prototype.collect = function(options) {
var self = this;
var opts = utils.extend({indexer: 'default'}, this.options, options);
var indexer = this.indexer(opts.indexer);
return utils.through.obj(function(file, enc, next) {
indexer.collect(file, function(err, obj) {
if (err) return next(err);
if (obj) {
self.files[obj.key || file.key] = obj;
}
next(null, file);
});
});
};
/**
* Executes the `.index` method on the specified indexer
* passing the collected files and options along with a callback to indicate when indexing
* is finished.
*
* ```js
* // use default indexer specified when adding the plugin
* sarge.index(function(err) {
* if (err) return console.error(err);
* console.log('indexing finished');
* });
*
* // use registered indexer
* sarge.index({indexer: 'foo'}, function(err) {
* if (err) return console.error(err);
* console.log('indexing finished');
* });
* ```
* @param {Object} `options` Options to specify the indexer to use and to pass into the `.index` method.
* @param {String} `options.indexer` Indexer to use. Defaults to 'default'
* @param {Boolean} `options.clear` Optionally clear the stored `files` object. This is useful for incremental indexing in a continuous stream.
* @param {Function} `cb` Callback function passed into the indexer's `.index` method to specify when indexing is finished.
* @api public
*/
Sarge.prototype.index = function(options, cb) {
if (typeof options === 'function') {
cb = options;
options = {};
}
if (typeof cb !== 'function') {
throw new TypeError('expected "cb" to be a function');
}
var opts = utils.extend({indexer: 'default', clear: false}, this.options, options);
var files = utils.extend({}, this.files);
if (opts.clear === true) {
this.files = {};
}
var indexer = this.indexer(opts.indexer);
indexer.index(files, opts, cb);
};
/**
* Exposes `Sarge`
*/
module.exports = Sarge;