mirror of
https://github.com/hcengineering/platform.git
synced 2025-06-09 01:10:17 +00:00
introduce TxResult
Signed-off-by: Andrey Platov <andrey@hardcoreeng.com>
This commit is contained in:
parent
e080f6e724
commit
d75d17bfec
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import type { Tx, Storage, Ref, Doc, Class, DocumentQuery, FindResult, FindOptions, TxHander, ServerStorage } from '@anticrm/core'
|
||||
import type { Tx, Storage, Ref, Doc, Class, DocumentQuery, FindResult, FindOptions, TxHander, ServerStorage, TxResult } from '@anticrm/core'
|
||||
import { DOMAIN_TX } from '@anticrm/core'
|
||||
import { createInMemoryAdapter, createInMemoryTxAdapter } from '@anticrm/dev-storage'
|
||||
import { createServerStorage, FullTextAdapter, IndexedDoc } from '@anticrm/server-core'
|
||||
@ -28,19 +28,22 @@ class ServerStorageWrapper implements Storage {
|
||||
return this.storage.findAll(c, q, o)
|
||||
}
|
||||
|
||||
async tx (tx: Tx): Promise<void> {
|
||||
async tx (tx: Tx): Promise<TxResult> {
|
||||
const _tx = protoDeserialize(protoSerialize(tx))
|
||||
const derived = await this.storage.tx(_tx)
|
||||
for (const tx of derived) { this.handler(tx) }
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
class NullFullTextAdapter implements FullTextAdapter {
|
||||
async index (doc: IndexedDoc): Promise<void> {
|
||||
async index (doc: IndexedDoc): Promise<TxResult> {
|
||||
console.log('noop full text indexer: ', doc)
|
||||
return {}
|
||||
}
|
||||
|
||||
async update (id: Ref<Doc>, update: Record<string, any>): Promise<void> {
|
||||
async update (id: Ref<Doc>, update: Record<string, any>): Promise<TxResult> {
|
||||
return {}
|
||||
}
|
||||
|
||||
async search (query: any): Promise<IndexedDoc[]> {
|
||||
|
@ -15,7 +15,7 @@
|
||||
//
|
||||
|
||||
import { DOMAIN_TX } from '@anticrm/core'
|
||||
import type { Ref, Doc } from '@anticrm/core'
|
||||
import type { Ref, Doc, TxResult } from '@anticrm/core'
|
||||
import { start as startJsonRpc } from '@anticrm/server-ws'
|
||||
import { createInMemoryAdapter, createInMemoryTxAdapter } from '@anticrm/dev-storage'
|
||||
import { createServerStorage, FullTextAdapter, IndexedDoc } from '@anticrm/server-core'
|
||||
@ -25,11 +25,13 @@ import { addLocation } from '@anticrm/platform'
|
||||
import { serverChunterId } from '@anticrm/server-chunter'
|
||||
|
||||
class NullFullTextAdapter implements FullTextAdapter {
|
||||
async index (doc: IndexedDoc): Promise<void> {
|
||||
async index (doc: IndexedDoc): Promise<TxResult> {
|
||||
console.log('noop full text indexer: ', doc)
|
||||
return {}
|
||||
}
|
||||
|
||||
async update (id: Ref<Doc>, update: Record<string, any>): Promise<void> {
|
||||
async update (id: Ref<Doc>, update: Record<string, any>): Promise<TxResult> {
|
||||
return {}
|
||||
}
|
||||
|
||||
async search (query: any): Promise<IndexedDoc[]> {
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import type { Tx, Ref, Doc, Class, DocumentQuery, FindResult, FindOptions } from '@anticrm/core'
|
||||
import type { Tx, Ref, Doc, Class, DocumentQuery, FindResult, FindOptions, TxResult } from '@anticrm/core'
|
||||
import { ModelDb, TxDb, Hierarchy } from '@anticrm/core'
|
||||
import type { DbAdapter, TxAdapter } from '@anticrm/server-core'
|
||||
|
||||
@ -30,7 +30,7 @@ class InMemoryTxAdapter implements TxAdapter {
|
||||
return await this.txdb.findAll(_class, query, options)
|
||||
}
|
||||
|
||||
tx (tx: Tx): Promise<void> {
|
||||
tx (tx: Tx): Promise<TxResult> {
|
||||
return this.txdb.tx(tx)
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ class InMemoryAdapter implements DbAdapter {
|
||||
return await this.modeldb.findAll(_class, query, options)
|
||||
}
|
||||
|
||||
async tx (tx: Tx): Promise<void> {
|
||||
async tx (tx: Tx): Promise<TxResult> {
|
||||
return await this.modeldb.tx(tx)
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import type { Storage, DocumentQuery, FindResult } from '../storage'
|
||||
import type { Storage, DocumentQuery, FindResult, TxResult } from '../storage'
|
||||
import type { Class, Doc, Ref } from '../classes'
|
||||
import type { Tx } from '../tx'
|
||||
import core from '../component'
|
||||
@ -43,11 +43,12 @@ export async function connect (handler: (tx: Tx) => void): Promise<Storage> {
|
||||
|
||||
return {
|
||||
findAll,
|
||||
tx: async (tx: Tx): Promise<void> => {
|
||||
tx: async (tx: Tx): Promise<TxResult> => {
|
||||
if (tx.objectSpace === core.space.Model) {
|
||||
hierarchy.tx(tx)
|
||||
}
|
||||
await Promise.all([model.tx(tx), transactions.tx(tx)])
|
||||
const result = await Promise.all([model.tx(tx), transactions.tx(tx)])
|
||||
return result[0]
|
||||
// handler(tx) - we have only one client, should not update?
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
import type { Doc, Ref, Class } from './classes'
|
||||
import type { Tx } from './tx'
|
||||
import type { Storage, DocumentQuery, FindOptions, FindResult, WithLookup } from './storage'
|
||||
import type { Storage, DocumentQuery, FindOptions, FindResult, WithLookup, TxResult } from './storage'
|
||||
|
||||
import { SortingOrder } from './storage'
|
||||
import { Hierarchy } from './hierarchy'
|
||||
@ -73,13 +73,13 @@ class ClientImpl implements Client {
|
||||
return (await this.findAll(_class, query, options))[0]
|
||||
}
|
||||
|
||||
async tx (tx: Tx): Promise<void> {
|
||||
async tx (tx: Tx): Promise<TxResult> {
|
||||
if (tx.objectSpace === core.space.Model) {
|
||||
this.hierarchy.tx(tx)
|
||||
await this.model.tx(tx)
|
||||
}
|
||||
this.notify?.(tx)
|
||||
await this.conn.tx(tx)
|
||||
return await this.conn.tx(tx)
|
||||
}
|
||||
|
||||
async updateFromRemote (tx: Tx): Promise<void> {
|
||||
|
@ -20,7 +20,7 @@ import core from './component'
|
||||
import type { Hierarchy } from './hierarchy'
|
||||
import { _getOperator } from './operator'
|
||||
import { findProperty, resultSort } from './query'
|
||||
import type { DocumentQuery, FindOptions, FindResult, Storage, WithLookup, LookupData, Refs } from './storage'
|
||||
import type { DocumentQuery, FindOptions, FindResult, Storage, WithLookup, LookupData, Refs, TxResult } from './storage'
|
||||
import { TxProcessor } from './tx'
|
||||
|
||||
import clone from 'just-clone'
|
||||
@ -149,28 +149,29 @@ export abstract class MemDb extends TxProcessor {
|
||||
* @public
|
||||
*/
|
||||
export class TxDb extends MemDb implements Storage {
|
||||
protected txCreateDoc (tx: TxCreateDoc<Doc>): Promise<void> {
|
||||
protected txCreateDoc (tx: TxCreateDoc<Doc>): Promise<TxResult> {
|
||||
throw new Error('Method not implemented.')
|
||||
}
|
||||
|
||||
protected txPutBag (tx: TxPutBag<any>): Promise<void> {
|
||||
protected txPutBag (tx: TxPutBag<any>): Promise<TxResult> {
|
||||
throw new Error('Method not implemented.')
|
||||
}
|
||||
|
||||
protected txUpdateDoc (tx: TxUpdateDoc<Doc>): Promise<void> {
|
||||
protected txUpdateDoc (tx: TxUpdateDoc<Doc>): Promise<TxResult> {
|
||||
throw new Error('Method not implemented.')
|
||||
}
|
||||
|
||||
protected txRemoveDoc (tx: TxRemoveDoc<Doc>): Promise<void> {
|
||||
protected txRemoveDoc (tx: TxRemoveDoc<Doc>): Promise<TxResult> {
|
||||
throw new Error('Method not implemented.')
|
||||
}
|
||||
|
||||
protected txMixin (tx: TxMixin<Doc, Doc>): Promise<void> {
|
||||
protected txMixin (tx: TxMixin<Doc, Doc>): Promise<TxResult> {
|
||||
throw new Error('Method not implemented.')
|
||||
}
|
||||
|
||||
async tx (tx: Tx): Promise<void> {
|
||||
async tx (tx: Tx): Promise<TxResult> {
|
||||
this.addDoc(tx)
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -180,7 +181,7 @@ export class TxDb extends MemDb implements Storage {
|
||||
* @public
|
||||
*/
|
||||
export class ModelDb extends MemDb implements Storage {
|
||||
protected override async txPutBag (tx: TxPutBag<any>): Promise<void> {
|
||||
protected override async txPutBag (tx: TxPutBag<any>): Promise<TxResult> {
|
||||
const doc = this.getObject(tx.objectId) as any
|
||||
let bag = doc[tx.bag]
|
||||
if (bag === undefined) {
|
||||
@ -189,13 +190,15 @@ export class ModelDb extends MemDb implements Storage {
|
||||
bag[tx.key] = tx.value
|
||||
doc.modifiedBy = tx.modifiedBy
|
||||
doc.modifiedOn = tx.modifiedOn
|
||||
return {}
|
||||
}
|
||||
|
||||
protected override async txCreateDoc (tx: TxCreateDoc<Doc>): Promise<void> {
|
||||
protected override async txCreateDoc (tx: TxCreateDoc<Doc>): Promise<TxResult> {
|
||||
this.addDoc(TxProcessor.createDoc2Doc(tx))
|
||||
return {}
|
||||
}
|
||||
|
||||
protected async txUpdateDoc (tx: TxUpdateDoc<Doc>): Promise<void> {
|
||||
protected async txUpdateDoc (tx: TxUpdateDoc<Doc>): Promise<TxResult> {
|
||||
const doc = this.getObject(tx.objectId) as any
|
||||
const ops = tx.operations as any
|
||||
for (const key in ops) {
|
||||
@ -208,15 +211,18 @@ export class ModelDb extends MemDb implements Storage {
|
||||
}
|
||||
doc.modifiedBy = tx.modifiedBy
|
||||
doc.modifiedOn = tx.modifiedOn
|
||||
return {}
|
||||
}
|
||||
|
||||
protected async txRemoveDoc (tx: TxRemoveDoc<Doc>): Promise<void> {
|
||||
protected async txRemoveDoc (tx: TxRemoveDoc<Doc>): Promise<TxResult> {
|
||||
this.delDoc(tx.objectId)
|
||||
return {}
|
||||
}
|
||||
|
||||
// TODO: process ancessor mixins
|
||||
protected async txMixin (tx: TxMixin<Doc, Doc>): Promise<void> {
|
||||
protected async txMixin (tx: TxMixin<Doc, Doc>): Promise<TxResult> {
|
||||
const obj = this.getObject(tx.objectId) as any
|
||||
obj[tx.mixin] = tx.attributes
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
@ -101,6 +101,12 @@ export type WithLookup<T extends Doc> = T & {
|
||||
*/
|
||||
export type FindResult<T extends Doc> = WithLookup<T>[]
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface TxResult {}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
@ -110,5 +116,5 @@ export interface Storage {
|
||||
query: DocumentQuery<T>,
|
||||
options?: FindOptions<T>
|
||||
) => Promise<FindResult<T>>
|
||||
tx: (tx: Tx) => Promise<void>
|
||||
tx: (tx: Tx) => Promise<TxResult>
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
import type { KeysByType } from 'simplytyped'
|
||||
import type { Class, Data, Doc, Domain, Ref, Account, Space, Arr, Mixin, PropertyType } from './classes'
|
||||
import { DocumentQuery, FindOptions, FindResult, Storage, WithLookup } from './storage'
|
||||
import type { DocumentQuery, FindOptions, FindResult, Storage, WithLookup, TxResult } from './storage'
|
||||
import core from './component'
|
||||
import { generateId } from './utils'
|
||||
|
||||
@ -172,14 +172,14 @@ export const DOMAIN_TX = 'tx' as Domain
|
||||
* @public
|
||||
*/
|
||||
export interface WithTx {
|
||||
tx: (tx: Tx) => Promise<void>
|
||||
tx: (tx: Tx) => Promise<TxResult>
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export abstract class TxProcessor implements WithTx {
|
||||
async tx (tx: Tx): Promise<void> {
|
||||
async tx (tx: Tx): Promise<TxResult> {
|
||||
switch (tx._class) {
|
||||
case core.class.TxCreateDoc:
|
||||
return await this.txCreateDoc(tx as TxCreateDoc<Doc>)
|
||||
@ -209,17 +209,18 @@ export abstract class TxProcessor implements WithTx {
|
||||
} as T
|
||||
}
|
||||
|
||||
protected abstract txCreateDoc (tx: TxCreateDoc<Doc>): Promise<void>
|
||||
protected abstract txPutBag (tx: TxPutBag<PropertyType>): Promise<void>
|
||||
protected abstract txUpdateDoc (tx: TxUpdateDoc<Doc>): Promise<void>
|
||||
protected abstract txRemoveDoc (tx: TxRemoveDoc<Doc>): Promise<void>
|
||||
protected abstract txMixin (tx: TxMixin<Doc, Doc>): Promise<void>
|
||||
protected abstract txCreateDoc (tx: TxCreateDoc<Doc>): Promise<TxResult>
|
||||
protected abstract txPutBag (tx: TxPutBag<PropertyType>): Promise<TxResult>
|
||||
protected abstract txUpdateDoc (tx: TxUpdateDoc<Doc>): Promise<TxResult>
|
||||
protected abstract txRemoveDoc (tx: TxRemoveDoc<Doc>): Promise<TxResult>
|
||||
protected abstract txMixin (tx: TxMixin<Doc, Doc>): Promise<TxResult>
|
||||
|
||||
protected async txBulkWrite (bulkTx: TxBulkWrite): Promise<void> {
|
||||
protected async txBulkWrite (bulkTx: TxBulkWrite): Promise<TxResult> {
|
||||
for (const tx of bulkTx.txes) {
|
||||
console.log('bulk', tx)
|
||||
await this.tx(tx)
|
||||
}
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -241,7 +242,7 @@ export class TxOperations implements Storage {
|
||||
return (await this.findAll(_class, query, options))[0]
|
||||
}
|
||||
|
||||
tx (tx: Tx): Promise<void> {
|
||||
tx (tx: Tx): Promise<TxResult> {
|
||||
return this.storage.tx(tx)
|
||||
}
|
||||
|
||||
@ -263,7 +264,7 @@ export class TxOperations implements Storage {
|
||||
bag: string,
|
||||
key: string,
|
||||
value: P
|
||||
): Promise<void> {
|
||||
): Promise<TxResult> {
|
||||
const tx = this.txFactory.createTxPutBag(_class, space, objectId, bag, key, value)
|
||||
return this.storage.tx(tx)
|
||||
}
|
||||
@ -273,7 +274,7 @@ export class TxOperations implements Storage {
|
||||
space: Ref<Space>,
|
||||
objectId: Ref<T>,
|
||||
operations: DocumentUpdate<T>
|
||||
): Promise<void> {
|
||||
): Promise<TxResult> {
|
||||
const tx = this.txFactory.createTxUpdateDoc(_class, space, objectId, operations)
|
||||
return this.storage.tx(tx)
|
||||
}
|
||||
@ -282,7 +283,7 @@ export class TxOperations implements Storage {
|
||||
_class: Ref<Class<T>>,
|
||||
space: Ref<Space>,
|
||||
objectId: Ref<T>
|
||||
): Promise<void> {
|
||||
): Promise<TxResult> {
|
||||
const tx = this.txFactory.createTxRemoveDoc(_class, space, objectId)
|
||||
return this.storage.tx(tx)
|
||||
}
|
||||
@ -292,7 +293,7 @@ export class TxOperations implements Storage {
|
||||
objectClass: Ref<Class<D>>,
|
||||
mixin: Ref<Mixin<M>>,
|
||||
attributes: ExtendedAttributes<D, M>
|
||||
): Promise<void> {
|
||||
): Promise<TxResult> {
|
||||
const tx = this.txFactory.createTxMixin(objectId, objectClass, mixin, attributes)
|
||||
return this.storage.tx(tx)
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
import { onDestroy } from 'svelte'
|
||||
|
||||
import { Doc, Ref, Class, DocumentQuery, FindOptions, Client, Hierarchy, Tx, getCurrentAccount, ModelDb } from '@anticrm/core'
|
||||
import { Doc, Ref, Class, DocumentQuery, FindOptions, Client, Hierarchy, Tx, getCurrentAccount, ModelDb, TxResult } from '@anticrm/core'
|
||||
import { TxOperations } from '@anticrm/core'
|
||||
import { LiveQuery as LQ } from '@anticrm/query'
|
||||
import core from '@anticrm/core'
|
||||
@ -38,7 +38,7 @@ class UIClient extends TxOperations implements Client {
|
||||
return this.client.getModel()
|
||||
}
|
||||
|
||||
tx(tx: Tx): Promise<void> {
|
||||
tx(tx: Tx): Promise<TxResult> {
|
||||
// return Promise.all([super.tx(tx), this.liveQuery.tx(tx)]) as unknown as Promise<void>
|
||||
return super.tx(tx)
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
import {
|
||||
Ref, Class, Doc, Tx, DocumentQuery, TxCreateDoc, TxRemoveDoc, Client,
|
||||
FindOptions, TxUpdateDoc, _getOperator, TxProcessor, resultSort, SortingQuery,
|
||||
FindResult, Hierarchy, Refs, WithLookup, LookupData, TxMixin, TxPutBag, ModelDb, TxBulkWrite
|
||||
FindResult, Hierarchy, Refs, WithLookup, LookupData, TxMixin, TxPutBag, ModelDb, TxBulkWrite, TxResult
|
||||
} from '@anticrm/core'
|
||||
|
||||
interface Query {
|
||||
@ -91,7 +91,7 @@ export class LiveQuery extends TxProcessor implements Client {
|
||||
}
|
||||
}
|
||||
|
||||
protected override async txPutBag (tx: TxPutBag<any>): Promise<void> {
|
||||
protected override async txPutBag (tx: TxPutBag<any>): Promise<TxResult> {
|
||||
for (const q of this.queries) {
|
||||
if (q.result instanceof Promise) {
|
||||
q.result = await q.result
|
||||
@ -107,13 +107,14 @@ export class LiveQuery extends TxProcessor implements Client {
|
||||
await this.callback(updatedDoc, q)
|
||||
}
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
protected txMixin (tx: TxMixin<Doc, Doc>): Promise<void> {
|
||||
protected txMixin (tx: TxMixin<Doc, Doc>): Promise<TxResult> {
|
||||
throw new Error('Method not implemented.')
|
||||
}
|
||||
|
||||
protected async txUpdateDoc (tx: TxUpdateDoc<Doc>): Promise<void> {
|
||||
protected async txUpdateDoc (tx: TxUpdateDoc<Doc>): Promise<TxResult> {
|
||||
console.log(`updating ${this.queries.length} queries`)
|
||||
for (const q of this.queries) {
|
||||
if (q.result instanceof Promise) {
|
||||
@ -126,6 +127,7 @@ export class LiveQuery extends TxProcessor implements Client {
|
||||
await this.callback(updatedDoc, q)
|
||||
}
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
private async lookup (doc: Doc, lookup: Refs<Doc>): Promise<void> {
|
||||
@ -138,7 +140,7 @@ export class LiveQuery extends TxProcessor implements Client {
|
||||
(doc as WithLookup<Doc>).$lookup = result
|
||||
}
|
||||
|
||||
protected async txCreateDoc (tx: TxCreateDoc<Doc>): Promise<void> {
|
||||
protected async txCreateDoc (tx: TxCreateDoc<Doc>): Promise<TxResult> {
|
||||
console.log('query tx', tx)
|
||||
for (const q of this.queries) {
|
||||
const doc = TxProcessor.createDoc2Doc(tx)
|
||||
@ -162,9 +164,10 @@ export class LiveQuery extends TxProcessor implements Client {
|
||||
}
|
||||
}
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
protected async txRemoveDoc (tx: TxRemoveDoc<Doc>): Promise<void> {
|
||||
protected async txRemoveDoc (tx: TxRemoveDoc<Doc>): Promise<TxResult> {
|
||||
for (const q of this.queries) {
|
||||
if (q.result instanceof Promise) {
|
||||
q.result = await q.result
|
||||
@ -175,16 +178,17 @@ export class LiveQuery extends TxProcessor implements Client {
|
||||
q.callback(q.result)
|
||||
}
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
protected override async txBulkWrite (tx: TxBulkWrite): Promise<void> {
|
||||
protected override async txBulkWrite (tx: TxBulkWrite): Promise<TxResult> {
|
||||
console.log('query: bulk')
|
||||
await super.txBulkWrite(tx)
|
||||
return await super.txBulkWrite(tx)
|
||||
}
|
||||
|
||||
async tx (tx: Tx): Promise<void> {
|
||||
async tx (tx: Tx): Promise<TxResult> {
|
||||
console.log('query tx', tx)
|
||||
await super.tx(tx)
|
||||
return await super.tx(tx)
|
||||
}
|
||||
|
||||
// why this is separate from txUpdateDoc?
|
||||
|
@ -14,7 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import type { Class, Doc, DocumentQuery, FindOptions, FindResult, Ref, Storage, Tx, TxHander } from '@anticrm/core'
|
||||
import type { Class, Doc, DocumentQuery, FindOptions, FindResult, Ref, Storage, Tx, TxHander, TxResult } from '@anticrm/core'
|
||||
import type { ReqId } from '@anticrm/platform'
|
||||
import { serialize, readResponse } from '@anticrm/platform'
|
||||
|
||||
@ -94,7 +94,7 @@ class Connection implements Storage {
|
||||
return this.sendRequest('findAll', _class, query, options)
|
||||
}
|
||||
|
||||
tx (tx: Tx): Promise<void> {
|
||||
tx (tx: Tx): Promise<TxResult> {
|
||||
return this.sendRequest('tx', tx)
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { Tx, Storage, Class, Doc, DocumentQuery, FindOptions, Ref, FindResult } from '@anticrm/core'
|
||||
import type { Tx, Storage, Class, Doc, DocumentQuery, FindOptions, Ref, FindResult, TxResult } from '@anticrm/core'
|
||||
import { serialize } from '@anticrm/platform'
|
||||
import WebSocket from 'ws'
|
||||
|
||||
@ -29,11 +29,12 @@ export class ContributingClient implements Storage {
|
||||
throw new Error('findAll not implemeneted for contributing client')
|
||||
}
|
||||
|
||||
async tx (tx: Tx): Promise<void> {
|
||||
async tx (tx: Tx): Promise<TxResult> {
|
||||
this.websocket.send(serialize({
|
||||
method: 'tx',
|
||||
params: [tx]
|
||||
}))
|
||||
return {}
|
||||
}
|
||||
|
||||
close (): void {
|
||||
|
@ -15,7 +15,7 @@
|
||||
//
|
||||
|
||||
import core, { Hierarchy, AnyAttribute, Storage, DocumentQuery, FindOptions, FindResult, TxProcessor, TxMixin, TxPutBag, TxRemoveDoc } from '@anticrm/core'
|
||||
import type { AttachedDoc, TxUpdateDoc, TxCreateDoc, Doc, Ref, Class, Obj } from '@anticrm/core'
|
||||
import type { AttachedDoc, TxUpdateDoc, TxCreateDoc, Doc, Ref, Class, Obj, TxResult } from '@anticrm/core'
|
||||
|
||||
import type { IndexedDoc, FullTextAdapter, WithFind } from './types'
|
||||
|
||||
@ -33,15 +33,17 @@ export class FullTextIndex extends TxProcessor implements Storage {
|
||||
super()
|
||||
}
|
||||
|
||||
protected override async txPutBag (tx: TxPutBag<any>): Promise<void> {
|
||||
protected override async txPutBag (tx: TxPutBag<any>): Promise<TxResult> {
|
||||
console.log('FullTextIndex.txPutBag: Method not implemented.')
|
||||
return {}
|
||||
}
|
||||
|
||||
protected override async txRemoveDoc (tx: TxRemoveDoc<Doc>): Promise<void> {
|
||||
protected override async txRemoveDoc (tx: TxRemoveDoc<Doc>): Promise<TxResult> {
|
||||
console.log('FullTextIndex.txRemoveDoc: Method not implemented.')
|
||||
return {}
|
||||
}
|
||||
|
||||
protected txMixin (tx: TxMixin<Doc, Doc>): Promise<void> {
|
||||
protected txMixin (tx: TxMixin<Doc, Doc>): Promise<TxResult> {
|
||||
throw new Error('Method not implemented.')
|
||||
}
|
||||
|
||||
@ -74,9 +76,9 @@ export class FullTextIndex extends TxProcessor implements Storage {
|
||||
}
|
||||
}
|
||||
|
||||
protected override async txCreateDoc (tx: TxCreateDoc<Doc>): Promise<void> {
|
||||
protected override async txCreateDoc (tx: TxCreateDoc<Doc>): Promise<TxResult> {
|
||||
const attributes = this.getFullTextAttributes(tx.objectClass)
|
||||
if (attributes === undefined) return
|
||||
if (attributes === undefined) return {}
|
||||
const doc = TxProcessor.createDoc2Doc(tx)
|
||||
const content = attributes.map(attr => (doc as any)[attr.name]) // buildContent(doc, attributes) // (doc as any)[attribute.name]
|
||||
const indexedDoc: IndexedDoc = {
|
||||
@ -100,9 +102,9 @@ export class FullTextIndex extends TxProcessor implements Storage {
|
||||
return await this.adapter.index(indexedDoc)
|
||||
}
|
||||
|
||||
protected override async txUpdateDoc (tx: TxUpdateDoc<Doc>): Promise<void> {
|
||||
protected override async txUpdateDoc (tx: TxUpdateDoc<Doc>): Promise<TxResult> {
|
||||
const attributes = this.getFullTextAttributes(tx.objectClass)
|
||||
if (attributes === undefined) return
|
||||
if (attributes === undefined) return {}
|
||||
const ops: any = tx.operations
|
||||
const update: any = {}
|
||||
let i = 0
|
||||
@ -117,5 +119,6 @@ export class FullTextIndex extends TxProcessor implements Storage {
|
||||
if (shouldUpdate) {
|
||||
return await this.adapter.update(tx.objectId, update)
|
||||
}
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import type { ServerStorage, Domain, Tx, TxCUD, Doc, Ref, Class, DocumentQuery, FindResult, FindOptions, Storage, TxBulkWrite } from '@anticrm/core'
|
||||
import type { ServerStorage, Domain, Tx, TxCUD, Doc, Ref, Class, DocumentQuery, FindResult, FindOptions, Storage, TxBulkWrite, TxResult } from '@anticrm/core'
|
||||
import core, { Hierarchy, DOMAIN_TX, ModelDb } from '@anticrm/core'
|
||||
import type { FullTextAdapterFactory, FullTextAdapter } from './types'
|
||||
import { FullTextIndex } from './fulltext'
|
||||
@ -88,7 +88,7 @@ class TServerStorage implements ServerStorage {
|
||||
return adapter
|
||||
}
|
||||
|
||||
private async routeTx (tx: Tx): Promise<void> {
|
||||
private async routeTx (tx: Tx): Promise<TxResult> {
|
||||
if (this.hierarchy.isDerived(tx._class, core.class.TxCUD)) {
|
||||
const txCUD = tx as TxCUD<Doc>
|
||||
const domain = this.hierarchy.getDomain(txCUD.objectClass)
|
||||
@ -102,6 +102,7 @@ class TServerStorage implements ServerStorage {
|
||||
} else {
|
||||
throw new Error('not implemented (routeTx)')
|
||||
}
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import type { Tx, Ref, Doc, Class, Space, Timestamp, Account, FindResult, DocumentQuery, FindOptions } from '@anticrm/core'
|
||||
import type { Tx, Ref, Doc, Class, Space, Timestamp, Account, FindResult, DocumentQuery, FindOptions, TxResult } from '@anticrm/core'
|
||||
import { TxFactory, Hierarchy } from '@anticrm/core'
|
||||
import type { Resource } from '@anticrm/platform'
|
||||
|
||||
@ -67,8 +67,8 @@ export type SearchQuery = any // TODO: replace with DocumentQuery
|
||||
* @public
|
||||
*/
|
||||
export interface FullTextAdapter {
|
||||
index: (doc: IndexedDoc) => Promise<void>
|
||||
update: (id: Ref<Doc>, update: Record<string, any>) => Promise<void>
|
||||
index: (doc: IndexedDoc) => Promise<TxResult>
|
||||
update: (id: Ref<Doc>, update: Record<string, any>) => Promise<TxResult>
|
||||
search: (query: SearchQuery) => Promise<IndexedDoc[]>
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import type { Doc, Ref } from '@anticrm/core'
|
||||
import type { Doc, Ref, TxResult } from '@anticrm/core'
|
||||
import type { FullTextAdapter, IndexedDoc, SearchQuery } from '@anticrm/server-core'
|
||||
|
||||
import { Client } from '@elastic/elasticsearch'
|
||||
@ -58,7 +58,7 @@ class ElasticAdapter implements FullTextAdapter {
|
||||
return hits.map(hit => hit._source)
|
||||
}
|
||||
|
||||
async index (doc: IndexedDoc): Promise<void> {
|
||||
async index (doc: IndexedDoc): Promise<TxResult> {
|
||||
console.log('eastic: index', doc)
|
||||
if (doc.data === undefined) {
|
||||
const resp = await this.client.index({
|
||||
@ -81,9 +81,10 @@ class ElasticAdapter implements FullTextAdapter {
|
||||
console.log('resp', resp)
|
||||
console.log('error', (resp.meta as any)?.body?.error)
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
async update (id: Ref<Doc>, update: Record<string, any>): Promise<void> {
|
||||
async update (id: Ref<Doc>, update: Record<string, any>): Promise<TxResult> {
|
||||
const resp = await this.client.update({
|
||||
index: this.db,
|
||||
id,
|
||||
@ -92,6 +93,7 @@ class ElasticAdapter implements FullTextAdapter {
|
||||
}
|
||||
})
|
||||
console.log('update', resp)
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import type { Tx, Ref, Doc, Class, DocumentQuery, FindResult, FindOptions, TxCreateDoc, TxUpdateDoc, TxMixin, TxPutBag, TxRemoveDoc } from '@anticrm/core'
|
||||
import type { Tx, Ref, Doc, Class, DocumentQuery, FindResult, FindOptions, TxCreateDoc, TxUpdateDoc, TxMixin, TxPutBag, TxRemoveDoc, TxResult } from '@anticrm/core'
|
||||
import core, { DOMAIN_TX, DOMAIN_MODEL, SortingOrder, TxProcessor, Hierarchy, isOperator, ModelDb } from '@anticrm/core'
|
||||
|
||||
import type { DbAdapter, TxAdapter } from '@anticrm/server-core'
|
||||
@ -121,27 +121,29 @@ abstract class MongoAdapterBase extends TxProcessor {
|
||||
}
|
||||
|
||||
class MongoAdapter extends MongoAdapterBase {
|
||||
protected override async txPutBag (tx: TxPutBag<any>): Promise<void> {
|
||||
protected override async txPutBag (tx: TxPutBag<any>): Promise<TxResult> {
|
||||
const domain = this.hierarchy.getDomain(tx.objectClass)
|
||||
console.log('mongo', { $set: { [tx.bag + '.' + tx.key]: tx.value } })
|
||||
await this.db.collection(domain).updateOne({ _id: tx.objectId }, { $set: { [tx.bag + '.' + tx.key]: tx.value } })
|
||||
return {}
|
||||
}
|
||||
|
||||
protected txRemoveDoc (tx: TxRemoveDoc<Doc>): Promise<void> {
|
||||
protected txRemoveDoc (tx: TxRemoveDoc<Doc>): Promise<TxResult> {
|
||||
throw new Error('Method not implemented.')
|
||||
}
|
||||
|
||||
protected txMixin (tx: TxMixin<Doc, Doc>): Promise<void> {
|
||||
protected txMixin (tx: TxMixin<Doc, Doc>): Promise<TxResult> {
|
||||
throw new Error('Method not implemented.')
|
||||
}
|
||||
|
||||
protected override async txCreateDoc (tx: TxCreateDoc<Doc>): Promise<void> {
|
||||
protected override async txCreateDoc (tx: TxCreateDoc<Doc>): Promise<TxResult> {
|
||||
const doc = TxProcessor.createDoc2Doc(tx)
|
||||
const domain = this.hierarchy.getDomain(doc._class)
|
||||
await this.db.collection(domain).insertOne(translateDoc(doc))
|
||||
return {}
|
||||
}
|
||||
|
||||
protected override async txUpdateDoc (tx: TxUpdateDoc<Doc>): Promise<void> {
|
||||
protected override async txUpdateDoc (tx: TxUpdateDoc<Doc>): Promise<TxResult> {
|
||||
const domain = this.hierarchy.getDomain(tx.objectClass)
|
||||
if (isOperator(tx.operations)) {
|
||||
const operator = Object.keys(tx.operations)[0]
|
||||
@ -182,38 +184,40 @@ class MongoAdapter extends MongoAdapterBase {
|
||||
} else {
|
||||
await this.db.collection(domain).updateOne({ _id: tx.objectId }, { $set: tx.operations })
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
override tx (tx: Tx): Promise<void> {
|
||||
override tx (tx: Tx): Promise<TxResult> {
|
||||
console.log('mongo', tx)
|
||||
return super.tx(tx)
|
||||
}
|
||||
}
|
||||
|
||||
class MongoTxAdapter extends MongoAdapterBase implements TxAdapter {
|
||||
protected txCreateDoc (tx: TxCreateDoc<Doc>): Promise<void> {
|
||||
protected txCreateDoc (tx: TxCreateDoc<Doc>): Promise<TxResult> {
|
||||
throw new Error('Method not implemented.')
|
||||
}
|
||||
|
||||
protected txPutBag (tx: TxPutBag<any>): Promise<void> {
|
||||
protected txPutBag (tx: TxPutBag<any>): Promise<TxResult> {
|
||||
throw new Error('Method not implemented.')
|
||||
}
|
||||
|
||||
protected txUpdateDoc (tx: TxUpdateDoc<Doc>): Promise<void> {
|
||||
protected txUpdateDoc (tx: TxUpdateDoc<Doc>): Promise<TxResult> {
|
||||
throw new Error('Method not implemented.')
|
||||
}
|
||||
|
||||
protected txRemoveDoc (tx: TxRemoveDoc<Doc>): Promise<void> {
|
||||
protected txRemoveDoc (tx: TxRemoveDoc<Doc>): Promise<TxResult> {
|
||||
throw new Error('Method not implemented.')
|
||||
}
|
||||
|
||||
protected txMixin (tx: TxMixin<Doc, Doc>): Promise<void> {
|
||||
protected txMixin (tx: TxMixin<Doc, Doc>): Promise<TxResult> {
|
||||
throw new Error('Method not implemented.')
|
||||
}
|
||||
|
||||
override async tx (tx: Tx): Promise<void> {
|
||||
override async tx (tx: Tx): Promise<TxResult> {
|
||||
console.log('mongotx', tx)
|
||||
await this.db.collection(DOMAIN_TX).insertOne(translateDoc(tx))
|
||||
return {}
|
||||
}
|
||||
|
||||
async getModel (): Promise<Tx[]> {
|
||||
|
@ -14,7 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { Class, Doc, DocumentQuery, DOMAIN_MODEL, DOMAIN_TX, FindOptions, FindResult, Hierarchy, ModelDb, Ref, Tx } from '@anticrm/core'
|
||||
import { Class, Doc, DocumentQuery, DOMAIN_MODEL, DOMAIN_TX, FindOptions, FindResult, Hierarchy, ModelDb, Ref, Tx, TxResult } from '@anticrm/core'
|
||||
import { start as startJsonRpc } from '@anticrm/server-ws'
|
||||
import { createMongoAdapter, createMongoTxAdapter } from '@anticrm/mongo'
|
||||
import { createElasticAdapter } from '@anticrm/elastic'
|
||||
@ -29,7 +29,7 @@ import { serverViewId } from '@anticrm/server-view'
|
||||
class NullDbAdapter implements DbAdapter {
|
||||
async init (model: Tx[]): Promise<void> {}
|
||||
async findAll <T extends Doc>(_class: Ref<Class<T>>, query: DocumentQuery<T>, options?: FindOptions<T> | undefined): Promise<FindResult<T>> { return [] }
|
||||
async tx (tx: Tx): Promise<void> {}
|
||||
async tx (tx: Tx): Promise<TxResult> { return {} }
|
||||
}
|
||||
|
||||
async function createNullAdapter (hierarchy: Hierarchy, url: string, db: string, modelDb: ModelDb): Promise<DbAdapter> {
|
||||
|
@ -20,7 +20,7 @@ import { createServer, IncomingMessage } from 'http'
|
||||
import WebSocket, { Server } from 'ws'
|
||||
import { decode } from 'jwt-simple'
|
||||
|
||||
import type { Doc, Ref, Class, FindOptions, FindResult, Tx, DocumentQuery, Storage, ServerStorage } from '@anticrm/core'
|
||||
import type { Doc, Ref, Class, FindOptions, FindResult, Tx, DocumentQuery, Storage, ServerStorage, TxResult } from '@anticrm/core'
|
||||
|
||||
let LOGGING_ENABLED = true
|
||||
|
||||
@ -39,12 +39,13 @@ class Session implements Storage {
|
||||
return await this.storage.findAll(_class, query, options)
|
||||
}
|
||||
|
||||
async tx (tx: Tx): Promise<void> {
|
||||
async tx (tx: Tx): Promise<TxResult> {
|
||||
const derived = await this.storage.tx(tx)
|
||||
this.manager.broadcast(this, this.token, { result: tx })
|
||||
for (const tx of derived) {
|
||||
this.manager.broadcast(null, this.token, { result: tx })
|
||||
}
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user