New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@blocksuite/store

Package Overview
Dependencies
Maintainers
5
Versions
1299
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@blocksuite/store - npm Package Compare versions

Comparing version 0.4.0-20230126161407-c60bfba to 0.4.0-20230127234317-bfe4022

dist/persistence/blob/cloud-sync-manager.d.ts

74

dist/base.d.ts

@@ -6,6 +6,76 @@ /// <reference types="@blocksuite/global" />

import type * as Y from 'yjs';
import { z } from 'zod';
export declare const BlockSchema: z.ZodObject<{
version: z.ZodNumber;
model: z.ZodObject<{
flavour: z.ZodString;
tag: z.ZodObject<{
_$litStatic$: z.ZodString;
r: z.ZodSymbol;
}, "strip", z.ZodTypeAny, {
_$litStatic$: string;
r: symbol;
}, {
_$litStatic$: string;
r: symbol;
}>;
state: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodAny>>;
}, "strip", z.ZodTypeAny, {
flavour: string;
tag: {
_$litStatic$: string;
r: symbol;
};
state: (...args: unknown[]) => Record<string, any>;
}, {
flavour: string;
tag: {
_$litStatic$: string;
r: symbol;
};
state: (...args: unknown[]) => Record<string, any>;
}>;
}, "strip", z.ZodTypeAny, {
version: number;
model: {
flavour: string;
tag: {
_$litStatic$: string;
r: symbol;
};
state: (...args: unknown[]) => Record<string, any>;
};
}, {
version: number;
model: {
flavour: string;
tag: {
_$litStatic$: string;
r: symbol;
};
state: (...args: unknown[]) => Record<string, any>;
};
}>;
interface StaticValue {
_$litStatic$: string;
r: unknown;
r: symbol;
}
export type SchemaToModel<Schema extends {
model: {
state: () => Record<string, unknown>;
flavour: string;
};
}> = BaseBlockModel & ReturnType<Schema['model']['state']> & {
flavour: Schema['model']['flavour'];
};
export declare function defineBlockSchema<Flavour extends string, State extends Record<string, unknown>, Metadata extends Readonly<{
version: number;
tag: StaticValue;
}>>(flavour: Flavour, state: () => State, metadata: Metadata): {
version: number;
model: {
state: () => State;
flavour: Flavour;
} & Metadata;
};
export declare class BaseBlockModel<Props = unknown> implements BlockSuiteInternal.IBaseBlockProps {

@@ -20,3 +90,3 @@ static version: number;

childMap: Map<string, number>;
type: string;
type?: string;
children: BaseBlockModel[];

@@ -23,0 +93,0 @@ tags?: Y.Map<Y.Map<unknown>>;

import { Signal } from '@blocksuite/global/utils';
import { z } from 'zod';
const FlavourSchema = z.string();
const TagSchema = z.object({
_$litStatic$: z.string(),
r: z.symbol(),
});
export const BlockSchema = z.object({
version: z.number(),
model: z.object({
flavour: FlavourSchema,
tag: TagSchema,
state: z.function().returns(z.record(z.any())),
}),
});
export function defineBlockSchema(flavour, state, metadata) {
const schema = {
version: metadata.version,
model: {
flavour,
tag: metadata.tag,
state,
},
};
BlockSchema.parse(schema);
return schema;
}
export class BaseBlockModel {

@@ -3,0 +29,0 @@ constructor(page, props) {

4

dist/index.d.ts

@@ -5,6 +5,6 @@ export * from './space.js';

export * from './awareness.js';
export * from './blob/index.js';
export * from './persistence/blob/index.js';
export * from './text-adapter.js';
export * from '@blocksuite/global/utils';
export * from './doc-providers.js';
export * from './persistence/doc/index.js';
export * from './workspace/index.js';

@@ -11,0 +11,0 @@ export * as Utils from './utils/utils.js';

@@ -6,6 +6,6 @@ /// <reference types="@blocksuite/global" />

export * from './awareness.js';
export * from './blob/index.js';
export * from './persistence/blob/index.js';
export * from './text-adapter.js';
export * from '@blocksuite/global/utils';
export * from './doc-providers.js';
export * from './persistence/doc/index.js';
export * from './workspace/index.js';

@@ -12,0 +12,0 @@ export * as Utils from './utils/utils.js';

@@ -5,6 +5,6 @@ /// <reference types="@blocksuite/global" />

import { Awareness } from 'y-protocols/awareness.js';
import type { DocProvider, DocProviderConstructor } from './doc-providers.js';
import type { DocProvider, DocProviderConstructor } from './persistence/doc/index.js';
import { BlockSuiteDoc } from './yjs/index.js';
import { AwarenessStore, RawAwarenessState } from './awareness.js';
import type { BlobOptionsGetter } from './blob/index.js';
import type { BlobOptionsGetter } from './persistence/blob/index.js';
export interface SerializedStore {

@@ -11,0 +11,0 @@ [key: string]: {

@@ -9,3 +9,3 @@ /// <reference types="@blocksuite/global" />

export declare function initInternalProps(yBlock: YBlock, props: Partial<BlockProps>): void;
export declare function syncBlockProps(yBlock: YBlock, props: Partial<BlockProps>, ignoredKeys: Set<string>): void;
export declare function syncBlockProps(defaultState: Record<string, unknown>, yBlock: YBlock, props: Partial<BlockProps>, ignoredKeys: Set<string>): void;
export declare function trySyncTextProp(splitSet: Set<Text | PrelimText>, yBlock: YBlock, text?: TextType | void): void;

@@ -12,0 +12,0 @@ export declare function toBlockProps(yBlock: YBlock): Partial<BlockProps>;

@@ -27,61 +27,35 @@ import * as Y from 'yjs';

}
export function syncBlockProps(yBlock, props, ignoredKeys) {
export function syncBlockProps(
// schema: z.infer<typeof BlockSchema>,
defaultState, yBlock, props, ignoredKeys) {
Object.keys(props).forEach(key => {
if (SYS_KEYS.has(key) || ignoredKeys.has(key))
return;
const value = props[key];
// TODO use schema
if (key === 'text')
return;
if (!isPrimitive(props[key]) && !Array.isArray(props[key])) {
if (!isPrimitive(value) && !Array.isArray(value)) {
throw new Error('Only top level primitives are supported for now');
}
// TODO compare with current yBlock value
if (props[key] !== undefined) {
yBlock.set('prop:' + key, props[key]);
if (value !== undefined) {
if (Array.isArray(value)) {
yBlock.set(`prop:${key}`, Y.Array.from(value));
}
else {
yBlock.set(`prop:${key}`, value);
}
}
});
// TODO use schema
if (props.flavour === 'affine:paragraph' &&
!props.type &&
!yBlock.has('prop:type')) {
yBlock.set('prop:type', 'text');
}
if (props.flavour === 'affine:list' && !yBlock.has('prop:type')) {
yBlock.set('prop:type', props.type ?? 'bulleted');
}
if (props.flavour === 'affine:list' && !yBlock.has('prop:checked')) {
yBlock.set('prop:checked', props.checked ?? false);
}
if (props.flavour === 'affine:frame' && !yBlock.has('prop:xywh')) {
yBlock.set('prop:xywh', props.xywh ?? '[0,0,720,480]');
}
if (props.flavour === 'affine:embed' && !yBlock.has('prop:width')) {
yBlock.set('prop:width', props.width ?? 20);
}
if (props.flavour === 'affine:embed' && !yBlock.has('prop:sourceId')) {
yBlock.set('prop:sourceId', props.sourceId ?? '');
}
if (props.flavour === 'affine:embed' && !yBlock.has('prop:caption')) {
yBlock.set('prop:caption', props.caption ?? '');
}
if (props.flavour === 'affine:shape') {
if (!yBlock.has('prop:xywh')) {
yBlock.set('prop:xywh', props.xywh ?? '[0,0,50,50]');
// set default value
Object.entries(defaultState).forEach(([key, value]) => {
if (!yBlock.has(`prop:${key}`)) {
if (Array.isArray(value)) {
yBlock.set(`prop:${key}`, Y.Array.from(value));
}
else {
yBlock.set(`prop:${key}`, value);
}
}
if (!yBlock.has('prop:type')) {
yBlock.set('prop:type', props.type ?? 'rectangle');
}
if (!yBlock.has('prop:color')) {
yBlock.set('prop:color', props.color ?? 'black');
}
}
if (props.flavour === 'affine:database') {
if (!yBlock.has('prop:columns')) {
const columns = Y.Array.from(props.columns ?? []);
yBlock.set('prop:columns', columns);
}
if (!yBlock.has('prop:title')) {
yBlock.set('prop:title', '');
}
}
});
}

@@ -88,0 +62,0 @@ export function trySyncTextProp(splitSet, yBlock, text) {

@@ -55,3 +55,3 @@ /// <reference types="@blocksuite/global" />

get root(): BaseBlockModel<unknown> | null;
get rootLayer(): BaseBlockModel<unknown> | null;
get surface(): BaseBlockModel<unknown> | null;
/** @internal used for getting surface block elements for phasor */

@@ -58,0 +58,0 @@ get ySurfaceContainer(): Y.Map<unknown>;

@@ -131,3 +131,3 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {

}
get rootLayer() {
get surface() {
return Array.isArray(this._root) ? this._root[1] : null;

@@ -137,4 +137,4 @@ }

get ySurfaceContainer() {
assertExists(this.rootLayer);
const ySurface = this._yBlocks.get(this.rootLayer.id);
assertExists(this.surface);
const ySurface = this._yBlocks.get(this.surface.id);
if (ySurface?.has('elements')) {

@@ -277,7 +277,2 @@ return ySurface.get('elements');

}
// if (blockProps.flavour === 'affine:shape') {
// if (parent != null || parentIndex != null) {
// throw new Error('Shape block should only be appear under page');
// }
// }
const clonedProps = { flavour, ...blockProps };

@@ -288,5 +283,9 @@ const id = this._idGenerator();

const yBlock = new Y.Map();
// set the yBlock at the very beginning, otherwise yBlock will be always empty
this._yBlocks.set(id, yBlock);
assertValidChildren(this._yBlocks, clonedProps);
initInternalProps(yBlock, clonedProps);
syncBlockProps(yBlock, clonedProps, this._ignoredKeys);
const defaultState = this.workspace.flavourInitialStateMap.get(flavour);
assertExists(defaultState);
syncBlockProps(defaultState, yBlock, clonedProps, this._ignoredKeys);
trySyncTextProp(this._splitSet, yBlock, clonedProps.text);

@@ -303,3 +302,2 @@ if (typeof parent === 'string') {

}
this._yBlocks.set(id, yBlock);
});

@@ -375,3 +373,5 @@ return id;

}
syncBlockProps(yBlock, props, this._ignoredKeys);
const defaultState = this.workspace.flavourInitialStateMap.get(model.flavour);
assertExists(defaultState);
syncBlockProps(defaultState, yBlock, props, this._ignoredKeys);
});

@@ -506,4 +506,4 @@ }

_createBlockModel(props) {
const BlockModelCtor = this.workspace.flavourMap.get(props.flavour);
if (!BlockModelCtor) {
const schema = this.workspace.flavourSchemaMap.get(props.flavour);
if (!schema) {
throw new Error(`Block flavour ${props.flavour} is not registered`);

@@ -514,3 +514,11 @@ }

}
const blockModel = new BlockModelCtor(this, props);
const blockModel = new BaseBlockModel(this, props);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
blockModel.flavour = schema.model.flavour;
blockModel.tag = schema.model.tag;
const state = schema.model.state();
Object.entries(state).forEach(([key, value]) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
blockModel[key] = props[key] ?? value;
});
return blockModel;

@@ -545,2 +553,7 @@ }

}
// todo: use schema
if (model.flavour === 'affine:database') {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
model.columns = yBlock.get('prop:columns').toArray();
}
const yChildren = yBlock.get('sys:children');

@@ -613,5 +626,10 @@ if (yChildren instanceof Y.Array) {

}
// Update props
const value = event.target.get(key);
hasPropsUpdate = true;
props[key.replace('prop:', '')] = event.target.get(key);
if (value instanceof Y.Array) {
props[key.replace('prop:', '')] = value.toArray();
}
else {
props[key.replace('prop:', '')] = value;
}
}

@@ -618,0 +636,0 @@ if (hasPropsUpdate) {

@@ -8,6 +8,7 @@ /// <reference types="@blocksuite/global" />

import { QueryContent } from './search.js';
import type { BaseBlockModel } from '../base.js';
import { BlobStorage, BlobOptionsGetter } from '../blob/index.js';
import { BlobStorage, BlobOptionsGetter } from '../persistence/blob/index.js';
import type { BlockSuiteDoc } from '../yjs/index.js';
import type { AwarenessStore } from '../awareness.js';
import type { z } from 'zod';
import { BlockSchema } from '../base.js';
export interface PageMeta {

@@ -67,10 +68,21 @@ id: string;

};
flavourMap: Map<string, typeof BaseBlockModel>;
flavourSchemaMap: Map<string, {
version: number;
model: {
flavour: string;
tag: {
_$litStatic$: string;
r: symbol;
};
state: (...args: unknown[]) => Record<string, any>;
};
}>;
flavourInitialStateMap: Map<string, Record<string, unknown>>;
constructor(options: StoreOptions);
get awarenessStore(): AwarenessStore;
get providers(): import("../doc-providers.js").DocProvider[];
get providers(): import("../index.js").DocProvider[];
get blobs(): Promise<BlobStorage | null>;
private get _pages();
get doc(): BlockSuiteDoc<import("../yjs/index.js").BlockSuiteDocData>;
register(blockSchema: Record<string, typeof BaseBlockModel>): this;
register(blockSchema: z.infer<typeof BlockSchema>[]): this;
private _hasPage;

@@ -77,0 +89,0 @@ getPage(pageId: string): Page | null;

@@ -7,3 +7,4 @@ import * as Y from 'yjs';

import { Indexer } from './search.js';
import { getBlobStorage, } from '../blob/index.js';
import { getBlobStorage, } from '../persistence/blob/index.js';
import { BlockSchema } from '../base.js';
class WorkspaceMeta extends Space {

@@ -104,4 +105,4 @@ constructor(id, doc, awarenessStore) {

const versions = this.proxy.versions;
workspace.flavourMap.forEach((model, flavour) => {
versions.set(flavour, model.version);
workspace.flavourSchemaMap.forEach((schema, flavour) => {
versions.set(flavour, schema.version);
});

@@ -121,3 +122,3 @@ }

const dataVersion = versions[dataFlavour];
const editorVersion = workspace.flavourMap.get(dataFlavour)?.version;
const editorVersion = workspace.flavourSchemaMap.get(dataFlavour)?.version;
if (!editorVersion) {

@@ -162,3 +163,4 @@ throw new Error(`Editor missing ${dataFlavour} flavour. Please make sure this block flavour is registered.`);

this._blobOptionsGetter = (k) => ({ api: '/api/workspace' }[k]);
this.flavourMap = new Map();
this.flavourSchemaMap = new Map();
this.flavourInitialStateMap = new Map();
this._store = new Store(options);

@@ -204,4 +206,6 @@ this._indexer = new Indexer(this.doc);

register(blockSchema) {
Object.keys(blockSchema).forEach(key => {
this.flavourMap.set(key, blockSchema[key]);
blockSchema.forEach(schema => {
BlockSchema.parse(schema);
this.flavourSchemaMap.set(schema.model.flavour, schema);
this.flavourInitialStateMap.set(schema.model.flavour, schema.model.state());
});

@@ -208,0 +212,0 @@ return this;

{
"name": "@blocksuite/store",
"version": "0.4.0-20230126161407-c60bfba",
"version": "0.4.0-20230127234317-bfe4022",
"description": "BlockSuite data store built for general purpose state management.",

@@ -11,3 +11,3 @@ "main": "dist/index.js",

"dependencies": {
"@blocksuite/global": "0.4.0-20230126161407-c60bfba",
"@blocksuite/global": "0.4.0-20230127234317-bfe4022",
"@types/flexsearch": "^0.7.3",

@@ -22,3 +22,4 @@ "buffer": "^6.0.3",

"y-protocols": "^1.0.5",
"y-webrtc": "^10.2.4"
"y-webrtc": "^10.2.4",
"zod": "^3.20.2"
},

@@ -25,0 +26,0 @@ "devDependencies": {

@@ -9,7 +9,7 @@ /* eslint-disable @typescript-eslint/no-restricted-imports */

// Use manual per-module import/export to support vitest environment on Node.js
import { PageBlockModel } from '../../../blocks/src/page-block/page-model.js';
import { ParagraphBlockModel } from '../../../blocks/src/paragraph-block/paragraph-model.js';
import { ListBlockModel } from '../../../blocks/src/list-block/list-model.js';
import { FrameBlockModel } from '../../../blocks/src/frame-block/frame-model.js';
import { DividerBlockModel } from '../../../blocks/src/divider-block/divider-model.js';
import { PageBlockModelSchema } from '../../../blocks/src/page-block/page-model.js';
import { ParagraphBlockModelSchema } from '../../../blocks/src/paragraph-block/paragraph-model.js';
import { ListBlockModelSchema } from '../../../blocks/src/list-block/list-model.js';
import { FrameBlockModelSchema } from '../../../blocks/src/frame-block/frame-model.js';
import { DividerBlockModelSchema } from '../../../blocks/src/divider-block/divider-model.js';
import type { PageMeta } from '../workspace/index.js';

@@ -24,9 +24,9 @@ import { assertExists } from './test-utils-dom.js';

// Create BlockSchema manually
export const BlockSchema = {
'affine:paragraph': ParagraphBlockModel,
'affine:page': PageBlockModel,
'affine:list': ListBlockModel,
'affine:frame': FrameBlockModel,
'affine:divider': DividerBlockModel,
} as const;
export const BlockSchema = [
ParagraphBlockModelSchema,
PageBlockModelSchema,
ListBlockModelSchema,
FrameBlockModelSchema,
DividerBlockModelSchema,
];

@@ -101,2 +101,3 @@ function serialize(page: Page) {

'meta:tagSchema': {},
'prop:title': '',
'sys:children': [],

@@ -137,2 +138,3 @@ 'sys:flavour': 'affine:page',

'sys:id': '0',
'prop:title': '',
},

@@ -154,3 +156,6 @@ '1': {

const block = await waitOnce(page.signals.rootAdded);
assert.ok(block instanceof BlockSchema['affine:page']);
if (Array.isArray(block)) {
throw new Error('');
}
assert.equal(block.flavour, 'affine:page');
});

@@ -164,6 +169,9 @@

const root = Array.isArray(roots) ? roots[0] : roots;
assert.ok(root instanceof BlockSchema['affine:page']);
if (Array.isArray(root)) {
throw new Error('');
}
assert.equal(root.flavour, 'affine:page');
page.addBlockByFlavour('affine:paragraph');
assert.ok(root.children[0] instanceof BlockSchema['affine:paragraph']);
assert.equal(root.children[0].flavour, 'affine:paragraph');
assert.equal(root.childMap.get('1'), 0);

@@ -264,2 +272,3 @@

'sys:id': '0',
'prop:title': '',
},

@@ -284,2 +293,3 @@ });

'meta:tagSchema': {},
'prop:title': '',
'sys:children': ['1'],

@@ -305,2 +315,3 @@ 'sys:flavour': 'affine:page',

'meta:tagSchema': {},
'prop:title': '',
'sys:children': [],

@@ -325,3 +336,3 @@ 'sys:flavour': 'affine:page',

const text = page.getBlockById('2') as BaseBlockModel;
assert.ok(text instanceof BlockSchema['affine:paragraph']);
assert.equal(text.flavour, 'affine:paragraph');
assert.equal(root.children.indexOf(text), 1);

@@ -398,3 +409,5 @@

expect(workspace.exportJSX()).toMatchInlineSnapshot(/* xml */ `
<affine:page>
<affine:page
prop:title=""
>
<affine:paragraph

@@ -401,0 +414,0 @@ prop:type="text"

@@ -5,9 +5,76 @@ import type { Page } from './workspace/index.js';

import type * as Y from 'yjs';
import { z } from 'zod';
const FlavourSchema = z.string();
const TagSchema = z.object({
_$litStatic$: z.string(),
r: z.symbol(),
});
export const BlockSchema = z.object({
version: z.number(),
model: z.object({
flavour: FlavourSchema,
tag: TagSchema,
state: z.function().returns(z.record(z.any())),
}),
});
// ported from lit
interface StaticValue {
_$litStatic$: string;
r: unknown;
r: symbol;
}
export type SchemaToModel<
Schema extends {
model: {
state: () => Record<string, unknown>;
flavour: string;
};
}
> = BaseBlockModel &
ReturnType<Schema['model']['state']> & {
flavour: Schema['model']['flavour'];
};
export function defineBlockSchema<
Flavour extends string,
State extends Record<string, unknown>,
Metadata extends Readonly<{
version: number;
tag: StaticValue;
}>
>(
flavour: Flavour,
state: () => State,
metadata: Metadata
): {
version: number;
model: {
state: () => State;
flavour: Flavour;
} & Metadata;
};
export function defineBlockSchema(
flavour: string,
state: () => Record<string, unknown>,
metadata: {
version: number;
tag: StaticValue;
}
): z.infer<typeof BlockSchema> {
const schema = {
version: metadata.version,
model: {
flavour,
tag: metadata.tag,
state,
},
} satisfies z.infer<typeof BlockSchema>;
BlockSchema.parse(schema);
return schema;
}
export class BaseBlockModel<Props = unknown>

@@ -26,3 +93,3 @@ implements BlockSuiteInternal.IBaseBlockProps

type!: string;
type?: string;
children: BaseBlockModel[];

@@ -29,0 +96,0 @@ // TODO use schema

@@ -6,6 +6,6 @@ /// <reference types="@blocksuite/global" />

export * from './awareness.js';
export * from './blob/index.js';
export * from './persistence/blob/index.js';
export * from './text-adapter.js';
export * from '@blocksuite/global/utils';
export * from './doc-providers.js';
export * from './persistence/doc/index.js';
export * from './workspace/index.js';

@@ -12,0 +12,0 @@ export * as Utils from './utils/utils.js';

import type { Space } from './space.js';
import type { IdGenerator } from './utils/id-generator.js';
import { Awareness } from 'y-protocols/awareness.js';
import type { DocProvider, DocProviderConstructor } from './doc-providers.js';
import type {
DocProvider,
DocProviderConstructor,
} from './persistence/doc/index.js';
import { serializeYDoc, yDocToJSXNode } from './utils/jsx.js';

@@ -15,3 +18,3 @@ import {

import { AwarenessStore, RawAwarenessState } from './awareness.js';
import type { BlobOptionsGetter } from './blob/index.js';
import type { BlobOptionsGetter } from './persistence/blob/index.js';

@@ -18,0 +21,0 @@ export interface SerializedStore {

@@ -44,2 +44,4 @@ import * as Y from 'yjs';

export function syncBlockProps(
// schema: z.infer<typeof BlockSchema>,
defaultState: Record<string, unknown>,
yBlock: YBlock,

@@ -51,62 +53,29 @@ props: Partial<BlockProps>,

if (SYS_KEYS.has(key) || ignoredKeys.has(key)) return;
const value = props[key];
// TODO use schema
if (key === 'text') return;
if (!isPrimitive(props[key]) && !Array.isArray(props[key])) {
if (!isPrimitive(value) && !Array.isArray(value)) {
throw new Error('Only top level primitives are supported for now');
}
// TODO compare with current yBlock value
if (props[key] !== undefined) {
yBlock.set('prop:' + key, props[key]);
if (value !== undefined) {
if (Array.isArray(value)) {
yBlock.set(`prop:${key}`, Y.Array.from(value));
} else {
yBlock.set(`prop:${key}`, value);
}
}
});
// TODO use schema
if (
props.flavour === 'affine:paragraph' &&
!props.type &&
!yBlock.has('prop:type')
) {
yBlock.set('prop:type', 'text');
}
if (props.flavour === 'affine:list' && !yBlock.has('prop:type')) {
yBlock.set('prop:type', props.type ?? 'bulleted');
}
if (props.flavour === 'affine:list' && !yBlock.has('prop:checked')) {
yBlock.set('prop:checked', props.checked ?? false);
}
if (props.flavour === 'affine:frame' && !yBlock.has('prop:xywh')) {
yBlock.set('prop:xywh', props.xywh ?? '[0,0,720,480]');
}
if (props.flavour === 'affine:embed' && !yBlock.has('prop:width')) {
yBlock.set('prop:width', props.width ?? 20);
}
if (props.flavour === 'affine:embed' && !yBlock.has('prop:sourceId')) {
yBlock.set('prop:sourceId', props.sourceId ?? '');
}
if (props.flavour === 'affine:embed' && !yBlock.has('prop:caption')) {
yBlock.set('prop:caption', props.caption ?? '');
}
if (props.flavour === 'affine:shape') {
if (!yBlock.has('prop:xywh')) {
yBlock.set('prop:xywh', props.xywh ?? '[0,0,50,50]');
// set default value
Object.entries(defaultState).forEach(([key, value]) => {
if (!yBlock.has(`prop:${key}`)) {
if (Array.isArray(value)) {
yBlock.set(`prop:${key}`, Y.Array.from(value));
} else {
yBlock.set(`prop:${key}`, value);
}
}
if (!yBlock.has('prop:type')) {
yBlock.set('prop:type', props.type ?? 'rectangle');
}
if (!yBlock.has('prop:color')) {
yBlock.set('prop:color', props.color ?? 'black');
}
}
if (props.flavour === 'affine:database') {
if (!yBlock.has('prop:columns')) {
const columns = Y.Array.from(props.columns ?? []);
yBlock.set('prop:columns', columns);
}
if (!yBlock.has('prop:title')) {
yBlock.set('prop:title', '');
}
}
});
}

@@ -113,0 +82,0 @@

@@ -124,3 +124,3 @@ import * as Y from 'yjs';

get rootLayer() {
get surface() {
return Array.isArray(this._root) ? this._root[1] : null;

@@ -131,4 +131,4 @@ }

get ySurfaceContainer() {
assertExists(this.rootLayer);
const ySurface = this._yBlocks.get(this.rootLayer.id);
assertExists(this.surface);
const ySurface = this._yBlocks.get(this.surface.id);
if (ySurface?.has('elements')) {

@@ -338,8 +338,2 @@ return ySurface.get('elements') as Y.Map<unknown>;

// if (blockProps.flavour === 'affine:shape') {
// if (parent != null || parentIndex != null) {
// throw new Error('Shape block should only be appear under page');
// }
// }
const clonedProps: Partial<BlockProps> = { flavour, ...blockProps };

@@ -351,6 +345,10 @@ const id = this._idGenerator();

const yBlock = new Y.Map() as YBlock;
// set the yBlock at the very beginning, otherwise yBlock will be always empty
this._yBlocks.set(id, yBlock);
assertValidChildren(this._yBlocks, clonedProps);
initInternalProps(yBlock, clonedProps);
syncBlockProps(yBlock, clonedProps, this._ignoredKeys);
const defaultState = this.workspace.flavourInitialStateMap.get(flavour);
assertExists(defaultState);
syncBlockProps(defaultState, yBlock, clonedProps, this._ignoredKeys);
trySyncTextProp(this._splitSet, yBlock, clonedProps.text);

@@ -370,4 +368,2 @@

}
this._yBlocks.set(id, yBlock);
});

@@ -462,3 +458,7 @@ return id;

syncBlockProps(yBlock, props, this._ignoredKeys);
const defaultState = this.workspace.flavourInitialStateMap.get(
model.flavour
);
assertExists(defaultState);
syncBlockProps(defaultState, yBlock, props, this._ignoredKeys);
});

@@ -672,4 +672,4 @@ }

private _createBlockModel(props: Omit<BlockProps, 'children'>) {
const BlockModelCtor = this.workspace.flavourMap.get(props.flavour);
if (!BlockModelCtor) {
const schema = this.workspace.flavourSchemaMap.get(props.flavour);
if (!schema) {
throw new Error(`Block flavour ${props.flavour} is not registered`);

@@ -679,7 +679,14 @@ } else if (!props.id) {

}
const blockModel = new BlockModelCtor(
const blockModel = new BaseBlockModel(
this,
props as PropsWithId<Omit<BlockProps, 'children'>>
);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
blockModel.flavour = schema.model.flavour as any;
blockModel.tag = schema.model.tag;
const state = schema.model.state();
Object.entries(state).forEach(([key, value]) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(blockModel as any)[key] = props[key] ?? value;
});
return blockModel;

@@ -720,2 +727,10 @@ }

// todo: use schema
if (model.flavour === 'affine:database') {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(model as any).columns = (
yBlock.get('prop:columns') as Y.Array<unknown>
).toArray();
}
const yChildren = yBlock.get('sys:children');

@@ -796,5 +811,9 @@ if (yChildren instanceof Y.Array) {

}
// Update props
const value = event.target.get(key);
hasPropsUpdate = true;
props[key.replace('prop:', '')] = event.target.get(key);
if (value instanceof Y.Array) {
props[key.replace('prop:', '')] = value.toArray();
} else {
props[key.replace('prop:', '')] = value;
}
}

@@ -801,0 +820,0 @@

@@ -7,3 +7,2 @@ import * as Y from 'yjs';

import { Indexer, QueryContent } from './search.js';
import type { BaseBlockModel } from '../base.js';
import {

@@ -13,5 +12,7 @@ BlobStorage,

getBlobStorage,
} from '../blob/index.js';
} from '../persistence/blob/index.js';
import type { BlockSuiteDoc } from '../yjs/index.js';
import type { AwarenessStore } from '../awareness.js';
import type { z } from 'zod';
import { BlockSchema } from '../base.js';

@@ -130,4 +131,4 @@ export interface PageMeta {

const versions = this.proxy.versions;
workspace.flavourMap.forEach((model, flavour) => {
versions.set(flavour, model.version);
workspace.flavourSchemaMap.forEach((schema, flavour) => {
versions.set(flavour, schema.version);
});

@@ -152,3 +153,4 @@ }

const dataVersion = versions[dataFlavour] as number;
const editorVersion = workspace.flavourMap.get(dataFlavour)?.version;
const editorVersion =
workspace.flavourSchemaMap.get(dataFlavour)?.version;
if (!editorVersion) {

@@ -239,3 +241,4 @@ throw new Error(

flavourMap = new Map<string, typeof BaseBlockModel>();
flavourSchemaMap = new Map<string, z.infer<typeof BlockSchema>>();
flavourInitialStateMap = new Map<string, Record<string, unknown>>();

@@ -290,5 +293,10 @@ constructor(options: StoreOptions) {

register(blockSchema: Record<string, typeof BaseBlockModel>) {
Object.keys(blockSchema).forEach(key => {
this.flavourMap.set(key, blockSchema[key]);
register(blockSchema: z.infer<typeof BlockSchema>[]) {
blockSchema.forEach(schema => {
BlockSchema.parse(schema);
this.flavourSchemaMap.set(schema.model.flavour, schema);
this.flavourInitialStateMap.set(
schema.model.flavour,
schema.model.state()
);
});

@@ -295,0 +303,0 @@ return this;

@@ -9,4 +9,4 @@ {

"include": ["./src"],
"exclude": ["./src/__tests__", "./src/blob/__tests__"],
"exclude": ["./src/__tests__", "src/persistence/blob/__tests__"],
"references": []
}

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

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc