platform/plugins/devmodel-resources/src/index.ts
Andrey Sobolev 76ed79c52c
UBERF-9455: Fix change of configurations and proper notifyTx (#7969)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
2025-02-10 22:47:46 +07:00

174 lines
5.0 KiB
TypeScript

//
// Copyright © 2020 Anticrm Platform Contributors.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
import core, {
DOMAIN_MODEL,
cutObjectArray,
type Class,
type Client,
type Doc,
type DocumentQuery,
type FindOptions,
type FindResult,
type Ref,
type SearchOptions,
type SearchQuery,
type SearchResult,
type Tx,
type TxResult,
type WithLookup
} from '@hcengineering/core'
import { getMetadata, type IntlString, type Resources } from '@hcengineering/platform'
import { addTxListener } from '@hcengineering/presentation'
import type { ClientHook } from '@hcengineering/presentation/src/plugin'
import { testing } from '@hcengineering/ui'
import devmodel from './plugin'
export interface TxWitHResult {
tx: Tx
result: TxResult
}
export interface QueryWithResult {
_class: Ref<Class<Doc>>
query: DocumentQuery<Doc>
options?: FindOptions<Doc>
result: FindResult<Doc>
findOne: boolean
}
export class PresentationClientHook implements ClientHook {
notifyEnabled = true
constructor () {
this.notifyEnabled = (localStorage.getItem('#platform.notification.logging') ?? 'true') === 'true'
addTxListener((tx) => {
if (this.notifyEnabled) {
const rtx = tx.filter((tx) => (tx as any).objectClass !== core.class.BenchmarkDoc)
if (rtx.length > 0) {
console.debug('devmodel# notify=>', testing ? cutObjectArray(rtx) : rtx.length === 1 ? rtx[0] : tx)
}
}
})
}
stackLine (): string {
const stack = (new Error().stack ?? '').split('\n')
let candidate = ''
for (let l of stack) {
l = l.trim()
if (l.includes('.svelte')) {
return l
}
if (l.includes('plugins/') && !l.includes('devmodel-resources/') && l.includes('.ts') && candidate === '') {
candidate = l
}
}
return candidate
}
async findOne<T extends Doc>(
client: Client,
_class: Ref<Class<T>>,
query: DocumentQuery<T>,
options?: FindOptions<T>
): Promise<WithLookup<T> | undefined> {
const startTime = Date.now()
const isModel = client.getHierarchy().findDomain(_class) === DOMAIN_MODEL
const result = await client.findOne(_class, query, options)
if (this.notifyEnabled && !isModel) {
console.debug(
'devmodel# findOne=>',
_class,
testing ? JSON.stringify(cutObjectArray(query)) : query,
options,
'result => ',
testing ? JSON.stringify(cutObjectArray(result)) : result,
' =>model',
client.getModel(),
getMetadata(devmodel.metadata.DevModel),
Date.now() - startTime,
this.stackLine()
)
}
return result
}
async findAll<T extends Doc>(
client: Client,
_class: Ref<Class<T>>,
query: DocumentQuery<T>,
options?: FindOptions<T>
): Promise<FindResult<T>> {
const startTime = Date.now()
const isModel = client.getHierarchy().findDomain(_class) === DOMAIN_MODEL
const result = await client.findAll(_class, query, options)
if (this.notifyEnabled && !isModel) {
console.debug(
'devmodel# findAll=>',
_class,
testing ? JSON.stringify(cutObjectArray(query)).slice(0, 160) : query,
options,
'result => ',
testing ? JSON.stringify(cutObjectArray(result)).slice(0, 160) : result,
' =>model',
client.getModel(),
getMetadata(devmodel.metadata.DevModel),
Date.now() - startTime,
JSON.stringify(result).length,
this.stackLine()
)
}
return result
}
async searchFulltext (client: Client, query: SearchQuery, options: SearchOptions): Promise<SearchResult> {
const result = await client.searchFulltext(query, options)
if (this.notifyEnabled) {
console.debug(
'devmodel# searchFulltext=>',
testing ? JSON.stringify(cutObjectArray(query)).slice(0, 160) : query,
options,
'result => ',
result
)
}
return result
}
async tx (client: Client, tx: Tx): Promise<TxResult> {
const startTime = Date.now()
const result = await client.tx(tx)
if (this.notifyEnabled && (tx as any).objectClass !== core.class.BenchmarkDoc) {
console.debug(
'devmodel# tx=>',
testing ? JSON.stringify(cutObjectArray(tx)).slice(0, 160) : tx,
result,
getMetadata(devmodel.metadata.DevModel),
Date.now() - startTime,
this.stackLine()
)
}
return result
}
}
export function toIntl (value: string): IntlString {
return value as IntlString
}
export default async (): Promise<Resources> => ({})