mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-27 19:00:02 +00:00
UBERF-7489: Fix various performance issues (#5983)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
9d3ce44ce7
commit
d5a83391c8
@ -21,7 +21,6 @@ import core, {
|
|||||||
concatLink,
|
concatLink,
|
||||||
getCurrentAccount,
|
getCurrentAccount,
|
||||||
reduceCalls,
|
reduceCalls,
|
||||||
type TxApplyIf,
|
|
||||||
type AnyAttribute,
|
type AnyAttribute,
|
||||||
type ArrOf,
|
type ArrOf,
|
||||||
type AttachedDoc,
|
type AttachedDoc,
|
||||||
@ -46,10 +45,11 @@ import core, {
|
|||||||
type SearchResult,
|
type SearchResult,
|
||||||
type Space,
|
type Space,
|
||||||
type Tx,
|
type Tx,
|
||||||
|
type TxApplyIf,
|
||||||
|
type TxCUD,
|
||||||
type TxResult,
|
type TxResult,
|
||||||
type TypeAny,
|
type TypeAny,
|
||||||
type WithLookup,
|
type WithLookup
|
||||||
type TxCUD
|
|
||||||
} from '@hcengineering/core'
|
} from '@hcengineering/core'
|
||||||
import { getMetadata, getResource } from '@hcengineering/platform'
|
import { getMetadata, getResource } from '@hcengineering/platform'
|
||||||
import { LiveQuery as LQ } from '@hcengineering/query'
|
import { LiveQuery as LQ } from '@hcengineering/query'
|
||||||
@ -57,13 +57,14 @@ import { getRawCurrentLocation, workspaceId, type AnyComponent, type AnySvelteCo
|
|||||||
import view, { type AttributeCategory, type AttributeEditor } from '@hcengineering/view'
|
import view, { type AttributeCategory, type AttributeEditor } from '@hcengineering/view'
|
||||||
import { deepEqual } from 'fast-equals'
|
import { deepEqual } from 'fast-equals'
|
||||||
import { onDestroy } from 'svelte'
|
import { onDestroy } from 'svelte'
|
||||||
import { type Writable, get, writable } from 'svelte/store'
|
import { get, writable, type Writable } from 'svelte/store'
|
||||||
import { type KeyedAttribute } from '..'
|
import { type KeyedAttribute } from '..'
|
||||||
import { OptimizeQueryMiddleware, PresentationPipelineImpl, type PresentationPipeline } from './pipeline'
|
import { OptimizeQueryMiddleware, PresentationPipelineImpl, type PresentationPipeline } from './pipeline'
|
||||||
import plugin from './plugin'
|
import plugin from './plugin'
|
||||||
export { reduceCalls } from '@hcengineering/core'
|
export { reduceCalls } from '@hcengineering/core'
|
||||||
|
|
||||||
let liveQuery: LQ
|
let liveQuery: LQ
|
||||||
|
let rawLiveQuery: LQ
|
||||||
let client: TxOperations & MeasureClient & OptimisticTxes
|
let client: TxOperations & MeasureClient & OptimisticTxes
|
||||||
let pipeline: PresentationPipeline
|
let pipeline: PresentationPipeline
|
||||||
|
|
||||||
@ -76,6 +77,10 @@ export function addTxListener (l: (tx: Tx) => void): void {
|
|||||||
txListeners.push(l)
|
txListeners.push(l)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getRawLiveQuery (): LQ {
|
||||||
|
return rawLiveQuery
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
@ -144,6 +149,8 @@ class UIClient extends TxOperations implements Client, MeasureClient, Optimistic
|
|||||||
|
|
||||||
await liveQuery.tx(...tx)
|
await liveQuery.tx(...tx)
|
||||||
|
|
||||||
|
await rawLiveQuery.tx(...tx)
|
||||||
|
|
||||||
txListeners.forEach((it) => {
|
txListeners.forEach((it) => {
|
||||||
it(...tx)
|
it(...tx)
|
||||||
})
|
})
|
||||||
@ -250,17 +257,24 @@ export async function setClient (_client: MeasureClient): Promise<void> {
|
|||||||
if (liveQuery !== undefined) {
|
if (liveQuery !== undefined) {
|
||||||
await liveQuery.close()
|
await liveQuery.close()
|
||||||
}
|
}
|
||||||
|
if (rawLiveQuery !== undefined) {
|
||||||
|
await rawLiveQuery.close()
|
||||||
|
}
|
||||||
if (pipeline !== undefined) {
|
if (pipeline !== undefined) {
|
||||||
await pipeline.close()
|
await pipeline.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const needRefresh = liveQuery !== undefined
|
||||||
|
rawLiveQuery = new LQ(_client)
|
||||||
|
|
||||||
const factories = await _client.findAll(plugin.class.PresentationMiddlewareFactory, {})
|
const factories = await _client.findAll(plugin.class.PresentationMiddlewareFactory, {})
|
||||||
const promises = factories.map(async (it) => await getResource(it.createPresentationMiddleware))
|
const promises = factories.map(async (it) => await getResource(it.createPresentationMiddleware))
|
||||||
const creators = await Promise.all(promises)
|
const creators = await Promise.all(promises)
|
||||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||||
pipeline = PresentationPipelineImpl.create(_client, [OptimizeQueryMiddleware.create, ...creators])
|
pipeline = PresentationPipelineImpl.create(_client, [OptimizeQueryMiddleware.create, ...creators])
|
||||||
|
|
||||||
const needRefresh = liveQuery !== undefined
|
|
||||||
liveQuery = new LQ(pipeline)
|
liveQuery = new LQ(pipeline)
|
||||||
|
|
||||||
const uiClient = new UIClient(pipeline, liveQuery)
|
const uiClient = new UIClient(pipeline, liveQuery)
|
||||||
client = uiClient
|
client = uiClient
|
||||||
|
|
||||||
|
@ -406,7 +406,27 @@
|
|||||||
$: projectPreferences.query(tracker.class.ProjectTargetPreference, {}, (res) => {
|
$: projectPreferences.query(tracker.class.ProjectTargetPreference, {}, (res) => {
|
||||||
preferences = res
|
preferences = res
|
||||||
})
|
})
|
||||||
$: spacePreferences = preferences.find((it) => it.attachedTo === _space)
|
|
||||||
|
async function updateCurrentProjectPref (currentProject: Ref<Project>): Promise<void> {
|
||||||
|
const spacePreferences = await client.findOne(tracker.class.ProjectTargetPreference, { attachedTo: currentProject })
|
||||||
|
if (spacePreferences === undefined) {
|
||||||
|
await client.createDoc(tracker.class.ProjectTargetPreference, currentProject, {
|
||||||
|
attachedTo: currentProject,
|
||||||
|
props: [],
|
||||||
|
usedOn: Date.now()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
if (spacePreferences.usedOn + 60 * 1000 < Date.now()) {
|
||||||
|
await client.update(spacePreferences, {
|
||||||
|
usedOn: Date.now()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$: if (_space !== undefined) {
|
||||||
|
void updateCurrentProjectPref(_space)
|
||||||
|
}
|
||||||
|
|
||||||
async function createIssue (): Promise<void> {
|
async function createIssue (): Promise<void> {
|
||||||
const _id: Ref<Issue> = generateId()
|
const _id: Ref<Issue> = generateId()
|
||||||
@ -713,24 +733,6 @@
|
|||||||
originalIssue,
|
originalIssue,
|
||||||
preferences
|
preferences
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateCurrentProjectPref (currentProject: Ref<Project>): void {
|
|
||||||
if (spacePreferences === undefined) {
|
|
||||||
void client.createDoc(tracker.class.ProjectTargetPreference, currentProject, {
|
|
||||||
attachedTo: currentProject,
|
|
||||||
props: [],
|
|
||||||
usedOn: Date.now()
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
void client.update(spacePreferences, {
|
|
||||||
usedOn: Date.now()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$: if (_space !== undefined) {
|
|
||||||
updateCurrentProjectPref(_space)
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<FocusHandler {manager} />
|
<FocusHandler {manager} />
|
||||||
|
@ -18,12 +18,15 @@ import { Analytics } from '@hcengineering/analytics'
|
|||||||
import core, {
|
import core, {
|
||||||
AccountRole,
|
AccountRole,
|
||||||
ClassifierKind,
|
ClassifierKind,
|
||||||
|
DocManager,
|
||||||
Hierarchy,
|
Hierarchy,
|
||||||
|
SortingOrder,
|
||||||
TxProcessor,
|
TxProcessor,
|
||||||
getCurrentAccount,
|
getCurrentAccount,
|
||||||
getObjectValue,
|
getObjectValue,
|
||||||
type Account,
|
type Account,
|
||||||
type AggregateValue,
|
type AggregateValue,
|
||||||
|
type AnyAttribute,
|
||||||
type AttachedDoc,
|
type AttachedDoc,
|
||||||
type CategoryType,
|
type CategoryType,
|
||||||
type Class,
|
type Class,
|
||||||
@ -42,6 +45,7 @@ import core, {
|
|||||||
type ReverseLookup,
|
type ReverseLookup,
|
||||||
type ReverseLookups,
|
type ReverseLookups,
|
||||||
type Space,
|
type Space,
|
||||||
|
type Tx,
|
||||||
type TxCUD,
|
type TxCUD,
|
||||||
type TxCollectionCUD,
|
type TxCollectionCUD,
|
||||||
type TxCreateDoc,
|
type TxCreateDoc,
|
||||||
@ -50,11 +54,7 @@ import core, {
|
|||||||
type TxUpdateDoc,
|
type TxUpdateDoc,
|
||||||
type TypeAny,
|
type TypeAny,
|
||||||
type TypedSpace,
|
type TypedSpace,
|
||||||
type WithLookup,
|
type WithLookup
|
||||||
type AnyAttribute,
|
|
||||||
DocManager,
|
|
||||||
SortingOrder,
|
|
||||||
type Tx
|
|
||||||
} from '@hcengineering/core'
|
} from '@hcengineering/core'
|
||||||
import { type Restrictions } from '@hcengineering/guest'
|
import { type Restrictions } from '@hcengineering/guest'
|
||||||
import type { Asset, IntlString } from '@hcengineering/platform'
|
import type { Asset, IntlString } from '@hcengineering/platform'
|
||||||
@ -64,11 +64,11 @@ import {
|
|||||||
getAttributePresenterClass,
|
getAttributePresenterClass,
|
||||||
getClient,
|
getClient,
|
||||||
getFiltredKeys,
|
getFiltredKeys,
|
||||||
|
getRawLiveQuery,
|
||||||
hasResource,
|
hasResource,
|
||||||
isAdminUser,
|
isAdminUser,
|
||||||
type KeyedAttribute
|
type KeyedAttribute
|
||||||
} from '@hcengineering/presentation'
|
} from '@hcengineering/presentation'
|
||||||
import { LiveQuery } from '@hcengineering/query'
|
|
||||||
import { type CollaborationUser } from '@hcengineering/text-editor'
|
import { type CollaborationUser } from '@hcengineering/text-editor'
|
||||||
import {
|
import {
|
||||||
ErrorPresenter,
|
ErrorPresenter,
|
||||||
@ -85,7 +85,6 @@ import {
|
|||||||
type Location
|
type Location
|
||||||
} from '@hcengineering/ui'
|
} from '@hcengineering/ui'
|
||||||
import view, {
|
import view, {
|
||||||
type IAggregationManager,
|
|
||||||
AttributeCategoryOrder,
|
AttributeCategoryOrder,
|
||||||
type AttributeCategory,
|
type AttributeCategory,
|
||||||
type AttributeModel,
|
type AttributeModel,
|
||||||
@ -93,9 +92,10 @@ import view, {
|
|||||||
type BuildModelKey,
|
type BuildModelKey,
|
||||||
type BuildModelOptions,
|
type BuildModelOptions,
|
||||||
type CollectionPresenter,
|
type CollectionPresenter,
|
||||||
|
type IAggregationManager,
|
||||||
|
type LinkIdProvider,
|
||||||
type Viewlet,
|
type Viewlet,
|
||||||
type ViewletDescriptor,
|
type ViewletDescriptor
|
||||||
type LinkIdProvider
|
|
||||||
} from '@hcengineering/view'
|
} from '@hcengineering/view'
|
||||||
|
|
||||||
import contact, { getName, type Contact, type PersonAccount } from '@hcengineering/contact'
|
import contact, { getName, type Contact, type PersonAccount } from '@hcengineering/contact'
|
||||||
@ -119,7 +119,6 @@ export class AggregationManager<T extends Doc> implements IAggregationManager<T>
|
|||||||
docs: T[] | undefined
|
docs: T[] | undefined
|
||||||
mgr: DocManager<T> | Promise<DocManager<T>> | undefined
|
mgr: DocManager<T> | Promise<DocManager<T>> | undefined
|
||||||
query: (() => void) | undefined
|
query: (() => void) | undefined
|
||||||
lq: LiveQuery
|
|
||||||
lqCallback: () => void
|
lqCallback: () => void
|
||||||
private readonly setStore: (manager: DocManager<T>) => void
|
private readonly setStore: (manager: DocManager<T>) => void
|
||||||
private readonly filter: (doc: T, target: T) => boolean
|
private readonly filter: (doc: T, target: T) => boolean
|
||||||
@ -132,7 +131,6 @@ export class AggregationManager<T extends Doc> implements IAggregationManager<T>
|
|||||||
categorizingFunc: (doc: T, target: T) => boolean,
|
categorizingFunc: (doc: T, target: T) => boolean,
|
||||||
_class: Ref<Class<T>>
|
_class: Ref<Class<T>>
|
||||||
) {
|
) {
|
||||||
this.lq = new LiveQuery(client)
|
|
||||||
this.lqCallback = lqCallback ?? (() => {})
|
this.lqCallback = lqCallback ?? (() => {})
|
||||||
this.setStore = setStore
|
this.setStore = setStore
|
||||||
this.filter = categorizingFunc
|
this.filter = categorizingFunc
|
||||||
@ -158,7 +156,7 @@ export class AggregationManager<T extends Doc> implements IAggregationManager<T>
|
|||||||
return this.mgr
|
return this.mgr
|
||||||
}
|
}
|
||||||
this.mgr = new Promise<DocManager<T>>((resolve) => {
|
this.mgr = new Promise<DocManager<T>>((resolve) => {
|
||||||
this.query = this.lq.query(
|
this.query = getRawLiveQuery().query(
|
||||||
this._class,
|
this._class,
|
||||||
{},
|
{},
|
||||||
(res) => {
|
(res) => {
|
||||||
@ -187,7 +185,7 @@ export class AggregationManager<T extends Doc> implements IAggregationManager<T>
|
|||||||
}
|
}
|
||||||
|
|
||||||
async notifyTx (...tx: Tx[]): Promise<void> {
|
async notifyTx (...tx: Tx[]): Promise<void> {
|
||||||
await this.lq.tx(...tx)
|
// This is intentional
|
||||||
}
|
}
|
||||||
|
|
||||||
getAttrClass (): Ref<Class<T>> {
|
getAttrClass (): Ref<Class<T>> {
|
||||||
|
Loading…
Reference in New Issue
Block a user