-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(query): add query persistence functionality
- Create angular-query-persist-client-package - Implement providePersistQueryClient in new package - Add isRestoring provider and injection token to main angular-query package - Include example of persister package usage
- Loading branch information
1 parent
0c720e1
commit 85fcf74
Showing
37 changed files
with
1,079 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"name": "Node.js", | ||
"image": "mcr.microsoft.com/devcontainers/javascript-node:18" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
// @ts-check | ||
|
||
/** @type {import('eslint').Linter.Config} */ | ||
const config = {} | ||
|
||
module.exports = config |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Angular Query persister example | ||
|
||
To run this example: | ||
|
||
- `npm install` or `yarn` or `pnpm i` or `bun i` | ||
- `npm run start` or `yarn start` or `pnpm start` or `bun start` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
{ | ||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json", | ||
"version": 1, | ||
"cli": { | ||
"packageManager": "pnpm", | ||
"analytics": false, | ||
"cache": { | ||
"enabled": false | ||
} | ||
}, | ||
"newProjectRoot": "projects", | ||
"projects": { | ||
"basic": { | ||
"projectType": "application", | ||
"schematics": { | ||
"@schematics/angular:component": { | ||
"inlineTemplate": true, | ||
"inlineStyle": true, | ||
"skipTests": true | ||
}, | ||
"@schematics/angular:class": { | ||
"skipTests": true | ||
}, | ||
"@schematics/angular:directive": { | ||
"skipTests": true | ||
}, | ||
"@schematics/angular:guard": { | ||
"skipTests": true | ||
}, | ||
"@schematics/angular:interceptor": { | ||
"skipTests": true | ||
}, | ||
"@schematics/angular:pipe": { | ||
"skipTests": true | ||
}, | ||
"@schematics/angular:resolver": { | ||
"skipTests": true | ||
}, | ||
"@schematics/angular:service": { | ||
"skipTests": true | ||
} | ||
}, | ||
"root": "", | ||
"sourceRoot": "src", | ||
"prefix": "app", | ||
"architect": { | ||
"build": { | ||
"builder": "@angular-devkit/build-angular:application", | ||
"options": { | ||
"outputPath": "dist/basic", | ||
"index": "src/index.html", | ||
"browser": "src/main.ts", | ||
"polyfills": ["zone.js"], | ||
"tsConfig": "tsconfig.app.json", | ||
"assets": ["src/favicon.ico", "src/assets"], | ||
"styles": [], | ||
"scripts": [] | ||
}, | ||
"configurations": { | ||
"production": { | ||
"budgets": [ | ||
{ | ||
"type": "initial", | ||
"maximumWarning": "500kb", | ||
"maximumError": "1mb" | ||
}, | ||
{ | ||
"type": "anyComponentStyle", | ||
"maximumWarning": "2kb", | ||
"maximumError": "4kb" | ||
} | ||
], | ||
"outputHashing": "all" | ||
}, | ||
"development": { | ||
"optimization": false, | ||
"extractLicenses": false, | ||
"sourceMap": true | ||
} | ||
}, | ||
"defaultConfiguration": "production" | ||
}, | ||
"serve": { | ||
"builder": "@angular-devkit/build-angular:dev-server", | ||
"configurations": { | ||
"production": { | ||
"buildTarget": "basic:build:production" | ||
}, | ||
"development": { | ||
"buildTarget": "basic:build:development" | ||
} | ||
}, | ||
"defaultConfiguration": "development" | ||
}, | ||
"extract-i18n": { | ||
"builder": "@angular-devkit/build-angular:extract-i18n", | ||
"options": { | ||
"buildTarget": "basic:build" | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
{ | ||
"name": "@tanstack/query-example-angular-persister", | ||
"type": "module", | ||
"scripts": { | ||
"ng": "ng", | ||
"start": "ng serve", | ||
"build": "ng build", | ||
"watch": "ng build --watch --configuration development" | ||
}, | ||
"private": true, | ||
"dependencies": { | ||
"@angular/common": "^17.3.12", | ||
"@angular/compiler": "^17.3.12", | ||
"@angular/core": "^17.3.12", | ||
"@angular/forms": "^18.2.8", | ||
"@angular/platform-browser": "^17.3.12", | ||
"@angular/platform-browser-dynamic": "^17.3.12", | ||
"@angular/router": "^17.3.12", | ||
"@tanstack/angular-query-experimental": "^5.54.1", | ||
"@tanstack/angular-query-persist-client-experimental": "^5.54.1", | ||
"@tanstack/query-sync-storage-persister": "^5.54.1", | ||
"rxjs": "^7.8.1", | ||
"tslib": "^2.6.3", | ||
"zone.js": "^0.14.8" | ||
}, | ||
"devDependencies": { | ||
"@angular-devkit/build-angular": "^17.3.8", | ||
"@angular/cli": "^17.3.8", | ||
"@angular/compiler-cli": "^17.3.12", | ||
"@tanstack/angular-query-devtools-experimental": "^5.54.1", | ||
"typescript": "5.3.3" | ||
}, | ||
"msw": { | ||
"workerDirectory": [ | ||
"src" | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { ChangeDetectionStrategy, Component } from '@angular/core' | ||
import { RouterOutlet } from '@angular/router' | ||
import { AngularQueryDevtools } from '@tanstack/angular-query-devtools-experimental' | ||
import { injectIsRestoring } from '@tanstack/angular-query-experimental' | ||
|
||
@Component({ | ||
changeDetection: ChangeDetectionStrategy.OnPush, | ||
selector: 'root', | ||
standalone: true, | ||
template: ` | ||
<h1>Angular Query - Persister</h1> | ||
<p> | ||
Try to mock offline behavior with the button in the devtools. You can | ||
navigate around as long as there is already data in the cache. You'll get | ||
a refetch as soon as you go "online" again. | ||
</p> | ||
<router-outlet /> | ||
<angular-query-devtools initialIsOpen /> | ||
`, | ||
imports: [AngularQueryDevtools, RouterOutlet], | ||
}) | ||
export class AppComponent { | ||
isRestoring = injectIsRestoring() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { provideHttpClient, withFetch } from '@angular/common/http' | ||
import { QueryClient } from '@tanstack/angular-query-experimental' | ||
import { provideRouter, withComponentInputBinding } from '@angular/router' | ||
import { providePersistAngularQuery } from '@tanstack/angular-query-persist-client-experimental' | ||
import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister' | ||
import type { Route } from '@angular/router' | ||
import type { ApplicationConfig } from '@angular/core' | ||
|
||
export const routes: Array<Route> = [ | ||
{ | ||
path: '', | ||
loadComponent: () => import('./posts/posts.component'), | ||
}, | ||
{ | ||
path: 'posts/:postId', | ||
loadComponent: () => import('./posts/post.component'), | ||
}, | ||
] | ||
|
||
const queryClient = new QueryClient({ | ||
defaultOptions: { | ||
queries: { | ||
gcTime: 1000 * 60 * 60 * 24, // 24 hours | ||
staleTime: 2000, | ||
}, | ||
}, | ||
}) | ||
|
||
const persister = createSyncStoragePersister({ | ||
storage: window.localStorage, | ||
}) | ||
|
||
export const appConfig: ApplicationConfig = { | ||
providers: [ | ||
provideHttpClient(withFetch()), | ||
providePersistAngularQuery(queryClient, [{ persister }]), | ||
provideRouter(routes, withComponentInputBinding()), | ||
], | ||
} |
19 changes: 19 additions & 0 deletions
19
examples/angular/persister/src/app/posts/post.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<div> | ||
<div> | ||
<a [routerLink]="['../../']"> Back </a> | ||
</div> | ||
@if (postQuery.status() === 'pending') { | ||
Loading... | ||
} @else if (postQuery.status() === 'error') { | ||
Error: {{ postQuery.error?.()?.message }} | ||
} | ||
@if (postQuery.data(); as post) { | ||
<h1>{{ post.title }}</h1> | ||
<div> | ||
<p>{{ post.body }}</p> | ||
</div> | ||
@if (postQuery.isFetching()) { | ||
Background Updating... | ||
} | ||
} | ||
</div> |
35 changes: 35 additions & 0 deletions
35
examples/angular/persister/src/app/posts/post.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { | ||
ChangeDetectionStrategy, | ||
Component, | ||
inject, | ||
input, | ||
} from '@angular/core' | ||
import { injectQuery } from '@tanstack/angular-query-experimental' | ||
import { fromEvent, lastValueFrom, takeUntil } from 'rxjs' | ||
import { RouterLink } from '@angular/router' | ||
import { PostsService } from './posts.service' | ||
|
||
@Component({ | ||
changeDetection: ChangeDetectionStrategy.OnPush, | ||
selector: 'post', | ||
standalone: true, | ||
templateUrl: './post.component.html', | ||
imports: [RouterLink], | ||
}) | ||
export default class PostComponent { | ||
#postsService = inject(PostsService) | ||
|
||
postId = input(0) | ||
|
||
postQuery = injectQuery(() => ({ | ||
enabled: this.postId() > 0, | ||
queryKey: ['post', this.postId()], | ||
queryFn: async (context) => { | ||
// Cancels the request when component is destroyed before the request finishes | ||
const abort$ = fromEvent(context.signal, 'abort') | ||
return lastValueFrom( | ||
this.#postsService.postById$(this.postId()).pipe(takeUntil(abort$)), | ||
) | ||
}, | ||
})) | ||
} |
36 changes: 36 additions & 0 deletions
36
examples/angular/persister/src/app/posts/posts.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<div> | ||
<h1>Posts</h1> | ||
@switch (postsQuery.status()) { | ||
@case ('pending') { | ||
Loading... | ||
} | ||
@case ('error') { | ||
Error: {{ postsQuery.error?.()?.message }} | ||
} | ||
@default { | ||
<div class="todo-container"> | ||
@for (post of postsQuery.data(); track post.id) { | ||
<p> | ||
<a | ||
[routerLink]="['posts', post.id]" | ||
[ngStyle]=" | ||
queryClient.getQueryData(['post', post.id.toString()]) | ||
? { | ||
fontWeight: 'bold', | ||
color: 'green', | ||
} | ||
: {} | ||
" | ||
>{{ post.title }}</a | ||
> | ||
</p> | ||
} | ||
</div> | ||
} | ||
} | ||
<div> | ||
@if (postsQuery.isFetching()) { | ||
Background Updating... | ||
} | ||
</div> | ||
</div> |
26 changes: 26 additions & 0 deletions
26
examples/angular/persister/src/app/posts/posts.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { ChangeDetectionStrategy, Component, inject } from '@angular/core' | ||
import { RouterLink } from '@angular/router' | ||
import { NgStyle } from '@angular/common' | ||
import { | ||
injectQuery, | ||
injectQueryClient, | ||
} from '@tanstack/angular-query-experimental' | ||
import { lastValueFrom } from 'rxjs' | ||
import { PostsService } from './posts.service' | ||
|
||
@Component({ | ||
changeDetection: ChangeDetectionStrategy.OnPush, | ||
selector: 'posts', | ||
standalone: true, | ||
templateUrl: './posts.component.html', | ||
imports: [RouterLink, NgStyle], | ||
}) | ||
export default class PostsComponent { | ||
#postsService = inject(PostsService) | ||
|
||
postsQuery = injectQuery(() => ({ | ||
queryKey: ['posts'], | ||
queryFn: () => lastValueFrom(this.#postsService.allPosts$()), | ||
})) | ||
queryClient = injectQueryClient() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { HttpClient } from '@angular/common/http' | ||
import { Injectable, inject } from '@angular/core' | ||
|
||
@Injectable({ | ||
providedIn: 'root', | ||
}) | ||
export class PostsService { | ||
#http = inject(HttpClient) | ||
|
||
postById$ = (postId: number) => | ||
this.#http.get<Post>(`https://jsonplaceholder.typicode.com/posts/${postId}`) | ||
|
||
allPosts$ = () => | ||
this.#http.get<Array<Post>>('https://jsonplaceholder.typicode.com/posts') | ||
} | ||
|
||
export interface Post { | ||
id: number | ||
title: string | ||
body: string | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<title>Angular Query basic example</title> | ||
<base href="/" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
<link rel="icon" type="image/x-icon" href="favicon.ico" /> | ||
</head> | ||
<body> | ||
<root /> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { bootstrapApplication } from '@angular/platform-browser' | ||
import { appConfig } from './app/app.config' | ||
import { AppComponent } from './app/app.component' | ||
|
||
bootstrapApplication(AppComponent, appConfig).catch((err) => console.error(err)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"extends": "./tsconfig.json", | ||
"compilerOptions": { | ||
"outDir": "./out-tsc/app", | ||
"types": [] | ||
}, | ||
"files": ["src/main.ts"], | ||
"include": ["src/**/*.d.ts"] | ||
} |
Oops, something went wrong.