@blocksuite/store
Advanced tools
Comparing version 0.4.0 to 0.4.1-20230219164430-614cf52
@@ -5,4 +5,8 @@ /// <reference types="@blocksuite/global" /> | ||
import { z } from 'zod'; | ||
import type { Text } from './text-adapter.js'; | ||
import { Text } from './text-adapter.js'; | ||
import type { Page } from './workspace/index.js'; | ||
export interface InternalPrimitives { | ||
Text: (input?: Y.Text | string) => Text; | ||
} | ||
export declare const internalPrimitives: InternalPrimitives; | ||
export declare const BlockSchema: z.ZodObject<{ | ||
@@ -22,3 +26,3 @@ version: z.ZodNumber; | ||
}>; | ||
props: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodAny>>; | ||
props: z.ZodFunction<z.ZodTuple<[z.ZodType<InternalPrimitives, z.ZodTypeDef, InternalPrimitives>], z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodAny>>; | ||
}, "strip", z.ZodTypeAny, { | ||
@@ -30,3 +34,3 @@ flavour: string; | ||
}; | ||
props: (...args: unknown[]) => Record<string, any>; | ||
props: (args_0: InternalPrimitives, ...args_1: unknown[]) => Record<string, any>; | ||
}, { | ||
@@ -38,3 +42,3 @@ flavour: string; | ||
}; | ||
props: (...args: unknown[]) => Record<string, any>; | ||
props: (args_0: InternalPrimitives, ...args_1: unknown[]) => Record<string, any>; | ||
}>; | ||
@@ -49,3 +53,3 @@ }, "strip", z.ZodTypeAny, { | ||
}; | ||
props: (...args: unknown[]) => Record<string, any>; | ||
props: (args_0: InternalPrimitives, ...args_1: unknown[]) => Record<string, any>; | ||
}; | ||
@@ -60,5 +64,7 @@ }, { | ||
}; | ||
props: (...args: unknown[]) => Record<string, any>; | ||
props: (args_0: InternalPrimitives, ...args_1: unknown[]) => Record<string, any>; | ||
}; | ||
}>; | ||
export type PropsSetter<Props extends Record<string, unknown>> = (props: Props) => Partial<Props>; | ||
export type PropsGetter<Props extends Record<string, unknown>> = (internalPrimitives: InternalPrimitives) => Props; | ||
interface StaticValue { | ||
@@ -70,3 +76,3 @@ _$litStatic$: string; | ||
model: { | ||
props: () => Record<string, unknown>; | ||
props: PropsGetter<Record<string, unknown>>; | ||
flavour: string; | ||
@@ -80,6 +86,6 @@ }; | ||
tag: StaticValue; | ||
}>>(flavour: Flavour, props: () => Props, metadata: Metadata): { | ||
}>>(flavour: Flavour, props: (internalPrimitives: InternalPrimitives) => Props, metadata: Metadata): { | ||
version: number; | ||
model: { | ||
props: () => Props; | ||
props: PropsGetter<Props>; | ||
flavour: Flavour; | ||
@@ -86,0 +92,0 @@ } & Metadata; |
import { Signal } from '@blocksuite/global/utils'; | ||
import { z } from 'zod'; | ||
import { Text } from './text-adapter.js'; | ||
const FlavourSchema = z.string(); | ||
@@ -8,2 +9,5 @@ const TagSchema = z.object({ | ||
}); | ||
export const internalPrimitives = Object.freeze({ | ||
Text: (input = '') => new Text(input), | ||
}); | ||
export const BlockSchema = z.object({ | ||
@@ -14,3 +18,6 @@ version: z.number(), | ||
tag: TagSchema, | ||
props: z.function().returns(z.record(z.any())), | ||
props: z | ||
.function() | ||
.args(z.custom()) | ||
.returns(z.record(z.any())), | ||
}), | ||
@@ -17,0 +24,0 @@ }); |
@@ -138,2 +138,5 @@ import * as Y from 'yjs'; | ||
insertList(insertTexts, index) { | ||
if (!insertTexts.length) { | ||
return; | ||
} | ||
this._transact(() => { | ||
@@ -140,0 +143,0 @@ for (let i = insertTexts.length - 1; i >= 0; i--) { |
/// <reference types="@blocksuite/global" /> | ||
import type { BaseBlockModel } from '../base.js'; | ||
import type { z } from 'zod'; | ||
import { BaseBlockModel, BlockSchema } from '../base.js'; | ||
import type { Workspace } from '../workspace/index.js'; | ||
@@ -8,3 +9,3 @@ import type { BlockProps, YBlock, YBlocks } from '../workspace/page.js'; | ||
export declare function initInternalProps(yBlock: YBlock, props: Partial<BlockProps>): void; | ||
export declare function syncBlockProps(defaultProps: Record<string, unknown>, yBlock: YBlock, props: Partial<BlockProps>, ignoredKeys: Set<string>): void; | ||
export declare function syncBlockProps(schema: z.infer<typeof BlockSchema>, defaultProps: Record<string, unknown>, yBlock: YBlock, props: Partial<BlockProps>, ignoredKeys: Set<string>): void; | ||
export declare function toBlockProps(yBlock: YBlock): Partial<BlockProps>; | ||
@@ -11,0 +12,0 @@ export declare function encodeWorkspaceAsYjsUpdateV2(workspace: Workspace): string; |
import { isPrimitive, matchFlavours, SYS_KEYS } from '@blocksuite/global/utils'; | ||
import { fromBase64, toBase64 } from 'lib0/buffer.js'; | ||
import * as Y from 'yjs'; | ||
import { internalPrimitives } from '../base.js'; | ||
import { Text } from '../text-adapter.js'; | ||
@@ -27,11 +28,9 @@ export function assertValidChildren(yBlocks, props) { | ||
} | ||
export function syncBlockProps( | ||
// schema: z.infer<typeof BlockSchema>, | ||
defaultProps, yBlock, props, ignoredKeys) { | ||
Object.keys(props).forEach(key => { | ||
export function syncBlockProps(schema, defaultProps, yBlock, props, ignoredKeys) { | ||
const propSchema = schema.model.props(internalPrimitives); | ||
Object.entries(props).forEach(([key, value]) => { | ||
if (SYS_KEYS.has(key) || ignoredKeys.has(key)) | ||
return; | ||
const value = props[key]; | ||
// TODO use schema | ||
if (key === 'text' && value instanceof Text) { | ||
const isText = propSchema[key] instanceof Text; | ||
if (isText) { | ||
yBlock.set(`prop:${key}`, value.yText); | ||
@@ -55,3 +54,6 @@ return; | ||
if (!yBlock.has(`prop:${key}`)) { | ||
if (Array.isArray(value)) { | ||
if (value instanceof Text) { | ||
yBlock.set(`prop:${key}`, new Y.Text()); | ||
} | ||
else if (Array.isArray(value)) { | ||
yBlock.set(`prop:${key}`, Y.Array.from(value)); | ||
@@ -58,0 +60,0 @@ } |
@@ -78,2 +78,14 @@ /// <reference types="@blocksuite/global" /> | ||
getNextSiblings(block: BaseBlockModel): BaseBlockModel<unknown>[]; | ||
getSchemaByFlavour(flavour: string): { | ||
version: number; | ||
model: { | ||
flavour: string; | ||
tag: { | ||
_$litStatic$: string; | ||
r: symbol; | ||
}; | ||
props: (args_0: import("../base.js").InternalPrimitives, ...args_1: unknown[]) => Record<string, any>; | ||
}; | ||
} | undefined; | ||
getInitialPropsMapByFlavour(flavour: string): Record<string, unknown> | undefined; | ||
addBlocksByFlavour<ALLProps extends Record<string, any> = BlockSuiteModelProps.ALL, Flavour extends keyof ALLProps & string = keyof ALLProps & string>(blocks: Array<{ | ||
@@ -80,0 +92,0 @@ flavour: Flavour; |
@@ -8,6 +8,6 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { | ||
import { debug } from '@blocksuite/global/debug'; | ||
import { assertExists, matchFlavours, Signal } from '@blocksuite/global/utils'; | ||
import { assertExists, Signal } from '@blocksuite/global/utils'; | ||
import { uuidv4 } from 'lib0/random.js'; | ||
import * as Y from 'yjs'; | ||
import { BaseBlockModel } from '../base.js'; | ||
import { BaseBlockModel, internalPrimitives } from '../base.js'; | ||
import { Space } from '../space.js'; | ||
@@ -128,3 +128,7 @@ import { RichTextAdapter, Text } from '../text-adapter.js'; | ||
get root() { | ||
return Array.isArray(this._root) ? this._root[0] : this._root; | ||
const root = Array.isArray(this._root) ? this._root[0] : this._root; | ||
if (root && root.flavour !== 'affine:page') { | ||
console.error('data broken'); | ||
} | ||
return root; | ||
} | ||
@@ -276,2 +280,8 @@ get surface() { | ||
} | ||
getSchemaByFlavour(flavour) { | ||
return this.workspace.flavourSchemaMap.get(flavour); | ||
} | ||
getInitialPropsMapByFlavour(flavour) { | ||
return this.workspace.flavourInitialPropsMap.get(flavour); | ||
} | ||
addBlocksByFlavour(blocks, parent, parentIndex) { | ||
@@ -308,3 +318,5 @@ const ids = []; | ||
assertExists(defaultProps); | ||
syncBlockProps(defaultProps, yBlock, clonedProps, this._ignoredKeys); | ||
const schema = this.getSchemaByFlavour(flavour); | ||
assertExists(schema); | ||
syncBlockProps(schema, defaultProps, yBlock, clonedProps, this._ignoredKeys); | ||
if (typeof parent === 'string') { | ||
@@ -388,3 +400,5 @@ parent = this._blockMap.get(parent); | ||
assertExists(defaultProps); | ||
syncBlockProps(defaultProps, yBlock, props, this._ignoredKeys); | ||
const schema = this.workspace.flavourSchemaMap.get(model.flavour); | ||
assertExists(schema); | ||
syncBlockProps(schema, defaultProps, yBlock, props, this._ignoredKeys); | ||
}); | ||
@@ -531,3 +545,3 @@ } | ||
blockModel.tag = schema.model.tag; | ||
const modelProps = schema.model.props(); | ||
const modelProps = schema.model.props(internalPrimitives); | ||
Object.entries(modelProps).forEach(([key, value]) => { | ||
@@ -541,3 +555,3 @@ // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const yBlock = this._getYBlock(id); | ||
const isRoot = this._blockMap.size === 0; | ||
let isRoot = false; | ||
let isSurface = false; | ||
@@ -549,15 +563,14 @@ const props = toBlockProps(yBlock); | ||
} | ||
if (model.flavour === 'affine:page') { | ||
isRoot = true; | ||
} | ||
this._blockMap.set(props.id, model); | ||
if ( | ||
// TODO use schema | ||
matchFlavours(model, [ | ||
'affine:paragraph', | ||
'affine:list', | ||
'affine:code', | ||
]) && | ||
!yBlock.get('prop:text')) { | ||
this.transact(() => yBlock.set('prop:text', new Y.Text())); | ||
} | ||
const yText = yBlock.get('prop:text'); | ||
model.text = new Text(yText); | ||
const initialProps = this.workspace.flavourInitialPropsMap.get(model.flavour); | ||
assertExists(initialProps); | ||
Object.entries(initialProps).forEach(([key, value]) => { | ||
if (value instanceof Text) { | ||
const yText = yBlock.get(`prop:${key}`); | ||
Object.assign(model, { [key]: new Text(yText) }); | ||
} | ||
}); | ||
if (model.flavour === 'affine:page') { | ||
@@ -564,0 +577,0 @@ model.tags = yBlock.get('meta:tags'); |
@@ -75,3 +75,3 @@ /// <reference types="@blocksuite/global" /> | ||
}; | ||
props: (...args: unknown[]) => Record<string, any>; | ||
props: (args_0: import("../base.js").InternalPrimitives, ...args_1: unknown[]) => Record<string, any>; | ||
}; | ||
@@ -78,0 +78,0 @@ }>; |
import { Signal } from '@blocksuite/global/utils'; | ||
import * as Y from 'yjs'; | ||
import { BlobUploadState } from '../awareness.js'; | ||
import { BlockSchema } from '../base.js'; | ||
import { BlockSchema, internalPrimitives } from '../base.js'; | ||
import { BlobSyncState, getBlobStorage, } from '../persistence/blob/index.js'; | ||
@@ -231,3 +231,3 @@ import { Space } from '../space.js'; | ||
this.flavourSchemaMap.set(schema.model.flavour, schema); | ||
this.flavourInitialPropsMap.set(schema.model.flavour, schema.model.props()); | ||
this.flavourInitialPropsMap.set(schema.model.flavour, schema.model.props(internalPrimitives)); | ||
}); | ||
@@ -234,0 +234,0 @@ return this; |
{ | ||
"name": "@blocksuite/store", | ||
"version": "0.4.0", | ||
"version": "0.4.1-20230219164430-614cf52", | ||
"description": "BlockSuite data store built for general purpose state management.", | ||
@@ -11,4 +11,4 @@ "main": "dist/index.js", | ||
"dependencies": { | ||
"@blocksuite/global": "0.4.0", | ||
"@blocksuite/virgo": "0.4.0", | ||
"@blocksuite/global": "0.4.1-20230219164430-614cf52", | ||
"@blocksuite/virgo": "0.4.1-20230219164430-614cf52", | ||
"@types/flexsearch": "^0.7.3", | ||
@@ -15,0 +15,0 @@ "buffer": "^6.0.3", |
@@ -5,3 +5,3 @@ import { Signal } from '@blocksuite/global/utils'; | ||
import type { Text } from './text-adapter.js'; | ||
import { Text } from './text-adapter.js'; | ||
import type { Page } from './workspace/index.js'; | ||
@@ -15,2 +15,10 @@ | ||
export interface InternalPrimitives { | ||
Text: (input?: Y.Text | string) => Text; | ||
} | ||
export const internalPrimitives: InternalPrimitives = Object.freeze({ | ||
Text: (input: Y.Text | string = '') => new Text(input), | ||
}); | ||
export const BlockSchema = z.object({ | ||
@@ -21,6 +29,16 @@ version: z.number(), | ||
tag: TagSchema, | ||
props: z.function().returns(z.record(z.any())), | ||
props: z | ||
.function() | ||
.args(z.custom<InternalPrimitives>()) | ||
.returns(z.record(z.any())), | ||
}), | ||
}); | ||
export type PropsSetter<Props extends Record<string, unknown>> = ( | ||
props: Props | ||
) => Partial<Props>; | ||
export type PropsGetter<Props extends Record<string, unknown>> = ( | ||
internalPrimitives: InternalPrimitives | ||
) => Props; | ||
// ported from lit | ||
@@ -35,3 +53,3 @@ interface StaticValue { | ||
model: { | ||
props: () => Record<string, unknown>; | ||
props: PropsGetter<Record<string, unknown>>; | ||
flavour: string; | ||
@@ -54,3 +72,3 @@ }; | ||
flavour: Flavour, | ||
props: () => Props, | ||
props: (internalPrimitives: InternalPrimitives) => Props, | ||
metadata: Metadata | ||
@@ -60,3 +78,3 @@ ): { | ||
model: { | ||
props: () => Props; | ||
props: PropsGetter<Props>; | ||
flavour: Flavour; | ||
@@ -68,3 +86,3 @@ } & Metadata; | ||
flavour: string, | ||
props: () => Record<string, unknown>, | ||
props: (internalPrimitives: InternalPrimitives) => Record<string, unknown>, | ||
metadata: { | ||
@@ -71,0 +89,0 @@ version: number; |
@@ -187,2 +187,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ | ||
insertList(insertTexts: DeltaOperation[], index: number) { | ||
if (!insertTexts.length) { | ||
return; | ||
} | ||
this._transact(() => { | ||
@@ -189,0 +192,0 @@ for (let i = insertTexts.length - 1; i >= 0; i--) { |
import { isPrimitive, matchFlavours, SYS_KEYS } from '@blocksuite/global/utils'; | ||
import { fromBase64, toBase64 } from 'lib0/buffer.js'; | ||
import * as Y from 'yjs'; | ||
import type { z } from 'zod'; | ||
import type { BaseBlockModel } from '../base.js'; | ||
import { BaseBlockModel, BlockSchema, internalPrimitives } from '../base.js'; | ||
import { Text } from '../text-adapter.js'; | ||
@@ -45,3 +46,3 @@ import type { Workspace } from '../workspace/index.js'; | ||
export function syncBlockProps( | ||
// schema: z.infer<typeof BlockSchema>, | ||
schema: z.infer<typeof BlockSchema>, | ||
defaultProps: Record<string, unknown>, | ||
@@ -52,8 +53,8 @@ yBlock: YBlock, | ||
) { | ||
Object.keys(props).forEach(key => { | ||
const propSchema = schema.model.props(internalPrimitives); | ||
Object.entries(props).forEach(([key, value]) => { | ||
if (SYS_KEYS.has(key) || ignoredKeys.has(key)) return; | ||
const value = props[key]; | ||
// TODO use schema | ||
if (key === 'text' && value instanceof Text) { | ||
const isText = propSchema[key] instanceof Text; | ||
if (isText) { | ||
yBlock.set(`prop:${key}`, value.yText); | ||
@@ -78,3 +79,5 @@ return; | ||
if (!yBlock.has(`prop:${key}`)) { | ||
if (Array.isArray(value)) { | ||
if (value instanceof Text) { | ||
yBlock.set(`prop:${key}`, new Y.Text()); | ||
} else if (Array.isArray(value)) { | ||
yBlock.set(`prop:${key}`, Y.Array.from(value)); | ||
@@ -81,0 +84,0 @@ } else { |
import type { BlockTag, TagSchema } from '@blocksuite/global/database'; | ||
import { debug } from '@blocksuite/global/debug'; | ||
import { assertExists, matchFlavours, Signal } from '@blocksuite/global/utils'; | ||
import { assertExists, Signal } from '@blocksuite/global/utils'; | ||
import { uuidv4 } from 'lib0/random.js'; | ||
@@ -9,3 +9,3 @@ import type { Quill } from 'quill'; | ||
import type { AwarenessStore } from '../awareness.js'; | ||
import { BaseBlockModel } from '../base.js'; | ||
import { BaseBlockModel, internalPrimitives } from '../base.js'; | ||
import { Space, StackItem } from '../space.js'; | ||
@@ -115,3 +115,7 @@ import { RichTextAdapter, Text } from '../text-adapter.js'; | ||
get root() { | ||
return Array.isArray(this._root) ? this._root[0] : this._root; | ||
const root = Array.isArray(this._root) ? this._root[0] : this._root; | ||
if (root && root.flavour !== 'affine:page') { | ||
console.error('data broken'); | ||
} | ||
return root; | ||
} | ||
@@ -318,2 +322,10 @@ | ||
getSchemaByFlavour(flavour: string) { | ||
return this.workspace.flavourSchemaMap.get(flavour); | ||
} | ||
getInitialPropsMapByFlavour(flavour: string) { | ||
return this.workspace.flavourInitialPropsMap.get(flavour); | ||
} | ||
@debug('CRUD') | ||
@@ -390,3 +402,11 @@ public addBlocksByFlavour< | ||
assertExists(defaultProps); | ||
syncBlockProps(defaultProps, yBlock, clonedProps, this._ignoredKeys); | ||
const schema = this.getSchemaByFlavour(flavour); | ||
assertExists(schema); | ||
syncBlockProps( | ||
schema, | ||
defaultProps, | ||
yBlock, | ||
clonedProps, | ||
this._ignoredKeys | ||
); | ||
@@ -495,3 +515,5 @@ if (typeof parent === 'string') { | ||
assertExists(defaultProps); | ||
syncBlockProps(defaultProps, yBlock, props, this._ignoredKeys); | ||
const schema = this.workspace.flavourSchemaMap.get(model.flavour); | ||
assertExists(schema); | ||
syncBlockProps(schema, defaultProps, yBlock, props, this._ignoredKeys); | ||
}); | ||
@@ -725,3 +747,3 @@ } | ||
blockModel.tag = schema.model.tag; | ||
const modelProps = schema.model.props(); | ||
const modelProps = schema.model.props(internalPrimitives); | ||
Object.entries(modelProps).forEach(([key, value]) => { | ||
@@ -736,3 +758,3 @@ // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const yBlock = this._getYBlock(id); | ||
const isRoot = this._blockMap.size === 0; | ||
let isRoot = false; | ||
let isSurface = false; | ||
@@ -745,18 +767,18 @@ | ||
} | ||
if (model.flavour === 'affine:page') { | ||
isRoot = true; | ||
} | ||
this._blockMap.set(props.id, model); | ||
if ( | ||
// TODO use schema | ||
matchFlavours(model, [ | ||
'affine:paragraph', | ||
'affine:list', | ||
'affine:code', | ||
]) && | ||
!yBlock.get('prop:text') | ||
) { | ||
this.transact(() => yBlock.set('prop:text', new Y.Text())); | ||
} | ||
const initialProps = this.workspace.flavourInitialPropsMap.get( | ||
model.flavour | ||
); | ||
assertExists(initialProps); | ||
Object.entries(initialProps).forEach(([key, value]) => { | ||
if (value instanceof Text) { | ||
const yText = yBlock.get(`prop:${key}`) as Y.Text; | ||
Object.assign(model, { [key]: new Text(yText) }); | ||
} | ||
}); | ||
const yText = yBlock.get('prop:text') as Y.Text; | ||
model.text = new Text(yText); | ||
if (model.flavour === 'affine:page') { | ||
@@ -763,0 +785,0 @@ model.tags = yBlock.get('meta:tags') as Y.Map<Y.Map<unknown>>; |
@@ -6,3 +6,3 @@ import { Signal } from '@blocksuite/global/utils'; | ||
import { AwarenessStore, BlobUploadState } from '../awareness.js'; | ||
import { BlockSchema } from '../base.js'; | ||
import { BlockSchema, internalPrimitives } from '../base.js'; | ||
import { | ||
@@ -330,3 +330,3 @@ BlobOptionsGetter, | ||
schema.model.flavour, | ||
schema.model.props() | ||
schema.model.props(internalPrimitives) | ||
); | ||
@@ -333,0 +333,0 @@ }); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
524395
8605
+ Added@blocksuite/global@0.4.1-20230219164430-614cf52(transitive)
+ Added@blocksuite/virgo@0.4.1-20230219164430-614cf52(transitive)
- Removed@blocksuite/global@0.4.0(transitive)
- Removed@blocksuite/virgo@0.4.0(transitive)