UNPKG

@rx-angular/cdk

Version:

@rx-angular/cdk is a Component Development Kit for ergonomic and highly performant angular applications. It helps to to build Large scale applications, UI libs, state management, rendering systems and much more. Furthermore the unique way of mixing reacti

1 lines 15 kB
{"version":3,"file":"cdk-notifications.mjs","sources":["../../../../libs/cdk/notifications/src/lib/notification-transforms.ts","../../../../libs/cdk/notifications/src/lib/rx-materialize.ts","../../../../libs/cdk/notifications/src/lib/create-template-notifier.ts","../../../../libs/cdk/notifications/src/lib/template-trigger-handling.ts","../../../../libs/cdk/notifications/src/cdk-notifications.ts"],"sourcesContent":["import {\n RxCompleteNotification,\n RxErrorNotification,\n RxNotificationKind,\n RxSuspenseNotification,\n} from './model';\n\nexport function toRxErrorNotification<T>(\n error?: any,\n value?: T\n): RxErrorNotification<T> {\n return {\n value,\n kind: RxNotificationKind.Error,\n hasValue: !!value || false,\n complete: false,\n error: error || true,\n };\n}\n\nexport function toRxSuspenseNotification<T>(\n value?: T\n): RxSuspenseNotification<T> {\n return {\n value,\n kind: RxNotificationKind.Suspense,\n hasValue: !!value || false,\n complete: false,\n error: false,\n };\n}\n\nexport function toRxCompleteNotification<T>(\n value?: T\n): RxCompleteNotification<T> {\n return {\n value,\n kind: RxNotificationKind.Complete,\n hasValue: !!value || false,\n complete: true,\n error: false,\n };\n}\n","import { Notification, OperatorFunction } from 'rxjs';\nimport { map, materialize, tap } from 'rxjs/operators';\nimport { RxNotification, RxNotificationKind } from './model';\n\nexport function rxMaterialize<T>(): OperatorFunction<T, RxNotification<T>> {\n return (o$) =>\n o$.pipe(\n materialize(),\n tap(({ kind, error }) => {\n // As we dont want to just swallow errors we log them here\n if (kind === 'E') {\n console.error(error);\n }\n }),\n map(({ value, error, kind, hasValue }) => {\n const rxNotificationKind = notificationKindToRxNotificationKind(kind);\n return {\n value,\n hasValue,\n error,\n kind: rxNotificationKind,\n complete: rxNotificationKind === RxNotificationKind.Complete,\n };\n })\n );\n}\n\n/**\n * @internal\n *\n * @description\n * This function is here to turn RxJS notification kind values into RxNotification kind names.\n * The main reason for the naming is the RxNotification kind values map directly to the default\n * template names (`suspense`, `next`, `error` `complete`) in the directives of the template package\n */\nexport function notificationKindToRxNotificationKind(\n kind: Notification<unknown>['kind']\n): RxNotificationKind {\n switch (kind) {\n case 'C':\n return RxNotificationKind.Complete;\n case 'E':\n return RxNotificationKind.Error;\n case 'N':\n default:\n return RxNotificationKind.Next;\n }\n}\n","import {\n from,\n isObservable,\n NEVER,\n Observable,\n ObservableInput,\n ReplaySubject,\n Subscribable,\n} from 'rxjs';\nimport {\n distinctUntilChanged,\n map,\n startWith,\n switchMap,\n tap,\n} from 'rxjs/operators';\nimport { RxNotification, RxNotificationKind } from './model';\nimport { toRxSuspenseNotification } from './notification-transforms';\nimport { rxMaterialize } from './rx-materialize';\n\n/**\n * @description\n * Sends value and an initial `undefined` as value With a NEVER.\n * This is needed to render the suspense template and avoid completing (and render the complete template).\n * @param value\n */\nconst emitAndDontComplete = (value) => NEVER.pipe(startWith(value));\n\n/**\n * This helper is responsible for turning a stream of materialized notifications\n * (next error, complete as object in the next stream) into an enriched version with an additional suspense\n * notification type.\n *\n * If a notification enters and is of type next we store tne value of `notification.next` as last value emitted.\n * This value is important in the template to show an e.g. error and also have access to the last emitted value of\n * next.\n * The value can be very useful in error or complete messages or to display the old value overlays by a loading spinner\n * in case of the suspense state.\n *\n * If a notification of kind `next` enters and its value is undefined we turn it into a suspense notification\n * If a notification of kind `error`, `complete`, `suspense` enters we take the last value from of a next notification\n * and assign it as new value to the notification\n */\nconst handleSuspenseAndLastValueInNotifications = <T>() => {\n // Used to store the last value per handleSuspenseAndLastValueInNotifications call\n let latestNextValue: T;\n\n // returns a projection function with a lastValue cache\n return (notification: RxNotification<T>): RxNotification<T> => {\n // if it is the notification is of type next we take its value\n // otherwise we keep the existing last value\n if (notification.kind === RxNotificationKind.Next) {\n latestNextValue = notification.value;\n }\n\n // If a next notification enters with a value of undefined we turn it into a suspense notification\n if (\n notification.kind === RxNotificationKind.Next &&\n notification.value === undefined\n ) {\n return toRxSuspenseNotification(undefined) as RxNotification<T>;\n }\n\n // If a Notification of type error, complete or suspense enters we assign the latest last value to them.\n // This is needed to access the old value in case of error or complete.\n // Next notifications will pass as they are.\n if (\n notification.kind === RxNotificationKind.Error ||\n notification.kind === RxNotificationKind.Complete ||\n notification.kind === RxNotificationKind.Suspense\n ) {\n notification.value = latestNextValue;\n }\n\n return notification as RxNotification<T>;\n };\n};\n\n/**\n * @internal\n *\n * @description\n * This factory function returns an object that can be driven imperatively over a `next` method.\n * Internally it prepares the incoming values for rendering by turning them into \"template notifications\",\n * an extended `ObservableNotification` object used to determine the respective template for values, errors, completing\n * or suspense states.\n *\n * Internally it handles different edge cases for initial emits. This helps to have or template creation lazy.\n * Also it maps any Observable to RxNotifications. These notifications are bound to the view later and handle the\n * display of the default template as well as the suspense, error, complete templates.\n */\nexport function createTemplateNotifier<U>(): {\n values$: Observable<RxNotification<U>>;\n next(observable: ObservableInput<U> | U | Subscribable<U>): void;\n withInitialSuspense(withInitialSuspense: boolean): void;\n} {\n // A Subject driven from the outside, it can contain Observables, static values null and undefined on purpose of from unassigned properties\n const observablesSubject = new ReplaySubject<\n ObservableInput<U> | U | Subscribable<U>\n >(1);\n\n let emittedValueOnce = false;\n\n const values$ = observablesSubject.pipe(\n distinctUntilChanged(),\n // handle static values inc null assignment and new Observable or Promises\n map((observable$): ObservableInput<U> | U => {\n if (isObservableInput<U>(observable$)) {\n return skipSuspenseIfHasValue(observable$);\n } else if (isSubscribableInput<U>(observable$)) {\n return skipSuspenseIfHasValue(mapSubscribableToObservable(observable$));\n } else if (!emittedValueOnce && observable$ === undefined) {\n return NEVER;\n }\n return emitAndDontComplete(observable$);\n }),\n switchMap((o: Observable<U>) => {\n return o.pipe(\n tap(() => (emittedValueOnce = true)),\n distinctUntilChanged(),\n rxMaterialize(),\n map(handleSuspenseAndLastValueInNotifications<U>()),\n );\n }),\n );\n\n return {\n next(observable: ObservableInput<U> | U | Subscribable<U>) {\n observablesSubject.next(observable);\n },\n withInitialSuspense(withInitialSuspense: boolean) {\n emittedValueOnce = emittedValueOnce || withInitialSuspense;\n },\n values$,\n };\n\n /**\n * @description\n * returns an observable that starts with an undefined value in case the input\n * observable$ does not emit a value immediately.\n * This is needed in order to skip the suspense template when we already know\n * there will be a next template rendered afterwards\n * @param observable$\n */\n function skipSuspenseIfHasValue<T>(\n observable$: ObservableInput<T>,\n ): Observable<T> {\n return new Observable((subscriber) => {\n let startWithUndefined = true;\n const inner = from(observable$).subscribe({\n next: (v) => {\n startWithUndefined = false;\n subscriber.next(v);\n },\n error: (e) => {\n startWithUndefined = false;\n subscriber.error(e);\n },\n complete: () => subscriber.complete(),\n });\n if (emittedValueOnce && startWithUndefined) {\n subscriber.next(undefined);\n }\n return () => {\n inner.unsubscribe();\n };\n });\n }\n}\n\nfunction isObservableInput<T>(input: unknown): input is ObservableInput<T> {\n return (\n typeof (input as Promise<T>)?.then === 'function' || isObservable(input)\n );\n}\n\nfunction isSubscribableInput<T>(input: unknown): input is Subscribable<T> {\n return typeof (input as Subscribable<T>)?.subscribe === 'function';\n}\n\nfunction mapSubscribableToObservable<T>(input: Subscribable<T>): Observable<T> {\n return new Observable<T>((subscriber) => {\n const sub = input.subscribe({ next: (value) => subscriber.next(value) });\n return () => {\n sub.unsubscribe();\n };\n });\n}\n","import { coerceAllFactory } from '@rx-angular/cdk/coercing';\nimport { Observable, Subject } from 'rxjs';\nimport { mergeAll, share } from 'rxjs/operators';\nimport { RxNotification } from './model';\n\n/**\n * @internal\n *\n * A factory function returning an object to handle the process of switching templates by Notification channel.\n * You can next a Observable of `RxNotification` multiple times and merge them into the Observable exposed under `trigger$`\n *\n */\nexport function templateTriggerHandling<T>(): {\n trigger$: Observable<RxNotification<T>>;\n next(templateName: Observable<RxNotification<T>>): void;\n} {\n const hotFlattened = coerceAllFactory(\n () => new Subject<Observable<RxNotification<T> | RxNotification<T>>>(),\n mergeAll()\n );\n return {\n next(templateName: Observable<RxNotification<T> | RxNotification<T>>) {\n hotFlattened.next(templateName);\n },\n trigger$: hotFlattened.values$.pipe(share()),\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}