@river-build/sdk
Version:
For more details, visit the following resources:
77 lines • 2.82 kB
JavaScript
import { check } from '@river-build/dlog';
import { Observable } from './observable';
import { LoadPriority } from '../store/store';
import { isDefined } from '../check';
const all_tables = new Set();
/// decorator
export function persistedObservable(options) {
check(!all_tables.has(options.tableName), `duplicate table name: ${options.tableName}`);
all_tables.add(options.tableName);
return function (constructor) {
return class extends constructor {
constructor(...args) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
super(...args);
this.tableName = options.tableName;
this.store.withTransaction(`new-${options.tableName}`, () => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
;
this.load();
});
}
static tableName = options.tableName;
};
};
}
export class PersistedObservable extends Observable {
tableName = '';
store;
loadPriority;
// must be called in a store transaction
constructor(initialValue, store, loadPriority = LoadPriority.low) {
super({ status: 'loading', data: initialValue });
this.loadPriority = loadPriority;
this.store = store;
}
load() {
check(super.value.status === 'loading', 'already loaded');
this.store.load(this.tableName, this.data.id, this.loadPriority, (data) => {
super.setValue({ status: 'loaded', data: data ?? this.data });
}, (error) => {
super.setValue({ status: 'error', data: this.data, error });
}, () => {
this.onLoaded();
});
}
get value() {
return super.value;
}
setValue(_newValue) {
throw new Error('use updateData instead of set value');
}
get data() {
return super.value.data;
}
// must be called in a store transaction
setData(newDataPartial) {
check(isDefined(newDataPartial), 'value is undefined');
const prevData = this.data;
const newData = { ...this.data, ...newDataPartial };
check(newData.id === this.data.id, 'id mismatch');
super.setValue({ status: 'loaded', data: newData });
this.store.withTransaction(`update-${this.tableName}:${this.data.id}`, () => {
this.store.save(this.tableName, newData, () => { }, (e) => {
super.setValue({ status: 'error', data: prevData, error: e });
}, () => {
this.onSaved();
});
});
}
onLoaded() {
// abstract
}
onSaved() {
// abstract
}
}
//# sourceMappingURL=persistedObservable.js.map