inqjs 1.0.0
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/LICENSE +21 -0
- package/README.md +226 -0
- package/dist/src/Query.js +115 -0
- package/dist/src/async/AsyncQuery.js +107 -0
- package/dist/src/async/operators/allAsync.js +11 -0
- package/dist/src/async/operators/anyAsync.js +17 -0
- package/dist/src/async/operators/countAsync.js +12 -0
- package/dist/src/async/operators/distinctAsync.js +13 -0
- package/dist/src/async/operators/firstAsync.js +20 -0
- package/dist/src/async/operators/maxAsync.js +16 -0
- package/dist/src/async/operators/minAsync.js +16 -0
- package/dist/src/async/operators/orderByAsync.js +18 -0
- package/dist/src/async/operators/selectAsync.js +9 -0
- package/dist/src/async/operators/skipAsync.js +13 -0
- package/dist/src/async/operators/sumAsync.js +14 -0
- package/dist/src/async/operators/takeAsync.js +12 -0
- package/dist/src/async/operators/toArrayAsync.js +10 -0
- package/dist/src/async/operators/whereAsync.js +11 -0
- package/dist/src/json/fromJson.js +48 -0
- package/dist/src/operators/all.js +11 -0
- package/dist/src/operators/any.js +16 -0
- package/dist/src/operators/count.js +12 -0
- package/dist/src/operators/distinct.js +13 -0
- package/dist/src/operators/first.js +20 -0
- package/dist/src/operators/max.js +16 -0
- package/dist/src/operators/min.js +16 -0
- package/dist/src/operators/orderBy.js +14 -0
- package/dist/src/operators/select.js +9 -0
- package/dist/src/operators/skip.js +13 -0
- package/dist/src/operators/sum.js +14 -0
- package/dist/src/operators/take.js +12 -0
- package/dist/src/operators/toArray.js +6 -0
- package/dist/src/operators/where.js +11 -0
- package/dist/src/utils/comparers.js +20 -0
- package/dist/src/utils/guards.js +34 -0
- package/package.json +47 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 [Your Name]
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# inqjs (Integrated Query for JavaScript)
|
|
2
|
+
|
|
3
|
+
A lightweight, dependency-free LINQ engine for TypeScript and JavaScript with comprehensive query capabilities.
|
|
4
|
+
|
|
5
|
+
> **Note**: This project was developed with heavy assistance from AI (Google Gemini), demonstrating modern AI-powered software development workflows.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
✨ **Comprehensive LINQ Operations**
|
|
10
|
+
- Filtering: `where`, `distinct`
|
|
11
|
+
- Projection: `select`
|
|
12
|
+
- Ordering: `orderBy`
|
|
13
|
+
- Partitioning: `skip`, `take`
|
|
14
|
+
- Aggregation: `sum`, `min`, `max`, `count`
|
|
15
|
+
- Quantifiers: `any`, `all`
|
|
16
|
+
- Element: `first`
|
|
17
|
+
- Set Operations: `union`, `intersect`, `except`
|
|
18
|
+
- Sequence: `append`, `prepend`, `concat`
|
|
19
|
+
|
|
20
|
+
🚀 **Lazy Evaluation**
|
|
21
|
+
- Operators are lazily evaluated using generators
|
|
22
|
+
- Only materializes when calling terminal operators like `toArray()`
|
|
23
|
+
|
|
24
|
+
⚡ **Async Support**
|
|
25
|
+
- Full async/await support with `AsyncQuery`
|
|
26
|
+
- Works with `AsyncIterable<T>`
|
|
27
|
+
|
|
28
|
+
📦 **JSON Querying**
|
|
29
|
+
- Query JSON data directly with `fromJson`, `fromJsonArray`, `fromJsonObject`
|
|
30
|
+
|
|
31
|
+
🔒 **Type Safe**
|
|
32
|
+
- Written in TypeScript with `strict: true`
|
|
33
|
+
- Full type inference and safety
|
|
34
|
+
|
|
35
|
+
🎯 **Zero Dependencies**
|
|
36
|
+
- No external runtime dependencies
|
|
37
|
+
- Works with any `Iterable<T>` (Arrays, Sets, Maps, Generators)
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm install inqjs
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Quick Start
|
|
46
|
+
|
|
47
|
+
### Basic Query (Sync)
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { from } from 'inqjs';
|
|
51
|
+
|
|
52
|
+
const numbers = [1, 2, 3, 4, 5, 6];
|
|
53
|
+
|
|
54
|
+
const result = from(numbers)
|
|
55
|
+
.where(x => x % 2 === 0)
|
|
56
|
+
.select(x => x * x)
|
|
57
|
+
.orderBy()
|
|
58
|
+
.toArray();
|
|
59
|
+
|
|
60
|
+
console.log(result); // [4, 16, 36]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Async Query
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import { fromAsync } from 'inqjs';
|
|
67
|
+
|
|
68
|
+
async function* asyncNumbers() {
|
|
69
|
+
yield 1; yield 2; yield 3;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const result = await fromAsync(asyncNumbers())
|
|
73
|
+
.where(async x => x > 1)
|
|
74
|
+
.select(async x => x * 2)
|
|
75
|
+
.toArray();
|
|
76
|
+
|
|
77
|
+
console.log(result); // [4, 6]
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### JSON Querying
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { fromJsonArray } from 'inqjs';
|
|
84
|
+
|
|
85
|
+
const json = '[{"name": "Alice", "age": 25}, {"name": "Bob", "age": 30}]';
|
|
86
|
+
|
|
87
|
+
const adults = fromJsonArray(json)
|
|
88
|
+
.where(user => user.age >= 18)
|
|
89
|
+
.select(user => user.name)
|
|
90
|
+
.toArray();
|
|
91
|
+
|
|
92
|
+
console.log(adults); // ['Alice', 'Bob']
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Set Operations
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
import { from } from 'inqjs';
|
|
99
|
+
|
|
100
|
+
const list1 = [1, 2, 3, 4];
|
|
101
|
+
const list2 = [3, 4, 5, 6];
|
|
102
|
+
|
|
103
|
+
// Union
|
|
104
|
+
from(list1).union(list2).toArray();
|
|
105
|
+
// => [1, 2, 3, 4, 5, 6]
|
|
106
|
+
|
|
107
|
+
// Intersect
|
|
108
|
+
from(list1).intersect(list2).toArray();
|
|
109
|
+
// => [3, 4]
|
|
110
|
+
|
|
111
|
+
// Except
|
|
112
|
+
from(list1).except(list2).toArray();
|
|
113
|
+
// => [1, 2]
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## API Reference
|
|
117
|
+
|
|
118
|
+
### Query Creation
|
|
119
|
+
|
|
120
|
+
- `from(iterable)` - Create query from any iterable
|
|
121
|
+
- `fromAsync(asyncIterable)` - Create async query
|
|
122
|
+
- `fromJson(jsonString)` - Parse and query JSON
|
|
123
|
+
- `fromJsonArray(jsonString)` - Parse JSON array
|
|
124
|
+
- `fromJsonObject(jsonString)` - Parse JSON object
|
|
125
|
+
|
|
126
|
+
### Filtering & Projection
|
|
127
|
+
|
|
128
|
+
- `where(predicate)` - Filter elements
|
|
129
|
+
- `select(selector)` - Transform elements
|
|
130
|
+
- `distinct(keySelector?)` - Remove duplicates
|
|
131
|
+
|
|
132
|
+
### Ordering & Partitioning
|
|
133
|
+
|
|
134
|
+
- `orderBy(keySelector?, comparer?)` - Sort elements
|
|
135
|
+
- `skip(count)` - Skip first N elements
|
|
136
|
+
- `take(count)` - Take first N elements
|
|
137
|
+
|
|
138
|
+
### Aggregation
|
|
139
|
+
|
|
140
|
+
- `sum(selector?)` - Sum numeric values
|
|
141
|
+
- `min(selector?)` - Find minimum
|
|
142
|
+
- `max(selector?)` - Find maximum
|
|
143
|
+
- `count(predicate?)` - Count elements
|
|
144
|
+
|
|
145
|
+
### Quantifiers
|
|
146
|
+
|
|
147
|
+
- `any(predicate?)` - Check if any match
|
|
148
|
+
- `all(predicate)` - Check if all match
|
|
149
|
+
|
|
150
|
+
### Element Access
|
|
151
|
+
|
|
152
|
+
- `first(predicate?)` - Get first element
|
|
153
|
+
|
|
154
|
+
### Set Operations
|
|
155
|
+
|
|
156
|
+
- `union(other, keySelector?)` - Set union
|
|
157
|
+
- `intersect(other, keySelector?)` - Set intersection
|
|
158
|
+
- `except(other, keySelector?)` - Set difference
|
|
159
|
+
|
|
160
|
+
### Sequence Operations
|
|
161
|
+
|
|
162
|
+
- `append(element)` - Add element to end
|
|
163
|
+
- `prepend(element)` - Add element to start
|
|
164
|
+
- `concat(other)` - Concatenate sequences
|
|
165
|
+
|
|
166
|
+
### Terminal Operations
|
|
167
|
+
|
|
168
|
+
- `toArray()` - Materialize to array
|
|
169
|
+
- `toAsync()` - Convert to async query
|
|
170
|
+
|
|
171
|
+
## Testing
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
# Run TypeScript tests (Vitest)
|
|
175
|
+
npm test
|
|
176
|
+
|
|
177
|
+
# Run JavaScript tests
|
|
178
|
+
node tests/query.test.js
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Test Coverage**: 93 tests across TypeScript and JavaScript
|
|
182
|
+
- 70 TypeScript tests (Vitest)
|
|
183
|
+
- 23 Pure JavaScript tests
|
|
184
|
+
|
|
185
|
+
## Examples
|
|
186
|
+
|
|
187
|
+
See the `examples/` directory for more usage examples:
|
|
188
|
+
- `examples/usage.ts` - Basic LINQ operations
|
|
189
|
+
- `examples/json-usage.ts` - JSON querying examples
|
|
190
|
+
|
|
191
|
+
## Architecture
|
|
192
|
+
|
|
193
|
+
- **Lazy Evaluation**: Uses generator functions for deferred execution
|
|
194
|
+
- **Immutable**: Each operation returns a new `Query` instance
|
|
195
|
+
- **Type Safe**: Full TypeScript support with strict mode
|
|
196
|
+
- **Modular**: Operators are separate modules in `src/operators/`
|
|
197
|
+
|
|
198
|
+
## Limitations
|
|
199
|
+
|
|
200
|
+
- `orderBy` materializes the sequence (requires full iteration to sort)
|
|
201
|
+
- No `join` or `groupBy` operators (by design)
|
|
202
|
+
- Set operations (`union`, `intersect`, `except`) materialize the second sequence
|
|
203
|
+
|
|
204
|
+
## Development
|
|
205
|
+
|
|
206
|
+
This project was developed using AI-assisted coding with Google Gemini, showcasing:
|
|
207
|
+
- Rapid prototyping and iteration
|
|
208
|
+
- Comprehensive test coverage generation
|
|
209
|
+
- Documentation and example creation
|
|
210
|
+
- Code refactoring and optimization
|
|
211
|
+
|
|
212
|
+
The AI helped with:
|
|
213
|
+
- Initial architecture design
|
|
214
|
+
- Operator implementations (sync and async)
|
|
215
|
+
- Test suite creation and organization
|
|
216
|
+
- JSON querying capabilities
|
|
217
|
+
- Set operations implementation
|
|
218
|
+
- Documentation and examples
|
|
219
|
+
|
|
220
|
+
## License
|
|
221
|
+
|
|
222
|
+
MIT
|
|
223
|
+
|
|
224
|
+
## Contributing
|
|
225
|
+
|
|
226
|
+
Contributions are welcome! This project demonstrates how AI can accelerate development while maintaining code quality through comprehensive testing.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fromJsonObject = exports.fromJsonArray = exports.fromJson = exports.Query = void 0;
|
|
4
|
+
exports.from = from;
|
|
5
|
+
const guards_1 = require("./utils/guards");
|
|
6
|
+
const comparers_1 = require("./utils/comparers");
|
|
7
|
+
const where_1 = require("./operators/where");
|
|
8
|
+
const select_1 = require("./operators/select");
|
|
9
|
+
const orderBy_1 = require("./operators/orderBy");
|
|
10
|
+
const skip_1 = require("./operators/skip");
|
|
11
|
+
const distinct_1 = require("./operators/distinct");
|
|
12
|
+
const any_1 = require("./operators/any");
|
|
13
|
+
const all_1 = require("./operators/all");
|
|
14
|
+
const sum_1 = require("./operators/sum");
|
|
15
|
+
const min_1 = require("./operators/min");
|
|
16
|
+
const max_1 = require("./operators/max");
|
|
17
|
+
const first_1 = require("./operators/first");
|
|
18
|
+
const toArray_1 = require("./operators/toArray");
|
|
19
|
+
const take_1 = require("./operators/take");
|
|
20
|
+
const count_1 = require("./operators/count");
|
|
21
|
+
const AsyncQuery_1 = require("./async/AsyncQuery");
|
|
22
|
+
class Query {
|
|
23
|
+
constructor(source) {
|
|
24
|
+
(0, guards_1.assertIterable)(source, 'source');
|
|
25
|
+
this._source = source;
|
|
26
|
+
}
|
|
27
|
+
[Symbol.iterator]() {
|
|
28
|
+
return this._source[Symbol.iterator]();
|
|
29
|
+
}
|
|
30
|
+
static from(source) {
|
|
31
|
+
if (source instanceof Map) {
|
|
32
|
+
return new Query(source.entries());
|
|
33
|
+
}
|
|
34
|
+
return new Query(source);
|
|
35
|
+
}
|
|
36
|
+
where(predicate) {
|
|
37
|
+
(0, guards_1.assertFunction)(predicate, 'predicate');
|
|
38
|
+
return new Query((0, where_1.where)(this._source, predicate));
|
|
39
|
+
}
|
|
40
|
+
select(selector) {
|
|
41
|
+
(0, guards_1.assertFunction)(selector, 'selector');
|
|
42
|
+
return new Query((0, select_1.select)(this._source, selector));
|
|
43
|
+
}
|
|
44
|
+
orderBy(keySelector = comparers_1.identity, comparer = comparers_1.defaultComparer) {
|
|
45
|
+
if (keySelector !== undefined)
|
|
46
|
+
(0, guards_1.assertFunction)(keySelector, 'keySelector');
|
|
47
|
+
if (comparer !== undefined)
|
|
48
|
+
(0, guards_1.assertFunction)(comparer, 'comparer');
|
|
49
|
+
return new Query((0, orderBy_1.orderBy)(this._source, keySelector, comparer));
|
|
50
|
+
}
|
|
51
|
+
skip(count) {
|
|
52
|
+
(0, guards_1.assertInteger)(count, 'count');
|
|
53
|
+
(0, guards_1.assertNonNegative)(count, 'count');
|
|
54
|
+
return new Query((0, skip_1.skip)(this._source, count));
|
|
55
|
+
}
|
|
56
|
+
distinct(keySelector = comparers_1.identity) {
|
|
57
|
+
if (keySelector !== undefined)
|
|
58
|
+
(0, guards_1.assertFunction)(keySelector, 'keySelector');
|
|
59
|
+
return new Query((0, distinct_1.distinct)(this._source, keySelector));
|
|
60
|
+
}
|
|
61
|
+
any(predicate) {
|
|
62
|
+
if (predicate !== undefined)
|
|
63
|
+
(0, guards_1.assertFunction)(predicate, 'predicate');
|
|
64
|
+
return (0, any_1.any)(this._source, predicate);
|
|
65
|
+
}
|
|
66
|
+
all(predicate) {
|
|
67
|
+
(0, guards_1.assertFunction)(predicate, 'predicate');
|
|
68
|
+
return (0, all_1.all)(this._source, predicate);
|
|
69
|
+
}
|
|
70
|
+
sum(selector = comparers_1.identity) {
|
|
71
|
+
if (selector !== undefined)
|
|
72
|
+
(0, guards_1.assertFunction)(selector, 'selector');
|
|
73
|
+
return (0, sum_1.sum)(this._source, selector);
|
|
74
|
+
}
|
|
75
|
+
min(selector = comparers_1.identity) {
|
|
76
|
+
if (selector !== undefined)
|
|
77
|
+
(0, guards_1.assertFunction)(selector, 'selector');
|
|
78
|
+
return (0, min_1.min)(this._source, selector);
|
|
79
|
+
}
|
|
80
|
+
max(selector = comparers_1.identity) {
|
|
81
|
+
if (selector !== undefined)
|
|
82
|
+
(0, guards_1.assertFunction)(selector, 'selector');
|
|
83
|
+
return (0, max_1.max)(this._source, selector);
|
|
84
|
+
}
|
|
85
|
+
first(predicate) {
|
|
86
|
+
if (predicate !== undefined)
|
|
87
|
+
(0, guards_1.assertFunction)(predicate, 'predicate');
|
|
88
|
+
return (0, first_1.first)(this._source, predicate);
|
|
89
|
+
}
|
|
90
|
+
toArray() {
|
|
91
|
+
return (0, toArray_1.toArray)(this._source);
|
|
92
|
+
}
|
|
93
|
+
take(count) {
|
|
94
|
+
(0, guards_1.assertInteger)(count, 'count');
|
|
95
|
+
(0, guards_1.assertNonNegative)(count, 'count');
|
|
96
|
+
return new Query((0, take_1.take)(this._source, count));
|
|
97
|
+
}
|
|
98
|
+
count(predicate) {
|
|
99
|
+
if (predicate !== undefined)
|
|
100
|
+
(0, guards_1.assertFunction)(predicate, 'predicate');
|
|
101
|
+
return (0, count_1.count)(this._source, predicate);
|
|
102
|
+
}
|
|
103
|
+
toAsync() {
|
|
104
|
+
return AsyncQuery_1.AsyncQuery.from(this._source);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
exports.Query = Query;
|
|
108
|
+
function from(source) {
|
|
109
|
+
return Query.from(source);
|
|
110
|
+
}
|
|
111
|
+
// JSON helpers
|
|
112
|
+
var fromJson_1 = require("./json/fromJson");
|
|
113
|
+
Object.defineProperty(exports, "fromJson", { enumerable: true, get: function () { return fromJson_1.fromJson; } });
|
|
114
|
+
Object.defineProperty(exports, "fromJsonArray", { enumerable: true, get: function () { return fromJson_1.fromJsonArray; } });
|
|
115
|
+
Object.defineProperty(exports, "fromJsonObject", { enumerable: true, get: function () { return fromJson_1.fromJsonObject; } });
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AsyncQuery = void 0;
|
|
4
|
+
exports.fromAsync = fromAsync;
|
|
5
|
+
const guards_1 = require("../utils/guards");
|
|
6
|
+
const comparers_1 = require("../utils/comparers");
|
|
7
|
+
const whereAsync_1 = require("./operators/whereAsync");
|
|
8
|
+
const selectAsync_1 = require("./operators/selectAsync");
|
|
9
|
+
const orderByAsync_1 = require("./operators/orderByAsync");
|
|
10
|
+
const skipAsync_1 = require("./operators/skipAsync");
|
|
11
|
+
const distinctAsync_1 = require("./operators/distinctAsync");
|
|
12
|
+
const anyAsync_1 = require("./operators/anyAsync");
|
|
13
|
+
const allAsync_1 = require("./operators/allAsync");
|
|
14
|
+
const sumAsync_1 = require("./operators/sumAsync");
|
|
15
|
+
const minAsync_1 = require("./operators/minAsync");
|
|
16
|
+
const maxAsync_1 = require("./operators/maxAsync");
|
|
17
|
+
const firstAsync_1 = require("./operators/firstAsync");
|
|
18
|
+
const toArrayAsync_1 = require("./operators/toArrayAsync");
|
|
19
|
+
const takeAsync_1 = require("./operators/takeAsync");
|
|
20
|
+
const countAsync_1 = require("./operators/countAsync");
|
|
21
|
+
class AsyncQuery {
|
|
22
|
+
constructor(source) {
|
|
23
|
+
this._source = source;
|
|
24
|
+
}
|
|
25
|
+
[Symbol.asyncIterator]() {
|
|
26
|
+
return this._source[Symbol.asyncIterator]();
|
|
27
|
+
}
|
|
28
|
+
static from(source) {
|
|
29
|
+
async function* wrap(src) {
|
|
30
|
+
for await (const item of src) {
|
|
31
|
+
yield item;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return new AsyncQuery(wrap(source));
|
|
35
|
+
}
|
|
36
|
+
where(predicate) {
|
|
37
|
+
(0, guards_1.assertFunction)(predicate, 'predicate');
|
|
38
|
+
return new AsyncQuery((0, whereAsync_1.whereAsync)(this._source, predicate));
|
|
39
|
+
}
|
|
40
|
+
select(selector) {
|
|
41
|
+
(0, guards_1.assertFunction)(selector, 'selector');
|
|
42
|
+
return new AsyncQuery((0, selectAsync_1.selectAsync)(this._source, selector));
|
|
43
|
+
}
|
|
44
|
+
orderBy(keySelector = comparers_1.identity, comparer = comparers_1.defaultComparer) {
|
|
45
|
+
if (keySelector !== undefined)
|
|
46
|
+
(0, guards_1.assertFunction)(keySelector, 'keySelector');
|
|
47
|
+
if (comparer !== undefined)
|
|
48
|
+
(0, guards_1.assertFunction)(comparer, 'comparer');
|
|
49
|
+
return new AsyncQuery((0, orderByAsync_1.orderByAsync)(this._source, keySelector, comparer));
|
|
50
|
+
}
|
|
51
|
+
skip(count) {
|
|
52
|
+
(0, guards_1.assertInteger)(count, 'count');
|
|
53
|
+
(0, guards_1.assertNonNegative)(count, 'count');
|
|
54
|
+
return new AsyncQuery((0, skipAsync_1.skipAsync)(this._source, count));
|
|
55
|
+
}
|
|
56
|
+
distinct(keySelector = comparers_1.identity) {
|
|
57
|
+
if (keySelector !== undefined)
|
|
58
|
+
(0, guards_1.assertFunction)(keySelector, 'keySelector');
|
|
59
|
+
return new AsyncQuery((0, distinctAsync_1.distinctAsync)(this._source, keySelector));
|
|
60
|
+
}
|
|
61
|
+
any(predicate) {
|
|
62
|
+
if (predicate !== undefined)
|
|
63
|
+
(0, guards_1.assertFunction)(predicate, 'predicate');
|
|
64
|
+
return (0, anyAsync_1.anyAsync)(this._source, predicate);
|
|
65
|
+
}
|
|
66
|
+
all(predicate) {
|
|
67
|
+
(0, guards_1.assertFunction)(predicate, 'predicate');
|
|
68
|
+
return (0, allAsync_1.allAsync)(this._source, predicate);
|
|
69
|
+
}
|
|
70
|
+
sum(selector = comparers_1.identity) {
|
|
71
|
+
if (selector !== undefined)
|
|
72
|
+
(0, guards_1.assertFunction)(selector, 'selector');
|
|
73
|
+
return (0, sumAsync_1.sumAsync)(this._source, selector);
|
|
74
|
+
}
|
|
75
|
+
min(selector = comparers_1.identity) {
|
|
76
|
+
if (selector !== undefined)
|
|
77
|
+
(0, guards_1.assertFunction)(selector, 'selector');
|
|
78
|
+
return (0, minAsync_1.minAsync)(this._source, selector);
|
|
79
|
+
}
|
|
80
|
+
max(selector = comparers_1.identity) {
|
|
81
|
+
if (selector !== undefined)
|
|
82
|
+
(0, guards_1.assertFunction)(selector, 'selector');
|
|
83
|
+
return (0, maxAsync_1.maxAsync)(this._source, selector);
|
|
84
|
+
}
|
|
85
|
+
first(predicate) {
|
|
86
|
+
if (predicate !== undefined)
|
|
87
|
+
(0, guards_1.assertFunction)(predicate, 'predicate');
|
|
88
|
+
return (0, firstAsync_1.firstAsync)(this._source, predicate);
|
|
89
|
+
}
|
|
90
|
+
toArray() {
|
|
91
|
+
return (0, toArrayAsync_1.toArrayAsync)(this._source);
|
|
92
|
+
}
|
|
93
|
+
take(count) {
|
|
94
|
+
(0, guards_1.assertInteger)(count, 'count');
|
|
95
|
+
(0, guards_1.assertNonNegative)(count, 'count');
|
|
96
|
+
return new AsyncQuery((0, takeAsync_1.takeAsync)(this._source, count));
|
|
97
|
+
}
|
|
98
|
+
count(predicate) {
|
|
99
|
+
if (predicate !== undefined)
|
|
100
|
+
(0, guards_1.assertFunction)(predicate, 'predicate');
|
|
101
|
+
return (0, countAsync_1.countAsync)(this._source, predicate);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
exports.AsyncQuery = AsyncQuery;
|
|
105
|
+
function fromAsync(source) {
|
|
106
|
+
return AsyncQuery.from(source);
|
|
107
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.allAsync = allAsync;
|
|
4
|
+
async function allAsync(source, predicate) {
|
|
5
|
+
for await (const item of source) {
|
|
6
|
+
if (!(await predicate(item))) {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.anyAsync = anyAsync;
|
|
4
|
+
async function anyAsync(source, predicate) {
|
|
5
|
+
if (predicate) {
|
|
6
|
+
for await (const item of source) {
|
|
7
|
+
if (await predicate(item)) {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
// If no predicate, check if source has any elements
|
|
14
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
15
|
+
const result = await iterator.next();
|
|
16
|
+
return !result.done;
|
|
17
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.countAsync = countAsync;
|
|
4
|
+
async function countAsync(source, predicate) {
|
|
5
|
+
let count = 0;
|
|
6
|
+
for await (const item of source) {
|
|
7
|
+
if (!predicate || await predicate(item)) {
|
|
8
|
+
count++;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return count;
|
|
12
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.distinctAsync = distinctAsync;
|
|
4
|
+
async function* distinctAsync(source, keySelector) {
|
|
5
|
+
const seen = new Set();
|
|
6
|
+
for await (const item of source) {
|
|
7
|
+
const key = await keySelector(item);
|
|
8
|
+
if (!seen.has(key)) {
|
|
9
|
+
seen.add(key);
|
|
10
|
+
yield item;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.firstAsync = firstAsync;
|
|
4
|
+
async function firstAsync(source, predicate) {
|
|
5
|
+
if (predicate) {
|
|
6
|
+
for await (const item of source) {
|
|
7
|
+
if (await predicate(item)) {
|
|
8
|
+
return item;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
14
|
+
const result = await iterator.next();
|
|
15
|
+
if (!result.done) {
|
|
16
|
+
return result.value;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
throw new Error('Sequence contains no matching element.');
|
|
20
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.maxAsync = maxAsync;
|
|
4
|
+
async function maxAsync(source, selector) {
|
|
5
|
+
let maxValue;
|
|
6
|
+
for await (const item of source) {
|
|
7
|
+
const value = await selector(item);
|
|
8
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
9
|
+
throw new TypeError('maxAsync: value must be a finite number.');
|
|
10
|
+
}
|
|
11
|
+
if (maxValue === undefined || value > maxValue) {
|
|
12
|
+
maxValue = value;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return maxValue;
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.minAsync = minAsync;
|
|
4
|
+
async function minAsync(source, selector) {
|
|
5
|
+
let minValue;
|
|
6
|
+
for await (const item of source) {
|
|
7
|
+
const value = await selector(item);
|
|
8
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
9
|
+
throw new TypeError('minAsync: value must be a finite number.');
|
|
10
|
+
}
|
|
11
|
+
if (minValue === undefined || value < minValue) {
|
|
12
|
+
minValue = value;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return minValue;
|
|
16
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.orderByAsync = orderByAsync;
|
|
4
|
+
async function* orderByAsync(source, keySelector, comparer) {
|
|
5
|
+
const buffer = [];
|
|
6
|
+
for await (const item of source) {
|
|
7
|
+
buffer.push(item);
|
|
8
|
+
}
|
|
9
|
+
// We need to resolve keys for all items to sort them
|
|
10
|
+
const itemsWithKeys = await Promise.all(buffer.map(async (item) => ({
|
|
11
|
+
item,
|
|
12
|
+
key: await keySelector(item),
|
|
13
|
+
})));
|
|
14
|
+
itemsWithKeys.sort((a, b) => comparer(a.key, b.key));
|
|
15
|
+
for (const { item } of itemsWithKeys) {
|
|
16
|
+
yield item;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.selectAsync = selectAsync;
|
|
4
|
+
async function* selectAsync(source, selector) {
|
|
5
|
+
let index = 0;
|
|
6
|
+
for await (const item of source) {
|
|
7
|
+
yield await selector(item, index++);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.skipAsync = skipAsync;
|
|
4
|
+
async function* skipAsync(source, count) {
|
|
5
|
+
let skipped = 0;
|
|
6
|
+
for await (const item of source) {
|
|
7
|
+
if (skipped < count) {
|
|
8
|
+
skipped++;
|
|
9
|
+
continue;
|
|
10
|
+
}
|
|
11
|
+
yield item;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sumAsync = sumAsync;
|
|
4
|
+
async function sumAsync(source, selector) {
|
|
5
|
+
let total = 0;
|
|
6
|
+
for await (const item of source) {
|
|
7
|
+
const value = await selector(item);
|
|
8
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
9
|
+
throw new TypeError('sumAsync: value must be a finite number.');
|
|
10
|
+
}
|
|
11
|
+
total += value;
|
|
12
|
+
}
|
|
13
|
+
return total;
|
|
14
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.takeAsync = takeAsync;
|
|
4
|
+
async function* takeAsync(source, count) {
|
|
5
|
+
let taken = 0;
|
|
6
|
+
for await (const item of source) {
|
|
7
|
+
if (taken >= count)
|
|
8
|
+
break;
|
|
9
|
+
yield item;
|
|
10
|
+
taken++;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toArrayAsync = toArrayAsync;
|
|
4
|
+
async function toArrayAsync(source) {
|
|
5
|
+
const result = [];
|
|
6
|
+
for await (const item of source) {
|
|
7
|
+
result.push(item);
|
|
8
|
+
}
|
|
9
|
+
return result;
|
|
10
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.whereAsync = whereAsync;
|
|
4
|
+
async function* whereAsync(source, predicate) {
|
|
5
|
+
let index = 0;
|
|
6
|
+
for await (const item of source) {
|
|
7
|
+
if (await predicate(item, index++)) {
|
|
8
|
+
yield item;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fromJson = fromJson;
|
|
4
|
+
exports.fromJsonArray = fromJsonArray;
|
|
5
|
+
exports.fromJsonObject = fromJsonObject;
|
|
6
|
+
const Query_1 = require("../Query");
|
|
7
|
+
/**
|
|
8
|
+
* Parse a JSON string and return a Query over the result.
|
|
9
|
+
* - If the JSON is an array, returns a Query over the array elements.
|
|
10
|
+
* - If the JSON is an object, returns a Query over the object's entries as [key, value] tuples.
|
|
11
|
+
* - For primitive values, wraps them in a single-element array.
|
|
12
|
+
*/
|
|
13
|
+
function fromJson(jsonString) {
|
|
14
|
+
const parsed = JSON.parse(jsonString);
|
|
15
|
+
if (Array.isArray(parsed)) {
|
|
16
|
+
return Query_1.Query.from(parsed);
|
|
17
|
+
}
|
|
18
|
+
else if (parsed !== null && typeof parsed === 'object') {
|
|
19
|
+
return Query_1.Query.from(Object.entries(parsed));
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
// Primitive value - wrap in array
|
|
23
|
+
return Query_1.Query.from([parsed]);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Parse a JSON string as an array and return a Query over its elements.
|
|
28
|
+
* Throws if the JSON is not an array.
|
|
29
|
+
*/
|
|
30
|
+
function fromJsonArray(jsonString) {
|
|
31
|
+
const parsed = JSON.parse(jsonString);
|
|
32
|
+
if (!Array.isArray(parsed)) {
|
|
33
|
+
throw new TypeError('JSON value is not an array');
|
|
34
|
+
}
|
|
35
|
+
return Query_1.Query.from(parsed);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Parse a JSON string as an object and return a Query over its entries.
|
|
39
|
+
* Each entry is a [key, value] tuple.
|
|
40
|
+
* Throws if the JSON is not an object.
|
|
41
|
+
*/
|
|
42
|
+
function fromJsonObject(jsonString) {
|
|
43
|
+
const parsed = JSON.parse(jsonString);
|
|
44
|
+
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
45
|
+
throw new TypeError('JSON value is not an object');
|
|
46
|
+
}
|
|
47
|
+
return Query_1.Query.from(Object.entries(parsed));
|
|
48
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.any = any;
|
|
4
|
+
function any(source, predicate) {
|
|
5
|
+
if (predicate) {
|
|
6
|
+
for (const item of source) {
|
|
7
|
+
if (predicate(item)) {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
// If no predicate, check if source has any elements
|
|
14
|
+
const iterator = source[Symbol.iterator]();
|
|
15
|
+
return !iterator.next().done;
|
|
16
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.count = count;
|
|
4
|
+
function count(source, predicate) {
|
|
5
|
+
let count = 0;
|
|
6
|
+
for (const item of source) {
|
|
7
|
+
if (!predicate || predicate(item)) {
|
|
8
|
+
count++;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return count;
|
|
12
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.distinct = distinct;
|
|
4
|
+
function* distinct(source, keySelector) {
|
|
5
|
+
const seen = new Set();
|
|
6
|
+
for (const item of source) {
|
|
7
|
+
const key = keySelector(item);
|
|
8
|
+
if (!seen.has(key)) {
|
|
9
|
+
seen.add(key);
|
|
10
|
+
yield item;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.first = first;
|
|
4
|
+
function first(source, predicate) {
|
|
5
|
+
if (predicate) {
|
|
6
|
+
for (const item of source) {
|
|
7
|
+
if (predicate(item)) {
|
|
8
|
+
return item;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
const iterator = source[Symbol.iterator]();
|
|
14
|
+
const result = iterator.next();
|
|
15
|
+
if (!result.done) {
|
|
16
|
+
return result.value;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
throw new Error('Sequence contains no matching element.');
|
|
20
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.max = max;
|
|
4
|
+
function max(source, selector) {
|
|
5
|
+
let maxValue;
|
|
6
|
+
for (const item of source) {
|
|
7
|
+
const value = selector(item);
|
|
8
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
9
|
+
throw new TypeError('max: value must be a finite number.');
|
|
10
|
+
}
|
|
11
|
+
if (maxValue === undefined || value > maxValue) {
|
|
12
|
+
maxValue = value;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return maxValue;
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.min = min;
|
|
4
|
+
function min(source, selector) {
|
|
5
|
+
let minValue;
|
|
6
|
+
for (const item of source) {
|
|
7
|
+
const value = selector(item);
|
|
8
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
9
|
+
throw new TypeError('min: value must be a finite number.');
|
|
10
|
+
}
|
|
11
|
+
if (minValue === undefined || value < minValue) {
|
|
12
|
+
minValue = value;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return minValue;
|
|
16
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.orderBy = orderBy;
|
|
4
|
+
function* orderBy(source, keySelector, comparer) {
|
|
5
|
+
const buffer = Array.from(source);
|
|
6
|
+
buffer.sort((a, b) => {
|
|
7
|
+
const keyA = keySelector(a);
|
|
8
|
+
const keyB = keySelector(b);
|
|
9
|
+
return comparer(keyA, keyB);
|
|
10
|
+
});
|
|
11
|
+
for (const item of buffer) {
|
|
12
|
+
yield item;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.skip = skip;
|
|
4
|
+
function* skip(source, count) {
|
|
5
|
+
let skipped = 0;
|
|
6
|
+
for (const item of source) {
|
|
7
|
+
if (skipped < count) {
|
|
8
|
+
skipped++;
|
|
9
|
+
continue;
|
|
10
|
+
}
|
|
11
|
+
yield item;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sum = sum;
|
|
4
|
+
function sum(source, selector) {
|
|
5
|
+
let total = 0;
|
|
6
|
+
for (const item of source) {
|
|
7
|
+
const value = selector(item);
|
|
8
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
9
|
+
throw new TypeError('sum: value must be a finite number.');
|
|
10
|
+
}
|
|
11
|
+
total += value;
|
|
12
|
+
}
|
|
13
|
+
return total;
|
|
14
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defaultComparer = defaultComparer;
|
|
4
|
+
exports.identity = identity;
|
|
5
|
+
function defaultComparer(a, b) {
|
|
6
|
+
if (a === b)
|
|
7
|
+
return 0;
|
|
8
|
+
if (a === null || a === undefined)
|
|
9
|
+
return -1;
|
|
10
|
+
if (b === null || b === undefined)
|
|
11
|
+
return 1;
|
|
12
|
+
if (a < b)
|
|
13
|
+
return -1;
|
|
14
|
+
if (a > b)
|
|
15
|
+
return 1;
|
|
16
|
+
return 0;
|
|
17
|
+
}
|
|
18
|
+
function identity(item) {
|
|
19
|
+
return item;
|
|
20
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isIterable = isIterable;
|
|
4
|
+
exports.isFunction = isFunction;
|
|
5
|
+
exports.assertIterable = assertIterable;
|
|
6
|
+
exports.assertFunction = assertFunction;
|
|
7
|
+
exports.assertInteger = assertInteger;
|
|
8
|
+
exports.assertNonNegative = assertNonNegative;
|
|
9
|
+
function isIterable(obj) {
|
|
10
|
+
return obj != null && typeof obj[Symbol.iterator] === 'function';
|
|
11
|
+
}
|
|
12
|
+
function isFunction(obj) {
|
|
13
|
+
return typeof obj === 'function';
|
|
14
|
+
}
|
|
15
|
+
function assertIterable(source, name = 'source') {
|
|
16
|
+
if (!isIterable(source)) {
|
|
17
|
+
throw new TypeError(`${name} must be an iterable.`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function assertFunction(fn, name) {
|
|
21
|
+
if (!isFunction(fn)) {
|
|
22
|
+
throw new TypeError(`${name} must be a function.`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function assertInteger(num, name) {
|
|
26
|
+
if (typeof num !== 'number' || !Number.isFinite(num) || !Number.isInteger(num)) {
|
|
27
|
+
throw new TypeError(`${name} must be a finite integer.`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function assertNonNegative(num, name) {
|
|
31
|
+
if (num < 0) {
|
|
32
|
+
throw new TypeError(`${name} must be non-negative.`);
|
|
33
|
+
}
|
|
34
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "inqjs",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A lightweight, dependency-free LINQ engine for TypeScript and JavaScript with comprehensive query capabilities",
|
|
5
|
+
"main": "dist/src/Query.js",
|
|
6
|
+
"types": "dist/src/Query.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist/src/**/*",
|
|
9
|
+
"README.md",
|
|
10
|
+
"LICENSE"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"test": "vitest run",
|
|
15
|
+
"prepublishOnly": "npm run build && npm test"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"linq",
|
|
19
|
+
"query",
|
|
20
|
+
"typescript",
|
|
21
|
+
"javascript",
|
|
22
|
+
"functional",
|
|
23
|
+
"lazy-evaluation",
|
|
24
|
+
"async",
|
|
25
|
+
"json",
|
|
26
|
+
"set-operations"
|
|
27
|
+
],
|
|
28
|
+
"author": "Parth Parikh",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "https://github.com/ptp28/inqjs.git"
|
|
33
|
+
},
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/ptp28/inqjs/issues"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://github.com/ptp28/inqjs#readme",
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/node": "^24.10.1",
|
|
40
|
+
"tsx": "^4.20.6",
|
|
41
|
+
"typescript": "^5.9.3",
|
|
42
|
+
"vitest": "^4.0.14"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=14.0.0"
|
|
46
|
+
}
|
|
47
|
+
}
|