fix(core-sdk): CB-CB-2503 cached resource includes observing

This commit is contained in:
Wroud
2022-09-08 09:20:18 +03:00
parent ac4b70fdd2
commit 863cd7b739
6 changed files with 43 additions and 41 deletions
@@ -6,7 +6,7 @@
* you may not use this file except in compliance with the License.
*/
import { computed, makeObservable, runInAction } from 'mobx';
import { computed, makeObservable, observable, runInAction } from 'mobx';
import { injectable } from '@cloudbeaver/core-di';
import { SyncExecutor, ISyncExecutor, ITask, AutoRunningTask, whileTask } from '@cloudbeaver/core-executor';
@@ -253,7 +253,7 @@ UserInfoIncludes
protected resetIncludes(): void {
const metadata = this.getMetadata();
metadata.includes = [...this.defaultIncludes];
metadata.includes = observable([...this.defaultIncludes]);
}
getIncludes(key: void): string[] {
@@ -14,6 +14,7 @@ import { NotificationService } from '@cloudbeaver/core-events';
import { CachedResourceIncludeArgs, CachedMapResource, CachedMapResourceGetter, ResourceKey, CachedMapResourceValue, CachedMapResourceKey, CachedMapResourceArguments, CachedMapResourceLoader, ResourceKeyList, CachedMapResourceListGetter, isResourceKeyList } from '@cloudbeaver/core-sdk';
import { isArraysEqual } from '@cloudbeaver/core-utils';
import { getComputed } from './getComputed';
import type { ILoadableState } from './Loader/ILoadableState';
import { useObservableRef } from './useObservableRef';
@@ -364,20 +365,22 @@ export function useMapResource<
loading: computed,
}, false);
// TODO: getComputed skips update somehow ...
const outdated = (
!result.loading
&& (result.outdated || !result.loaded)
);
const preloaded = refObj.preloaded; // make mobx subscription
const canLoad = getComputed(() => (
(
!keyRef.actual
|| result.outdated
|| !result.loaded
)
&& refObj.preloaded
&& keyRef.key !== null
&& (
result.exception === null
|| (Array.isArray(result.exception) && !result.exception.some(Boolean))
)
));
useEffect(() => {
if (!preloaded || (!outdated && keyRef.actual) || keyRef.key === null) {
return;
}
if (result.exception === null || (Array.isArray(result.exception) && !result.exception.some(Boolean))) {
if (canLoad) {
(refObj as any)[loadFunctionName]();
}
});
@@ -37,7 +37,7 @@ export class DBDriverResource extends CachedMapResource<string, DBDriver, Driver
super();
permissionsResource.require(this, EPermission.public);
this.serverConfigResource.onDataOutdated.addHandler(this.markOutdated.bind(this));
this.serverConfigResource.onDataOutdated.addHandler(() => this.markOutdated());
makeObservable(this, {
enabledDrivers: computed,
@@ -69,7 +69,7 @@ export class DBDriverResource extends CachedMapResource<string, DBDriver, Driver
includeDriverParameters: false,
includeDriverProperties: false,
includeProviderProperties: false,
...this.getIncludesMap(driverId, includes),
...this.getIncludesMap(driverId, (all ? this.defaultIncludes : includes)),
});
if (driverId && !drivers.some(driver => driver.id === driverId)) {
@@ -77,10 +77,9 @@ export class DBDriverResource extends CachedMapResource<string, DBDriver, Driver
}
runInAction(() => {
if (all) {
this.resetIncludes();
this.data.clear();
const removedDrivers = this.keys.filter(key => !drivers.some(driver => driver.id === key));
this.delete(resourceKeyList(removedDrivers));
}
this.updateDriver(...drivers);
@@ -94,6 +93,6 @@ export class DBDriverResource extends CachedMapResource<string, DBDriver, Driver
const keys = resourceKeyList(drivers.map(driver => driver.id));
const oldDriver = this.get(keys);
this.set(keys, oldDriver.map((oldDriver, i) => ({ ...oldDriver, ...drivers[i] })));
this.set(keys, oldDriver.map((oldDriver, i) => (Object.assign(oldDriver ?? {}, drivers[i]))));
}
}
@@ -366,25 +366,21 @@ export abstract class CachedMapResource<
}
includes(param: ResourceKey<TKey>, key: ResourceKey<TKey>): boolean {
if (param === key) {
if
(
this.isAliasEqual(param, key)
|| (ResourceKeyUtils.isEmpty(param) && ResourceKeyUtils.isEmpty(key))
) {
return true;
}
if (this.isAlias(param) || this.isAlias(key)) {
return this.isAliasEqual(param, key);
}
if (ResourceKeyUtils.isEmpty(param) || ResourceKeyUtils.isEmpty(key)) {
return ResourceKeyUtils.isEmpty(param) && ResourceKeyUtils.isEmpty(key);
return true;
}
param = ResourceKeyUtils.mapKey(param, this.getKeyRef.bind(this));
key = ResourceKeyUtils.mapKey(key, this.getKeyRef.bind(this));
if (param === key) {
return true;
}
return ResourceKeyUtils.includes(param, key, this.isKeyEqual);
}
@@ -467,10 +463,10 @@ export abstract class CachedMapResource<
key = this.transformParam(key);
}
runInAction(() => ResourceKeyUtils.forEach(key!, key => {
ResourceKeyUtils.forEach(key, key => {
const metadata = this.getMetadata(key);
metadata.outdated = true;
}));
});
this.onDataOutdated.execute(key);
}
@@ -366,7 +366,7 @@ export abstract class CachedResource<
break transform;
}
} else {
if (this.includes(alias.param, param)) {
if (alias.param === param) {
param = alias.getAlias(param);
deep++;
// eslint-disable-next-line no-labels
@@ -412,7 +412,7 @@ export abstract class CachedResource<
protected resetIncludes(): void {
for (const metadata of this.metadata.values()) {
metadata.includes = [...this.defaultIncludes];
metadata.includes = observable([...this.defaultIncludes]);
}
}
@@ -447,12 +447,16 @@ export abstract class CachedResource<
}
isAliasEqual(param: TParam, second: TParam): boolean {
if (param === second) {
return true;
}
return this.paramAliases.some(alias => {
if ('getter' in alias && alias.getter) {
return alias.param(param) && alias.param(second);
} else {
return alias.param === param && alias.param === second;
}
return false;
});
}
@@ -461,14 +465,10 @@ export abstract class CachedResource<
}
protected includes(param: TParam, second: TParam): boolean {
if (param === second) {
if (this.isAliasEqual(param, second)) {
return true;
}
if (this.isAlias(param) || this.isAlias(second)) {
return this.isAliasEqual(param, second);
}
param = this.transformParam(param);
second = this.transformParam(second);
return this.isKeyEqual(param, second);
@@ -188,6 +188,10 @@ export const ResourceKeyUtils: ResourceKeyUtils = {
key: ResourceKey<TKey>,
isEqual = (keyA: TKey, keyB: TKey) => keyA === keyB
): boolean {
if (param === key) {
return true;
}
if (isResourceKeyList(param)) {
return param.includes(key);
}