Skip to content

Commit 16c6206

Browse files
feat(lib): lazy url config
1 parent c8de395 commit 16c6206

File tree

7 files changed

+66
-41
lines changed

7 files changed

+66
-41
lines changed

packages/ngx-fast-icon-demo/src/app/app.component.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { Component, inject, PLATFORM_ID } from '@angular/core';
2-
import { ActivatedRoute, NavigationEnd, Router, RouterOutlet } from '@angular/router';
2+
import { NavigationEnd, Router, RouterOutlet } from '@angular/router';
33

44
import { filter, map, Observable, startWith } from 'rxjs';
5-
import {MediaMatcher} from '@angular/cdk/layout';
6-
import {ShellComponent} from './misc/shell.component';
7-
import {AsyncPipe, isPlatformServer} from '@angular/common';
5+
import { MediaMatcher } from '@angular/cdk/layout';
6+
import { ShellComponent } from './misc/shell.component';
7+
import { AsyncPipe, isPlatformServer } from '@angular/common';
88

99
@Component({
1010
selector: 'ngx-fast-icon-root',

packages/ngx-fast-icon-demo/src/app/app.config.server.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
import { join } from 'node:path';
2-
import { readFileSync } from 'node:fs';
2+
import { readFile } from 'node:fs/promises';
3+
import { cwd } from 'node:process';
34

45
import { ApplicationConfig, Injectable, mergeApplicationConfig } from '@angular/core';
56
import { provideServerRendering } from '@angular/platform-server';
67

7-
import { Observable, of } from 'rxjs';
8+
import { from, Observable, of, switchMap } from 'rxjs';
89

910
import { provideFastSVG, SvgLoadStrategy } from '@push-based/ngx-fast-svg';
1011

1112
import { appConfig } from './app.config';
1213

1314
@Injectable()
14-
export class SvgLoadStrategySsr extends SvgLoadStrategy {
15-
load(url: string): Observable<string> {
16-
const iconPath = join(process.cwd(), 'packages', 'ngx-fast-icon-demo', 'src', url);
17-
const iconSVG = readFileSync(iconPath, 'utf8')
18-
return of(iconSVG);
15+
export class SvgLoadStrategySsr implements SvgLoadStrategy {
16+
config = (url: string) => of(join(cwd(), 'packages', 'ngx-fast-icon-demo', 'src', 'assets', 'svg-icons', url));
17+
load(iconPath$: Observable<string>) {
18+
return iconPath$.pipe(switchMap((iconPath) => from(readFile(iconPath, { encoding: 'utf8' }))))
1919
}
2020
}
2121

@@ -24,7 +24,7 @@ const serverConfig: ApplicationConfig = {
2424
provideServerRendering(),
2525
provideFastSVG({
2626
svgLoadStrategy: SvgLoadStrategySsr,
27-
url: (name: string) => `assets/svg-icons/${name}.svg`,
27+
url: (name: string) => `${name}.svg`,
2828
}),
2929
],
3030
};

packages/ngx-fast-icon-demo/src/app/app.config.ts

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ApplicationConfig, Injectable } from '@angular/core';
1+
import { ApplicationConfig } from '@angular/core';
22
import {
33
provideRouter,
44
withComponentInputBinding,
@@ -9,20 +9,11 @@ import { provideHttpClient, withFetch } from '@angular/common/http';
99
import { provideClientHydration } from '@angular/platform-browser';
1010
import { provideAnimations } from '@angular/platform-browser/animations';
1111

12-
import { provideFastSVG, SvgLoadStrategyImpl } from '@push-based/ngx-fast-svg';
12+
import { provideFastSVG } from '@push-based/ngx-fast-svg';
1313
import { provideAngularSvgIcon } from 'angular-svg-icon';
1414
import { provideIonicAngular } from '@ionic/angular/standalone';
1515

1616
import { appRoutes } from './app.routes';
17-
import { Observable, of, switchMap, timer } from 'rxjs';
18-
19-
@Injectable({ providedIn: 'root' })
20-
export class ConfigService extends SvgLoadStrategyImpl {
21-
lazy$ = timer(10_000)
22-
override config(url: string): Observable<string> {
23-
return this.lazy$.pipe(switchMap(() => of(url)))
24-
}
25-
}
2617

2718
export const appConfig: ApplicationConfig = {
2819
providers: [
@@ -42,7 +33,6 @@ export const appConfig: ApplicationConfig = {
4233
provideIonicAngular({}),
4334
provideFastSVG({
4435
url: (name: string) => `assets/svg-icons/${name}.svg`,
45-
svgLoadStrategy: ConfigService
4636
}),
4737
],
4838
};

packages/ngx-fast-lib/README.md

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,14 @@ During setup phase you can provide additional optional settings such as:
102102
svgLoadStrategy?: Type<SvgLoadStrategy>;
103103
```
104104

105-
`svgLoadStrategy` can be any injectable class that has `load` method that accepts url and returns observable string:
105+
`svgLoadStrategy` can be any injectable class that has `config` that excepts method that accepts url and returns observable string,
106+
and `load` which accepts the configured url as an observable and returns the svg as an observable string.
106107

107108
```typescript
108109
@Injectable()
109110
export abstract class SvgLoadStrategy {
110-
abstract load(url: string): Observable<string>;
111+
abstract config(url: string): Observable<string>;
112+
abstract load(url: Observable<string>): Observable<string>;
111113
}
112114
```
113115

@@ -164,10 +166,9 @@ You can provide your own SSR loading strategy that can look like this:
164166
```typescript
165167
@Injectable()
166168
export class SvgLoadStrategySsr implements SvgLoadStrategy {
167-
load(url: string): Observable<string> {
168-
const iconPath = join(process.cwd(), 'dist', 'app-name', 'browser', url);
169-
const iconSVG = readFileSync(iconPath, 'utf8');
170-
return of(iconSVG);
169+
config = (url: string) => of(join(cwd(), 'path', 'to', 'svg', 'assets', url));
170+
load(iconPath$: Observable<string>) {
171+
return iconPath$.pipe(switchMap((iconPath) => from(readFile(iconPath, { encoding: 'utf8' }))));
171172
}
172173
}
173174
```
@@ -187,14 +188,44 @@ And then just provide it in you server module.
187188
providers: [
188189
provideFastSVG({
189190
svgLoadStrategy: SvgLoadStrategySsr,
190-
url: (name: string) => `assets/svg-icons/${name}.svg`,
191+
url: (name: string) => `${name}.svg`,
191192
}),
192193
],
193194
bootstrap: [AppComponent],
194195
})
195196
export class AppServerModule {}
196197
```
197198

199+
#### Providing a lazy configuration
200+
201+
If you need to provide a lazy configuration you can use the config method in the `SvgLoadStrategy`:
202+
203+
```typescript
204+
@Injectable()
205+
class LazyConfigSvgLoadStrategy extends SvgLoadStrategyImpl {
206+
lazyConfigService = inject(SvgConfigService);
207+
override config(url: string) {
208+
return this.lazyConfigService.urlConfig(url);
209+
}
210+
}
211+
```
212+
213+
And pass it to the provider function:
214+
215+
```typescript
216+
import { provideFastSVG } from '@push-based/ngx-fast-svg';
217+
218+
bootstrapApplication(AppComponent, {
219+
providers: [
220+
// ... other providers
221+
provideFastSVG({
222+
url: (name: string): Observable<string> => inject(ConfigService).svgUrl(name),
223+
svgLoadStrategy: LazyConfigSvgLoadStrategy,
224+
})
225+
]
226+
});
227+
```
228+
198229
## Features
199230

200231
### :sloth: Lazy loading for SVGs

packages/ngx-fast-lib/src/lib/svg-registry.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ export class SvgRegistry {
108108

109109
// trigger fetch
110110
this.svgLoadStrategy
111-
.load(this.svgOptions.url(svgName))
111+
.load(this.url(svgName))
112112
.subscribe({
113113
next: (body: string) => this.cacheSvgInDOM(svgId, body),
114114
error: console.error
Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
import { Observable, of } from 'rxjs';
1+
import { Observable } from 'rxjs';
22
import { Injectable } from '@angular/core';
33

44
@Injectable()
55
export abstract class SvgLoadStrategy {
6-
abstract load(url: string | Observable<string>): Observable<string>;
7-
config(url: string): Observable<string> {
8-
return of(url)
9-
};
6+
abstract config(url: string): Observable<string>;
7+
abstract load(url: Observable<string>): Observable<string>;
108
}
Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1-
import { from, Observable } from 'rxjs';
1+
import { from, Observable, of, switchMap } from 'rxjs';
22
import { getZoneUnPatchedApi } from '../internal/get-zone-unpatched-api';
33
import { SvgLoadStrategy } from './svg-load.strategy.model';
4+
import { Injectable } from '@angular/core';
45

5-
export class SvgLoadStrategyImpl extends SvgLoadStrategy {
6+
@Injectable()
7+
export class SvgLoadStrategyImpl implements SvgLoadStrategy {
68
fetch = getZoneUnPatchedApi('fetch', window as any);
79

8-
load(url: string): Observable<string> {
9-
return from(fetch(url).then((res) => (!res.ok ? '' : res.text())));
10+
load(url$: Observable<string>): Observable<string> {
11+
return url$.pipe(switchMap((url) => {
12+
return from(fetch(url).then((res) => (!res.ok ? '' : res.text())));
13+
}));
1014
}
15+
16+
config = (url: string) => of(url);
1117
}

0 commit comments

Comments
 (0)