diff --git a/cloud/dev-server/app/index.js b/cloud/dev-server/app/index.js new file mode 100644 index 0000000000..c9e487569e --- /dev/null +++ b/cloud/dev-server/app/index.js @@ -0,0 +1,19 @@ +// +// Copyright © 2020, 2021 Anticrm Platform Contributors. +// Copyright © 2021 Hardcore Engineering Inc. +// +// 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. +// + +const start = require('@anticrm/dev-server') + +start (3333) diff --git a/cloud/dev-server/app/package-lock.json b/cloud/dev-server/app/package-lock.json new file mode 100644 index 0000000000..0fd8a82573 --- /dev/null +++ b/cloud/dev-server/app/package-lock.json @@ -0,0 +1,126 @@ +{ + "name": "@anticrm/dev-server-app", + "version": "0.6.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@anticrm/core": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@anticrm/core/-/core-0.6.4.tgz", + "integrity": "sha512-R4sy4iOJn+7mTLOmeS03KTLmDlPFLvT4gLAIo7VWSStpslVex+YoyRXulnhTIbBZikQFW88nAvAm5e4fhoiVgA==", + "requires": { + "@anticrm/platform": "~0.6.1", + "simplytyped": "^3.3.0" + } + }, + "@anticrm/dev-server": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@anticrm/dev-server/-/dev-server-0.6.1.tgz", + "integrity": "sha512-Zh04YOsHprDMjCybAzizImZtRntEmuyS7ko8gdTZKgmHq3Bypf4jRIai0WF8sjULVrcOKRAGEAVqdPBhwkwz2Q==", + "requires": { + "@anticrm/core": "~0.6.1", + "@anticrm/dev-storage": "~0.6.1", + "@anticrm/platform": "~0.6.1", + "@anticrm/server-ws": "~0.6.1" + } + }, + "@anticrm/dev-storage": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@anticrm/dev-storage/-/dev-storage-0.6.1.tgz", + "integrity": "sha512-MSmHqp6O50FMYtisuDZdVFds6wslHYhypMZ4QN+DqRaDYWa+rkEIETW3FKs3YLaMvrPCHphcHI8ZCsHL3eX3ew==", + "requires": { + "@anticrm/core": "~0.6.1", + "@anticrm/platform": "~0.6.1" + } + }, + "@anticrm/platform": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@anticrm/platform/-/platform-0.6.1.tgz", + "integrity": "sha512-Ay/deCr9NH5SgztB9CuNOMX2pJSy8GR9JAQbGZXTl9KpzGJhlXyRnCKvPyEeY0mHiVk72jLymRo3+Uis8grNoA==", + "requires": { + "intl-messageformat": "^9.7.1" + } + }, + "@anticrm/server-ws": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@anticrm/server-ws/-/server-ws-0.6.1.tgz", + "integrity": "sha512-hQpDfPeLpia3f2SlITtI+iJ1vXW5JL/U6eKjkufCjQtLzUKtz08FO9MnoFxb3xSPLiHpy/C/d6oPMOMNMgg/Mg==", + "requires": { + "@anticrm/platform": "~0.6.1", + "jwt-simple": "^0.5.6", + "ws": "^8.0.0" + } + }, + "@formatjs/ecma402-abstract": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.9.5.tgz", + "integrity": "sha512-cGpEBzrf9bL2lTMEuRZ3gjLrEUEucxAXDIdX4tNqNdNZO81ZN558BfjiFfyPgrhILEuJU/+sgLwWxddSn6usHw==", + "requires": { + "@formatjs/intl-localematcher": "0.2.18", + "tslib": "^2.1.0" + } + }, + "@formatjs/fast-memoize": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-1.1.1.tgz", + "integrity": "sha512-mIqBr5uigIlx13eZTOPSEh2buDiy3BCdMYUtewICREQjbb4xarDiVWoXSnrERM7NanZ+0TAHNXSqDe6HpEFQUg==" + }, + "@formatjs/icu-messageformat-parser": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.0.8.tgz", + "integrity": "sha512-fZlQ7ls3eQswO4RFB0lSi+ritPvud0Z2EQB6SU8qI5+MIS4qU4AHjq/dFJNvhdEdmJqLWHe31K4yHaRdavkSQQ==", + "requires": { + "@formatjs/ecma402-abstract": "1.9.5", + "@formatjs/icu-skeleton-parser": "1.2.9", + "tslib": "^2.1.0" + } + }, + "@formatjs/icu-skeleton-parser": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.2.9.tgz", + "integrity": "sha512-cx8Ug1gxRtv0rRddWd6dt5Sn/BhnhktSHvokbmLUVOEp2dy/6Ehvv2e00wow28AaSIzvBvM6ew1Qwe9wzDzcOw==", + "requires": { + "@formatjs/ecma402-abstract": "1.9.5", + "tslib": "^2.1.0" + } + }, + "@formatjs/intl-localematcher": { + "version": "0.2.18", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.18.tgz", + "integrity": "sha512-xI9X+mi7wbucbh35GNTY+C0+oMJXAp8ueC73SOyJlBpRNjLuOlSwgw3yJaCZxy3WpjcRBCP0laJ5zlpITO0QpA==", + "requires": { + "tslib": "^2.1.0" + } + }, + "intl-messageformat": { + "version": "9.8.1", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-9.8.1.tgz", + "integrity": "sha512-2rSZQu8GmLOlxNiehRvxWjkIqzemW833zm8ZS63JNvSpSuGnpqSWRqqwqv1kEBto/97/UBjtWy14m/CIdwVqFg==", + "requires": { + "@formatjs/fast-memoize": "1.1.1", + "@formatjs/icu-messageformat-parser": "2.0.8", + "tslib": "^2.1.0" + } + }, + "jwt-simple": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/jwt-simple/-/jwt-simple-0.5.6.tgz", + "integrity": "sha512-40aUybvhH9t2h71ncA1/1SbtTNCVZHgsTsTgqPUxGWDmUDrXyDf2wMNQKEbdBjbf4AI+fQhbECNTV6lWxQKUzg==" + }, + "simplytyped": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/simplytyped/-/simplytyped-3.3.0.tgz", + "integrity": "sha512-mz4RaNdKTZiaKXgi6P1k/cdsxV3gz+y1Wh2NXHWD40dExktLh4Xx/h6MFakmQWODZHj/2rKe59acacpL74ZhQA==" + }, + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + }, + "ws": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.0.0.tgz", + "integrity": "sha512-6AcSIXpBlS0QvCVKk+3cWnWElLsA6SzC0lkQ43ciEglgXJXiCWK3/CGFEJ+Ybgp006CMibamAsqOlxE9s4AvYA==" + } + } +} diff --git a/cloud/dev-server/app/package.json b/cloud/dev-server/app/package.json new file mode 100644 index 0000000000..5c56ca08b8 --- /dev/null +++ b/cloud/dev-server/app/package.json @@ -0,0 +1,12 @@ +{ + "name": "@anticrm/dev-server-app", + "version": "0.6.0", + "description": "", + "main": "index.js", + "scripts": { + "start": "node ./index.js" + }, + "dependencies": { + "@anticrm/dev-server": "^0.6.1" + } +} diff --git a/dev/server/src/index.ts b/dev/server/src/index.ts index 65ead4648c..d67bdedb8a 100644 --- a/dev/server/src/index.ts +++ b/dev/server/src/index.ts @@ -14,4 +14,4 @@ // limitations under the License. // -export { start } from './server' +export { start as default } from './server' diff --git a/packages/core/src/client.ts b/packages/core/src/client.ts index 603cae717f..415f14a3d0 100644 --- a/packages/core/src/client.ts +++ b/packages/core/src/client.ts @@ -23,8 +23,14 @@ import { TxProcessor } from './tx' import core from './component' -type TxHander = (tx: Tx) => void +/** + * @public + */ +export type TxHander = (tx: Tx) => void +/** + * @public + */ export interface Client extends Storage { getHierarchy: () => Hierarchy } @@ -53,6 +59,9 @@ class ClientImpl extends TxProcessor implements Storage, Client { } } +/** + * @public + */ export async function createClient ( connect: (txHandler: TxHander) => Promise, notify?: (tx: Tx) => void diff --git a/packages/core/src/component.ts b/packages/core/src/component.ts index 80e54a625b..7d8522cf2c 100644 --- a/packages/core/src/component.ts +++ b/packages/core/src/component.ts @@ -17,6 +17,9 @@ import { plugin } from '@anticrm/platform' import type { Account, Class, Doc, Obj, Ref, Space, AnyAttribute, Tx, TxCreateDoc, TxMixin } from './classes' import type { TxRemoveDoc, TxUpdateDoc } from './tx' +/** + * @public + */ export const coreId = 'core' as Plugin export default plugin(coreId, { diff --git a/packages/core/src/memdb.ts b/packages/core/src/memdb.ts index 8f7f98434c..54a817de7d 100644 --- a/packages/core/src/memdb.ts +++ b/packages/core/src/memdb.ts @@ -17,13 +17,16 @@ import { PlatformError, Severity, Status } from '@anticrm/platform' import type { Class, Doc, Ref, Tx, TxCreateDoc, TxMixin } from './classes' import core from './component' import type { Hierarchy } from './hierarchy' -import { getOperator } from './operator' +import { _getOperator } from './operator' import { findProperty, resultSort } from './query' import type { DocumentQuery, FindOptions, FindResult, Storage, WithLookup, LookupData, Refs } from './storage' import type { TxRemoveDoc, TxUpdateDoc } from './tx' import { TxProcessor } from './tx' -class MemDb extends TxProcessor { +/** + * @public + */ +export class MemDb extends TxProcessor { protected readonly hierarchy: Hierarchy private readonly objectsByClass = new Map>, Doc[]>() private readonly objectById = new Map, Doc>() @@ -138,7 +141,7 @@ class MemDb extends TxProcessor { /** * Hold transactions - * + * * @public */ export class TxDb extends MemDb implements Storage { @@ -149,7 +152,7 @@ export class TxDb extends MemDb implements Storage { /** * Hold model objects and classes - * + * * @public */ export class ModelDb extends MemDb implements Storage { @@ -162,7 +165,7 @@ export class ModelDb extends MemDb implements Storage { const ops = tx.operations as any for (const key in ops) { if (key.startsWith('$')) { - const operator = getOperator(key) + const operator = _getOperator(key) operator(doc, ops[key]) } else { doc[key] = ops[key] diff --git a/packages/core/src/operator.ts b/packages/core/src/operator.ts index 7d40eadd10..deda9a9746 100644 --- a/packages/core/src/operator.ts +++ b/packages/core/src/operator.ts @@ -16,7 +16,10 @@ import type { Doc, PropertyType } from './classes' -type OperatorFunc = (doc: Doc, op: object) => void +/** + * @internal + */ +export type _OperatorFunc = (doc: Doc, op: object) => void function $push (document: Doc, keyval: Record): void { const doc = document as any @@ -30,11 +33,16 @@ function $push (document: Doc, keyval: Record): void { } } -const operators: Record = { +const operators: Record = { $push } -export function getOperator (name: string): OperatorFunc { +/** + * @internal + * @param name - + * @returns + */ +export function _getOperator (name: string): _OperatorFunc { const operator = operators[name] if (operator === undefined) throw new Error('unknown operator: ' + name) return operator diff --git a/packages/core/src/query.ts b/packages/core/src/query.ts index 72daf92206..71c66c8e3c 100644 --- a/packages/core/src/query.ts +++ b/packages/core/src/query.ts @@ -2,14 +2,23 @@ import { Doc } from './classes' import { createPredicates, isPredicate } from './predicate' import { SortingQuery } from './storage' +/** + * @public + */ export const likeSymbol = '%' +/** + * @public + */ export function checkLikeQuery (value: string, query: string): boolean { const searchString = query.split(likeSymbol).join('.*') const regex = RegExp(`^${searchString}$`) return regex.test(value) } +/** + * @public + */ export function findProperty (objects: Doc[], propertyKey: string, value: any): Doc[] { if (isPredicate(value)) { const preds = createPredicates(value, propertyKey) @@ -27,6 +36,9 @@ export function findProperty (objects: Doc[], propertyKey: string, value: any): return result } +/** + * @public + */ export function resultSort (result: T[], sortOptions: SortingQuery): void { const sortFunc = (a: any, b: any): number => { for (const key in sortOptions) { diff --git a/packages/core/src/storage.ts b/packages/core/src/storage.ts index a911aa030f..072a7a63bf 100644 --- a/packages/core/src/storage.ts +++ b/packages/core/src/storage.ts @@ -16,20 +16,35 @@ import type { KeysByType } from 'simplytyped' import type { Class, Doc, Ref, Tx } from './classes' +/** + * @public + */ // eslint-disable-next-line @typescript-eslint/consistent-type-definitions export type QuerySelector = { $in?: T[] $like?: string } +/** + * @public + */ export type ObjQueryType = T | QuerySelector +/** + * @public + */ export type DocumentQuery = { [P in keyof T]?: ObjQueryType } +/** + * @public + */ export type Refs = Partial>>> +/** + * @public + */ // eslint-disable-next-line @typescript-eslint/consistent-type-definitions export type FindOptions = { limit?: number @@ -37,29 +52,53 @@ export type FindOptions = { lookup?: Refs } +/** + * @public + */ export type SortingQuery = { [P in keyof T]?: T[P] extends object ? never : SortingOrder } +/** + * @public + */ export enum SortingOrder { Ascending = 1, Descending = -1 } -type RefsAsDocs = { +/** + * @public + */ +export type RefsAsDocs = { [P in keyof T]: T[P] extends Ref ? X : never } -type RemoveNever = Omit> +/** + * @public + */ +export type RemoveNever = Omit> +/** + * @public + */ export type LookupData = Partial>> +/** + * @public + */ export type WithLookup = T & { $lookup?: LookupData } +/** + * @public + */ export type FindResult = WithLookup[] +/** + * @public + */ export interface Storage { findAll: ( _class: Ref>, diff --git a/packages/core/src/tx.ts b/packages/core/src/tx.ts index d6c4882497..c3d5373d18 100644 --- a/packages/core/src/tx.ts +++ b/packages/core/src/tx.ts @@ -18,31 +18,58 @@ import type { Class, Data, Doc, Domain, Ref, Account, Space, Arr, Mixin, Tx, TxC import core from './component' import { generateId } from './utils' -type ArrayAsElement = { +/** + * @public + */ +export type ArrayAsElement = { [P in keyof T]: T[P] extends Arr ? X : never } -type OmitNever = Omit> +/** + * @public + */ +export type OmitNever = Omit> -interface PushOptions { +/** + * @public + */ +export interface PushOptions { $push?: Partial>> } +/** + * @public + */ export type DocumentUpdate = Partial> & PushOptions +/** + * @public + */ export interface TxUpdateDoc extends Tx { operations: DocumentUpdate } +/** + * @public + */ export interface TxRemoveDoc extends Tx { } +/** + * @public + */ export const DOMAIN_TX = 'tx' as Domain -interface WithTx { +/** + * @public + */ +export interface WithTx { tx: (tx: Tx) => Promise } +/** + * @public + */ export class TxProcessor implements WithTx { async tx (tx: Tx): Promise { switch (tx._class) { @@ -75,6 +102,9 @@ export class TxProcessor implements WithTx { protected async txMixin (tx: TxMixin): Promise {} } +/** + * @public + */ export interface TxOperations { createDoc: (_class: Ref>, space: Ref, attributes: Data) => Promise updateDoc: ( @@ -86,6 +116,9 @@ export interface TxOperations { removeDoc: (_class: Ref>, space: Ref, objectId: Ref) => Promise } +/** + * @public + */ export function withOperations (user: Ref, storage: T): T & TxOperations { const result = storage as T & TxOperations @@ -150,6 +183,9 @@ export function withOperations (user: Ref, storage: T return result } +/** + * @public + */ export class DefaultTxFactory implements TxFactory { constructor (readonly account: Ref) {} diff --git a/packages/core/src/utils.ts b/packages/core/src/utils.ts index eef2c862ef..46a511992b 100644 --- a/packages/core/src/utils.ts +++ b/packages/core/src/utils.ts @@ -36,6 +36,10 @@ function count (): string { return toHex(val, 6) } +/** + * @public + * @returns + */ export function generateId (): Ref { return (timestamp() + random + count()) as Ref }