Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c83605b

Browse filesBrowse files
Add aspnet-angular NPM package containing HttpWithStateTransfer utility
1 parent fc12d72 commit c83605b
Copy full SHA for c83605b

File tree

Expand file treeCollapse file tree

7 files changed

+161
-0
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

7 files changed

+161
-0
lines changed
Open diff view settings
Collapse file
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/node_modules/
2+
**/*.js
3+
**/*.d.ts
Collapse file
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
!/*.js
2+
!/*.d.ts
Collapse file
+12Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Copyright (c) .NET Foundation. All rights reserved.
2+
3+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
4+
these files except in compliance with the License. You may obtain a copy of the
5+
License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software distributed
10+
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
11+
CONDITIONS OF ANY KIND, either express or implied. See the License for the
12+
specific language governing permissions and limitations under the License.
Collapse file
+32Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"name": "aspnet-angular",
3+
"version": "0.1.0",
4+
"description": "Helpers for using Angular in ASP.NET Core projects",
5+
"main": "index.js",
6+
"scripts": {
7+
"prepublish": "rimraf *.d.ts && tsc && echo 'Finished building NPM package \"aspnet-angular\"'",
8+
"test": "echo \"Error: no test specified\" && exit 1"
9+
},
10+
"repository": {
11+
"type": "git",
12+
"url": "https://github.com/aspnet/JavaScriptServices.git"
13+
},
14+
"author": "Microsoft",
15+
"license": "Apache-2.0",
16+
"bugs": {
17+
"url": "https://github.com/aspnet/JavaScriptServices/issues"
18+
},
19+
"devDependencies": {
20+
"@angular/common": "^4.3.2",
21+
"@angular/core": "^4.3.2",
22+
"@angular/http": "^4.3.2",
23+
"@angular/platform-browser": "^4.3.2",
24+
"rimraf": "^2.6.1",
25+
"typescript": "^2.4.2",
26+
"rxjs": "^5.4.2",
27+
"zone.js": "^0.8.16"
28+
},
29+
"peerDependencies": {
30+
"@angular/core": "^4.2.5 || ^5.0.0-beta"
31+
}
32+
}
Collapse file
+94Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { Provider, NgModule, Inject } from '@angular/core';
2+
import { Headers, Http, ResponseOptions, RequestOptionsArgs, Response } from '@angular/http';
3+
import { Observable } from 'rxjs/Observable';
4+
import 'rxjs/add/observable/of';
5+
import 'rxjs/add/operator/map';
6+
const globalSerializedStateKey = 'HTTP_STATE_TRANSFER';
7+
const backingStoreDIToken = 'HTTP_STATE_BACKING_STORE';
8+
9+
export interface CacheOptions {
10+
permanent: boolean;
11+
}
12+
13+
export interface CachedHttpResponse {
14+
headers: { [name: string]: any } | null;
15+
status: number;
16+
statusText: string | null;
17+
text: string;
18+
url: string;
19+
}
20+
21+
export type BackingStore = { [key: string]: CachedHttpResponse };
22+
23+
export class HttpWithStateTransfer {
24+
private backingStore: BackingStore;
25+
private http: Http;
26+
27+
constructor(@Inject(Http) http: Http, @Inject(backingStoreDIToken) backingStore: BackingStore) {
28+
this.http = http;
29+
this.backingStore = backingStore;
30+
}
31+
32+
public stateForTransfer(): any {
33+
return { [globalSerializedStateKey]: this.backingStore };
34+
}
35+
36+
public get(url: string, options?: CacheOptions, requestOptions?: RequestOptionsArgs): Observable<Response> {
37+
return this.getCachedResponse(/* cacheKey */ url, () => this.http.get(url, requestOptions), options);
38+
}
39+
40+
private getCachedResponse(cacheKey: string, provider: () => Observable<Response>, options?: CacheOptions): Observable<Response> {
41+
// By default, the cache is only used for the *first* client-side read. So, we're only performing
42+
// a one-time transfer of server-side response to the client. If you want to keep and reuse cached
43+
// responses continually during server-side and client-side execution, set 'permanent' to 'true.
44+
const isClient = typeof window !== 'undefined';
45+
const isPermanent = options && options.permanent;
46+
47+
const allowReadFromCache = isClient || isPermanent;
48+
if (allowReadFromCache && this.backingStore.hasOwnProperty(cacheKey)) {
49+
const cachedValue = this.backingStore[cacheKey];
50+
if (!isPermanent) {
51+
delete this.backingStore[cacheKey];
52+
}
53+
return Observable.of(new Response(new ResponseOptions({
54+
body: cachedValue.text,
55+
headers: new Headers(cachedValue.headers),
56+
status: cachedValue.status,
57+
url: cachedValue.url
58+
})));
59+
}
60+
61+
return provider()
62+
.map(response => {
63+
const allowWriteToCache = !isClient || isPermanent;
64+
if (allowWriteToCache) {
65+
this.backingStore[cacheKey] = {
66+
headers: response.headers ? response.headers.toJSON() : null,
67+
status: response.status,
68+
statusText: response.statusText,
69+
text: response.text(),
70+
url: response.url
71+
};
72+
}
73+
74+
return response;
75+
});
76+
}
77+
}
78+
79+
export function defaultBackingStoreFactory() {
80+
const transferredData = typeof window !== 'undefined' ? (window as any)[globalSerializedStateKey] : null;
81+
return transferredData || {};
82+
}
83+
84+
@NgModule({
85+
providers: [
86+
// The backing store is a separate DI service so you could override exactly how it gets
87+
// transferred from server to client
88+
{ provide: backingStoreDIToken, useFactory: defaultBackingStoreFactory },
89+
90+
{ provide: HttpWithStateTransfer, useClass: HttpWithStateTransfer },
91+
]
92+
})
93+
export class HttpWithStateTransferModule {
94+
}
Collapse file
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './HttpWithStateTransfer';
Collapse file
+17Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"compilerOptions": {
3+
"experimentalDecorators": true,
4+
"moduleResolution": "node",
5+
"module": "commonjs",
6+
"target": "es5",
7+
"declaration": true,
8+
"outDir": ".",
9+
"lib": ["es2015", "dom"]
10+
},
11+
"files": [
12+
"src/index.ts"
13+
],
14+
"exclude": [
15+
"node_modules"
16+
]
17+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.