Skip to content

Commit c342224

Browse files
committed
fix(datasource): sync with latest Angular and rxjs
1 parent cd5c9b7 commit c342224

14 files changed

+116
-89
lines changed

libs/datasource/README.md

+4-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ This library provides an abstract `ReactiveDataSource` and `MatDataSource` class
88

99
You can pass it to a Material Table:
1010

11-
```
11+
```html
1212
<mat-datasource [dataSource]="source">
1313
<mat-table [dataSource]="source">
1414
...
@@ -20,12 +20,11 @@ You can pass it to a Material Table:
2020
></mat-paginator>
2121
</footer>
2222
</mat-datasource>
23-
2423
```
2524

2625
Or consume it via the `dataSource` pipe:
2726

28-
```
27+
```html
2928
<ng-container *ngIf="source | dataSource as items">
3029
<mat-nav-list>
3130
<mat-list-item *ngFor="let item of items">
@@ -38,7 +37,7 @@ Or consume it via the `dataSource` pipe:
3837
## Demo
3938

4039
An example of how it can work with a Firebase backend it's here:
41-
https://stackblitz.com/edit/matdatasource
40+
<https://stackblitz.com/edit/matdatasource>
4241

4342
And the concepts behind are explained here:
44-
https://medium.com/@matheo/reactive-datasource-for-angular-1d869b0155f6
43+
<https://medium.com/@matheo/reactive-datasource-for-angular-1d869b0155f6>
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
1-
module.exports = {
1+
/* eslint-disable */
2+
export default {
23
displayName: 'datasource',
34
preset: '../../jest.preset.js',
45
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
5-
globals: {},
66
coverageDirectory: '../../coverage/libs/datasource',
7-
snapshotSerializers: [
8-
'jest-preset-angular/build/serializers/no-ng-attributes',
9-
'jest-preset-angular/build/serializers/ng-snapshot',
10-
'jest-preset-angular/build/serializers/html-comment',
11-
],
127
transform: {
13-
'^.+.(ts|mjs|js|html)$': [
8+
'^.+\\.(ts|mjs|js|html)$': [
149
'jest-preset-angular',
1510
{
16-
stringifyContentPathRegex: '\\.(html|svg)$',
17-
1811
tsconfig: '<rootDir>/tsconfig.spec.json',
12+
stringifyContentPathRegex: '\\.(html|svg)$',
1913
},
2014
],
2115
},
22-
transformIgnorePatterns: ['node_modules/(?!.*.mjs$)'],
16+
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
17+
snapshotSerializers: [
18+
'jest-preset-angular/build/serializers/no-ng-attributes',
19+
'jest-preset-angular/build/serializers/ng-snapshot',
20+
'jest-preset-angular/build/serializers/html-comment',
21+
],
2322
};

libs/datasource/project.json

+7-7
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,24 @@
77
"targets": {
88
"build": {
99
"executor": "@nx/angular:package",
10+
"outputs": ["{workspaceRoot}/dist/{projectRoot}"],
1011
"options": {
1112
"tsConfig": "libs/datasource/tsconfig.lib.json",
12-
"project": "libs/datasource/ng-package.json",
13-
"buildableProjectDepsInPackageJsonType": "dependencies",
14-
"updateBuildableProjectDepsInPackageJson": true
13+
"project": "libs/datasource/ng-package.json"
1514
},
1615
"configurations": {
1716
"production": {
1817
"tsConfig": "libs/datasource/tsconfig.lib.prod.json"
1918
}
20-
}
19+
},
20+
"defaultConfiguration": "production"
2121
},
2222
"test": {
2323
"executor": "@nx/jest:jest",
24+
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
2425
"options": {
25-
"jestConfig": "libs/datasource/jest.config.js"
26-
},
27-
"outputs": ["{workspaceRoot}/coverage/libs/datasource"]
26+
"jestConfig": "libs/datasource/jest.config.ts"
27+
}
2828
}
2929
},
3030
"tags": ["shared"]

libs/datasource/src/lib/container.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {
33
ChangeDetectionStrategy,
44
Component,
55
Input,
6-
ViewEncapsulation
6+
ViewEncapsulation,
77
} from '@angular/core';
88
import { MatDataSource } from './datasource';
99
import { missingDataSourceInput } from './messages';
@@ -13,13 +13,13 @@ import { missingDataSourceInput } from './messages';
1313
templateUrl: './container.html',
1414
styleUrls: ['./container.scss', './directives.scss', './overlay.scss'],
1515
host: {
16-
class: 'mat-datasource'
16+
class: 'mat-datasource',
1717
},
1818
encapsulation: ViewEncapsulation.None,
19-
changeDetection: ChangeDetectionStrategy.OnPush
19+
changeDetection: ChangeDetectionStrategy.OnPush,
2020
})
2121
export class DataSourceContainer<REQ, RAW, RES> implements AfterContentInit {
22-
@Input() dataSource: MatDataSource<REQ, RAW, RES>;
22+
@Input({ required: true }) dataSource!: MatDataSource<REQ, RAW, RES>;
2323

2424
@Input() diameter = 40;
2525
@Input() strokeWidth = 5;

libs/datasource/src/lib/datasource-logger.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export class DataSourceLogger {
1313
set config(config: DataSourceConfig) {
1414
this._config = config;
1515
}
16-
private _config: DataSourceConfig;
16+
private _config!: DataSourceConfig;
1717

1818
constructor(private sourceName: string, private _intl?: MatDataSourceIntl) {}
1919

@@ -45,12 +45,12 @@ export class DataSourceLogger {
4545
);
4646
}
4747

48-
getTimeoutError(attempt: number) {
48+
getTimeoutError(attempt: number): string {
4949
switch (attempt) {
5050
case 0:
51-
return this._intl?.waitMsg || this._config.waitMsg;
51+
return this._intl?.waitMsg || this._config.waitMsg || '';
5252
case 1:
53-
return this._intl?.delayMsg || this._config.delayMsg;
53+
return this._intl?.delayMsg || this._config.delayMsg || '';
5454
default:
5555
throw new Error(this._intl?.timeoutMsg || this._config.timeoutMsg);
5656
}

libs/datasource/src/lib/datasource-pipe.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ import {
44
Pipe,
55
PipeTransform,
66
Type,
7-
ɵisObservable,
87
ɵstringify as stringify,
98
} from '@angular/core';
10-
import { Observable, SubscriptionLike } from 'rxjs';
9+
import { Observable, SubscriptionLike, isObservable } from 'rxjs';
1110
import { ReactiveDataSource } from './datasource-reactive';
1211

1312
export function invalidPipeArgumentError(type: Type<any>, value: Object) {
@@ -100,7 +99,7 @@ export class DataSourcePipe implements OnDestroy, PipeTransform {
10099
}
101100

102101
private _selectStrategy(obj: ReactiveDataSource<any, any, any>): any {
103-
if (ɵisObservable(obj.change$)) {
102+
if (isObservable(obj.change$)) {
104103
return _observableStrategy;
105104
}
106105

@@ -109,7 +108,7 @@ export class DataSourcePipe implements OnDestroy, PipeTransform {
109108

110109
private _dispose(): void {
111110
this._strategy.dispose(this._subscription!);
112-
this._obj.disconnect();
111+
this._obj?.disconnect();
113112
this._latestValue = null;
114113
this._subscription = null;
115114
this._obj = null;

libs/datasource/src/lib/datasource.ts

+23-24
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export abstract class MatDataSource<REQ = any, RAW = any, RES = any>
104104
get outputMsg() {
105105
return this._outputMsg;
106106
}
107-
protected _outputMsg: string;
107+
protected _outputMsg: string = '';
108108

109109
/**
110110
* Accessors
@@ -155,7 +155,7 @@ export abstract class MatDataSource<REQ = any, RAW = any, RES = any>
155155
*/
156156
protected defaults: Partial<REQ> = {};
157157
protected overrides: Partial<REQ> = {};
158-
protected arguments: REQ & DataSourceOpts;
158+
protected arguments?: REQ & DataSourceOpts;
159159

160160
/**
161161
* Error control vars.
@@ -227,9 +227,9 @@ export abstract class MatDataSource<REQ = any, RAW = any, RES = any>
227227
): string {
228228
const src: DataSourceStream<REQ | DataSourceOpts> = isObservable(stream)
229229
? {
230-
name: this._streams.length.toString(),
231-
stream,
232-
}
230+
name: this._streams.length.toString(),
231+
stream,
232+
}
233233
: stream;
234234

235235
this._logger.check(this._triggered, addWhenRunning(src.name || src.stream));
@@ -311,9 +311,9 @@ export abstract class MatDataSource<REQ = any, RAW = any, RES = any>
311311
...this.overrides,
312312
} as any;
313313

314-
delete this.arguments.forceReload;
314+
delete this.arguments?.forceReload;
315315

316-
return this.arguments;
316+
return this.args;
317317
}
318318

319319
private _isEqual(): (prev: REQ, curr: REQ) => boolean {
@@ -342,28 +342,27 @@ export abstract class MatDataSource<REQ = any, RAW = any, RES = any>
342342
return merge(
343343
query,
344344
// timers check
345-
timer(this.config.waitMs, this.config.intervalMs).pipe(
345+
timer(this.config.waitMs ?? 5000, this.config.intervalMs || 10000).pipe(
346346
takeUntil(query),
347-
take(3) // by default: 5s, 15s, 25s
348-
)
349-
).pipe(
350-
// delay check
351-
tap((val) => {
352-
if (typeof val !== 'number') {
353-
this._logger.print(queryResponse(), val);
354-
} else {
355-
this._logger.print(queryTimeout(), val);
347+
take(3), // by default: 5s, 15s, 25s
348+
tap((sequence) => {
349+
this._logger.print(queryTimeout(), sequence);
356350
try {
357-
this._outputMsg = this._logger.getTimeoutError(val);
358-
} catch (e) {
359-
this._logger.addError('timeout', e.message);
351+
this._outputMsg = this._logger.getTimeoutError(sequence);
352+
} catch (e: unknown) {
353+
if (e instanceof Error) {
354+
this._logger.addError('timeout', e.message);
355+
}
360356
this._loading = false;
361357
}
362358
this._change$.next({});
363-
}
364-
}),
365-
// discard timer result
366-
filter<RAW>((result) => typeof result !== 'number'),
359+
}),
360+
filter((result: number | RAW): result is RAW => {
361+
return typeof result !== 'number';
362+
})
363+
)
364+
).pipe(
365+
tap((result) => this._logger.print(queryResponse(), result)),
367366
catchError((err) => {
368367
// isolate query error
369368
this._logger.handleError('query', err);

libs/datasource/src/lib/mappers.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { pipe } from 'rxjs';
44
import { map, startWith } from 'rxjs/operators';
55

66
/**
7-
* Premade Mappers
7+
* Pre-made Mappers
88
*/
99

1010
export function mapPaginator(pageSize: number) {

libs/datasource/src/lib/overlay.ts

+9-8
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
HostBinding,
77
Input,
88
OnDestroy,
9-
ViewEncapsulation
9+
ViewEncapsulation,
1010
} from '@angular/core';
1111
import { Subject } from 'rxjs';
1212
import { takeUntil } from 'rxjs/operators';
@@ -17,20 +17,21 @@ import { missingDataSourceInput } from './messages';
1717
selector: 'mat-datasource-overlay',
1818
templateUrl: './overlay.html',
1919
host: {
20-
class: 'mat-datasource-overlay'
20+
class: 'mat-datasource-overlay',
2121
},
2222
encapsulation: ViewEncapsulation.None,
23-
changeDetection: ChangeDetectionStrategy.OnPush
23+
changeDetection: ChangeDetectionStrategy.OnPush,
2424
})
2525
export class DataSourceOverlay<REQ, RAW, RES>
26-
implements AfterContentInit, OnDestroy {
27-
@Input() dataSource: MatDataSource<REQ, RAW, RES>;
26+
implements AfterContentInit, OnDestroy
27+
{
28+
@Input({ required: true }) dataSource!: MatDataSource<REQ, RAW, RES>;
2829

29-
@Input() diameter: number;
30-
@Input() strokeWidth: number;
30+
@Input() diameter?: number;
31+
@Input() strokeWidth?: number;
3132

3233
@HostBinding('style.display')
33-
_display: string;
34+
_display?: string;
3435

3536
private onDestroy = new Subject<void>();
3637

libs/datasource/tsconfig.json

+16-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
{
22
"extends": "../../tsconfig.base.json",
3-
"include": [],
3+
"compilerOptions": {
4+
"target": "es2022",
5+
"useDefineForClassFields": false,
6+
"forceConsistentCasingInFileNames": true,
7+
"strict": true,
8+
"noImplicitOverride": true,
9+
"noPropertyAccessFromIndexSignature": false,
10+
"noImplicitReturns": true,
11+
"noFallthroughCasesInSwitch": true
12+
},
413
"files": [],
14+
"include": [],
515
"references": [
616
{
717
"path": "./tsconfig.lib.json"
@@ -13,7 +23,10 @@
1323
"path": "./tsconfig.spec.json"
1424
}
1525
],
16-
"compilerOptions": {
17-
"target": "es2020"
26+
"angularCompilerOptions": {
27+
"enableI18nLegacyMessageIdFormat": false,
28+
"strictInjectionParameters": true,
29+
"strictInputAccessModifiers": true,
30+
"strictTemplates": true
1831
}
1932
}

libs/datasource/tsconfig.lib.json

+7-8
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@
77
"declarationMap": true,
88
"inlineSources": true,
99
"useDefineForClassFields": false,
10-
"types": [],
11-
"lib": ["dom", "es2018"]
10+
"types": []
1211
},
13-
"angularCompilerOptions": {
14-
"skipTemplateCodegen": true,
15-
"strictMetadataEmit": true,
16-
"enableResourceInlining": true
17-
},
18-
"exclude": ["src/test-setup.ts", "**/*.spec.ts", "**/*.test.ts"],
12+
"exclude": [
13+
"src/**/*.spec.ts",
14+
"src/test-setup.ts",
15+
"jest.config.ts",
16+
"src/**/*.test.ts"
17+
],
1918
"include": ["**/*.ts"]
2019
}

libs/datasource/tsconfig.lib.prod.json

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
{
22
"extends": "./tsconfig.lib.json",
33
"compilerOptions": {
4-
"declarationMap": false,
5-
"useDefineForClassFields": false,
6-
"target": "ES2022"
4+
"declarationMap": false
75
},
86
"angularCompilerOptions": {
97
"compilationMode": "partial"

libs/datasource/tsconfig.spec.json

+7-1
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,14 @@
33
"compilerOptions": {
44
"outDir": "../../dist/out-tsc",
55
"module": "commonjs",
6+
"target": "es2016",
67
"types": ["jest", "node"]
78
},
89
"files": ["src/test-setup.ts"],
9-
"include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts"]
10+
"include": [
11+
"jest.config.ts",
12+
"src/**/*.test.ts",
13+
"src/**/*.spec.ts",
14+
"src/**/*.d.ts"
15+
]
1016
}

0 commit comments

Comments
 (0)