diff --git a/package.json b/package.json index a639e6bc92..296fe7b8d5 100644 --- a/package.json +++ b/package.json @@ -69,9 +69,9 @@ "@ng-bootstrap/ng-bootstrap": "^10.0.0", "@ng-dynamic-forms/core": "^14.0.1", "@ng-dynamic-forms/ui-ng-bootstrap": "^14.0.1", - "@ngrx/effects": "^12.5.1", - "@ngrx/router-store": "^12.5.1", - "@ngrx/store": "^12.5.1", + "@ngrx/effects": "^13.0.2", + "@ngrx/router-store": "^13.0.2", + "@ngrx/store": "^13.0.2", "@nguniversal/express-engine": "^13.0.2", "@ngx-translate/core": "^13.0.0", "@nicky-lenaers/ngx-scroll-to": "^9.0.0", @@ -134,7 +134,7 @@ "@angular/language-service": "~13.2.6", "@cypress/schematic": "^1.5.0", "@fortawesome/fontawesome-free": "^5.5.0", - "@ngrx/store-devtools": "^12.5.1", + "@ngrx/store-devtools": "^13.0.2", "@ngtools/webpack": "^13.2.6", "@nguniversal/builders": "^13.0.2", "@types/deep-freeze": "0.1.2", @@ -198,4 +198,4 @@ "webpack-cli": "^4.2.0", "webpack-dev-server": "^4.5.0" } -} +} \ No newline at end of file diff --git a/src/app/core/auth/auth.effects.ts b/src/app/core/auth/auth.effects.ts index 4f1494051f..d876add98e 100644 --- a/src/app/core/auth/auth.effects.ts +++ b/src/app/core/auth/auth.effects.ts @@ -10,7 +10,7 @@ import { } from 'rxjs'; import { catchError, filter, map, observeOn, switchMap, take, tap } from 'rxjs/operators'; // import @ngrx -import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Actions, createEffect, ofType } from '@ngrx/effects'; import { Action, select, Store } from '@ngrx/store'; // import services @@ -67,8 +67,8 @@ export class AuthEffects { * Authenticate user. * @method authenticate */ - @Effect() - public authenticate$: Observable = this.actions$.pipe( + + public authenticate$: Observable = createEffect(() => this.actions$.pipe( ofType(AuthActionTypes.AUTHENTICATE), switchMap((action: AuthenticateAction) => { return this.authService.authenticate(action.payload.email, action.payload.password).pipe( @@ -77,26 +77,26 @@ export class AuthEffects { catchError((error) => observableOf(new AuthenticationErrorAction(error))) ); }) - ); + )); - @Effect() - public authenticateSuccess$: Observable = this.actions$.pipe( + + public authenticateSuccess$: Observable = createEffect(() => this.actions$.pipe( ofType(AuthActionTypes.AUTHENTICATE_SUCCESS), map((action: AuthenticationSuccessAction) => new AuthenticatedAction(action.payload)) - ); + )); - @Effect() - public authenticated$: Observable = this.actions$.pipe( + + public authenticated$: Observable = createEffect(() => this.actions$.pipe( ofType(AuthActionTypes.AUTHENTICATED), switchMap((action: AuthenticatedAction) => { return this.authService.authenticatedUser(action.payload).pipe( map((userHref: string) => new AuthenticatedSuccessAction((userHref !== null), action.payload, userHref)), catchError((error) => observableOf(new AuthenticatedErrorAction(error))),); }) - ); + )); - @Effect() - public authenticatedSuccess$: Observable = this.actions$.pipe( + + public authenticatedSuccess$: Observable = createEffect(() => this.actions$.pipe( ofType(AuthActionTypes.AUTHENTICATED_SUCCESS), tap((action: AuthenticatedSuccessAction) => this.authService.storeToken(action.payload.authToken)), switchMap((action: AuthenticatedSuccessAction) => this.authService.getRedirectUrl().pipe( @@ -110,26 +110,26 @@ export class AuthEffects { return new RetrieveAuthenticatedEpersonAction(action.payload.userHref); } }) - ); + )); - @Effect({ dispatch: false }) - public redirectAfterLoginSuccess$: Observable = this.actions$.pipe( + + public redirectAfterLoginSuccess$: Observable = createEffect(() => this.actions$.pipe( ofType(AuthActionTypes.REDIRECT_AFTER_LOGIN_SUCCESS), tap((action: RedirectAfterLoginSuccessAction) => { this.authService.clearRedirectUrl(); this.authService.navigateToRedirectUrl(action.payload); }) - ); + ), { dispatch: false }); // It means "reacts to this action but don't send another" - @Effect({ dispatch: false }) - public authenticatedError$: Observable = this.actions$.pipe( + + public authenticatedError$: Observable = createEffect(() => this.actions$.pipe( ofType(AuthActionTypes.AUTHENTICATED_ERROR), tap((action: LogOutSuccessAction) => this.authService.removeToken()) - ); + ), { dispatch: false }); - @Effect() - public retrieveAuthenticatedEperson$: Observable = this.actions$.pipe( + + public retrieveAuthenticatedEperson$: Observable = createEffect(() => this.actions$.pipe( ofType(AuthActionTypes.RETRIEVE_AUTHENTICATED_EPERSON), switchMap((action: RetrieveAuthenticatedEpersonAction) => { const impersonatedUserID = this.authService.getImpersonateID(); @@ -143,20 +143,20 @@ export class AuthEffects { map((user: EPerson) => new RetrieveAuthenticatedEpersonSuccessAction(user.id)), catchError((error) => observableOf(new RetrieveAuthenticatedEpersonErrorAction(error)))); }) - ); + )); - @Effect() - public checkToken$: Observable = this.actions$.pipe(ofType(AuthActionTypes.CHECK_AUTHENTICATION_TOKEN), + + public checkToken$: Observable = createEffect(() => this.actions$.pipe(ofType(AuthActionTypes.CHECK_AUTHENTICATION_TOKEN), switchMap(() => { return this.authService.hasValidAuthenticationToken().pipe( map((token: AuthTokenInfo) => new AuthenticatedAction(token)), catchError((error) => observableOf(new CheckAuthenticationTokenCookieAction())) ); }) - ); + )); - @Effect() - public checkTokenCookie$: Observable = this.actions$.pipe( + + public checkTokenCookie$: Observable = createEffect(() => this.actions$.pipe( ofType(AuthActionTypes.CHECK_AUTHENTICATION_TOKEN_COOKIE), switchMap(() => { return this.authService.checkAuthenticationCookie().pipe( @@ -171,10 +171,10 @@ export class AuthEffects { catchError((error) => observableOf(new AuthenticatedErrorAction(error))) ); }) - ); + )); - @Effect() - public retrieveToken$: Observable = this.actions$.pipe( + + public retrieveToken$: Observable = createEffect(() => this.actions$.pipe( ofType(AuthActionTypes.RETRIEVE_TOKEN), switchMap((action: AuthenticateAction) => { return this.authService.refreshAuthenticationToken(null).pipe( @@ -183,31 +183,31 @@ export class AuthEffects { catchError((error) => observableOf(new AuthenticationErrorAction(error))) ); }) - ); + )); - @Effect() - public refreshToken$: Observable = this.actions$.pipe(ofType(AuthActionTypes.REFRESH_TOKEN), + + public refreshToken$: Observable = createEffect(() => this.actions$.pipe(ofType(AuthActionTypes.REFRESH_TOKEN), switchMap((action: RefreshTokenAction) => { return this.authService.refreshAuthenticationToken(action.payload).pipe( map((token: AuthTokenInfo) => new RefreshTokenSuccessAction(token)), catchError((error) => observableOf(new RefreshTokenErrorAction())) ); }) - ); + )); // It means "reacts to this action but don't send another" - @Effect({ dispatch: false }) - public refreshTokenSuccess$: Observable = this.actions$.pipe( + + public refreshTokenSuccess$: Observable = createEffect(() => this.actions$.pipe( ofType(AuthActionTypes.REFRESH_TOKEN_SUCCESS), tap((action: RefreshTokenSuccessAction) => this.authService.replaceToken(action.payload)) - ); + ), { dispatch: false }); /** * When the store is rehydrated in the browser, * clear a possible invalid token or authentication errors */ - @Effect({ dispatch: false }) - public clearInvalidTokenOnRehydrate$: Observable = this.actions$.pipe( + + public clearInvalidTokenOnRehydrate$: Observable = createEffect(() => this.actions$.pipe( ofType(StoreActionTypes.REHYDRATE), switchMap(() => { const isLoaded$ = this.store.pipe(select(isAuthenticatedLoaded)); @@ -218,20 +218,20 @@ export class AuthEffects { tap(() => this.authService.removeToken()), tap(() => this.authService.resetAuthenticationError()) ); - })); + })), { dispatch: false }); /** * When the store is rehydrated in the browser, invalidate all cache hits regarding the * authorizations endpoint, to be sure to have consistent responses after a login with external idp * */ - @Effect({ dispatch: false }) invalidateAuthorizationsRequestCache$ = this.actions$ + invalidateAuthorizationsRequestCache$ = createEffect(() => this.actions$ .pipe(ofType(StoreActionTypes.REHYDRATE), tap(() => this.authorizationsService.invalidateAuthorizationsRequestCache()) - ); + ), { dispatch: false }); - @Effect() - public logOut$: Observable = this.actions$ + + public logOut$: Observable = createEffect(() => this.actions$ .pipe( ofType(AuthActionTypes.LOG_OUT), switchMap(() => { @@ -241,26 +241,26 @@ export class AuthEffects { catchError((error) => observableOf(new LogOutErrorAction(error))) ); }) - ); + )); - @Effect({ dispatch: false }) - public logOutSuccess$: Observable = this.actions$ + + public logOutSuccess$: Observable = createEffect(() => this.actions$ .pipe(ofType(AuthActionTypes.LOG_OUT_SUCCESS), tap(() => this.authService.removeToken()), tap(() => this.authService.clearRedirectUrl()), tap(() => this.authService.refreshAfterLogout()) - ); + ), { dispatch: false }); - @Effect({ dispatch: false }) - public redirectToLoginTokenExpired$: Observable = this.actions$ + + public redirectToLoginTokenExpired$: Observable = createEffect(() => this.actions$ .pipe( ofType(AuthActionTypes.REDIRECT_TOKEN_EXPIRED), tap(() => this.authService.removeToken()), tap(() => this.authService.redirectToLoginWhenTokenExpired()) - ); + ), { dispatch: false }); - @Effect() - public retrieveMethods$: Observable = this.actions$ + + public retrieveMethods$: Observable = createEffect(() => this.actions$ .pipe( ofType(AuthActionTypes.RETRIEVE_AUTH_METHODS), switchMap((action: RetrieveAuthMethodsAction) => { @@ -270,7 +270,7 @@ export class AuthEffects { catchError((error) => observableOf(new RetrieveAuthMethodsErrorAction())) ); }) - ); + )); /** * For any action that is not in {@link IDLE_TIMER_IGNORE_TYPES} that comes in => Start the idleness timer @@ -278,8 +278,8 @@ export class AuthEffects { * => Return the action to set the user as idle ({@link SetUserAsIdleAction}) * @method trackIdleness */ - @Effect() - public trackIdleness$: Observable = this.actions$.pipe( + + public trackIdleness$: Observable = createEffect(() => this.actions$.pipe( filter((action: Action) => !IDLE_TIMER_IGNORE_TYPES.includes(action.type)), // Using switchMap the effect will stop subscribing to the previous timer if a new action comes // in, and start a new timer @@ -290,7 +290,7 @@ export class AuthEffects { // Re-enter the zone to dispatch the action observeOn(new EnterZoneScheduler(this.zone, queueScheduler)), map(() => new SetUserAsIdleAction()), - ); + )); /** * @constructor diff --git a/src/app/core/cache/object-cache.effects.ts b/src/app/core/cache/object-cache.effects.ts index 2bd8ad0e3c..fa2bf6f690 100644 --- a/src/app/core/cache/object-cache.effects.ts +++ b/src/app/core/cache/object-cache.effects.ts @@ -1,6 +1,6 @@ import { map } from 'rxjs/operators'; import { Injectable } from '@angular/core'; -import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Actions, createEffect, ofType } from '@ngrx/effects'; import { StoreActionTypes } from '../../store.actions'; import { ResetObjectCacheTimestampsAction } from './object-cache.actions'; @@ -16,10 +16,10 @@ export class ObjectCacheEffects { * This assumes that the server cached everything a negligible * time ago, and will likely need to be revisited later */ - @Effect() fixTimestampsOnRehydrate = this.actions$ + fixTimestampsOnRehydrate = createEffect(() => this.actions$ .pipe(ofType(StoreActionTypes.REHYDRATE), map(() => new ResetObjectCacheTimestampsAction(new Date().getTime())) - ); + )); constructor(private actions$: Actions) { } diff --git a/src/app/core/cache/server-sync-buffer.effects.ts b/src/app/core/cache/server-sync-buffer.effects.ts index d8ed88e12c..be43f88099 100644 --- a/src/app/core/cache/server-sync-buffer.effects.ts +++ b/src/app/core/cache/server-sync-buffer.effects.ts @@ -1,6 +1,6 @@ import { delay, exhaustMap, map, switchMap, take } from 'rxjs/operators'; import { Injectable } from '@angular/core'; -import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Actions, createEffect, ofType } from '@ngrx/effects'; import { coreSelector } from '../core.selectors'; import { AddToSSBAction, @@ -32,7 +32,7 @@ export class ServerSyncBufferEffects { * Then dispatch a CommitSSBAction * When the delay is running, no new AddToSSBActions are processed in this effect */ - @Effect() setTimeoutForServerSync = this.actions$ + setTimeoutForServerSync = createEffect(() => this.actions$ .pipe( ofType(ServerSyncBufferActionTypes.ADD), exhaustMap((action: AddToSSBAction) => { @@ -42,7 +42,7 @@ export class ServerSyncBufferEffects { delay(timeoutInSeconds * 1000), ); }) - ); + )); /** * When a CommitSSBAction is dispatched @@ -50,7 +50,7 @@ export class ServerSyncBufferEffects { * When the list of actions is not empty, also dispatch an EmptySSBAction * When the list is empty dispatch a NO_ACTION placeholder action */ - @Effect() commitServerSyncBuffer = this.actions$ + commitServerSyncBuffer = createEffect(() => this.actions$ .pipe( ofType(ServerSyncBufferActionTypes.COMMIT), switchMap((action: CommitSSBAction) => { @@ -86,7 +86,7 @@ export class ServerSyncBufferEffects { }) ); }) - ); + )); /** * private method to create an ApplyPatchObjectCacheAction based on a cache entry diff --git a/src/app/core/data/object-updates/object-updates.effects.ts b/src/app/core/data/object-updates/object-updates.effects.ts index c9c3237ef5..1dfdc95f23 100644 --- a/src/app/core/data/object-updates/object-updates.effects.ts +++ b/src/app/core/data/object-updates/object-updates.effects.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Actions, createEffect, ofType } from '@ngrx/effects'; import { DiscardObjectUpdatesAction, ObjectUpdatesAction, @@ -52,7 +52,7 @@ export class ObjectUpdatesEffects { /** * Effect that makes sure all last fired ObjectUpdatesActions are stored in the map of this service, with the url as their key */ - @Effect({ dispatch: false }) mapLastActions$ = this.actions$ + mapLastActions$ = createEffect(() => this.actions$ .pipe( ofType(...Object.values(ObjectUpdatesActionTypes)), map((action: ObjectUpdatesAction) => { @@ -64,12 +64,12 @@ export class ObjectUpdatesEffects { this.actionMap$[url].next(action); } }) - ); + ), { dispatch: false }); /** * Effect that makes sure all last fired NotificationActions are stored in the notification map of this service, with the id as their key */ - @Effect({ dispatch: false }) mapLastNotificationActions$ = this.actions$ + mapLastNotificationActions$ = createEffect(() => this.actions$ .pipe( ofType(...Object.values(NotificationsActionTypes)), map((action: RemoveNotificationAction) => { @@ -80,7 +80,7 @@ export class ObjectUpdatesEffects { this.notificationActionMap$[id].next(action); } ) - ); + ), { dispatch: false }); /** * Effect that checks whether the removeAction's notification timeout ends before a user triggers another ObjectUpdatesAction @@ -88,7 +88,7 @@ export class ObjectUpdatesEffects { * When a REINSTATE action is fired during the timeout, a NO_ACTION action will be returned * When any other ObjectUpdatesAction is fired during the timeout, a RemoteObjectUpdatesAction will be returned */ - @Effect() removeAfterDiscardOrReinstateOnUndo$ = this.actions$ + removeAfterDiscardOrReinstateOnUndo$ = createEffect(() => this.actions$ .pipe( ofType(ObjectUpdatesActionTypes.DISCARD), switchMap((action: DiscardObjectUpdatesAction) => { @@ -134,7 +134,7 @@ export class ObjectUpdatesEffects { ); } ) - ); + )); constructor(private actions$: Actions, private notificationsService: NotificationsService) { diff --git a/src/app/core/data/request.effects.ts b/src/app/core/data/request.effects.ts index acac82afa5..5965430cc3 100644 --- a/src/app/core/data/request.effects.ts +++ b/src/app/core/data/request.effects.ts @@ -1,6 +1,6 @@ import { Injectable, Injector } from '@angular/core'; -import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Actions, createEffect, ofType } from '@ngrx/effects'; import { catchError, filter, map, mergeMap, take } from 'rxjs/operators'; import { hasValue, isNotEmpty } from '../../shared/empty.util'; @@ -24,7 +24,7 @@ import { ParsedResponse } from '../cache/response.models'; @Injectable() export class RequestEffects { - @Effect() execute = this.actions$.pipe( + execute = createEffect(() => this.actions$.pipe( ofType(RequestActionTypes.EXECUTE), mergeMap((action: RequestExecuteAction) => { return this.requestService.getByUUID(action.payload).pipe( @@ -53,7 +53,7 @@ export class RequestEffects { }) ); }) - ); + )); /** * When the store is rehydrated in the browser, set all cache @@ -63,10 +63,10 @@ export class RequestEffects { * This assumes that the server cached everything a negligible * time ago, and will likely need to be revisited later */ - @Effect() fixTimestampsOnRehydrate = this.actions$ + fixTimestampsOnRehydrate = createEffect(() => this.actions$ .pipe(ofType(StoreActionTypes.REHYDRATE), map(() => new ResetResponseTimestampsAction(new Date().getTime())) - ); + )); constructor( private actions$: Actions, diff --git a/src/app/core/index/index.effects.ts b/src/app/core/index/index.effects.ts index a1ab0b20a8..315bd4ecc6 100644 --- a/src/app/core/index/index.effects.ts +++ b/src/app/core/index/index.effects.ts @@ -1,6 +1,6 @@ import { filter, map, switchMap, take } from 'rxjs/operators'; import { Injectable } from '@angular/core'; -import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Actions, createEffect, ofType } from '@ngrx/effects'; import { AddToObjectCacheAction, @@ -24,7 +24,7 @@ import { NoOpAction } from '../../shared/ngrx/no-op.action'; @Injectable() export class UUIDIndexEffects { - @Effect() addObject$ = this.actions$ + addObject$ = createEffect(() => this.actions$ .pipe( ofType(ObjectCacheActionTypes.ADD), filter((action: AddToObjectCacheAction) => hasValue(action.payload.objectToCache.uuid)), @@ -35,13 +35,13 @@ export class UUIDIndexEffects { action.payload.objectToCache._links.self.href ); }) - ); + )); /** * Adds an alternative link to an object to the ALTERNATIVE_OBJECT_LINK index * When the self link of the objectToCache is not the same as the alternativeLink */ - @Effect() addAlternativeObjectLink$ = this.actions$ + addAlternativeObjectLink$ = createEffect(() => this.actions$ .pipe( ofType(ObjectCacheActionTypes.ADD), map((action: AddToObjectCacheAction) => { @@ -57,9 +57,9 @@ export class UUIDIndexEffects { return new NoOpAction(); } }) - ); + )); - @Effect() removeObject$ = this.actions$ + removeObject$ = createEffect(() => this.actions$ .pipe( ofType(ObjectCacheActionTypes.REMOVE), map((action: RemoveFromObjectCacheAction) => { @@ -68,9 +68,9 @@ export class UUIDIndexEffects { action.payload ); }) - ); + )); - @Effect() addRequest$ = this.actions$ + addRequest$ = createEffect(() => this.actions$ .pipe( ofType(RequestActionTypes.CONFIGURE), filter((action: RequestConfigureAction) => action.payload.method === RestRequestMethod.GET), @@ -95,7 +95,7 @@ export class UUIDIndexEffects { )]; return actions; }) - ); + )); constructor(private actions$: Actions, private store: Store) { diff --git a/src/app/core/json-patch/json-patch-operations.effects.ts b/src/app/core/json-patch/json-patch-operations.effects.ts index 3304db5b9e..3acfcba910 100644 --- a/src/app/core/json-patch/json-patch-operations.effects.ts +++ b/src/app/core/json-patch/json-patch-operations.effects.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { map } from 'rxjs/operators'; -import { Effect, Actions, ofType } from '@ngrx/effects'; +import { createEffect, Actions, ofType } from '@ngrx/effects'; import { CommitPatchOperationsAction, FlushPatchOperationsAction, @@ -17,11 +17,11 @@ export class JsonPatchOperationsEffects { /** * Dispatches a FlushPatchOperationsAction for every dispatched CommitPatchOperationsAction */ - @Effect() commit$ = this.actions$.pipe( + commit$ = createEffect(() => this.actions$.pipe( ofType(JsonPatchOperationsActionTypes.COMMIT_JSON_PATCH_OPERATIONS), map((action: CommitPatchOperationsAction) => { return new FlushPatchOperationsAction(action.payload.resourceType, action.payload.resourceId); - })); + }))); constructor(private actions$: Actions) {} diff --git a/src/app/core/router/router.effects.ts b/src/app/core/router/router.effects.ts index b19ff88fd5..c2e3155eff 100644 --- a/src/app/core/router/router.effects.ts +++ b/src/app/core/router/router.effects.ts @@ -1,6 +1,6 @@ import { filter, map, pairwise } from 'rxjs/operators'; import { Injectable } from '@angular/core'; -import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Actions, createEffect, ofType } from '@ngrx/effects'; import * as fromRouter from '@ngrx/router-store'; import { RouterNavigationAction } from '@ngrx/router-store'; import { Router } from '@angular/router'; @@ -12,7 +12,7 @@ export class RouterEffects { * Effect that fires a new RouteUpdateAction when then path of route is changed * @type {Observable} */ - @Effect() routeChange$ = this.actions$ + routeChange$ = createEffect(() => this.actions$ .pipe( ofType(fromRouter.ROUTER_NAVIGATION), pairwise(), @@ -23,7 +23,7 @@ export class RouterEffects { })), filter((actions: string[]) => actions[0] !== actions[1]), map(() => new RouteUpdateAction()) - ); + )); constructor(private actions$: Actions, private router: Router) { } diff --git a/src/app/core/services/route.effects.ts b/src/app/core/services/route.effects.ts index ace58e7bca..2b19761d21 100644 --- a/src/app/core/services/route.effects.ts +++ b/src/app/core/services/route.effects.ts @@ -1,6 +1,6 @@ import { map, tap } from 'rxjs/operators'; import { Injectable } from '@angular/core'; -import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Actions, createEffect, ofType } from '@ngrx/effects'; import { ResetRouteStateAction, RouteActionTypes } from './route.actions'; import { RouterActionTypes } from '../router/router.actions'; import { RouteService } from './route.service'; @@ -11,17 +11,17 @@ export class RouteEffects { * Effect that resets the route state on reroute * @type {Observable} */ - @Effect() routeChange$ = this.actions$ + routeChange$ = createEffect(() => this.actions$ .pipe( ofType(RouterActionTypes.ROUTE_UPDATE), map(() => new ResetRouteStateAction()), - ); + )); - @Effect({dispatch: false }) afterResetChange$ = this.actions$ + afterResetChange$ = createEffect(() => this.actions$ .pipe( ofType(RouteActionTypes.RESET), tap(() => this.service.setCurrentRouteInfo()), - ); + ), {dispatch: false }); constructor(private actions$: Actions, private service: RouteService) { } diff --git a/src/app/navbar/navbar.effects.ts b/src/app/navbar/navbar.effects.ts index 6cb11f21c0..4a6aa20caf 100644 --- a/src/app/navbar/navbar.effects.ts +++ b/src/app/navbar/navbar.effects.ts @@ -1,6 +1,6 @@ import { first, map, switchMap } from 'rxjs/operators'; import { Injectable } from '@angular/core'; -import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Actions, createEffect, ofType } from '@ngrx/effects'; import * as fromRouter from '@ngrx/router-store'; import { HostWindowActionTypes } from '../shared/host-window.actions'; @@ -21,26 +21,26 @@ export class NavbarEffects { * Effect that collapses the public menu on window resize * @type {Observable} */ - @Effect() resize$ = this.actions$ + resize$ = createEffect(() => this.actions$ .pipe( ofType(HostWindowActionTypes.RESIZE), map(() => new CollapseMenuAction(this.menuID)) - ); + )); /** * Effect that collapses the public menu on reroute * @type {Observable} */ - @Effect() routeChange$ = this.actions$ + routeChange$ = createEffect(() => this.actions$ .pipe( ofType(fromRouter.ROUTER_NAVIGATION), map(() => new CollapseMenuAction(this.menuID)) - ); + )); /** * Effect that collapses the public menu when the admin sidebar opens * @type {Observable} */ - @Effect() openAdminSidebar$ = this.actions$ + openAdminSidebar$ = createEffect(() => this.actions$ .pipe( ofType(MenuActionTypes.EXPAND_MENU_PREVIEW), switchMap((action: ExpandMenuPreviewAction) => { @@ -55,7 +55,7 @@ export class NavbarEffects { return new NoOpAction(); })); }) - ); + )); constructor(private actions$: Actions, private menuService: MenuService) { } diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/relationship.effects.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/relationship.effects.ts index a810cb0ad9..16a51d9991 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/relationship.effects.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/relationship.effects.ts @@ -1,5 +1,5 @@ import { Inject, Injectable } from '@angular/core'; -import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Actions, createEffect, ofType } from '@ngrx/effects'; import { filter, map, mergeMap, switchMap, take } from 'rxjs/operators'; import { BehaviorSubject, Observable } from 'rxjs'; import { RelationshipService } from '../../../../../core/data/relationship.service'; @@ -61,7 +61,7 @@ export class RelationshipEffects { /** * Effect that makes sure all last fired RelationshipActions' types are stored in the map of this service, with the object uuid as their key */ - @Effect({ dispatch: false }) mapLastActions$ = this.actions$ + mapLastActions$ = createEffect(() => this.actions$ .pipe( ofType(RelationshipActionTypes.ADD_RELATIONSHIP, RelationshipActionTypes.REMOVE_RELATIONSHIP), map((action: RelationshipAction) => { @@ -97,14 +97,14 @@ export class RelationshipEffects { } } ) - ); + ), { dispatch: false }); /** * Updates the namevariant in a relationship * If the relationship is currently being added or removed, it will add the name variant to an update map so it will be sent with the next add request instead * Otherwise the update is done immediately */ - @Effect({ dispatch: false }) updateNameVariantsActions$ = this.actions$ + updateNameVariantsActions$ = createEffect(() => this.actions$ .pipe( ofType(RelationshipActionTypes.UPDATE_NAME_VARIANT), map((action: UpdateRelationshipNameVariantAction) => { @@ -125,29 +125,29 @@ export class RelationshipEffects { } } ) - ); + ), { dispatch: false }); /** * Save the latest submission ID, to make sure it's updated when the patch is finished */ - @Effect({ dispatch: false }) updateRelationshipActions$ = this.actions$ + updateRelationshipActions$ = createEffect(() => this.actions$ .pipe( ofType(RelationshipActionTypes.UPDATE_RELATIONSHIP), map((action: UpdateRelationshipAction) => { this.updateAfterPatchSubmissionId = action.payload.submissionId; }) - ); + ), { dispatch: false }); /** * Save the submission object with ID updateAfterPatchSubmissionId */ - @Effect() saveSubmissionSection = this.actions$ + saveSubmissionSection = createEffect(() => this.actions$ .pipe( ofType(ServerSyncBufferActionTypes.EMPTY, JsonPatchOperationsActionTypes.COMMIT_JSON_PATCH_OPERATIONS), filter(() => hasValue(this.updateAfterPatchSubmissionId)), switchMap(() => this.refreshWorkspaceItemInCache(this.updateAfterPatchSubmissionId)), map((submissionObject) => new SaveSubmissionSectionFormSuccessAction(this.updateAfterPatchSubmissionId, [submissionObject], false)) - ); + )); constructor(private actions$: Actions, private relationshipService: RelationshipService, diff --git a/src/app/shared/menu/menu.effects.ts b/src/app/shared/menu/menu.effects.ts index 5eafad7a98..8baea9a374 100644 --- a/src/app/shared/menu/menu.effects.ts +++ b/src/app/shared/menu/menu.effects.ts @@ -1,7 +1,7 @@ import { ActivatedRoute } from '@angular/router'; import { MenuSection } from './menu.reducer'; import { hasNoValue, hasValue } from '../empty.util'; -import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Actions, createEffect, ofType } from '@ngrx/effects'; import { MenuService } from './menu.service'; import { Observable } from 'rxjs'; import { Action } from '@ngrx/store'; @@ -19,8 +19,8 @@ export class MenuEffects { /** * On route change, build menu sections for every menu type depending on the current route data */ - @Effect({ dispatch: false }) - public buildRouteMenuSections$: Observable = this.actions$ + + public buildRouteMenuSections$: Observable = createEffect(() => this.actions$ .pipe( ofType(ROUTER_NAVIGATED), tap(() => { @@ -28,7 +28,7 @@ export class MenuEffects { this.buildRouteMenuSections(menuID); }); }) - ); + ), { dispatch: false }); constructor(private actions$: Actions, private menuService: MenuService, diff --git a/src/app/shared/sidebar/sidebar-effects.service.ts b/src/app/shared/sidebar/sidebar-effects.service.ts index aaeef99c22..7bcff4ecd7 100644 --- a/src/app/shared/sidebar/sidebar-effects.service.ts +++ b/src/app/shared/sidebar/sidebar-effects.service.ts @@ -1,6 +1,6 @@ import { map, tap, filter } from 'rxjs/operators'; import { Injectable } from '@angular/core'; -import { Effect, Actions, ofType } from '@ngrx/effects'; +import { createEffect, Actions, ofType } from '@ngrx/effects'; import * as fromRouter from '@ngrx/router-store'; import { SidebarCollapseAction } from './sidebar.actions'; @@ -12,7 +12,7 @@ import { URLBaser } from '../../core/url-baser/url-baser'; @Injectable() export class SidebarEffects { private previousPath: string; - @Effect() routeChange$ = this.actions$ + routeChange$ = createEffect(() => this.actions$ .pipe( ofType(fromRouter.ROUTER_NAVIGATION), filter((action) => this.previousPath !== this.getBaseUrl(action)), @@ -20,7 +20,7 @@ export class SidebarEffects { this.previousPath = this.getBaseUrl(action); }), map(() => new SidebarCollapseAction()) - ); + )); constructor(private actions$: Actions) { diff --git a/src/app/store.effects.ts b/src/app/store.effects.ts index 4ea458f9a0..c7add76add 100644 --- a/src/app/store.effects.ts +++ b/src/app/store.effects.ts @@ -2,7 +2,7 @@ import { of as observableOf } from 'rxjs'; import { map } from 'rxjs/operators'; import { Injectable } from '@angular/core'; import { Action, Store } from '@ngrx/store'; -import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Actions, createEffect, ofType } from '@ngrx/effects'; import { AppState } from './app.reducer'; import { StoreActionTypes } from './store.actions'; @@ -11,7 +11,7 @@ import { HostWindowResizeAction } from './shared/host-window.actions'; @Injectable() export class StoreEffects { - @Effect({ dispatch: false }) replay = this.actions.pipe( + replay = createEffect(() => this.actions.pipe( ofType(StoreActionTypes.REPLAY), map((replayAction: Action) => { // TODO: should be able to replay all actions before the browser attempts to @@ -19,12 +19,12 @@ export class StoreEffects { // this.store.dispatch(action); // }); return observableOf({}); - })); + })), { dispatch: false }); - @Effect() resize = this.actions.pipe( + resize = createEffect(() => this.actions.pipe( ofType(StoreActionTypes.REPLAY, StoreActionTypes.REHYDRATE), map(() => new HostWindowResizeAction(window.innerWidth, window.innerHeight)) - ); + )); constructor(private actions: Actions, private store: Store) { diff --git a/src/app/submission/objects/submission-objects.effects.ts b/src/app/submission/objects/submission-objects.effects.ts index e8de418436..95028c0e49 100644 --- a/src/app/submission/objects/submission-objects.effects.ts +++ b/src/app/submission/objects/submission-objects.effects.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Actions, createEffect, ofType } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { TranslateService } from '@ngx-translate/core'; import { isEqual, union } from 'lodash'; @@ -58,7 +58,7 @@ export class SubmissionObjectEffects { /** * Dispatch a [InitSectionAction] for every submission sections and dispatch a [CompleteInitSubmissionFormAction] */ - @Effect() loadForm$ = this.actions$.pipe( + loadForm$ = createEffect(() => this.actions$.pipe( ofType(SubmissionObjectActionTypes.INIT_SUBMISSION_FORM), map((action: InitSubmissionFormAction) => { const definition = action.payload.submissionDefinition; @@ -97,12 +97,12 @@ export class SubmissionObjectEffects { result.mappedActions.concat( new CompleteInitSubmissionFormAction(result.action.payload.submissionId) )); - })); + }))); /** * Dispatch a [InitSubmissionFormAction] */ - @Effect() resetForm$ = this.actions$.pipe( + resetForm$ = createEffect(() => this.actions$.pipe( ofType(SubmissionObjectActionTypes.RESET_SUBMISSION_FORM), map((action: ResetSubmissionFormAction) => new InitSubmissionFormAction( @@ -113,12 +113,12 @@ export class SubmissionObjectEffects { action.payload.sections, action.payload.item, null - ))); + )))); /** * Dispatch a [SaveSubmissionFormSuccessAction] or a [SaveSubmissionFormErrorAction] on error */ - @Effect() saveSubmission$ = this.actions$.pipe( + saveSubmission$ = createEffect(() => this.actions$.pipe( ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM), switchMap((action: SaveSubmissionFormAction) => { return this.operationsService.jsonPatchByResourceType( @@ -127,12 +127,12 @@ export class SubmissionObjectEffects { 'sections').pipe( map((response: SubmissionObject[]) => new SaveSubmissionFormSuccessAction(action.payload.submissionId, response, action.payload.isManual)), catchError(() => observableOf(new SaveSubmissionFormErrorAction(action.payload.submissionId)))); - })); + }))); /** * Dispatch a [SaveForLaterSubmissionFormSuccessAction] or a [SaveSubmissionFormErrorAction] on error */ - @Effect() saveForLaterSubmission$ = this.actions$.pipe( + saveForLaterSubmission$ = createEffect(() => this.actions$.pipe( ofType(SubmissionObjectActionTypes.SAVE_FOR_LATER_SUBMISSION_FORM), switchMap((action: SaveForLaterSubmissionFormAction) => { return this.operationsService.jsonPatchByResourceType( @@ -141,37 +141,37 @@ export class SubmissionObjectEffects { 'sections').pipe( map((response: SubmissionObject[]) => new SaveForLaterSubmissionFormSuccessAction(action.payload.submissionId, response)), catchError(() => observableOf(new SaveSubmissionFormErrorAction(action.payload.submissionId)))); - })); + }))); /** * Call parseSaveResponse and dispatch actions */ - @Effect() saveSubmissionSuccess$ = this.actions$.pipe( + saveSubmissionSuccess$ = createEffect(() => this.actions$.pipe( ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM_SUCCESS), withLatestFrom(this.store$), map(([action, currentState]: [SaveSubmissionFormSuccessAction, any]) => { return this.parseSaveResponse((currentState.submission as SubmissionState).objects[action.payload.submissionId], action.payload.submissionObject, action.payload.submissionId, currentState.forms, action.payload.notify); }), - mergeMap((actions) => observableFrom(actions))); + mergeMap((actions) => observableFrom(actions)))); /** * Call parseSaveResponse and dispatch actions. * Notification system is forced to be disabled. */ - @Effect() saveSubmissionSectionSuccess$ = this.actions$.pipe( + saveSubmissionSectionSuccess$ = createEffect(() => this.actions$.pipe( ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM_SUCCESS), withLatestFrom(this.store$), map(([action, currentState]: [SaveSubmissionSectionFormSuccessAction, any]) => { return this.parseSaveResponse((currentState.submission as SubmissionState).objects[action.payload.submissionId], action.payload.submissionObject, action.payload.submissionId, currentState.forms, false); }), - mergeMap((actions) => observableFrom(actions))); + mergeMap((actions) => observableFrom(actions)))); /** * Dispatch a [SaveSubmissionSectionFormSuccessAction] or a [SaveSubmissionSectionFormErrorAction] on error */ - @Effect() saveSection$ = this.actions$.pipe( + saveSection$ = createEffect(() => this.actions$.pipe( ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM), switchMap((action: SaveSubmissionSectionFormAction) => { return this.operationsService.jsonPatchByResourceID( @@ -181,20 +181,20 @@ export class SubmissionObjectEffects { action.payload.sectionId).pipe( map((response: SubmissionObject[]) => new SaveSubmissionSectionFormSuccessAction(action.payload.submissionId, response)), catchError(() => observableOf(new SaveSubmissionSectionFormErrorAction(action.payload.submissionId)))); - })); + }))); /** * Show a notification on error */ - @Effect({ dispatch: false }) saveError$ = this.actions$.pipe( + saveError$ = createEffect(() => this.actions$.pipe( ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM_ERROR, SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM_ERROR), withLatestFrom(this.store$), - tap(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.save_error_notice')))); + tap(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.save_error_notice')))), { dispatch: false }); /** * Call parseSaveResponse and dispatch actions or dispatch [SaveSubmissionFormErrorAction] on error */ - @Effect() saveAndDeposit$ = this.actions$.pipe( + saveAndDeposit$ = createEffect(() => this.actions$.pipe( ofType(SubmissionObjectActionTypes.SAVE_AND_DEPOSIT_SUBMISSION), withLatestFrom(this.submissionService.hasUnsavedModification()), switchMap(([action, hasUnsavedModification]: [SaveAndDepositSubmissionAction, boolean]) => { @@ -219,58 +219,58 @@ export class SubmissionObjectEffects { } }), catchError(() => observableOf(new SaveSubmissionFormErrorAction(action.payload.submissionId)))); - })); + }))); /** * Dispatch a [DepositSubmissionSuccessAction] or a [DepositSubmissionErrorAction] on error */ - @Effect() depositSubmission$ = this.actions$.pipe( + depositSubmission$ = createEffect(() => this.actions$.pipe( ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION), withLatestFrom(this.store$), switchMap(([action, state]: [DepositSubmissionAction, any]) => { return this.submissionService.depositSubmission(state.submission.objects[action.payload.submissionId].selfUrl).pipe( map(() => new DepositSubmissionSuccessAction(action.payload.submissionId)), catchError((error) => observableOf(new DepositSubmissionErrorAction(action.payload.submissionId)))); - })); + }))); /** * Show a notification on success and redirect to MyDSpace page */ - @Effect({ dispatch: false }) saveForLaterSubmissionSuccess$ = this.actions$.pipe( + saveForLaterSubmissionSuccess$ = createEffect(() => this.actions$.pipe( ofType(SubmissionObjectActionTypes.SAVE_FOR_LATER_SUBMISSION_FORM_SUCCESS), tap(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.save_success_notice'))), - tap(() => this.submissionService.redirectToMyDSpace())); + tap(() => this.submissionService.redirectToMyDSpace())), { dispatch: false }); /** * Show a notification on success and redirect to MyDSpace page */ - @Effect({ dispatch: false }) depositSubmissionSuccess$ = this.actions$.pipe( + depositSubmissionSuccess$ = createEffect(() => this.actions$.pipe( ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION_SUCCESS), tap(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.deposit_success_notice'))), - tap(() => this.submissionService.redirectToMyDSpace())); + tap(() => this.submissionService.redirectToMyDSpace())), { dispatch: false }); /** * Show a notification on error */ - @Effect({ dispatch: false }) depositSubmissionError$ = this.actions$.pipe( + depositSubmissionError$ = createEffect(() => this.actions$.pipe( ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION_ERROR), - tap(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.deposit_error_notice')))); + tap(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.deposit_error_notice')))), { dispatch: false }); /** * Dispatch a [DiscardSubmissionSuccessAction] or a [DiscardSubmissionErrorAction] on error */ - @Effect() discardSubmission$ = this.actions$.pipe( + discardSubmission$ = createEffect(() => this.actions$.pipe( ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION), switchMap((action: DepositSubmissionAction) => { return this.submissionService.discardSubmission(action.payload.submissionId).pipe( map(() => new DiscardSubmissionSuccessAction(action.payload.submissionId)), catchError(() => observableOf(new DiscardSubmissionErrorAction(action.payload.submissionId)))); - })); + }))); /** * Adds all metadata an item to the SubmissionForm sections of the submission */ - @Effect() addAllMetadataToSectionData = this.actions$.pipe( + addAllMetadataToSectionData = createEffect(() => this.actions$.pipe( ofType(SubmissionObjectActionTypes.UPDATE_SECTION_DATA), switchMap((action: UpdateSectionDataAction) => { return this.sectionService.getSectionState(action.payload.submissionId, action.payload.sectionId, SectionsType.Upload) @@ -298,23 +298,23 @@ export class SubmissionObjectEffects { return observableOf(new UpdateSectionDataSuccessAction()); } }), - ); + )); /** * Show a notification on success and redirect to MyDSpace page */ - @Effect({ dispatch: false }) - discardSubmissionSuccess$ = this.actions$.pipe( + + discardSubmissionSuccess$ = createEffect(() => this.actions$.pipe( ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION_SUCCESS), tap(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.discard_success_notice'))), - tap(() => this.submissionService.redirectToMyDSpace())); + tap(() => this.submissionService.redirectToMyDSpace())), { dispatch: false }); /** * Show a notification on error */ - @Effect({ dispatch: false }) discardSubmissionError$ = this.actions$.pipe( + discardSubmissionError$ = createEffect(() => this.actions$.pipe( ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION_ERROR), - tap(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.discard_error_notice')))); + tap(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.discard_error_notice')))), { dispatch: false }); constructor(private actions$: Actions, private notificationsService: NotificationsService, diff --git a/yarn.lock b/yarn.lock index 014004ec9d..af1fa602c9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1582,31 +1582,31 @@ dependencies: tslib "^2.0.0" -"@ngrx/effects@^12.5.1": - version "12.5.1" - resolved "https://registry.yarnpkg.com/@ngrx/effects/-/effects-12.5.1.tgz#acd0ff86d8db514e47337508dde83cc98f7a3416" - integrity sha512-fVNGIIntYLRWW1XWe0os2XOv03L22S4WTkX0OPZ9O6ztwuaNq0yzxWN7UeAC6H385F+g0k76KwRV78zHyP0bfQ== +"@ngrx/effects@^13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@ngrx/effects/-/effects-13.0.2.tgz#785e54459efaef70ed3754a33d9f4ddd0ff9f033" + integrity sha512-7yW/KCxlRatDkdEriSnORlOYX8+1QAWEjPulNmHSPwehkzTQ3fIPfRBQy8xP8bnjwvGxnEZNwQlU4q1KVYOfhg== dependencies: tslib "^2.0.0" -"@ngrx/router-store@^12.5.1": - version "12.5.1" - resolved "https://registry.yarnpkg.com/@ngrx/router-store/-/router-store-12.5.1.tgz#006e9a05a81a6238b408dfb2de3aeb9a5b8f61e4" - integrity sha512-F3D4lo0HCvzcNUZlMcpkBQOU4dQyqLwFvJBgNetIFT376aPp+LOy7m3gAT4BMRRx6dM0zj9Gosubyc+/DoOymA== +"@ngrx/router-store@^13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@ngrx/router-store/-/router-store-13.0.2.tgz#e57084cd74071760378645417bba94805c8b4514" + integrity sha512-XrzHjrD2hhnXdGeIpQm/msN77hoAL/QD3ZYGFJs3yT5d3x/T3L1JFlra7wC0OlKJkOs6zAh5Kz9cJ94YO/TEtQ== dependencies: tslib "^2.0.0" -"@ngrx/store-devtools@^12.5.1": - version "12.5.1" - resolved "https://registry.yarnpkg.com/@ngrx/store-devtools/-/store-devtools-12.5.1.tgz#75f8ef9a4bf4a40d5343ff437651f0f3092914b5" - integrity sha512-SXMxVO3KzQUfB9G20gdNT5t/RcbtbaUySXLuH+b69z/eb34wH9AOYifdSdcEi8oqPjDrWYBq6a8Uh+yDHf9IfA== +"@ngrx/store-devtools@^13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@ngrx/store-devtools/-/store-devtools-13.0.2.tgz#2b412fe47894fbb0c2aec8c1402f150bc139d5e9" + integrity sha512-fcQ5A7cv9PONFvqlpFPXHswWjEflJvqrNt6wmywlxMtJDjkgzCHpvRiJqup/FiTosblRERoeZXN0oHW3Er3+rw== dependencies: tslib "^2.0.0" -"@ngrx/store@^12.5.1": - version "12.5.1" - resolved "https://registry.yarnpkg.com/@ngrx/store/-/store-12.5.1.tgz#a7c21d7df1d017d2cb7e77804b210cc14bcf8786" - integrity sha512-NLVkHLVeZc7IboXSDZlFoq1QrupmwYTYKRHS6se7ZasAv/lrIjHWsVVdICKSVRBsHZYu3+dmCXmu+YgulP7iHw== +"@ngrx/store@^13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@ngrx/store/-/store-13.0.2.tgz#43f187956e07f33baed3e6215cd2fc59a06e9789" + integrity sha512-F7tsc3oCvKh+62MKiXTrvSeaxR41u4p8bch3BLjz12F37376rMuBnXf+V1thsPTZ6RB6aycAi821EQYVXFCXZg== dependencies: tslib "^2.0.0"