@rxap/data-source
Version:
Provides a set of classes and decorators for creating and managing data sources in Angular applications, including base classes, static data sources, observable data sources, and method data sources. It also includes a component for displaying data source
656 lines (642 loc) • 29.7 kB
JavaScript
import { NgIf, JsonPipe } from '@angular/common';
import * as i0 from '@angular/core';
import { signal, Component, ChangeDetectionStrategy, Inject, Input, isDevMode, Injectable, Optional, InjectionToken } from '@angular/core';
import * as i1 from '@angular/material/button';
import { MatButtonModule } from '@angular/material/button';
import * as i2 from '@angular/material/progress-spinner';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { IsNotReleaseVersion, RXAP_ENVIRONMENT } from '@rxap/environment';
import * as i1$1 from 'rxjs';
import { Subscription, Observable, Subject, EMPTY, ReplaySubject, firstValueFrom, from, isObservable } from 'rxjs';
import { BaseDefinition, RXAP_DEFINITION_METADATA, DefinitionMetadata, DefinitionLoader } from '@rxap/definition';
import { ToggleSubject, CloneObservable } from '@rxap/rxjs';
import { clone, GenerateRandomString, deepMerge, RxapError, isPromiseLike, isPromise } from '@rxap/utilities';
import { tap, finalize, takeUntil, startWith, take, switchMap, map } from 'rxjs/operators';
import { ToMethod } from '@rxap/pattern';
class DataSourceErrorComponent {
set dataSourceLike(value) {
this.refresh ??= value.refresh;
this.retry ??= value.retry;
this.reset ??= value.reset;
this.loading ??= value.loading ?? value.loading$;
this.error ??= value.error ?? value.error$;
}
constructor(environment) {
this.environment = environment;
this.isNotRelease = false;
this.errorMessage = signal('Unknown Error');
this.retryInProgress = signal(false);
this.resetInProgress = signal(false);
this.isNotRelease = IsNotReleaseVersion(environment);
}
ngOnChanges(changes) {
if (changes['error']) {
this.retryInProgress.set(false);
this.resetInProgress.set(false);
}
if (changes['loading']) {
if (!changes['loading'].currentValue && typeof changes['loading'].currentValue === 'boolean') {
this.retryInProgress.set(false);
this.resetInProgress.set(false);
}
}
}
ngOnDestroy() {
this._subscription?.unsubscribe();
}
ngOnInit() {
this._subscription = new Subscription();
if (this.loading instanceof Observable) {
this._subscription.add(this.loading.subscribe((loading) => {
if (!loading) {
if (this.retryInProgress()) {
this.retryInProgress.set(false);
}
if (this.resetInProgress()) {
this.resetInProgress.set(false);
}
}
}));
}
if (this.error instanceof Observable) {
this._subscription.add(this.error.subscribe((error) => {
if (error) {
this.errorMessage.set(error.message);
}
}));
}
}
triggerRetry() {
if (this.retry) {
this.retryInProgress.set(true);
this.retry();
}
else if (this.refresh) {
this.retryInProgress.set(true);
this.refresh();
}
}
triggerReset() {
if (this.reset) {
this.resetInProgress.set(true);
this.reset();
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: DataSourceErrorComponent, deps: [{ token: RXAP_ENVIRONMENT }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.16", type: DataSourceErrorComponent, isStandalone: true, selector: "rxap-data-source-error", inputs: { error: "error", refresh: "refresh", retry: "retry", reset: "reset", dataSourceLike: "dataSourceLike", loading: "loading" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"p-10 w-full\">\n <div class=\"flex flex-col justify-center items-center gap-8\">\n <span i18n>Something has gone wrong!</span>\n <div class=\"flex flex-row justify-center items-center gap-4\">\n <button *ngIf=\"refresh || retry\" type=\"button\" (click)=\"triggerRetry()\" [disabled]=\"retryInProgress() || resetInProgress()\" mat-stroked-button>\n <span class=\"flex flex-row items-center gap-4\">\n <span i18n>Retry</span>\n <mat-spinner *ngIf=\"retryInProgress()\" [diameter]=\"15\"></mat-spinner>\n </span>\n </button>\n <button *ngIf=\"reset\" type=\"button\" (click)=\"triggerReset()\" [disabled]=\"resetInProgress() || retryInProgress()\" mat-stroked-button>\n <span class=\"flex flex-row items-center gap-4\">\n <span i18n>Reset</span>\n <mat-spinner *ngIf=\"resetInProgress()\" [diameter]=\"15\"></mat-spinner>\n </span>\n </button>\n </div>\n <span *ngIf=\"isNotRelease\" class=\"text-red-700\">{{errorMessage()}}</span>\n </div>\n</div>\n", styles: [".container{padding:64px;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i2.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: DataSourceErrorComponent, decorators: [{
type: Component,
args: [{ selector: 'rxap-data-source-error', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
MatButtonModule,
NgIf,
MatProgressSpinnerModule,
JsonPipe,
], template: "<div class=\"p-10 w-full\">\n <div class=\"flex flex-col justify-center items-center gap-8\">\n <span i18n>Something has gone wrong!</span>\n <div class=\"flex flex-row justify-center items-center gap-4\">\n <button *ngIf=\"refresh || retry\" type=\"button\" (click)=\"triggerRetry()\" [disabled]=\"retryInProgress() || resetInProgress()\" mat-stroked-button>\n <span class=\"flex flex-row items-center gap-4\">\n <span i18n>Retry</span>\n <mat-spinner *ngIf=\"retryInProgress()\" [diameter]=\"15\"></mat-spinner>\n </span>\n </button>\n <button *ngIf=\"reset\" type=\"button\" (click)=\"triggerReset()\" [disabled]=\"resetInProgress() || retryInProgress()\" mat-stroked-button>\n <span class=\"flex flex-row items-center gap-4\">\n <span i18n>Reset</span>\n <mat-spinner *ngIf=\"resetInProgress()\" [diameter]=\"15\"></mat-spinner>\n </span>\n </button>\n </div>\n <span *ngIf=\"isNotRelease\" class=\"text-red-700\">{{errorMessage()}}</span>\n </div>\n</div>\n", styles: [".container{padding:64px;width:100%}\n"] }]
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Inject,
args: [RXAP_ENVIRONMENT]
}] }], propDecorators: { error: [{
type: Input
}], refresh: [{
type: Input
}], retry: [{
type: Input
}], reset: [{
type: Input
}], dataSourceLike: [{
type: Input
}], loading: [{
type: Input
}] } });
class BaseDataSource extends BaseDefinition {
get lastRefreshed() {
return this._lastRefreshed;
}
constructor(metadata = null) {
super(metadata);
this.change$ = new Subject();
/**
* Indicates weather the data source is currently loading new data
*/
this.loading$ = EMPTY;
this.hasError$ = new ToggleSubject();
this.error$ = new ReplaySubject(1);
this._lastRefreshed = null;
this._connectedViewer = new Map();
this._connectedViewerTeardown = new Map();
this._data$ = EMPTY;
/**
* a map of viewer to view id.
* Allows to create a view id from the viewer object reference
* @protected
*/
this._viewerIds = new Map();
this._retry$ = new Subject();
}
get data() {
return clone(this._data);
}
get hasConnections() {
return this._connectedViewer.size > 0;
}
getViewerId(viewer) {
if (viewer.id) {
return viewer.id;
}
if (!this._viewerIds.has(viewer)) {
this._viewerIds.set(viewer, GenerateRandomString());
}
return this._viewerIds.get(viewer);
}
connect(viewerOrString) {
let viewer;
if (typeof viewerOrString === 'string') {
viewer = { id: viewerOrString };
}
else {
viewer = viewerOrString;
}
if (!viewer.id) {
viewer.id = this.getViewerId(viewer);
}
if (this.isConnected(viewer)) {
return this._connectedViewer.get(viewer.id);
}
if (!viewer.viewChange) {
viewer.viewChange = EMPTY;
}
const _connection = this._connect(viewer);
let connection;
let teardownLogic = null;
if (Array.isArray(_connection)) {
if (_connection.length !== 2) {
throw new Error('if this._connect returns an array. The array should have two items');
}
connection = _connection[0];
teardownLogic = _connection[1];
}
else {
connection = _connection;
}
const destroy$ = new Subject();
const cacheKey = ['rxap', 'data-source', this.constructor.name, this.id].join('_');
const restore = viewer.restore ?? this.metadata.restore ?? false;
connection = connection.pipe(tap((data) => {
this._data = data;
if (restore) {
try {
const cache = JSON.stringify(data);
localStorage.setItem(cacheKey, cache);
}
catch (e) {
console.warn(`Failed to store data source '${this.id}' data in local storage`);
}
}
}), tap((data) => this.change$.next(data)), tap(() => this._lastRefreshed = new Date()), finalize(() => this.disconnect(viewer)), takeUntil(destroy$));
if (restore) {
const data = localStorage.getItem(cacheKey);
if (data) {
this._data = JSON.parse(data);
connection = connection.pipe(startWith(this._data));
}
}
this._connectedViewer.set(viewer.id, connection);
if (teardownLogic) {
const tl = teardownLogic;
teardownLogic = () => {
destroy$.next();
if (typeof tl === 'function') {
tl();
}
else {
tl.unsubscribe();
}
};
}
else {
teardownLogic = () => {
destroy$.next();
};
}
this._connectedViewerTeardown.set(viewer.id, teardownLogic);
return connection;
}
attach(viewerId) {
if (this.isConnected(viewerId)) {
return CloneObservable(this._connectedViewer.get(viewerId));
}
throw new Error(`No active connection with viewer id '${viewerId}' found`);
}
isConnected(viewerOrId) {
const viewerId = typeof viewerOrId === 'string'
? viewerOrId
: viewerOrId.id ?? this.getViewerId(viewerOrId);
return this._connectedViewer.has(viewerId);
}
disconnect(viewerOrId) {
const viewerId = typeof viewerOrId === 'string'
? viewerOrId
: viewerOrId.id ?? this.getViewerId(viewerOrId);
if (this.isConnected(viewerId)) {
this._disconnect(viewerId);
this._connectedViewer.delete(viewerId);
if (this._connectedViewerTeardown.has(viewerId)) {
const teardownLogic = this._connectedViewerTeardown.get(viewerId);
if (teardownLogic) {
if (typeof teardownLogic === 'function') {
teardownLogic();
}
else {
teardownLogic.unsubscribe();
}
}
}
}
else {
console.debug(`Connection with viewer id '${viewerId}' is not connected to the data source '${this.id}'`);
}
// TODO : find better cleanup solution
if (typeof viewerOrId === 'string') {
for (const [viewer, id] of this._viewerIds.entries()) {
if (viewerOrId === id) {
this._viewerIds.delete(viewer);
}
}
}
else {
this._viewerIds.delete(viewerOrId);
}
}
/**
* Creates a connection to tha data source and converts the Observable into a
* promise and then disconnects the viewer
*/
async toPromise(viewer) {
const result = await firstValueFrom(this.connect(viewer).pipe(take(1)));
this.disconnect(viewer);
return result;
}
derive(id, metadata = this.metadata) {
return new BaseDataSource({
...deepMerge(this.metadata, metadata),
id,
});
}
toJSON() {
return {
id: this.id,
metadata: this.metadata,
connected: this._connectedViewer.keys(),
data: this._data,
};
}
// eslint-disable-next-line @typescript-eslint/no-empty-function
refresh() {
}
retry() {
this._retry$.next();
}
reset() {
for (const viewerId of this._connectedViewer.keys()) {
this.disconnect(viewerId);
}
// eslint-disable-next-line no-prototype-builtins
if (this.metadata.hasOwnProperty('context')) {
delete this.metadata['context'];
}
}
// eslint-disable-next-line @typescript-eslint/no-empty-function
_disconnect(viewerId) {
}
genericRetryFunction(error, retryCount) {
return this._retry$.asObservable().pipe(tap(() => this.hasError$.disable()));
}
handelError(error) {
if (isDevMode()) {
console.log(`DataSource '${this.id}' has an error:`, error);
}
}
_connect(viewer) {
this.init();
return this._data$;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: BaseDataSource, deps: [{ token: RXAP_DEFINITION_METADATA, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: BaseDataSource }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: BaseDataSource, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [RXAP_DEFINITION_METADATA]
}] }] });
function RxapDataSource(dataSourceIdOrMetadata, className = 'BaseDataSource', packageName = '@rxap/data-source') {
return function (target) {
DefinitionMetadata(dataSourceIdOrMetadata, className, packageName)(target);
};
}
class DataSourceLoader extends DefinitionLoader {
connect(dataSourceIdOrInstanceOrToken, viewer, metadata, injector, notFoundValue, flags) {
return this
.load(dataSourceIdOrInstanceOrToken, metadata, injector, notFoundValue, flags)
.connect(viewer);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: DataSourceLoader, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: DataSourceLoader, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: DataSourceLoader, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}] });
function DataSourceRefreshToMethodAdapterFactory(dataSource) {
return ToMethod(() => dataSource.refresh());
}
class RxapDataSourceError extends RxapError {
constructor(message, code, className) {
super('@rxap/data-source', message, code, className);
}
}
const RXAP_STATIC_DATA_SOURCE_DATA = new InjectionToken('rxap/data-source/static-data-source-data');
const RXAP_DATA_SOURCE_REFRESH = new InjectionToken('rxap/data-source/refresh');
const RXAP_OBSERVABLE_DATA_SOURCE = new InjectionToken('rxap/data-source/observable-data-source');
const RXAP_DATA_SOURCE_METADATA = new InjectionToken('rxap/data-source/metadata');
const RXAP_DATA_SOURCE = new InjectionToken('rxap/data-source/instance');
const RXAP_PIPE_DATA_SOURCE_OPERATOR = new InjectionToken('rxap/data-source/pipe-operator');
const RXAP_DATA_SOURCE_METHOD = new InjectionToken('rxap/data-source/method');
const RXAP_DATA_SOURCE_METHOD_WITHOUT_PARAMETERS = new InjectionToken('rxap/data-source/method-without-parameters', {
providedIn: 'root',
factory: () => false,
});
class MethodDataSource extends BaseDataSource {
constructor(method, withoutParameters = false) {
super(method.metadata);
this.method = method;
this.withoutParameters = withoutParameters;
this._data$ = new ReplaySubject(1);
this.loading$ = new ToggleSubject(false);
this._refresh = new Subject();
}
ngOnInit() {
if (this.withoutParameters) {
this.executeWithoutParameters();
}
}
refresh() {
this._refresh.next();
if (this.withoutParameters) {
this.executeWithoutParameters();
}
}
_connect(viewer) {
if (this.withoutParameters) {
return super._connect(viewer);
}
else {
return this._refresh.pipe(tap(() => this.hasError$.disable()), startWith(undefined), switchMap(() => {
if (viewer.viewChange && viewer.viewChange !== EMPTY) {
return viewer.viewChange.pipe(tap(() => this.loading$.enable()), switchMap((parameters) => from(this.execute(parameters)).pipe(this.handelExecution())));
}
else {
this.loading$.enable();
return from(this.execute(viewer)).pipe(this.handelExecution());
}
}));
}
}
handelExecution() {
return tap({
next: () => {
this.loading$.disable();
},
error: (error) => {
this.loading$.disable();
this.hasError$.enable();
this.error$.next(error);
},
finalize: () => {
this.loading$.disable();
}
});
}
async execute(parameters) {
return this.method.call(parameters);
}
async executeWithoutParameters() {
this.hasError$.disable();
this.loading$.enable();
await firstValueFrom(from(this.execute()).pipe(this.handelExecution(), tap({
next: (data) => this._data$.next(data),
})));
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: MethodDataSource, deps: [{ token: RXAP_DATA_SOURCE_METHOD }, { token: RXAP_DATA_SOURCE_METHOD_WITHOUT_PARAMETERS }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: MethodDataSource }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: MethodDataSource, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Inject,
args: [RXAP_DATA_SOURCE_METHOD]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [RXAP_DATA_SOURCE_METHOD_WITHOUT_PARAMETERS]
}] }] });
class ObservableDataSource extends BaseDataSource {
constructor(observable, metadata = null) {
super(metadata);
if (observable) {
this._data$ = observable;
}
else if (this.metadata.data) {
this._data$ = this.metadata.data;
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: ObservableDataSource, deps: [{ token: RXAP_OBSERVABLE_DATA_SOURCE, optional: true }, { token: RXAP_DATA_SOURCE_METADATA, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: ObservableDataSource }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: ObservableDataSource, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: i1$1.Observable, decorators: [{
type: Optional
}, {
type: Inject,
args: [RXAP_OBSERVABLE_DATA_SOURCE]
}] }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [RXAP_DATA_SOURCE_METADATA]
}] }] });
function RxapObservableDataSource(metadata, className = 'ObservableDataSource', packageName = '@rxap/data-source') {
return function (target) {
RxapDataSource(metadata, className, packageName)(target);
};
}
function observableDataSource(data, metadata = { id: 'static' }) {
return new ObservableDataSource(data, metadata);
}
function RxapPipeDataSource(metadata, className = 'PipeDataSource', packageName = '@rxap/data-source') {
return function (target) {
RxapDataSource(metadata, className, packageName)(target);
};
}
class PipeDataSource extends BaseDataSource {
constructor(dataSource, operation = null, ...operations) {
super(dataSource.metadata);
this.dataSource = dataSource;
this._refresh = new Subject();
this._operations = [];
this.loading$ = this.dataSource.loading$;
if (operation) {
this.setOperations(operation, ...operations.filter(op => typeof op === 'function'));
if (operations.some(op => typeof op !== 'function')) {
this.metadata = {
...this.metadata,
...operations.find(op => typeof op !== 'function'),
};
}
}
}
get operations() {
return this._operations;
}
setOperations(operation, ...operations) {
if (this._initialised) {
throw new RxapDataSourceError('Can not set operations after the data source is initialised', '', 'PipeDataSource');
}
this._operations = [operation, ...operations];
}
ngOnDestroy() {
super.ngOnDestroy();
this.dataSource.disconnect(this.metadata);
}
/**
* @param parent true - call the refresh method of the parent data source
*/
refresh(parent = this.metadata['refreshParent'] ?? false) {
if (parent) {
this.dataSource.refresh();
}
else {
this._refresh.next();
}
}
reset() {
return this.dataSource.reset();
}
toJSON() {
return {
...super.toJSON(),
dataSource: this.dataSource,
};
}
_connect(viewer) {
this.init();
return [
this.dataSource.connect(viewer).pipe(switchMap(data => this._refresh.pipe(startWith(null), map(() => data))),
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
...this.viewerToOperations(viewer)),
() => this.dataSource.disconnect(viewer),
];
}
viewerToOperations(viewer) {
return this.operations;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: PipeDataSource, deps: [{ token: RXAP_DATA_SOURCE }, { token: RXAP_PIPE_DATA_SOURCE_OPERATOR, optional: true }, { token: Array }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: PipeDataSource }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: PipeDataSource, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: BaseDataSource, decorators: [{
type: Inject,
args: [RXAP_DATA_SOURCE]
}] }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [RXAP_PIPE_DATA_SOURCE_OPERATOR]
}] }, { type: Array }] });
function pipeDataSource(dataSource, operation, ...operations) {
return new PipeDataSource(dataSource, operation, ...operations);
}
class StaticDataSource extends BaseDataSource {
constructor(data, metadata) {
super(metadata);
this._data$ = new ReplaySubject(1);
if ((data === undefined || data === null) && this.metadata.data !== undefined) {
data = this.metadata.data;
}
if (data === undefined) {
throw new RxapDataSourceError(`Can not create static data source '${this.id}' with undefined as data`, '');
}
if (isObservable(data)) {
this._dataSubscription = data.pipe(tap({
next: data => this._data$.next(data),
error: error => this.error$.next(error),
})).subscribe();
}
else if (isPromiseLike(data)) {
if (isPromise(data)) {
data.then(data => this._data$.next(data)).catch((error) => this.error$.next(error));
}
else {
data.then(data => this._data$.next(data));
}
}
else if (typeof data === 'function') {
// TODO : fix typeof function cast
this._data$.next((this._data = data()));
}
else {
this._data$.next((this._data = data));
}
}
get data() {
return clone(this._data);
}
set data(value) {
const data = clone(value);
this._data = data;
this._data$.next(data);
}
ngOnDestroy() {
super.ngOnDestroy();
this._dataSubscription?.unsubscribe();
}
_connect() {
this.init();
return this._data$.asObservable();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: StaticDataSource, deps: [{ token: RXAP_STATIC_DATA_SOURCE_DATA, optional: true }, { token: RXAP_DATA_SOURCE_METADATA, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: StaticDataSource }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: StaticDataSource, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [RXAP_STATIC_DATA_SOURCE_DATA]
}] }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [RXAP_DATA_SOURCE_METADATA]
}] }] });
function RxapStaticDataSource(metadata, className = 'StaticDataSource', packageName = '@rxap/data-source') {
return function (target) {
RxapDataSource(metadata, className, packageName)(target);
};
}
function staticDataSource(data, metadata = { id: 'static' }) {
return new StaticDataSource(data, metadata);
}
// region data-source-error
// endregion
/**
* Generated bundle index. Do not edit.
*/
export { BaseDataSource, DataSourceErrorComponent, DataSourceLoader, DataSourceRefreshToMethodAdapterFactory, MethodDataSource, ObservableDataSource, PipeDataSource, RXAP_DATA_SOURCE, RXAP_DATA_SOURCE_METADATA, RXAP_DATA_SOURCE_METHOD, RXAP_DATA_SOURCE_METHOD_WITHOUT_PARAMETERS, RXAP_DATA_SOURCE_REFRESH, RXAP_OBSERVABLE_DATA_SOURCE, RXAP_PIPE_DATA_SOURCE_OPERATOR, RXAP_STATIC_DATA_SOURCE_DATA, RxapDataSource, RxapDataSourceError, RxapObservableDataSource, RxapPipeDataSource, RxapStaticDataSource, StaticDataSource, observableDataSource, pipeDataSource, staticDataSource };
//# sourceMappingURL=rxap-data-source.mjs.map