fusee-framework 2.7.1 → 2.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -32
- package/framework/actions/index.js +12 -0
- package/framework/auto-import-preset.js +18 -5
- package/framework/auto-imports.d.ts +30 -27
- package/framework/core/compiler.js +322 -310
- package/framework/core/h.js +632 -588
- package/framework/di/index.js +9 -0
- package/framework/index.js +10 -7
- package/framework/plugins/index.js +8 -0
- package/framework/store/index.js +12 -0
- package/framework/types/actions.d.ts +52 -50
- package/framework/types/di-entry.d.ts +9 -0
- package/framework/types/index.d.ts +112 -118
- package/package.json +19 -1
- package/framework/core/comet-js/comet-config.js +0 -14
- package/framework/core/comet-js/comet-fusee.d.ts +0 -10
- package/framework/core/comet-js/comet-fusee.js +0 -114
- package/framework/core/comet-js/comet-methods.js +0 -32
- package/framework/core/comet-js/comet.d.ts +0 -70
- package/framework/core/comet-js/comet.js +0 -534
- package/framework/frel/frel.d.ts +0 -152
- package/framework/frel/frel.js +0 -757
package/framework/frel/frel.js
DELETED
|
@@ -1,757 +0,0 @@
|
|
|
1
|
-
import { computed } from '../core/signal.js'
|
|
2
|
-
|
|
3
|
-
/** Default ascending comparer used by orderBy()/thenBy() when no comparer is supplied. */
|
|
4
|
-
function defaultComparer(a, b) {
|
|
5
|
-
if (a === b) return 0
|
|
6
|
-
if (a == null) return b == null ? 0 : -1
|
|
7
|
-
if (b == null) return 1
|
|
8
|
-
return a < b ? -1 : a > b ? 1 : 0
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/** Splits the flexible (predicate?, defaultValue?) argument list used by the *OrDefault() methods. */
|
|
12
|
-
function resolveOrDefaultArgs(args) {
|
|
13
|
-
if (args.length === 0) return { predicate: undefined, defaultValue: null }
|
|
14
|
-
if (typeof args[0] === 'function') {
|
|
15
|
-
return { predicate: args[0], defaultValue: args.length > 1 ? args[1] : null }
|
|
16
|
-
}
|
|
17
|
-
return { predicate: undefined, defaultValue: args[0] }
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/** Wraps a group's key with its elements; iterating the result yields the elements, like a LINQ grouping. */
|
|
21
|
-
function createGrouping(key, items) {
|
|
22
|
-
const grouping = new Enumerable(() => items)
|
|
23
|
-
grouping.key = key
|
|
24
|
-
return grouping
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* A lazily-evaluated LINQ-to-Objects style sequence.
|
|
29
|
-
* Every intermediate operator (where, select, orderBy, ...) is deferred
|
|
30
|
-
*/
|
|
31
|
-
export class Enumerable {
|
|
32
|
-
constructor(iteratorFactory) {
|
|
33
|
-
this._iteratorFactory = iteratorFactory
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
[Symbol.iterator]() {
|
|
37
|
-
const iterable = this._iteratorFactory()
|
|
38
|
-
return iterable[Symbol.iterator] ? iterable[Symbol.iterator]() : iterable
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// deferred (lazy) operators - each returns a new Enumerable
|
|
42
|
-
|
|
43
|
-
where(predicate) {
|
|
44
|
-
const self = this
|
|
45
|
-
return new Enumerable(function* () {
|
|
46
|
-
let i = 0
|
|
47
|
-
for (const item of self)
|
|
48
|
-
if (predicate(item, i++))
|
|
49
|
-
yield item
|
|
50
|
-
})
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
select(selector) {
|
|
54
|
-
const self = this
|
|
55
|
-
return new Enumerable(function* () {
|
|
56
|
-
let i = 0
|
|
57
|
-
for (const item of self)
|
|
58
|
-
yield selector(item, i++)
|
|
59
|
-
})
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
selectMany(collectionSelector, resultSelector) {
|
|
63
|
-
const self = this
|
|
64
|
-
return new Enumerable(function* () {
|
|
65
|
-
let i = 0
|
|
66
|
-
for (const item of self) {
|
|
67
|
-
for (const inner of collectionSelector(item, i++)) {
|
|
68
|
-
yield resultSelector ? resultSelector(item, inner) : inner
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
})
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
take(count) {
|
|
75
|
-
const self = this
|
|
76
|
-
return new Enumerable(function* () {
|
|
77
|
-
if (count <= 0) return
|
|
78
|
-
let i = 0
|
|
79
|
-
for (const item of self) {
|
|
80
|
-
yield item
|
|
81
|
-
if (++i >= count) break
|
|
82
|
-
}
|
|
83
|
-
})
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
takeWhile(predicate) {
|
|
87
|
-
const self = this
|
|
88
|
-
return new Enumerable(function* () {
|
|
89
|
-
let i = 0
|
|
90
|
-
for (const item of self) {
|
|
91
|
-
if (!predicate(item, i++)) break
|
|
92
|
-
yield item
|
|
93
|
-
}
|
|
94
|
-
})
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
takeLast(count) {
|
|
98
|
-
return new Enumerable(() => {
|
|
99
|
-
if (count <= 0) return []
|
|
100
|
-
const buffer = []
|
|
101
|
-
for (const item of this) {
|
|
102
|
-
buffer.push(item)
|
|
103
|
-
if (buffer.length > count)
|
|
104
|
-
buffer.shift()
|
|
105
|
-
}
|
|
106
|
-
return buffer
|
|
107
|
-
})
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
skip(count) {
|
|
111
|
-
const self = this
|
|
112
|
-
return new Enumerable(function* () {
|
|
113
|
-
let i = 0
|
|
114
|
-
for (const item of self) {
|
|
115
|
-
if (i++ < count) continue
|
|
116
|
-
yield item
|
|
117
|
-
}
|
|
118
|
-
})
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
skipWhile(predicate) {
|
|
122
|
-
const self = this
|
|
123
|
-
return new Enumerable(function* () {
|
|
124
|
-
let i = 0
|
|
125
|
-
let skipping = true
|
|
126
|
-
for (const item of self) {
|
|
127
|
-
if (skipping && predicate(item, i++)) continue
|
|
128
|
-
skipping = false
|
|
129
|
-
yield item
|
|
130
|
-
}
|
|
131
|
-
})
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
skipLast(count) {
|
|
135
|
-
const self = this
|
|
136
|
-
return new Enumerable(function* () {
|
|
137
|
-
if (count <= 0) {
|
|
138
|
-
yield* self
|
|
139
|
-
return
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
const buffer = []
|
|
143
|
-
for (const item of self) {
|
|
144
|
-
buffer.push(item)
|
|
145
|
-
if (buffer.length > count) {
|
|
146
|
-
yield buffer.shift()
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
})
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
distinct(keySelector) {
|
|
153
|
-
const self = this
|
|
154
|
-
return new Enumerable(function* () {
|
|
155
|
-
const seen = new Set()
|
|
156
|
-
for (const item of self) {
|
|
157
|
-
const key = keySelector ? keySelector(item) : item
|
|
158
|
-
if (seen.has(key)) continue
|
|
159
|
-
seen.add(key)
|
|
160
|
-
yield item
|
|
161
|
-
}
|
|
162
|
-
})
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
concat(...others) {
|
|
166
|
-
const self = this
|
|
167
|
-
return new Enumerable(function* () {
|
|
168
|
-
yield* self
|
|
169
|
-
for (const other of others)
|
|
170
|
-
yield* from(other)
|
|
171
|
-
})
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
union(other, keySelector) {
|
|
175
|
-
return this.concat(other).distinct(keySelector)
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
intersect(other, keySelector) {
|
|
179
|
-
const self = this
|
|
180
|
-
return new Enumerable(function* () {
|
|
181
|
-
const otherKeys = new Set()
|
|
182
|
-
for (const item of from(other))
|
|
183
|
-
otherKeys.add(keySelector ? keySelector(item) : item)
|
|
184
|
-
const seen = new Set()
|
|
185
|
-
for (const item of self) {
|
|
186
|
-
const key = keySelector ? keySelector(item) : item
|
|
187
|
-
if (otherKeys.has(key) && !seen.has(key)) {
|
|
188
|
-
seen.add(key)
|
|
189
|
-
yield item
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
})
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
except(other, keySelector) {
|
|
196
|
-
const self = this
|
|
197
|
-
return new Enumerable(function* () {
|
|
198
|
-
const otherKeys = new Set()
|
|
199
|
-
for (const item of from(other))
|
|
200
|
-
otherKeys.add(keySelector ? keySelector(item) : item)
|
|
201
|
-
const seen = new Set()
|
|
202
|
-
for (const item of self) {
|
|
203
|
-
const key = keySelector ? keySelector(item) : item
|
|
204
|
-
if (!otherKeys.has(key) && !seen.has(key)) {
|
|
205
|
-
seen.add(key)
|
|
206
|
-
yield item
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
})
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
zip(other, resultSelector) {
|
|
213
|
-
const self = this
|
|
214
|
-
return new Enumerable(function* () {
|
|
215
|
-
const it1 = self[Symbol.iterator]()
|
|
216
|
-
const it2 = from(other)[Symbol.iterator]()
|
|
217
|
-
while (true) {
|
|
218
|
-
const a = it1.next()
|
|
219
|
-
const b = it2.next()
|
|
220
|
-
if (a.done || b.done) return
|
|
221
|
-
yield resultSelector ? resultSelector(a.value, b.value) : [a.value, b.value]
|
|
222
|
-
}
|
|
223
|
-
})
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
append(item) {
|
|
227
|
-
return this.concat([item])
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
prepend(item) {
|
|
231
|
-
const self = this
|
|
232
|
-
return new Enumerable(function* () {
|
|
233
|
-
yield item
|
|
234
|
-
yield* self
|
|
235
|
-
})
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
defaultIfEmpty(defaultValue = null) {
|
|
239
|
-
const self = this
|
|
240
|
-
return new Enumerable(function* () {
|
|
241
|
-
let any = false
|
|
242
|
-
for (const item of self) {
|
|
243
|
-
any = true
|
|
244
|
-
yield item
|
|
245
|
-
}
|
|
246
|
-
if (!any) yield defaultValue
|
|
247
|
-
})
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
chunk(size) {
|
|
251
|
-
if (!(size > 0)) throw new Error('[framework] chunk() size must be greater than 0')
|
|
252
|
-
const self = this
|
|
253
|
-
return new Enumerable(function* () {
|
|
254
|
-
let buffer = []
|
|
255
|
-
for (const item of self) {
|
|
256
|
-
buffer.push(item)
|
|
257
|
-
if (buffer.length === size) {
|
|
258
|
-
yield buffer
|
|
259
|
-
buffer = []
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
if (buffer.length) yield buffer
|
|
263
|
-
})
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
reverse() {
|
|
267
|
-
const self = this
|
|
268
|
-
return new Enumerable(function* () {
|
|
269
|
-
const items = [...self]
|
|
270
|
-
for (let i = items.length - 1; i >= 0; i--)
|
|
271
|
-
yield items[i]
|
|
272
|
-
})
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
orderBy(keySelector, comparer = defaultComparer) {
|
|
276
|
-
return new OrderedEnumerable(() => this, [{ keySelector, comparer, descending: false }])
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
orderByDescending(keySelector, comparer = defaultComparer) {
|
|
280
|
-
return new OrderedEnumerable(() => this, [{ keySelector, comparer, descending: true }])
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
groupBy(keySelector, elementSelector, resultSelector) {
|
|
284
|
-
const self = this
|
|
285
|
-
return new Enumerable(function* () {
|
|
286
|
-
const groups = new Map()
|
|
287
|
-
for (const item of self) {
|
|
288
|
-
const key = keySelector(item)
|
|
289
|
-
const element = elementSelector ? elementSelector(item) : item
|
|
290
|
-
if (!groups.has(key))
|
|
291
|
-
groups.set(key, [])
|
|
292
|
-
groups.get(key).push(element)
|
|
293
|
-
}
|
|
294
|
-
for (const [key, items] of groups) {
|
|
295
|
-
yield resultSelector ? resultSelector(key, items) : createGrouping(key, items)
|
|
296
|
-
}
|
|
297
|
-
})
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
join(inner, outerKeySelector, innerKeySelector, resultSelector) {
|
|
301
|
-
const self = this
|
|
302
|
-
return new Enumerable(function* () {
|
|
303
|
-
const innerMap = new Map()
|
|
304
|
-
for (const item of from(inner)) {
|
|
305
|
-
const key = innerKeySelector(item)
|
|
306
|
-
if (!innerMap.has(key))
|
|
307
|
-
innerMap.set(key, [])
|
|
308
|
-
innerMap.get(key).push(item)
|
|
309
|
-
}
|
|
310
|
-
for (const outerItem of self) {
|
|
311
|
-
const matches = innerMap.get(outerKeySelector(outerItem))
|
|
312
|
-
if (!matches)
|
|
313
|
-
continue
|
|
314
|
-
for (const innerItem of matches)
|
|
315
|
-
yield resultSelector(outerItem, innerItem)
|
|
316
|
-
}
|
|
317
|
-
})
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
groupJoin(inner, outerKeySelector, innerKeySelector, resultSelector) {
|
|
321
|
-
const self = this
|
|
322
|
-
return new Enumerable(function* () {
|
|
323
|
-
const innerMap = new Map()
|
|
324
|
-
for (const item of from(inner)) {
|
|
325
|
-
const key = innerKeySelector(item)
|
|
326
|
-
if (!innerMap.has(key))
|
|
327
|
-
innerMap.set(key, [])
|
|
328
|
-
innerMap.get(key).push(item)
|
|
329
|
-
}
|
|
330
|
-
for (const outerItem of self) {
|
|
331
|
-
const matches = innerMap.get(outerKeySelector(outerItem)) || []
|
|
332
|
-
yield resultSelector(outerItem, matches)
|
|
333
|
-
}
|
|
334
|
-
})
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
// terminal (eager) operators
|
|
338
|
-
|
|
339
|
-
ofType(type) {
|
|
340
|
-
const self = this
|
|
341
|
-
return new Enumerable(function* () {
|
|
342
|
-
if (typeof type === 'string') {
|
|
343
|
-
for (const item of self) {
|
|
344
|
-
if (typeof item === type)
|
|
345
|
-
yield item
|
|
346
|
-
}
|
|
347
|
-
} else if (typeof type === 'function') {
|
|
348
|
-
for (const item of self) {
|
|
349
|
-
if (item instanceof type)
|
|
350
|
-
yield item
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
})
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
toArray() {
|
|
357
|
-
return [...this]
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
toMap(keySelector, valueSelector) {
|
|
361
|
-
const map = new Map()
|
|
362
|
-
let i = 0
|
|
363
|
-
for (const item of this) {
|
|
364
|
-
const key = keySelector(item, i)
|
|
365
|
-
if (map.has(key))
|
|
366
|
-
console.warn(`[framework] toMap(): duplicate key "${key}", overwriting previous value`)
|
|
367
|
-
map.set(key, valueSelector ? valueSelector(item, i) : item)
|
|
368
|
-
i++
|
|
369
|
-
}
|
|
370
|
-
return map
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
toSet(keySelector) {
|
|
374
|
-
const set = new Set()
|
|
375
|
-
let i = 0
|
|
376
|
-
for (const item of this) {
|
|
377
|
-
set.add(keySelector ? keySelector(item, i++) : item)
|
|
378
|
-
}
|
|
379
|
-
return set
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
toLookup(keySelector, elementSelector) {
|
|
383
|
-
const map = new Map()
|
|
384
|
-
let i = 0
|
|
385
|
-
for (const item of this) {
|
|
386
|
-
const key = keySelector(item, i)
|
|
387
|
-
if (!map.has(key)) map.set(key, [])
|
|
388
|
-
map.get(key).push(elementSelector ? elementSelector(item, i) : item)
|
|
389
|
-
i++
|
|
390
|
-
}
|
|
391
|
-
return map
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
toObject(keySelector, valueSelector = x => x) {
|
|
395
|
-
const obj = Object.create(null)
|
|
396
|
-
let i = 0
|
|
397
|
-
for (const item of this) {
|
|
398
|
-
obj[keySelector(item, i)] = valueSelector(item, i)
|
|
399
|
-
i++
|
|
400
|
-
}
|
|
401
|
-
return obj
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
forEach(action) {
|
|
405
|
-
let i = 0
|
|
406
|
-
for (const item of this)
|
|
407
|
-
action(item, i++)
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
count(predicate) {
|
|
411
|
-
let n = 0, i = 0
|
|
412
|
-
for (const item of this) {
|
|
413
|
-
if (!predicate || predicate(item, i)) n++
|
|
414
|
-
i++
|
|
415
|
-
}
|
|
416
|
-
return n
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
any(predicate) {
|
|
420
|
-
let i = 0
|
|
421
|
-
for (const item of this) {
|
|
422
|
-
if (!predicate || predicate(item, i)) return true
|
|
423
|
-
i++
|
|
424
|
-
}
|
|
425
|
-
return false
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
all(predicate) {
|
|
429
|
-
let i = 0
|
|
430
|
-
for (const item of this) {
|
|
431
|
-
if (!predicate(item, i)) return false
|
|
432
|
-
i++
|
|
433
|
-
}
|
|
434
|
-
return true
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
contains(value, comparer = Object.is) {
|
|
438
|
-
for (const item of this)
|
|
439
|
-
if (comparer(item, value))
|
|
440
|
-
return true
|
|
441
|
-
return false
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
sequenceEqual(other, comparer = Object.is) {
|
|
445
|
-
const it1 = this[Symbol.iterator]()
|
|
446
|
-
const it2 = from(other)[Symbol.iterator]()
|
|
447
|
-
while (true) {
|
|
448
|
-
const a = it1.next()
|
|
449
|
-
const b = it2.next()
|
|
450
|
-
if (a.done && b.done)
|
|
451
|
-
return true
|
|
452
|
-
if (a.done !== b.done)
|
|
453
|
-
return false
|
|
454
|
-
if (!comparer(a.value, b.value))
|
|
455
|
-
return false
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
first(predicate) {
|
|
460
|
-
let i = 0
|
|
461
|
-
for (const item of this) {
|
|
462
|
-
if (!predicate || predicate(item, i)) return item
|
|
463
|
-
i++
|
|
464
|
-
}
|
|
465
|
-
throw new Error('[framework] first(): sequence contains no matching element')
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
firstOrDefault(...args) {
|
|
469
|
-
const { predicate, defaultValue } = resolveOrDefaultArgs(args)
|
|
470
|
-
let i = 0
|
|
471
|
-
for (const item of this) {
|
|
472
|
-
if (!predicate || predicate(item, i)) return item
|
|
473
|
-
i++
|
|
474
|
-
}
|
|
475
|
-
return defaultValue
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
last(predicate) {
|
|
479
|
-
let found, has = false, i = 0
|
|
480
|
-
for (const item of this) {
|
|
481
|
-
if (!predicate || predicate(item, i)) {
|
|
482
|
-
found = item
|
|
483
|
-
has = true
|
|
484
|
-
}
|
|
485
|
-
i++
|
|
486
|
-
}
|
|
487
|
-
if (!has)
|
|
488
|
-
throw new Error('[framework] last(): sequence contains no matching element')
|
|
489
|
-
return found
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
lastOrDefault(...args) {
|
|
493
|
-
const { predicate, defaultValue } = resolveOrDefaultArgs(args)
|
|
494
|
-
let found = defaultValue, has = false, i = 0
|
|
495
|
-
for (const item of this) {
|
|
496
|
-
if (!predicate || predicate(item, i)) {
|
|
497
|
-
found = item
|
|
498
|
-
has = true
|
|
499
|
-
}
|
|
500
|
-
i++
|
|
501
|
-
}
|
|
502
|
-
return has ? found : defaultValue
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
single(predicate) {
|
|
506
|
-
let found, n = 0, i = 0
|
|
507
|
-
for (const item of this) {
|
|
508
|
-
if (!predicate || predicate(item, i)) {
|
|
509
|
-
if (++n > 1)
|
|
510
|
-
throw new Error('[framework] single(): sequence contains more than one matching element')
|
|
511
|
-
found = item
|
|
512
|
-
}
|
|
513
|
-
i++
|
|
514
|
-
}
|
|
515
|
-
if (n === 0)
|
|
516
|
-
throw new Error('[framework] single(): sequence contains no matching element')
|
|
517
|
-
return found
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
singleOrDefault(...args) {
|
|
521
|
-
const { predicate, defaultValue } = resolveOrDefaultArgs(args)
|
|
522
|
-
let found = defaultValue, n = 0, i = 0
|
|
523
|
-
for (const item of this) {
|
|
524
|
-
if (!predicate || predicate(item, i)) {
|
|
525
|
-
if (++n > 1)
|
|
526
|
-
throw new Error('[framework] singleOrDefault(): sequence contains more than one matching element')
|
|
527
|
-
found = item
|
|
528
|
-
}
|
|
529
|
-
i++
|
|
530
|
-
}
|
|
531
|
-
return n === 0 ? defaultValue : found
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
elementAt(index) {
|
|
535
|
-
let i = 0
|
|
536
|
-
for (const item of this)
|
|
537
|
-
if (i++ === index)
|
|
538
|
-
return item
|
|
539
|
-
throw new Error(`[framework] elementAt(): index ${index} is out of range`)
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
elementAtOrDefault(index, defaultValue = null) {
|
|
543
|
-
let i = 0
|
|
544
|
-
for (const item of this)
|
|
545
|
-
if (i++ === index)
|
|
546
|
-
return item
|
|
547
|
-
return defaultValue
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
sum(selector) {
|
|
551
|
-
let total = 0
|
|
552
|
-
for (const item of this)
|
|
553
|
-
total += selector ? selector(item) : item
|
|
554
|
-
return total
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
average(selector) {
|
|
558
|
-
let total = 0, n = 0
|
|
559
|
-
for (const item of this) {
|
|
560
|
-
total += selector ? selector(item) : item
|
|
561
|
-
n++
|
|
562
|
-
}
|
|
563
|
-
if (n === 0)
|
|
564
|
-
throw new Error('[framework] average(): sequence contains no elements')
|
|
565
|
-
return total / n
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
min(selector) {
|
|
569
|
-
let result, has = false
|
|
570
|
-
for (const item of this) {
|
|
571
|
-
const value = selector ? selector(item) : item
|
|
572
|
-
if (!has || value < result) {
|
|
573
|
-
result = value
|
|
574
|
-
has = true
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
if (!has)
|
|
578
|
-
throw new Error('[framework] min(): sequence contains no elements')
|
|
579
|
-
return result
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
max(selector) {
|
|
583
|
-
let result, has = false
|
|
584
|
-
for (const item of this) {
|
|
585
|
-
const value = selector ? selector(item) : item
|
|
586
|
-
if (!has || value > result) {
|
|
587
|
-
result = value
|
|
588
|
-
has = true
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
if (!has)
|
|
592
|
-
throw new Error('[framework] max(): sequence contains no elements')
|
|
593
|
-
return result
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
minBy(keySelector, comparer = defaultComparer) {
|
|
597
|
-
let minItem = null
|
|
598
|
-
let minKey
|
|
599
|
-
let has = false
|
|
600
|
-
|
|
601
|
-
for (const item of this) {
|
|
602
|
-
const key = keySelector(item)
|
|
603
|
-
if (!has || comparer(key, minKey) < 0) {
|
|
604
|
-
minKey = key
|
|
605
|
-
minItem = item
|
|
606
|
-
has = true
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
return minItem
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
maxBy(keySelector, comparer = defaultComparer) {
|
|
614
|
-
return this.minBy(keySelector, (a, b) => comparer(b, a))
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
aggregate(...args) {
|
|
618
|
-
if (args.length === 1) {
|
|
619
|
-
const [func] = args
|
|
620
|
-
let acc, has = false, i = 0
|
|
621
|
-
for (const item of this) {
|
|
622
|
-
acc = has ? func(acc, item, i) : item
|
|
623
|
-
has = true
|
|
624
|
-
i++
|
|
625
|
-
}
|
|
626
|
-
if (!has)
|
|
627
|
-
throw new Error('[framework] aggregate(): sequence contains no elements')
|
|
628
|
-
return acc
|
|
629
|
-
}
|
|
630
|
-
const [seed, func, resultSelector] = args
|
|
631
|
-
let acc = seed, i = 0
|
|
632
|
-
for (const item of this) {
|
|
633
|
-
acc = func(acc, item, i)
|
|
634
|
-
i++
|
|
635
|
-
}
|
|
636
|
-
return resultSelector ? resultSelector(acc) : acc
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
scan(...args) {
|
|
640
|
-
const self = this
|
|
641
|
-
if (args.length === 1) {
|
|
642
|
-
const [func] = args
|
|
643
|
-
return new Enumerable(function* () {
|
|
644
|
-
let acc, has = false, i = 0
|
|
645
|
-
for (const item of self) {
|
|
646
|
-
acc = has ? func(acc, item, i) : item
|
|
647
|
-
has = true
|
|
648
|
-
i++
|
|
649
|
-
yield acc
|
|
650
|
-
}
|
|
651
|
-
})
|
|
652
|
-
}
|
|
653
|
-
const [seed, func] = args
|
|
654
|
-
return new Enumerable(function* () {
|
|
655
|
-
let acc = seed, i = 0
|
|
656
|
-
for (const item of self) {
|
|
657
|
-
acc = func(acc, item, i)
|
|
658
|
-
i++
|
|
659
|
-
yield acc
|
|
660
|
-
}
|
|
661
|
-
})
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
// reactivity bridge
|
|
665
|
-
|
|
666
|
-
/** Wraps a terminal call to this query in computed(), so the result stays in sync with any signals it reads. */
|
|
667
|
-
toSignal(terminalOp) {
|
|
668
|
-
const run = terminalOp || (query => query.toArray())
|
|
669
|
-
return computed(() => run(this))
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
// JS-flavored aliases, for readability at call sites
|
|
673
|
-
|
|
674
|
-
filter(predicate) {
|
|
675
|
-
return this.where(predicate)
|
|
676
|
-
}
|
|
677
|
-
map(selector) {
|
|
678
|
-
return this.select(selector)
|
|
679
|
-
}
|
|
680
|
-
flatMap(collectionSelector, resultSelector) {
|
|
681
|
-
return this.selectMany(collectionSelector, resultSelector)
|
|
682
|
-
}
|
|
683
|
-
reduce(...args) {
|
|
684
|
-
return this.aggregate(...args)
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
/** An Enumerable produced by orderBy()/orderByDescending() that supports additional thenBy() tie-breakers. */
|
|
689
|
-
export class OrderedEnumerable extends Enumerable {
|
|
690
|
-
constructor(sourceFactory, comparers) {
|
|
691
|
-
super(function* () {
|
|
692
|
-
const items = [...sourceFactory()]
|
|
693
|
-
const indices = items.map((_, i) => i)
|
|
694
|
-
indices.sort((a, b) => {
|
|
695
|
-
for (const { keySelector, comparer, descending } of comparers) {
|
|
696
|
-
const cmp = comparer(keySelector(items[a]), keySelector(items[b]))
|
|
697
|
-
if (cmp !== 0)
|
|
698
|
-
return descending ? -cmp : cmp
|
|
699
|
-
}
|
|
700
|
-
return a - b
|
|
701
|
-
})
|
|
702
|
-
for (const i of indices)
|
|
703
|
-
yield items[i]
|
|
704
|
-
})
|
|
705
|
-
this._sourceFactory = sourceFactory
|
|
706
|
-
this._comparers = comparers
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
thenBy(keySelector, comparer = defaultComparer) {
|
|
710
|
-
return new OrderedEnumerable(this._sourceFactory, [...this._comparers, { keySelector, comparer, descending: false }])
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
thenByDescending(keySelector, comparer = defaultComparer) {
|
|
714
|
-
return new OrderedEnumerable(this._sourceFactory, [...this._comparers, { keySelector, comparer, descending: true }])
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
/**
|
|
719
|
-
* Wraps a source into a queryable, lazily-evaluated Enumerable.
|
|
720
|
-
* Accepts arrays, strings, Maps/Sets, any iterable, another Enumerable, or a
|
|
721
|
-
* function - including a Fusée signal/computed/resource accessor
|
|
722
|
-
*/
|
|
723
|
-
export function from(source) {
|
|
724
|
-
if (source instanceof Enumerable)
|
|
725
|
-
return source
|
|
726
|
-
if (source == null)
|
|
727
|
-
return new Enumerable(function* () {})
|
|
728
|
-
if (typeof source === 'function') {
|
|
729
|
-
return new Enumerable(function* () {
|
|
730
|
-
const resolved = source()
|
|
731
|
-
if (resolved != null)
|
|
732
|
-
yield* resolved
|
|
733
|
-
})
|
|
734
|
-
}
|
|
735
|
-
return new Enumerable(function* () { yield* source })
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
/** Produces a lazy sequence of `count` consecutive integers starting at `start`. */
|
|
739
|
-
export function range(start, count) {
|
|
740
|
-
return new Enumerable(function* () {
|
|
741
|
-
for (let i = 0; i < count; i++)
|
|
742
|
-
yield start + i
|
|
743
|
-
})
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
/** Produces a lazy sequence that repeats `element` `count` times. */
|
|
747
|
-
export function repeat(element, count) {
|
|
748
|
-
return new Enumerable(function* () {
|
|
749
|
-
for (let i = 0; i < count; i++)
|
|
750
|
-
yield element
|
|
751
|
-
})
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
/** Returns an empty sequence. */
|
|
755
|
-
export function empty() {
|
|
756
|
-
return new Enumerable(function* () {})
|
|
757
|
-
}
|