Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
jinhduong committed Apr 28, 2018
2 parents 70e2cb2 + 6080cb5 commit c6ebe9c
Show file tree
Hide file tree
Showing 54 changed files with 10,025 additions and 2,075 deletions.
125 changes: 34 additions & 91 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
# 👴 eslinq
.NET LINQ for Javascript, written by TypeScript.
- Provide `IQueryable<T>`, it's reusable, also variable and use `iterator list` for holding query and execute.
- Contains almost the original .NET and some extends methods.
- Support `Promise` like a input source.
- All `APIs` like a Javascript native methods so easily, simply implementation.
# linq-fns
.NET LINQ functions for Javascript, written by TypeScript.
- ⚡ Provide `Queryable<T>`, it's reusable, also variable and use `Predicate collection` for holding query and execute later.
- 🔨 Contains almost the original .NET and some extends methods.
- 🔨 Support `Promise` like as a input source.
- 🙅 All `APIs` like a Javascript native methods so easily, simply implementation.
- 📊 Have some drivers for `firebase realtime db` or any storage libraries...

### Basic example
#### Node or browser
```ts
// ES6
import { Queryable } from 'linq-fns';

// ES5
const Queryable = require('linq-fns').Queryable;

let query = Queryable
.from(nations)
.join(continents, (x, y) => x.areaId === y.id)
Expand All @@ -27,89 +35,25 @@ asyncData.then(data => {
});
```

### Sample data ⚽
This document will use below data to make examples :
```ts
let players = new Promise((resolve, reject) => {
// skills: attack, stamia, speed, shoot
console.log('get players...');
setTimeout(() => {
resolve([
{ name: 'Ronaldo', overall: 96, nationId: 1, skills: [96, 85, 87, 91] },
{ name: 'Messi', overall: 98, nationId: 2, skills: [97, 85, 91, 93] },
{ name: 'Mbappe', overall: 86, nationId: 3, skills: [89, 81, 95, 83] },
{ name: 'Matial', overall: 81, nationId: 3, skills: [81, 80, 89, 81] },
{ name: 'Salah', overall: 89, nationId: 4, skills: [88, 82, 97, 86] }
]);
}, 1000);
})
#### Firebase
``` ts
const FireBaseQueryale = require('linq-fns').FireBaseQueryale;
const admin = require('firebase-admin');
const serviceAccount = require('./serviceAccountKey');

let nations: Promise<{ id, name, areaId }[]> = new Promise(resolve => {
console.log('get nations...');
setTimeout(() => {
resolve([
{ id: 1, name: 'Portugal', areaId: 1 },
{ id: 2, name: 'Argentina', areaId: 2 },
{ id: 3, name: 'France', areaId: 1 },
{ id: 4, name: 'Egypt', areaId: 3 }
]);
}, 2000);
})
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'https://xxx.firebaseio.com'
});

let continents = new Promise<{ id, areaName }[]>(resolve => {
console.log('get continents...');
setTimeout(() => {
resolve([
{ id: 1, areaName: 'Euro' },
{ id: 2, areaName: 'South America' },
]);
}, 2300);
})
```
const db = admin.database();
const firebaseQuery = new FireBaseQueryale(db);

### Queryable
- `.from` => `Promise<any>`:
All data source will be converted to `Promise` notwithstanding that source is Promise or noramlly array data. Then once we call `toList()`, `count()`, `first()`... or any `execute methods` it will be return a `Promise`.
const postsQuery = firebaseQuery.getRepository('<rootTable>.<childTables>.<child...>');
// Then using like Queryable Apis

```ts
let query = Queryable
.from(nations)
.join(continents, (x, y) => x.areaId === y.id)
.groupBy(o => o.y.areaName)

const asyncData = query.count() // Will return Promise<number>
asyncData.then(num => {
console.log(num);
// 2
})
```

- `.fromSync` => `any`:
It's often use inside sub-query which are after all data already retrieved successfully or you make sure the input source is sync data like as `Array`.
``` ts
let query = Queryable
.from(nations)
.join(continents, (x, y) => x.areaId === y.id)
.groupBy(o => o.y.areaName)
.select(x => {
return {
area: x.key,
total: Queryable.fromSync(x.items).count() // Here will return number, not Promise<number>
}
})
const asyncData = query.toList() // Will return Promise<{area:string, total:number}>
asyncData.then(data => {
console.log(data);
// [
// {area: 'Euro': total: 2},
// {area:'South Ameria', total: 1}
// ]
});
```

> **> More**: at `from` method, all input sources at `from, join, leftJoin` methods,... will be converted to **Promise** and use **Promise.all** to **execute** and then use **Iterator collection** to query data and once faced **excuting methods** like as `toList(), first()` it will return data which be inside a Promise.

### Process
- [x] from
- [x] where
Expand All @@ -126,30 +70,29 @@ asyncData.then(data => {
- [x] skipWhile
- [x] groupBy
- [x] distinct
- [ ] concat
- [ ] zip
- [ ] union
- [ ] intersect
- [ ] except
- [x] concat
- [x] zip
- [x] union
- [x] intersect
- [x] except
- [x] first : `Promise<T>`
- [x] firstOrDefault : `Promise<T | null>`
- [x] last : `Promise<T>`
- [x] lastOrDefault : `Promise<T | null>`
- [x] single
- [x] singleOrDefault
- [x] contains
- [ ] sequenceEqual
- [x] sequenceEqual
- [x] any : `Promise<boolean>`
- [x] all : `Promise<boolean>`
- [x] count : `Promise<number>`
- [x] min : `Promise<number>`
- [x] max : `Promise<number>`
- [x] sum : `Promise<number>`
- [x] average
- [ ] aggregate
- [x] aggregate
- [x] toList : `Promise<T[]>`


### License

[MIT License](http:https://opensource.org/licenses/MIT)
21 changes: 21 additions & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const del = require('del');
const gulp = require('gulp');

gulp.task('clean', function () {
return del(['dist/**/*']);
});

gulp.task('clean-npm', function () {
return del(['npm-release/**/*']);
});

gulp.task('rl', () => {
gulp.src('./dist/browser-lib/*.js')
.pipe(gulp.dest('./release'));
});

gulp.task('npmrl', () => {
gulp.src(['dist/**/*', '!dist/browser/**/*', '!dist/browser-lib/**/*', '!dist/demo/**/*', 'package.json',
'README.md', 'LICENSE'])
.pipe(gulp.dest('./npm-release'));
})
Loading

0 comments on commit c6ebe9c

Please sign in to comment.