-
-
Notifications
You must be signed in to change notification settings - Fork 169
/
cursor.js
319 lines (296 loc) · 9.52 KB
/
cursor.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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
import { Meteor } from 'meteor/meteor';
/*
* @private
* @locus Anywhere
* @class FileCursor
* @param _fileRef {Object} - Mongo-Style selector (http://docs.meteor.com/api/collections.html#selectors)
* @param _collection {FilesCollection} - FilesCollection Instance
* @summary Internal class, represents each record in `FilesCursor.each()` or document returned from `.findOne()` method
*/
export class FileCursor {
constructor(_fileRef, _collection) {
this._fileRef = _fileRef;
this._collection = _collection;
Object.assign(this, _fileRef);
}
/*
* @locus Anywhere
* @memberOf FileCursor
* @name remove
* @param callback {Function} - Triggered asynchronously after item is removed or failed to be removed
* @summary Remove document
* @returns {FileCursor}
*/
remove(callback) {
this._collection._debug('[FilesCollection] [FileCursor] [remove()]');
if (this._fileRef) {
this._collection.remove(this._fileRef._id, callback);
} else {
callback && callback(new Meteor.Error(404, 'No such file'));
}
return this;
}
/*
* @locus Anywhere
* @memberOf FileCursor
* @name link
* @param version {String} - Name of file's subversion
* @param uriBase {String} - [Optional] URI base, see - https://github.com/veliovgroup/Meteor-Files/issues/626
* @summary Returns downloadable URL to File
* @returns {String}
*/
link(version = 'original', uriBase) {
this._collection._debug(`[FilesCollection] [FileCursor] [link(${version})]`);
if (this._fileRef) {
return this._collection.link(this._fileRef, version, uriBase);
}
return '';
}
/*
* @locus Anywhere
* @memberOf FileCursor
* @name get
* @param property {String} - Name of sub-object property
* @summary Returns current document as a plain Object, if `property` is specified - returns value of sub-object property
* @returns {Object|mix}
*/
get(property) {
this._collection._debug(`[FilesCollection] [FileCursor] [get(${property})]`);
if (property) {
return this._fileRef[property];
}
return this._fileRef;
}
/*
* @locus Anywhere
* @memberOf FileCursor
* @name fetch
* @summary Returns document as plain Object in Array
* @returns {[Object]}
*/
fetch() {
this._collection._debug('[FilesCollection] [FileCursor] [fetch()]');
return [this._fileRef];
}
/*
* @locus Anywhere
* @memberOf FileCursor
* @name with
* @summary Returns reactive version of current FileCursor, useful to use with `{{#with}}...{{/with}}` block template helper
* @returns {[Object]}
*/
with() {
this._collection._debug('[FilesCollection] [FileCursor] [with()]');
return Object.assign(this, this._collection.collection.findOne(this._fileRef._id));
}
}
/*
* @private
* @locus Anywhere
* @class FilesCursor
* @param _selector {String|Object} - Mongo-Style selector (http://docs.meteor.com/api/collections.html#selectors)
* @param options {Object} - Mongo-Style selector Options (http://docs.meteor.com/api/collections.html#selectors)
* @param _collection {FilesCollection} - FilesCollection Instance
* @summary Implementation of Cursor for FilesCollection
*/
export class FilesCursor {
constructor(_selector = {}, options, _collection) {
this._collection = _collection;
this._selector = _selector;
this._current = -1;
this.cursor = this._collection.collection.find(this._selector, options);
}
/*
* @locus Anywhere
* @memberOf FilesCursor
* @name get
* @summary Returns all matching document(s) as an Array. Alias of `.fetch()`
* @returns {[Object]}
*/
get() {
this._collection._debug('[FilesCollection] [FilesCursor] [get()]');
return this.cursor.fetch();
}
/*
* @locus Anywhere
* @memberOf FilesCursor
* @name hasNext
* @summary Returns `true` if there is next item available on Cursor
* @returns {Boolean}
*/
hasNext() {
this._collection._debug('[FilesCollection] [FilesCursor] [hasNext()]');
return this._current < (this.cursor.count() - 1);
}
/*
* @locus Anywhere
* @memberOf FilesCursor
* @name next
* @summary Returns next item on Cursor, if available
* @returns {Object|undefined}
*/
next() {
this._collection._debug('[FilesCollection] [FilesCursor] [next()]');
this.cursor.fetch()[++this._current];
}
/*
* @locus Anywhere
* @memberOf FilesCursor
* @name hasPrevious
* @summary Returns `true` if there is previous item available on Cursor
* @returns {Boolean}
*/
hasPrevious() {
this._collection._debug('[FilesCollection] [FilesCursor] [hasPrevious()]');
return this._current !== -1;
}
/*
* @locus Anywhere
* @memberOf FilesCursor
* @name previous
* @summary Returns previous item on Cursor, if available
* @returns {Object|undefined}
*/
previous() {
this._collection._debug('[FilesCollection] [FilesCursor] [previous()]');
this.cursor.fetch()[--this._current];
}
/*
* @locus Anywhere
* @memberOf FilesCursor
* @name fetch
* @summary Returns all matching document(s) as an Array.
* @returns {[Object]}
*/
fetch() {
this._collection._debug('[FilesCollection] [FilesCursor] [fetch()]');
return this.cursor.fetch() || [];
}
/*
* @locus Anywhere
* @memberOf FilesCursor
* @name first
* @summary Returns first item on Cursor, if available
* @returns {Object|undefined}
*/
first() {
this._collection._debug('[FilesCollection] [FilesCursor] [first()]');
this._current = 0;
return this.fetch()[this._current];
}
/*
* @locus Anywhere
* @memberOf FilesCursor
* @name last
* @summary Returns last item on Cursor, if available
* @returns {Object|undefined}
*/
last() {
this._collection._debug('[FilesCollection] [FilesCursor] [last()]');
this._current = this.count() - 1;
return this.fetch()[this._current];
}
/*
* @locus Anywhere
* @memberOf FilesCursor
* @name count
* @summary Returns the number of documents that match a query
* @returns {Number}
*/
count() {
this._collection._debug('[FilesCollection] [FilesCursor] [count()]');
return this.cursor.count();
}
/*
* @locus Anywhere
* @memberOf FilesCursor
* @name remove
* @param callback {Function} - Triggered asynchronously after item is removed or failed to be removed
* @summary Removes all documents that match a query
* @returns {FilesCursor}
*/
remove(callback) {
this._collection._debug('[FilesCollection] [FilesCursor] [remove()]');
this._collection.remove(this._selector, callback);
return this;
}
/*
* @locus Anywhere
* @memberOf FilesCursor
* @name forEach
* @param callback {Function} - Function to call. It will be called with three arguments: the `file`, a 0-based index, and cursor itself
* @param context {Object} - An object which will be the value of `this` inside `callback`
* @summary Call `callback` once for each matching document, sequentially and synchronously.
* @returns {undefined}
*/
forEach(callback, context = {}) {
this._collection._debug('[FilesCollection] [FilesCursor] [forEach()]');
this.cursor.forEach(callback, context);
}
/*
* @locus Anywhere
* @memberOf FilesCursor
* @name each
* @summary Returns an Array of FileCursor made for each document on current cursor
* Useful when using in {{#each FilesCursor#each}}...{{/each}} block template helper
* @returns {[FileCursor]}
*/
each() {
return this.map((file) => {
return new FileCursor(file, this._collection);
});
}
/*
* @locus Anywhere
* @memberOf FilesCursor
* @name map
* @param callback {Function} - Function to call. It will be called with three arguments: the `file`, a 0-based index, and cursor itself
* @param context {Object} - An object which will be the value of `this` inside `callback`
* @summary Map `callback` over all matching documents. Returns an Array.
* @returns {Array}
*/
map(callback, context = {}) {
this._collection._debug('[FilesCollection] [FilesCursor] [map()]');
return this.cursor.map(callback, context);
}
/*
* @locus Anywhere
* @memberOf FilesCursor
* @name current
* @summary Returns current item on Cursor, if available
* @returns {Object|undefined}
*/
current() {
this._collection._debug('[FilesCollection] [FilesCursor] [current()]');
if (this._current < 0) {
this._current = 0;
}
return this.fetch()[this._current];
}
/*
* @locus Anywhere
* @memberOf FilesCursor
* @name observe
* @param callbacks {Object} - Functions to call to deliver the result set as it changes
* @summary Watch a query. Receive callbacks as the result set changes.
* @url http://docs.meteor.com/api/collections.html#Mongo-Cursor-observe
* @returns {Object} - live query handle
*/
observe(callbacks) {
this._collection._debug('[FilesCollection] [FilesCursor] [observe()]');
return this.cursor.observe(callbacks);
}
/*
* @locus Anywhere
* @memberOf FilesCursor
* @name observeChanges
* @param callbacks {Object} - Functions to call to deliver the result set as it changes
* @summary Watch a query. Receive callbacks as the result set changes. Only the differences between the old and new documents are passed to the callbacks.
* @url http://docs.meteor.com/api/collections.html#Mongo-Cursor-observeChanges
* @returns {Object} - live query handle
*/
observeChanges(callbacks) {
this._collection._debug('[FilesCollection] [FilesCursor] [observeChanges()]');
return this.cursor.observeChanges(callbacks);
}
}