mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-24 05:07:06 +08:00
refactor(editor): reduce dependency to doc collection (#9492)
This commit is contained in:
@@ -30,6 +30,7 @@
|
|||||||
"date-fns": "^4.0.0",
|
"date-fns": "^4.0.0",
|
||||||
"lit": "^3.2.0",
|
"lit": "^3.2.0",
|
||||||
"minimatch": "^10.0.1",
|
"minimatch": "^10.0.1",
|
||||||
|
"yjs": "^13.6.21",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ export class NoteRenderer
|
|||||||
},
|
},
|
||||||
} satisfies AffineTextAttributes as BaseTextAttributes
|
} satisfies AffineTextAttributes as BaseTextAttributes
|
||||||
);
|
);
|
||||||
collection.setDocMeta(note.id, { title: rowContent });
|
collection.meta.setDocMeta(note.id, { title: rowContent });
|
||||||
if (note.root) {
|
if (note.root) {
|
||||||
(note.root as RootBlockModel).title.insert(rowContent ?? '', 0);
|
(note.root as RootBlockModel).title.insert(rowContent ?? '', 0);
|
||||||
note.root.children
|
note.root.children
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
"@toeverything/theme": "^1.1.3",
|
"@toeverything/theme": "^1.1.3",
|
||||||
"lit": "^3.2.0",
|
"lit": "^3.2.0",
|
||||||
"minimatch": "^10.0.1",
|
"minimatch": "^10.0.1",
|
||||||
|
"yjs": "^13.6.21",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
|
|||||||
@@ -22,13 +22,13 @@ import {
|
|||||||
referenceToNode,
|
referenceToNode,
|
||||||
} from '@blocksuite/affine-shared/utils';
|
} from '@blocksuite/affine-shared/utils';
|
||||||
import { Bound, throttle } from '@blocksuite/global/utils';
|
import { Bound, throttle } from '@blocksuite/global/utils';
|
||||||
import { DocCollection } from '@blocksuite/store';
|
|
||||||
import { computed } from '@preact/signals-core';
|
import { computed } from '@preact/signals-core';
|
||||||
import { html, nothing } from 'lit';
|
import { html, nothing } from 'lit';
|
||||||
import { property, queryAsync, state } from 'lit/decorators.js';
|
import { property, queryAsync, state } from 'lit/decorators.js';
|
||||||
import { classMap } from 'lit/directives/class-map.js';
|
import { classMap } from 'lit/directives/class-map.js';
|
||||||
import { styleMap } from 'lit/directives/style-map.js';
|
import { styleMap } from 'lit/directives/style-map.js';
|
||||||
import { when } from 'lit/directives/when.js';
|
import { when } from 'lit/directives/when.js';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import { EmbedBlockComponent } from '../common/embed-block-element.js';
|
import { EmbedBlockComponent } from '../common/embed-block-element.js';
|
||||||
import {
|
import {
|
||||||
@@ -163,7 +163,7 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
|
|||||||
}
|
}
|
||||||
const index = parent.children.indexOf(this.model);
|
const index = parent.children.indexOf(this.model);
|
||||||
|
|
||||||
const yText = new DocCollection.Y.Text();
|
const yText = new Y.Text();
|
||||||
yText.insert(0, REFERENCE_NODE);
|
yText.insert(0, REFERENCE_NODE);
|
||||||
yText.format(0, REFERENCE_NODE.length, {
|
yText.format(0, REFERENCE_NODE.length, {
|
||||||
reference: {
|
reference: {
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
|
|||||||
import { assertExists, Bound, getCommonBound } from '@blocksuite/global/utils';
|
import { assertExists, Bound, getCommonBound } from '@blocksuite/global/utils';
|
||||||
import {
|
import {
|
||||||
BlockViewType,
|
BlockViewType,
|
||||||
DocCollection,
|
|
||||||
type GetDocOptions,
|
type GetDocOptions,
|
||||||
type Query,
|
type Query,
|
||||||
} from '@blocksuite/store';
|
} from '@blocksuite/store';
|
||||||
@@ -38,6 +37,7 @@ import { choose } from 'lit/directives/choose.js';
|
|||||||
import { classMap } from 'lit/directives/class-map.js';
|
import { classMap } from 'lit/directives/class-map.js';
|
||||||
import { guard } from 'lit/directives/guard.js';
|
import { guard } from 'lit/directives/guard.js';
|
||||||
import { type StyleInfo, styleMap } from 'lit/directives/style-map.js';
|
import { type StyleInfo, styleMap } from 'lit/directives/style-map.js';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import { EmbedBlockComponent } from '../common/embed-block-element.js';
|
import { EmbedBlockComponent } from '../common/embed-block-element.js';
|
||||||
import { isEmptyDoc } from '../common/render-linked-doc.js';
|
import { isEmptyDoc } from '../common/render-linked-doc.js';
|
||||||
@@ -272,7 +272,7 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent<EmbedSynce
|
|||||||
assertExists(parent);
|
assertExists(parent);
|
||||||
const index = parent.children.indexOf(this.model);
|
const index = parent.children.indexOf(this.model);
|
||||||
|
|
||||||
const yText = new DocCollection.Y.Text();
|
const yText = new Y.Text();
|
||||||
yText.insert(0, REFERENCE_NODE);
|
yText.insert(0, REFERENCE_NODE);
|
||||||
yText.format(0, REFERENCE_NODE.length, {
|
yText.format(0, REFERENCE_NODE.length, {
|
||||||
reference: {
|
reference: {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
"lit": "^3.2.0",
|
"lit": "^3.2.0",
|
||||||
"lodash.chunk": "^4.2.0",
|
"lodash.chunk": "^4.2.0",
|
||||||
"nanoid": "^5.0.7",
|
"nanoid": "^5.0.7",
|
||||||
|
"yjs": "^13.6.21",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
rotatePoints,
|
rotatePoints,
|
||||||
} from '@blocksuite/global/utils';
|
} from '@blocksuite/global/utils';
|
||||||
import { deltaInsertsToChunks } from '@blocksuite/inline';
|
import { deltaInsertsToChunks } from '@blocksuite/inline';
|
||||||
import type { Y } from '@blocksuite/store';
|
import type * as Y from 'yjs';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getFontFacesByFontFamily,
|
getFontFacesByFontFamily,
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ import type { ConnectorElementModel } from '@blocksuite/affine-model';
|
|||||||
import type { SurfaceBlockProps } from '@blocksuite/block-std/gfx';
|
import type { SurfaceBlockProps } from '@blocksuite/block-std/gfx';
|
||||||
import { SurfaceBlockModel as BaseSurfaceModel } from '@blocksuite/block-std/gfx';
|
import { SurfaceBlockModel as BaseSurfaceModel } from '@blocksuite/block-std/gfx';
|
||||||
import { DisposableGroup } from '@blocksuite/global/utils';
|
import { DisposableGroup } from '@blocksuite/global/utils';
|
||||||
import { defineBlockSchema, DocCollection } from '@blocksuite/store';
|
import { defineBlockSchema } from '@blocksuite/store';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import { elementsCtorMap } from './element-model/index.js';
|
import { elementsCtorMap } from './element-model/index.js';
|
||||||
import { SurfaceBlockTransformer } from './surface-transformer.js';
|
import { SurfaceBlockTransformer } from './surface-transformer.js';
|
||||||
@@ -12,7 +13,7 @@ import { groupRelationWatcher } from './watchers/group.js';
|
|||||||
export const SurfaceBlockSchema = defineBlockSchema({
|
export const SurfaceBlockSchema = defineBlockSchema({
|
||||||
flavour: 'affine:surface',
|
flavour: 'affine:surface',
|
||||||
props: (internalPrimitives): SurfaceBlockProps => ({
|
props: (internalPrimitives): SurfaceBlockProps => ({
|
||||||
elements: internalPrimitives.Boxed(new DocCollection.Y.Map()),
|
elements: internalPrimitives.Boxed(new Y.Map()),
|
||||||
}),
|
}),
|
||||||
metadata: {
|
metadata: {
|
||||||
version: 5,
|
version: 5,
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ import type {
|
|||||||
FromSnapshotPayload,
|
FromSnapshotPayload,
|
||||||
SnapshotNode,
|
SnapshotNode,
|
||||||
ToSnapshotPayload,
|
ToSnapshotPayload,
|
||||||
Y,
|
|
||||||
} from '@blocksuite/store';
|
} from '@blocksuite/store';
|
||||||
import { BaseBlockTransformer, DocCollection } from '@blocksuite/store';
|
import { BaseBlockTransformer } from '@blocksuite/store';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
const SURFACE_TEXT_UNIQ_IDENTIFIER = 'affine:surface:text';
|
const SURFACE_TEXT_UNIQ_IDENTIFIER = 'affine:surface:text';
|
||||||
// Used for group children field
|
// Used for group children field
|
||||||
@@ -24,11 +24,11 @@ export class SurfaceBlockTransformer extends BaseBlockTransformer<SurfaceBlockPr
|
|||||||
private _fromJSON(value: unknown): unknown {
|
private _fromJSON(value: unknown): unknown {
|
||||||
if (value instanceof Object) {
|
if (value instanceof Object) {
|
||||||
if (Reflect.has(value, SURFACE_TEXT_UNIQ_IDENTIFIER)) {
|
if (Reflect.has(value, SURFACE_TEXT_UNIQ_IDENTIFIER)) {
|
||||||
const yText = new DocCollection.Y.Text();
|
const yText = new Y.Text();
|
||||||
yText.applyDelta(Reflect.get(value, 'delta'));
|
yText.applyDelta(Reflect.get(value, 'delta'));
|
||||||
return yText;
|
return yText;
|
||||||
} else if (Reflect.has(value, SURFACE_YMAP_UNIQ_IDENTIFIER)) {
|
} else if (Reflect.has(value, SURFACE_YMAP_UNIQ_IDENTIFIER)) {
|
||||||
const yMap = new DocCollection.Y.Map();
|
const yMap = new Y.Map();
|
||||||
const json = Reflect.get(value, 'json') as Record<string, unknown>;
|
const json = Reflect.get(value, 'json') as Record<string, unknown>;
|
||||||
Object.entries(json).forEach(([key, value]) => {
|
Object.entries(json).forEach(([key, value]) => {
|
||||||
yMap.set(key, value);
|
yMap.set(key, value);
|
||||||
@@ -40,12 +40,12 @@ export class SurfaceBlockTransformer extends BaseBlockTransformer<SurfaceBlockPr
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _toJSON(value: unknown): unknown {
|
private _toJSON(value: unknown): unknown {
|
||||||
if (value instanceof DocCollection.Y.Text) {
|
if (value instanceof Y.Text) {
|
||||||
return {
|
return {
|
||||||
[SURFACE_TEXT_UNIQ_IDENTIFIER]: true,
|
[SURFACE_TEXT_UNIQ_IDENTIFIER]: true,
|
||||||
delta: value.toDelta(),
|
delta: value.toDelta(),
|
||||||
};
|
};
|
||||||
} else if (value instanceof DocCollection.Y.Map) {
|
} else if (value instanceof Y.Map) {
|
||||||
return {
|
return {
|
||||||
[SURFACE_YMAP_UNIQ_IDENTIFIER]: true,
|
[SURFACE_YMAP_UNIQ_IDENTIFIER]: true,
|
||||||
json: value.toJSON(),
|
json: value.toJSON(),
|
||||||
@@ -55,7 +55,7 @@ export class SurfaceBlockTransformer extends BaseBlockTransformer<SurfaceBlockPr
|
|||||||
}
|
}
|
||||||
|
|
||||||
elementFromJSON(element: Record<string, unknown>) {
|
elementFromJSON(element: Record<string, unknown>) {
|
||||||
const yMap = new DocCollection.Y.Map();
|
const yMap = new Y.Map();
|
||||||
Object.entries(element).forEach(([key, value]) => {
|
Object.entries(element).forEach(([key, value]) => {
|
||||||
yMap.set(key, this._fromJSON(value));
|
yMap.set(key, this._fromJSON(value));
|
||||||
});
|
});
|
||||||
@@ -71,7 +71,7 @@ export class SurfaceBlockTransformer extends BaseBlockTransformer<SurfaceBlockPr
|
|||||||
string,
|
string,
|
||||||
unknown
|
unknown
|
||||||
>;
|
>;
|
||||||
const yMap = new DocCollection.Y.Map<Y.Map<unknown>>();
|
const yMap = new Y.Map<Y.Map<unknown>>();
|
||||||
|
|
||||||
Object.entries(elementsJSON).forEach(([key, value]) => {
|
Object.entries(elementsJSON).forEach(([key, value]) => {
|
||||||
const element = this.elementFromJSON(value as Record<string, unknown>);
|
const element = this.elementFromJSON(value as Record<string, unknown>);
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
type SurfaceBlockModel,
|
type SurfaceBlockModel,
|
||||||
} from '@blocksuite/block-std/gfx';
|
} from '@blocksuite/block-std/gfx';
|
||||||
import { assertType, isEqual, type IVec, last } from '@blocksuite/global/utils';
|
import { assertType, isEqual, type IVec, last } from '@blocksuite/global/utils';
|
||||||
import { DocCollection } from '@blocksuite/store';
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import { fitContent } from '../../renderer/elements/shape/utils.js';
|
import { fitContent } from '../../renderer/elements/shape/utils.js';
|
||||||
import { layout } from './layout.js';
|
import { layout } from './layout.js';
|
||||||
@@ -360,7 +360,7 @@ export function createFromTree(
|
|||||||
layoutType: LayoutType,
|
layoutType: LayoutType,
|
||||||
surface: SurfaceBlockModel
|
surface: SurfaceBlockModel
|
||||||
) {
|
) {
|
||||||
const children = new DocCollection.Y.Map();
|
const children = new Y.Map();
|
||||||
const traverse = (subtree: MindmapNode, parent?: string) => {
|
const traverse = (subtree: MindmapNode, parent?: string) => {
|
||||||
const value: NodeDetail = {
|
const value: NodeDetail = {
|
||||||
...subtree.detail,
|
...subtree.detail,
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
"lit-html": "^3.2.1",
|
"lit-html": "^3.2.1",
|
||||||
"lodash.clonedeep": "^4.5.0",
|
"lodash.clonedeep": "^4.5.0",
|
||||||
"shiki": "^1.12.0",
|
"shiki": "^1.12.0",
|
||||||
|
"yjs": "^13.6.21",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import {
|
|||||||
KEYBOARD_ALLOW_DEFAULT,
|
KEYBOARD_ALLOW_DEFAULT,
|
||||||
type KeyboardBindingContext,
|
type KeyboardBindingContext,
|
||||||
} from '@blocksuite/inline';
|
} from '@blocksuite/inline';
|
||||||
import type { Y } from '@blocksuite/store';
|
import type * as Y from 'yjs';
|
||||||
import { z, type ZodObject, type ZodTypeAny } from 'zod';
|
import { z, type ZodObject, type ZodTypeAny } from 'zod';
|
||||||
|
|
||||||
import { MarkdownMatcherIdentifier } from './markdown-matcher.js';
|
import { MarkdownMatcherIdentifier } from './markdown-matcher.js';
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import type {
|
|||||||
InlineRange,
|
InlineRange,
|
||||||
KeyboardBindingHandler,
|
KeyboardBindingHandler,
|
||||||
} from '@blocksuite/inline';
|
} from '@blocksuite/inline';
|
||||||
import type { Y } from '@blocksuite/store';
|
import type * as Y from 'yjs';
|
||||||
import type { ZodTypeAny } from 'zod';
|
import type { ZodTypeAny } from 'zod';
|
||||||
|
|
||||||
export type InlineSpecs<
|
export type InlineSpecs<
|
||||||
|
|||||||
+2
-3
@@ -4,12 +4,11 @@ import { unsafeCSSVar } from '@blocksuite/affine-shared/theme';
|
|||||||
import { type BlockStdScope, ShadowlessElement } from '@blocksuite/block-std';
|
import { type BlockStdScope, ShadowlessElement } from '@blocksuite/block-std';
|
||||||
import { noop, SignalWatcher, WithDisposable } from '@blocksuite/global/utils';
|
import { noop, SignalWatcher, WithDisposable } from '@blocksuite/global/utils';
|
||||||
import { DoneIcon } from '@blocksuite/icons/lit';
|
import { DoneIcon } from '@blocksuite/icons/lit';
|
||||||
import type { Y } from '@blocksuite/store';
|
|
||||||
import { DocCollection } from '@blocksuite/store';
|
|
||||||
import { effect, type Signal, signal } from '@preact/signals-core';
|
import { effect, type Signal, signal } from '@preact/signals-core';
|
||||||
import { css, html } from 'lit';
|
import { css, html } from 'lit';
|
||||||
import { property } from 'lit/decorators.js';
|
import { property } from 'lit/decorators.js';
|
||||||
import { codeToTokensBase, type ThemedToken } from 'shiki';
|
import { codeToTokensBase, type ThemedToken } from 'shiki';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import { InlineManagerExtension } from '../../../../extension/index.js';
|
import { InlineManagerExtension } from '../../../../extension/index.js';
|
||||||
import { LatexEditorUnitSpecExtension } from '../../affine-inline-specs.js';
|
import { LatexEditorUnitSpecExtension } from '../../affine-inline-specs.js';
|
||||||
@@ -111,7 +110,7 @@ export class LatexEditorMenu extends SignalWatcher(
|
|||||||
override connectedCallback(): void {
|
override connectedCallback(): void {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
|
|
||||||
const doc = new DocCollection.Y.Doc();
|
const doc = new Y.Doc();
|
||||||
this.yText = doc.getText('latex');
|
this.yText = doc.getText('latex');
|
||||||
this.yText.insert(0, this.latexSignal.value);
|
this.yText.insert(0, this.latexSignal.value);
|
||||||
|
|
||||||
|
|||||||
@@ -11,12 +11,12 @@ import {
|
|||||||
type KeyboardBindingContext,
|
type KeyboardBindingContext,
|
||||||
type VLine,
|
type VLine,
|
||||||
} from '@blocksuite/inline';
|
} from '@blocksuite/inline';
|
||||||
import type { Y } from '@blocksuite/store';
|
import { Text } from '@blocksuite/store';
|
||||||
import { DocCollection, Text } from '@blocksuite/store';
|
|
||||||
import { effect } from '@preact/signals-core';
|
import { effect } from '@preact/signals-core';
|
||||||
import { css, html, type TemplateResult } from 'lit';
|
import { css, html, type TemplateResult } from 'lit';
|
||||||
import { property, query } from 'lit/decorators.js';
|
import { property, query } from 'lit/decorators.js';
|
||||||
import { classMap } from 'lit/directives/class-map.js';
|
import { classMap } from 'lit/directives/class-map.js';
|
||||||
|
import * as Y from 'yjs';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { onVBeforeinput, onVCompositionEnd } from './hooks.js';
|
import { onVBeforeinput, onVCompositionEnd } from './hooks.js';
|
||||||
@@ -289,7 +289,7 @@ export class RichText extends WithDisposable(ShadowlessElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!this.undoManager) {
|
if (!this.undoManager) {
|
||||||
this.undoManager = new DocCollection.Y.UndoManager(this._yText, {
|
this.undoManager = new Y.UndoManager(this._yText, {
|
||||||
trackedOrigins: new Set([this._yText.doc.clientID]),
|
trackedOrigins: new Set([this._yText.doc.clientID]),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"@toeverything/theme": "^1.1.3",
|
"@toeverything/theme": "^1.1.3",
|
||||||
"date-fns": "^4.0.0",
|
"date-fns": "^4.0.0",
|
||||||
"lit": "^3.2.0",
|
"lit": "^3.2.0",
|
||||||
|
"yjs": "^13.6.21",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { ShadowlessElement } from '@blocksuite/block-std';
|
import { ShadowlessElement } from '@blocksuite/block-std';
|
||||||
import { assertEquals } from '@blocksuite/global/utils';
|
import { assertEquals } from '@blocksuite/global/utils';
|
||||||
import { DocCollection, type Text } from '@blocksuite/store';
|
import { type Text } from '@blocksuite/store';
|
||||||
import { css, html } from 'lit';
|
import { css, html } from 'lit';
|
||||||
import { state } from 'lit/decorators.js';
|
import { state } from 'lit/decorators.js';
|
||||||
import { createRef, ref } from 'lit/directives/ref.js';
|
import { createRef, ref } from 'lit/directives/ref.js';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import { t } from '../../../../core/index.js';
|
import { t } from '../../../../core/index.js';
|
||||||
import type { TableAreaSelection } from '../../types.js';
|
import type { TableAreaSelection } from '../../types.js';
|
||||||
@@ -98,7 +99,7 @@ export function fillSelectionWithFocusCellData(
|
|||||||
curCellText.clear();
|
curCellText.clear();
|
||||||
curCellText.applyDelta(delta);
|
curCellText.applyDelta(delta);
|
||||||
} else {
|
} else {
|
||||||
const newText = new DocCollection.Y.Text();
|
const newText = new Y.Text();
|
||||||
newText.applyDelta(delta);
|
newText.applyDelta(delta);
|
||||||
curCell.valueSet(newText);
|
curCell.valueSet(newText);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
"@blocksuite/inline": "workspace:*",
|
"@blocksuite/inline": "workspace:*",
|
||||||
"@blocksuite/store": "workspace:*",
|
"@blocksuite/store": "workspace:*",
|
||||||
"fractional-indexing": "^3.2.0",
|
"fractional-indexing": "^3.2.0",
|
||||||
|
"yjs": "^13.6.21",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export class RootBlockModel extends BlockModel<RootBlockProps> {
|
|||||||
if (model instanceof RootBlockModel) {
|
if (model instanceof RootBlockModel) {
|
||||||
const newDocMeta = this.doc.collection.meta.getDocMeta(model.doc.id);
|
const newDocMeta = this.doc.collection.meta.getDocMeta(model.doc.id);
|
||||||
if (!newDocMeta || newDocMeta.title !== model.title.toString()) {
|
if (!newDocMeta || newDocMeta.title !== model.title.toString()) {
|
||||||
this.doc.collection.setDocMeta(model.doc.id, {
|
this.doc.collection.meta.setDocMeta(model.doc.id, {
|
||||||
title: model.title.toString(),
|
title: model.title.toString(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import {
|
|||||||
polyLineNearestPoint,
|
polyLineNearestPoint,
|
||||||
Vec,
|
Vec,
|
||||||
} from '@blocksuite/global/utils';
|
} from '@blocksuite/global/utils';
|
||||||
import { DocCollection, type Y } from '@blocksuite/store';
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CONNECTOR_LABEL_MAX_WIDTH,
|
CONNECTOR_LABEL_MAX_WIDTH,
|
||||||
@@ -126,8 +126,8 @@ export class ConnectorElementModel extends GfxPrimitiveElementModel<ConnectorEle
|
|||||||
}
|
}
|
||||||
|
|
||||||
static override propsToY(props: ConnectorElementProps) {
|
static override propsToY(props: ConnectorElementProps) {
|
||||||
if (props.text && !(props.text instanceof DocCollection.Y.Text)) {
|
if (props.text && !(props.text instanceof Y.Text)) {
|
||||||
props.text = new DocCollection.Y.Text(props.text);
|
props.text = new Y.Text(props.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
return props;
|
return props;
|
||||||
|
|||||||
@@ -12,8 +12,7 @@ import {
|
|||||||
} from '@blocksuite/block-std/gfx';
|
} from '@blocksuite/block-std/gfx';
|
||||||
import type { IVec, PointLocation } from '@blocksuite/global/utils';
|
import type { IVec, PointLocation } from '@blocksuite/global/utils';
|
||||||
import { Bound, keys, linePolygonIntersects } from '@blocksuite/global/utils';
|
import { Bound, keys, linePolygonIntersects } from '@blocksuite/global/utils';
|
||||||
import type { Y } from '@blocksuite/store';
|
import * as Y from 'yjs';
|
||||||
import { DocCollection } from '@blocksuite/store';
|
|
||||||
|
|
||||||
type GroupElementProps = BaseElementProps & {
|
type GroupElementProps = BaseElementProps & {
|
||||||
children: Y.Map<boolean>;
|
children: Y.Map<boolean>;
|
||||||
@@ -37,12 +36,12 @@ export class GroupElementModel extends GfxGroupLikeElementModel<GroupElementProp
|
|||||||
}
|
}
|
||||||
|
|
||||||
static override propsToY(props: Record<string, unknown>) {
|
static override propsToY(props: Record<string, unknown>) {
|
||||||
if ('title' in props && !(props.title instanceof DocCollection.Y.Text)) {
|
if ('title' in props && !(props.title instanceof Y.Text)) {
|
||||||
props.title = new DocCollection.Y.Text(props.title as string);
|
props.title = new Y.Text(props.title as string);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (props.children && !(props.children instanceof DocCollection.Y.Map)) {
|
if (props.children && !(props.children instanceof Y.Map)) {
|
||||||
const children = new DocCollection.Y.Map() as Y.Map<boolean>;
|
const children = new Y.Map() as Y.Map<boolean>;
|
||||||
|
|
||||||
keys(props.children).forEach(key => {
|
keys(props.children).forEach(key => {
|
||||||
children.set(key as string, true);
|
children.set(key as string, true);
|
||||||
@@ -112,13 +111,13 @@ export class GroupElementModel extends GfxGroupLikeElementModel<GroupElementProp
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
@field()
|
@field()
|
||||||
accessor children: Y.Map<boolean> = new DocCollection.Y.Map<boolean>();
|
accessor children: Y.Map<boolean> = new Y.Map<boolean>();
|
||||||
|
|
||||||
@local()
|
@local()
|
||||||
accessor showTitle: boolean = true;
|
accessor showTitle: boolean = true;
|
||||||
|
|
||||||
@field()
|
@field()
|
||||||
accessor title: Y.Text = new DocCollection.Y.Text();
|
accessor title: Y.Text = new Y.Text();
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ import {
|
|||||||
noop,
|
noop,
|
||||||
pick,
|
pick,
|
||||||
} from '@blocksuite/global/utils';
|
} from '@blocksuite/global/utils';
|
||||||
import { DocCollection, type Y } from '@blocksuite/store';
|
|
||||||
import { generateKeyBetween } from 'fractional-indexing';
|
import { generateKeyBetween } from 'fractional-indexing';
|
||||||
|
import * as Y from 'yjs';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { ConnectorMode } from '../../consts/connector.js';
|
import { ConnectorMode } from '../../consts/connector.js';
|
||||||
@@ -183,9 +183,9 @@ export class MindmapElementModel extends GfxGroupLikeElementModel<MindmapElement
|
|||||||
if (
|
if (
|
||||||
props.children &&
|
props.children &&
|
||||||
!isNodeType(props.children as Record<string, unknown>) &&
|
!isNodeType(props.children as Record<string, unknown>) &&
|
||||||
!(props.children instanceof DocCollection.Y.Map)
|
!(props.children instanceof Y.Map)
|
||||||
) {
|
) {
|
||||||
const children: Y.Map<NodeDetail> = new DocCollection.Y.Map();
|
const children: Y.Map<NodeDetail> = new Y.Map();
|
||||||
|
|
||||||
keys(props.children).forEach(key => {
|
keys(props.children).forEach(key => {
|
||||||
const detail = pick<Record<string, unknown>, keyof NodeDetail>(
|
const detail = pick<Record<string, unknown>, keyof NodeDetail>(
|
||||||
@@ -284,9 +284,7 @@ export class MindmapElementModel extends GfxGroupLikeElementModel<MindmapElement
|
|||||||
throw new Error(`Parent node ${parent} not found`);
|
throw new Error(`Parent node ${parent} not found`);
|
||||||
}
|
}
|
||||||
|
|
||||||
props['text'] = new DocCollection.Y.Text(
|
props['text'] = new Y.Text((props['text'] as string) ?? 'New node');
|
||||||
(props['text'] as string) ?? 'New node'
|
|
||||||
);
|
|
||||||
|
|
||||||
const type = (props.type as string) ?? 'shape';
|
const type = (props.type as string) ?? 'shape';
|
||||||
let id: string;
|
let id: string;
|
||||||
@@ -919,12 +917,12 @@ export class MindmapElementModel extends GfxGroupLikeElementModel<MindmapElement
|
|||||||
}
|
}
|
||||||
|
|
||||||
@convert((initialValue, instance) => {
|
@convert((initialValue, instance) => {
|
||||||
if (!(initialValue instanceof DocCollection.Y.Map)) {
|
if (!(initialValue instanceof Y.Map)) {
|
||||||
nodeSchema.parse(initialValue);
|
nodeSchema.parse(initialValue);
|
||||||
|
|
||||||
assertType<NodeType>(initialValue);
|
assertType<NodeType>(initialValue);
|
||||||
|
|
||||||
const map: Y.Map<NodeDetail> = new DocCollection.Y.Map();
|
const map: Y.Map<NodeDetail> = new Y.Map();
|
||||||
const surface = instance.surface;
|
const surface = instance.surface;
|
||||||
const doc = surface.doc;
|
const doc = surface.doc;
|
||||||
const recursive = (
|
const recursive = (
|
||||||
@@ -967,7 +965,7 @@ export class MindmapElementModel extends GfxGroupLikeElementModel<MindmapElement
|
|||||||
// since this model package is imported by playwright
|
// since this model package is imported by playwright
|
||||||
@observe(observeChildren)
|
@observe(observeChildren)
|
||||||
@field()
|
@field()
|
||||||
accessor children: Y.Map<NodeDetail> = new DocCollection.Y.Map();
|
accessor children: Y.Map<NodeDetail> = new Y.Map();
|
||||||
|
|
||||||
@watch(watchLayoutType)
|
@watch(watchLayoutType)
|
||||||
@field()
|
@field()
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import type {
|
|||||||
PointLocation,
|
PointLocation,
|
||||||
SerializedXYWH,
|
SerializedXYWH,
|
||||||
} from '@blocksuite/global/utils';
|
} from '@blocksuite/global/utils';
|
||||||
import { DocCollection, type Y } from '@blocksuite/store';
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DEFAULT_ROUGHNESS,
|
DEFAULT_ROUGHNESS,
|
||||||
@@ -68,8 +68,8 @@ export class ShapeElementModel extends GfxPrimitiveElementModel<ShapeProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static override propsToY(props: ShapeProps) {
|
static override propsToY(props: ShapeProps) {
|
||||||
if (props.text && !(props.text instanceof DocCollection.Y.Text)) {
|
if (props.text && !(props.text instanceof Y.Text)) {
|
||||||
props.text = new DocCollection.Y.Text(props.text);
|
props.text = new Y.Text(props.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
return props;
|
return props;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
pointInPolygon,
|
pointInPolygon,
|
||||||
polygonNearestPoint,
|
polygonNearestPoint,
|
||||||
} from '@blocksuite/global/utils';
|
} from '@blocksuite/global/utils';
|
||||||
import { DocCollection, type Y } from '@blocksuite/store';
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
FontFamily,
|
FontFamily,
|
||||||
@@ -31,8 +31,8 @@ export class TextElementModel extends GfxPrimitiveElementModel<TextElementProps>
|
|||||||
}
|
}
|
||||||
|
|
||||||
static override propsToY(props: Record<string, unknown>) {
|
static override propsToY(props: Record<string, unknown>) {
|
||||||
if (props.text && !(props.text instanceof DocCollection.Y.Text)) {
|
if (props.text && !(props.text instanceof Y.Text)) {
|
||||||
props.text = new DocCollection.Y.Text(props.text as string);
|
props.text = new Y.Text(props.text as string);
|
||||||
}
|
}
|
||||||
|
|
||||||
return props;
|
return props;
|
||||||
@@ -82,7 +82,7 @@ export class TextElementModel extends GfxPrimitiveElementModel<TextElementProps>
|
|||||||
accessor rotate: number = 0;
|
accessor rotate: number = 0;
|
||||||
|
|
||||||
@field()
|
@field()
|
||||||
accessor text: Y.Text = new DocCollection.Y.Text();
|
accessor text: Y.Text = new Y.Text();
|
||||||
|
|
||||||
@field()
|
@field()
|
||||||
accessor textAlign: TextAlign = TextAlign.Center;
|
accessor textAlign: TextAlign = TextAlign.Center;
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
"remark-parse": "^11.0.0",
|
"remark-parse": "^11.0.0",
|
||||||
"remark-stringify": "^11.0.0",
|
"remark-stringify": "^11.0.0",
|
||||||
"unified": "^11.0.5",
|
"unified": "^11.0.5",
|
||||||
|
"yjs": "^13.6.21",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
|
|||||||
@@ -17,12 +17,12 @@ import {
|
|||||||
type BlockModel,
|
type BlockModel,
|
||||||
type BlockSnapshot,
|
type BlockSnapshot,
|
||||||
type DeltaOperation,
|
type DeltaOperation,
|
||||||
DocCollection,
|
|
||||||
fromJSON,
|
fromJSON,
|
||||||
type JobMiddleware,
|
type JobMiddleware,
|
||||||
type SliceSnapshot,
|
type SliceSnapshot,
|
||||||
type Text,
|
type Text,
|
||||||
} from '@blocksuite/store';
|
} from '@blocksuite/store';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import { REFERENCE_NODE } from '../../consts';
|
import { REFERENCE_NODE } from '../../consts';
|
||||||
import {
|
import {
|
||||||
@@ -357,7 +357,7 @@ class PasteTr {
|
|||||||
!matchFlavours(this.pointState.model, ['affine:code'])
|
!matchFlavours(this.pointState.model, ['affine:code'])
|
||||||
) {
|
) {
|
||||||
const text = fromJSON(this.lastSnapshot.props.text) as Text;
|
const text = fromJSON(this.lastSnapshot.props.text) as Text;
|
||||||
const doc = new DocCollection.Y.Doc();
|
const doc = new Y.Doc();
|
||||||
const temp = doc.getMap('temp');
|
const temp = doc.getMap('temp');
|
||||||
temp.set('text', text.yText);
|
temp.set('text', text.yText);
|
||||||
this.lastIndex = text.length;
|
this.lastIndex = text.length;
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import {
|
|||||||
DisposableGroup,
|
DisposableGroup,
|
||||||
Slot,
|
Slot,
|
||||||
} from '@blocksuite/global/utils';
|
} from '@blocksuite/global/utils';
|
||||||
import { DocCollection } from '@blocksuite/store';
|
|
||||||
import { computed, type Signal, signal } from '@preact/signals-core';
|
import { computed, type Signal, signal } from '@preact/signals-core';
|
||||||
import clonedeep from 'lodash.clonedeep';
|
import clonedeep from 'lodash.clonedeep';
|
||||||
import mergeWith from 'lodash.mergewith';
|
import mergeWith from 'lodash.mergewith';
|
||||||
|
import * as Y from 'yjs';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { makeDeepOptional, NodePropsSchema } from '../utils/index.js';
|
import { makeDeepOptional, NodePropsSchema } from '../utils/index.js';
|
||||||
@@ -63,9 +63,9 @@ function isSessionProp(key: string): key is keyof SessionProps {
|
|||||||
function customizer(_target: unknown, source: unknown) {
|
function customizer(_target: unknown, source: unknown) {
|
||||||
if (
|
if (
|
||||||
ColorSchema.safeParse(source).success ||
|
ColorSchema.safeParse(source).success ||
|
||||||
source instanceof DocCollection.Y.Text ||
|
source instanceof Y.Text ||
|
||||||
source instanceof DocCollection.Y.Array ||
|
source instanceof Y.Array ||
|
||||||
source instanceof DocCollection.Y.Map
|
source instanceof Y.Map
|
||||||
) {
|
) {
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export function createDefaultDoc(
|
|||||||
const rootId = doc.addBlock('affine:page', {
|
const rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(title),
|
title: new doc.Text(title),
|
||||||
});
|
});
|
||||||
collection.setDocMeta(doc.id, {
|
collection.meta.setDocMeta(doc.id, {
|
||||||
title,
|
title,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -80,6 +80,7 @@
|
|||||||
"shiki": "^1.14.1",
|
"shiki": "^1.14.1",
|
||||||
"simple-xml-to-json": "^1.2.2",
|
"simple-xml-to-json": "^1.2.2",
|
||||||
"unified": "^11.0.5",
|
"unified": "^11.0.5",
|
||||||
|
"yjs": "^13.6.21",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
|
|||||||
@@ -57,12 +57,12 @@ import {
|
|||||||
import {
|
import {
|
||||||
type BlockSnapshot,
|
type BlockSnapshot,
|
||||||
BlockSnapshotSchema,
|
BlockSnapshotSchema,
|
||||||
DocCollection,
|
|
||||||
fromJSON,
|
fromJSON,
|
||||||
Job,
|
Job,
|
||||||
type SliceSnapshot,
|
type SliceSnapshot,
|
||||||
} from '@blocksuite/store';
|
} from '@blocksuite/store';
|
||||||
import DOMPurify from 'dompurify';
|
import DOMPurify from 'dompurify';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import { ExportManager } from '../../../_common/export-manager/export-manager.js';
|
import { ExportManager } from '../../../_common/export-manager/export-manager.js';
|
||||||
import { getRootByEditorHost } from '../../../_common/utils/query.js';
|
import { getRootByEditorHost } from '../../../_common/utils/query.js';
|
||||||
@@ -522,7 +522,7 @@ export class EdgelessClipboardController extends PageClipboard {
|
|||||||
newXYWH: SerializedXYWH
|
newXYWH: SerializedXYWH
|
||||||
) {
|
) {
|
||||||
if (clipboardData.type === GROUP) {
|
if (clipboardData.type === GROUP) {
|
||||||
const yMap = new DocCollection.Y.Map();
|
const yMap = new Y.Map();
|
||||||
const children = clipboardData.children ?? {};
|
const children = clipboardData.children ?? {};
|
||||||
|
|
||||||
for (const [key, value] of Object.entries(children)) {
|
for (const [key, value] of Object.entries(children)) {
|
||||||
@@ -536,7 +536,7 @@ export class EdgelessClipboardController extends PageClipboard {
|
|||||||
clipboardData.children = yMap;
|
clipboardData.children = yMap;
|
||||||
clipboardData.xywh = newXYWH;
|
clipboardData.xywh = newXYWH;
|
||||||
} else if (clipboardData.type === MINDMAP) {
|
} else if (clipboardData.type === MINDMAP) {
|
||||||
const yMap = new DocCollection.Y.Map();
|
const yMap = new Y.Map();
|
||||||
const children = clipboardData.children ?? {};
|
const children = clipboardData.children ?? {};
|
||||||
|
|
||||||
for (const [oldKey, oldValue] of Object.entries(children)) {
|
for (const [oldKey, oldValue] of Object.entries(children)) {
|
||||||
@@ -1112,7 +1112,7 @@ export class EdgelessClipboardController extends PageClipboard {
|
|||||||
TextUtils.splitIntoLines(content).forEach((line, idx) => {
|
TextUtils.splitIntoLines(content).forEach((line, idx) => {
|
||||||
this.crud.addBlock(
|
this.crud.addBlock(
|
||||||
'affine:paragraph',
|
'affine:paragraph',
|
||||||
{ text: new DocCollection.Y.Text(line) },
|
{ text: new Y.Text(line) },
|
||||||
noteId,
|
noteId,
|
||||||
idx
|
idx
|
||||||
);
|
);
|
||||||
|
|||||||
+3
-3
@@ -40,13 +40,13 @@ import {
|
|||||||
Vec,
|
Vec,
|
||||||
WithDisposable,
|
WithDisposable,
|
||||||
} from '@blocksuite/global/utils';
|
} from '@blocksuite/global/utils';
|
||||||
import { DocCollection } from '@blocksuite/store';
|
|
||||||
import { consume } from '@lit/context';
|
import { consume } from '@lit/context';
|
||||||
import { baseTheme } from '@toeverything/theme';
|
import { baseTheme } from '@toeverything/theme';
|
||||||
import { css, html, LitElement, nothing, unsafeCSS } from 'lit';
|
import { css, html, LitElement, nothing, unsafeCSS } from 'lit';
|
||||||
import { property } from 'lit/decorators.js';
|
import { property } from 'lit/decorators.js';
|
||||||
import { repeat } from 'lit/directives/repeat.js';
|
import { repeat } from 'lit/directives/repeat.js';
|
||||||
import { styleMap } from 'lit/directives/style-map.js';
|
import { styleMap } from 'lit/directives/style-map.js';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import type { EdgelessRootBlockComponent } from '../../edgeless-root-block.js';
|
import type { EdgelessRootBlockComponent } from '../../edgeless-root-block.js';
|
||||||
import {
|
import {
|
||||||
@@ -157,7 +157,7 @@ export class EdgelessAutoCompletePanel extends WithDisposable(LitElement) {
|
|||||||
const id = this.crud.addBlock(
|
const id = this.crud.addBlock(
|
||||||
'affine:frame',
|
'affine:frame',
|
||||||
{
|
{
|
||||||
title: new DocCollection.Y.Text(`Frame ${frameIndex}`),
|
title: new Y.Text(`Frame ${frameIndex}`),
|
||||||
xywh: serializeXYWH(...xywh),
|
xywh: serializeXYWH(...xywh),
|
||||||
presentationIndex: frameMgr.generatePresentationIndex(),
|
presentationIndex: frameMgr.generatePresentationIndex(),
|
||||||
},
|
},
|
||||||
@@ -275,7 +275,7 @@ export class EdgelessAutoCompletePanel extends WithDisposable(LitElement) {
|
|||||||
} else {
|
} else {
|
||||||
const textId = this.crud.addElement(CanvasElementType.TEXT, {
|
const textId = this.crud.addElement(CanvasElementType.TEXT, {
|
||||||
xywh: bound.serialize(),
|
xywh: bound.serialize(),
|
||||||
text: new DocCollection.Y.Text(),
|
text: new Y.Text(),
|
||||||
textAlign: 'left',
|
textAlign: 'left',
|
||||||
fontSize: 24,
|
fontSize: 24,
|
||||||
fontFamily: FontFamily.Inter,
|
fontFamily: FontFamily.Inter,
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import type { GfxController, GfxModel } from '@blocksuite/block-std/gfx';
|
|||||||
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
|
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
|
||||||
import type { XYWH } from '@blocksuite/global/utils';
|
import type { XYWH } from '@blocksuite/global/utils';
|
||||||
import { assertType, Bound } from '@blocksuite/global/utils';
|
import { assertType, Bound } from '@blocksuite/global/utils';
|
||||||
import { DocCollection } from '@blocksuite/store';
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import type { EdgelessRootBlockComponent } from '../../edgeless-root-block.js';
|
import type { EdgelessRootBlockComponent } from '../../edgeless-root-block.js';
|
||||||
import { type Shape, ShapeFactory } from '../../utils/tool-overlay.js';
|
import { type Shape, ShapeFactory } from '../../utils/tool-overlay.js';
|
||||||
@@ -284,7 +284,7 @@ export function createEdgelessElement(
|
|||||||
if (isShape(current)) {
|
if (isShape(current)) {
|
||||||
id = crud.addElement(current.type, {
|
id = crud.addElement(current.type, {
|
||||||
...current.serialize(),
|
...current.serialize(),
|
||||||
text: new DocCollection.Y.Text(),
|
text: new Y.Text(),
|
||||||
xywh: bound.serialize(),
|
xywh: bound.serialize(),
|
||||||
});
|
});
|
||||||
if (!id) return null;
|
if (!id) return null;
|
||||||
@@ -340,7 +340,7 @@ export function createShapeElement(
|
|||||||
const id = crud.addElement('shape', {
|
const id = crud.addElement('shape', {
|
||||||
shapeType: getShapeType(targetType),
|
shapeType: getShapeType(targetType),
|
||||||
radius: getShapeRadius(targetType),
|
radius: getShapeRadius(targetType),
|
||||||
text: new DocCollection.Y.Text(),
|
text: new Y.Text(),
|
||||||
});
|
});
|
||||||
if (!id) return null;
|
if (!id) return null;
|
||||||
const element = crud.getElementById(id);
|
const element = crud.getElementById(id);
|
||||||
|
|||||||
+2
-2
@@ -16,10 +16,10 @@ import {
|
|||||||
Vec,
|
Vec,
|
||||||
WithDisposable,
|
WithDisposable,
|
||||||
} from '@blocksuite/global/utils';
|
} from '@blocksuite/global/utils';
|
||||||
import { DocCollection } from '@blocksuite/store';
|
|
||||||
import { css, html, nothing } from 'lit';
|
import { css, html, nothing } from 'lit';
|
||||||
import { property, query } from 'lit/decorators.js';
|
import { property, query } from 'lit/decorators.js';
|
||||||
import { styleMap } from 'lit/directives/style-map.js';
|
import { styleMap } from 'lit/directives/style-map.js';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import type { EdgelessRootBlockComponent } from '../../edgeless-root-block.js';
|
import type { EdgelessRootBlockComponent } from '../../edgeless-root-block.js';
|
||||||
|
|
||||||
@@ -187,7 +187,7 @@ export class EdgelessConnectorLabelEditor extends WithDisposable(
|
|||||||
} else if (len < text.length) {
|
} else if (len < text.length) {
|
||||||
this.crud.updateElement(connector.id, {
|
this.crud.updateElement(connector.id, {
|
||||||
// @TODO: trim in Y.Text?
|
// @TODO: trim in Y.Text?
|
||||||
text: new DocCollection.Y.Text(trimed),
|
text: new Y.Text(trimed),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -18,10 +18,10 @@ import {
|
|||||||
Vec,
|
Vec,
|
||||||
WithDisposable,
|
WithDisposable,
|
||||||
} from '@blocksuite/global/utils';
|
} from '@blocksuite/global/utils';
|
||||||
import { DocCollection } from '@blocksuite/store';
|
|
||||||
import { html, nothing } from 'lit';
|
import { html, nothing } from 'lit';
|
||||||
import { property, query } from 'lit/decorators.js';
|
import { property, query } from 'lit/decorators.js';
|
||||||
import { styleMap } from 'lit/directives/style-map.js';
|
import { styleMap } from 'lit/directives/style-map.js';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import type { EdgelessRootBlockComponent } from '../../edgeless-root-block.js';
|
import type { EdgelessRootBlockComponent } from '../../edgeless-root-block.js';
|
||||||
|
|
||||||
@@ -110,7 +110,7 @@ export class EdgelessShapeTextEditor extends WithDisposable(ShadowlessElement) {
|
|||||||
if (len === 0) {
|
if (len === 0) {
|
||||||
this.element.text = undefined;
|
this.element.text = undefined;
|
||||||
} else if (len < text.length) {
|
} else if (len < text.length) {
|
||||||
this.element.text = new DocCollection.Y.Text(trimed);
|
this.element.text = new Y.Text(trimed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@ import { CanvasElementType } from '@blocksuite/affine-block-surface';
|
|||||||
import { type MindmapStyle, TextElementModel } from '@blocksuite/affine-model';
|
import { type MindmapStyle, TextElementModel } from '@blocksuite/affine-model';
|
||||||
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
||||||
import { assertInstanceOf, Bound } from '@blocksuite/global/utils';
|
import { assertInstanceOf, Bound } from '@blocksuite/global/utils';
|
||||||
import { DocCollection } from '@blocksuite/store';
|
|
||||||
import type { TemplateResult } from 'lit';
|
import type { TemplateResult } from 'lit';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import type { EdgelessRootBlockComponent } from '../../../edgeless-root-block.js';
|
import type { EdgelessRootBlockComponent } from '../../../edgeless-root-block.js';
|
||||||
import type { EdgelessRootService } from '../../../edgeless-root-service.js';
|
import type { EdgelessRootService } from '../../../edgeless-root-service.js';
|
||||||
@@ -114,7 +114,7 @@ export const textRender: DraggableTool['render'] = (
|
|||||||
} else {
|
} else {
|
||||||
id = service.crud.addElement(CanvasElementType.TEXT, {
|
id = service.crud.addElement(CanvasElementType.TEXT, {
|
||||||
xywh: new Bound(bound.x, vCenter - h / 2, w, h).serialize(),
|
xywh: new Bound(bound.x, vCenter - h / 2, w, h).serialize(),
|
||||||
text: new DocCollection.Y.Text(),
|
text: new Y.Text(),
|
||||||
}) as string;
|
}) as string;
|
||||||
|
|
||||||
edgeless.doc.captureSync();
|
edgeless.doc.captureSync();
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ import {
|
|||||||
type SerializedXYWH,
|
type SerializedXYWH,
|
||||||
} from '@blocksuite/global/utils';
|
} from '@blocksuite/global/utils';
|
||||||
import type { Doc } from '@blocksuite/store';
|
import type { Doc } from '@blocksuite/store';
|
||||||
import { DocCollection, Text } from '@blocksuite/store';
|
import { Text } from '@blocksuite/store';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import type { FrameBlockModel, NoteBlockModel } from '../../index.js';
|
import type { FrameBlockModel, NoteBlockModel } from '../../index.js';
|
||||||
import { areSetsEqual } from './utils/misc.js';
|
import { areSetsEqual } from './utils/misc.js';
|
||||||
@@ -196,9 +197,7 @@ export class EdgelessFrameManager extends GfxExtension {
|
|||||||
const id = this.gfx.doc.addBlock(
|
const id = this.gfx.doc.addBlock(
|
||||||
'affine:frame',
|
'affine:frame',
|
||||||
{
|
{
|
||||||
title: new Text(
|
title: new Text(new Y.Text(`Frame ${this.frames.length + 1}`)),
|
||||||
new DocCollection.Y.Text(`Frame ${this.frames.length + 1}`)
|
|
||||||
),
|
|
||||||
xywh: bound.serialize(),
|
xywh: bound.serialize(),
|
||||||
index: this.gfx.layer.generateIndex(true),
|
index: this.gfx.layer.generateIndex(true),
|
||||||
presentationIndex: this.generatePresentationIndex(),
|
presentationIndex: this.generatePresentationIndex(),
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ import {
|
|||||||
} from '@blocksuite/block-std/gfx';
|
} from '@blocksuite/block-std/gfx';
|
||||||
import type { IPoint, IVec } from '@blocksuite/global/utils';
|
import type { IPoint, IVec } from '@blocksuite/global/utils';
|
||||||
import { Bound, Vec } from '@blocksuite/global/utils';
|
import { Bound, Vec } from '@blocksuite/global/utils';
|
||||||
import { DocCollection, Text } from '@blocksuite/store';
|
import { Text } from '@blocksuite/store';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import type { EdgelessFrameManager, FrameOverlay } from '../frame-manager.js';
|
import type { EdgelessFrameManager, FrameOverlay } from '../frame-manager.js';
|
||||||
|
|
||||||
@@ -72,9 +73,7 @@ export class FrameTool extends BaseTool {
|
|||||||
const id = this.doc.addBlock(
|
const id = this.doc.addBlock(
|
||||||
'affine:frame',
|
'affine:frame',
|
||||||
{
|
{
|
||||||
title: new Text(
|
title: new Text(new Y.Text(`Frame ${frames.length + 1}`)),
|
||||||
new DocCollection.Y.Text(`Frame ${frames.length + 1}`)
|
|
||||||
),
|
|
||||||
xywh: Bound.fromPoints([this._startPoint, currentPoint]).serialize(),
|
xywh: Bound.fromPoints([this._startPoint, currentPoint]).serialize(),
|
||||||
index: this.gfx.layer.generateIndex(true),
|
index: this.gfx.layer.generateIndex(true),
|
||||||
presentationIndex: this.frameManager.generatePresentationIndex(),
|
presentationIndex: this.frameManager.generatePresentationIndex(),
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
|||||||
import type { PointerEventState } from '@blocksuite/block-std';
|
import type { PointerEventState } from '@blocksuite/block-std';
|
||||||
import { BaseTool, type GfxController } from '@blocksuite/block-std/gfx';
|
import { BaseTool, type GfxController } from '@blocksuite/block-std/gfx';
|
||||||
import { Bound } from '@blocksuite/global/utils';
|
import { Bound } from '@blocksuite/global/utils';
|
||||||
import { DocCollection } from '@blocksuite/store';
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import type { EdgelessRootBlockComponent } from '../edgeless-root-block.js';
|
import type { EdgelessRootBlockComponent } from '../edgeless-root-block.js';
|
||||||
import { mountTextElementEditor } from '../utils/text.js';
|
import { mountTextElementEditor } from '../utils/text.js';
|
||||||
@@ -22,7 +22,7 @@ export function addText(gfx: GfxController, event: PointerEventState) {
|
|||||||
const id = gfx.surface.addElement({
|
const id = gfx.surface.addElement({
|
||||||
type: 'text',
|
type: 'text',
|
||||||
xywh: new Bound(modelX, modelY, 32, 32).serialize(),
|
xywh: new Bound(modelX, modelY, 32, 32).serialize(),
|
||||||
text: new DocCollection.Y.Text(),
|
text: new Y.Text(),
|
||||||
});
|
});
|
||||||
gfx.doc.captureSync();
|
gfx.doc.captureSync();
|
||||||
const textElement = gfx.getElementById(id) as TextElementModel;
|
const textElement = gfx.getElementById(id) as TextElementModel;
|
||||||
|
|||||||
@@ -17,9 +17,8 @@ import {
|
|||||||
DocSnapshotSchema,
|
DocSnapshotSchema,
|
||||||
Job,
|
Job,
|
||||||
type SnapshotNode,
|
type SnapshotNode,
|
||||||
type Y,
|
|
||||||
} from '@blocksuite/store';
|
} from '@blocksuite/store';
|
||||||
|
import type * as Y from 'yjs';
|
||||||
/**
|
/**
|
||||||
* Those block contains other block's id
|
* Those block contains other block's id
|
||||||
* should defer the loading
|
* should defer the loading
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import type { PointerEventState } from '@blocksuite/block-std';
|
|||||||
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
|
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
|
||||||
import type { IVec } from '@blocksuite/global/utils';
|
import type { IVec } from '@blocksuite/global/utils';
|
||||||
import { assertInstanceOf, Bound } from '@blocksuite/global/utils';
|
import { assertInstanceOf, Bound } from '@blocksuite/global/utils';
|
||||||
import { DocCollection } from '@blocksuite/store';
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import { EdgelessConnectorLabelEditor } from '../components/text/edgeless-connector-label-editor.js';
|
import { EdgelessConnectorLabelEditor } from '../components/text/edgeless-connector-label-editor.js';
|
||||||
import { EdgelessFrameTitleEditor } from '../components/text/edgeless-frame-title-editor.js';
|
import { EdgelessFrameTitleEditor } from '../components/text/edgeless-frame-title-editor.js';
|
||||||
@@ -73,7 +73,7 @@ export function mountShapeTextEditor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!shapeElement.text) {
|
if (!shapeElement.text) {
|
||||||
const text = new DocCollection.Y.Text();
|
const text = new Y.Text();
|
||||||
edgeless.std
|
edgeless.std
|
||||||
.get(EdgelessCRUDIdentifier)
|
.get(EdgelessCRUDIdentifier)
|
||||||
.updateElement(shapeElement.id, { text });
|
.updateElement(shapeElement.id, { text });
|
||||||
@@ -167,7 +167,7 @@ export function addText(
|
|||||||
.get(EdgelessCRUDIdentifier)
|
.get(EdgelessCRUDIdentifier)
|
||||||
.addElement(CanvasElementType.TEXT, {
|
.addElement(CanvasElementType.TEXT, {
|
||||||
xywh: new Bound(modelX, modelY, 32, 32).serialize(),
|
xywh: new Bound(modelX, modelY, 32, 32).serialize(),
|
||||||
text: new DocCollection.Y.Text(),
|
text: new Y.Text(),
|
||||||
});
|
});
|
||||||
if (!id) return;
|
if (!id) return;
|
||||||
edgeless.doc.captureSync();
|
edgeless.doc.captureSync();
|
||||||
@@ -192,7 +192,7 @@ export function mountConnectorLabelEditor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!connector.text) {
|
if (!connector.text) {
|
||||||
const text = new DocCollection.Y.Text();
|
const text = new Y.Text();
|
||||||
const labelOffset = connector.labelOffset;
|
const labelOffset = connector.labelOffset;
|
||||||
let labelXYWH = connector.labelXYWH ?? [0, 0, 16, 16];
|
let labelXYWH = connector.labelXYWH ?? [0, 0, 16, 16];
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ import {
|
|||||||
} from '@blocksuite/affine-shared/services';
|
} from '@blocksuite/affine-shared/services';
|
||||||
import { getHostName, referenceToNode } from '@blocksuite/affine-shared/utils';
|
import { getHostName, referenceToNode } from '@blocksuite/affine-shared/utils';
|
||||||
import { type BlockStdScope, WidgetComponent } from '@blocksuite/block-std';
|
import { type BlockStdScope, WidgetComponent } from '@blocksuite/block-std';
|
||||||
import { type BlockModel, DocCollection } from '@blocksuite/store';
|
import { type BlockModel } from '@blocksuite/store';
|
||||||
import { autoUpdate, computePosition, flip, offset } from '@floating-ui/dom';
|
import { autoUpdate, computePosition, flip, offset } from '@floating-ui/dom';
|
||||||
import { html, nothing, type TemplateResult } from 'lit';
|
import { html, nothing, type TemplateResult } from 'lit';
|
||||||
import { query, state } from 'lit/decorators.js';
|
import { query, state } from 'lit/decorators.js';
|
||||||
@@ -61,6 +61,7 @@ import { classMap } from 'lit/directives/class-map.js';
|
|||||||
import { ifDefined } from 'lit/directives/if-defined.js';
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
||||||
import { join } from 'lit/directives/join.js';
|
import { join } from 'lit/directives/join.js';
|
||||||
import { repeat } from 'lit/directives/repeat.js';
|
import { repeat } from 'lit/directives/repeat.js';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
isBookmarkBlock,
|
isBookmarkBlock,
|
||||||
@@ -614,7 +615,7 @@ export class EmbedCardToolbar extends WidgetComponent<
|
|||||||
const parent = doc.getParent(targetModel);
|
const parent = doc.getParent(targetModel);
|
||||||
const index = parent?.children.indexOf(targetModel);
|
const index = parent?.children.indexOf(targetModel);
|
||||||
|
|
||||||
const yText = new DocCollection.Y.Text();
|
const yText = new Y.Text();
|
||||||
const insert = title || caption || url;
|
const insert = title || caption || url;
|
||||||
yText.insert(0, insert);
|
yText.insert(0, insert);
|
||||||
yText.format(0, insert.length, { link: url });
|
yText.format(0, insert.length, { link: url });
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
"rehype-parse": "^9.0.0",
|
"rehype-parse": "^9.0.0",
|
||||||
"unified": "^11.0.5",
|
"unified": "^11.0.5",
|
||||||
"w3c-keyname": "^2.2.8",
|
"w3c-keyname": "^2.2.8",
|
||||||
|
"yjs": "^13.6.21",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Y } from '@blocksuite/store';
|
import type * as Y from 'yjs';
|
||||||
|
|
||||||
import type { GfxPrimitiveElementModel } from '../element-model.js';
|
import type { GfxPrimitiveElementModel } from '../element-model.js';
|
||||||
import { getObjectPropMeta, setObjectPropMeta } from './common.js';
|
import { getObjectPropMeta, setObjectPropMeta } from './common.js';
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ import {
|
|||||||
Slot,
|
Slot,
|
||||||
type XYWH,
|
type XYWH,
|
||||||
} from '@blocksuite/global/utils';
|
} from '@blocksuite/global/utils';
|
||||||
import { DocCollection, type Y } from '@blocksuite/store';
|
|
||||||
import { createMutex } from 'lib0/mutex';
|
import { createMutex } from 'lib0/mutex';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
descendantElementsImpl,
|
descendantElementsImpl,
|
||||||
@@ -538,7 +538,7 @@ export function syncElementFromY(
|
|||||||
if (type.action === 'update' || type.action === 'add') {
|
if (type.action === 'update' || type.action === 'add') {
|
||||||
const value = model.yMap.get(key);
|
const value = model.yMap.get(key);
|
||||||
|
|
||||||
if (value instanceof DocCollection.Y.Text) {
|
if (value instanceof Y.Text) {
|
||||||
disposables[key]?.();
|
disposables[key]?.();
|
||||||
disposables[key] = watchText(key, value, callback);
|
disposables[key] = watchText(key, value, callback);
|
||||||
}
|
}
|
||||||
@@ -560,7 +560,7 @@ export function syncElementFromY(
|
|||||||
};
|
};
|
||||||
|
|
||||||
Array.from(model.yMap.entries()).forEach(([key, value]) => {
|
Array.from(model.yMap.entries()).forEach(([key, value]) => {
|
||||||
if (value instanceof DocCollection.Y.Text) {
|
if (value instanceof Y.Text) {
|
||||||
disposables[key] = watchText(key, value, callback);
|
disposables[key] = watchText(key, value, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { assertType, type Constructor, Slot } from '@blocksuite/global/utils';
|
import { assertType, type Constructor, Slot } from '@blocksuite/global/utils';
|
||||||
import type { Boxed, Y } from '@blocksuite/store';
|
import type { Boxed } from '@blocksuite/store';
|
||||||
import { BlockModel, DocCollection, nanoid } from '@blocksuite/store';
|
import { BlockModel, nanoid } from '@blocksuite/store';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
type GfxGroupCompatibleInterface,
|
type GfxGroupCompatibleInterface,
|
||||||
@@ -124,7 +125,7 @@ export class SurfaceBlockModel extends BlockModel<SurfaceBlockProps> {
|
|||||||
throw new Error('Cannot find id in props');
|
throw new Error('Cannot find id in props');
|
||||||
}
|
}
|
||||||
|
|
||||||
const yMap = new DocCollection.Y.Map();
|
const yMap = new Y.Map();
|
||||||
const elementModel = this._createElementFromYMap(
|
const elementModel = this._createElementFromYMap(
|
||||||
type as string,
|
type as string,
|
||||||
id as string,
|
id as string,
|
||||||
|
|||||||
@@ -18,14 +18,6 @@
|
|||||||
],
|
],
|
||||||
"author": "toeverything",
|
"author": "toeverything",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
|
||||||
"lit": "^3.2.0",
|
|
||||||
"yjs": "^13.6.21"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"lit": "^3.2.0",
|
|
||||||
"yjs": "*"
|
|
||||||
},
|
|
||||||
"exports": {
|
"exports": {
|
||||||
".": "./src/index.ts",
|
".": "./src/index.ts",
|
||||||
"./consts": "./src/consts.ts",
|
"./consts": "./src/consts.ts",
|
||||||
@@ -35,6 +27,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@blocksuite/global": "workspace:*",
|
"@blocksuite/global": "workspace:*",
|
||||||
"@preact/signals-core": "^1.8.0",
|
"@preact/signals-core": "^1.8.0",
|
||||||
|
"lit": "^3.2.0",
|
||||||
|
"yjs": "^13.6.21",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"version": "0.19.0"
|
"version": "0.19.0"
|
||||||
|
|||||||
@@ -18,10 +18,8 @@
|
|||||||
"@blocksuite/inline": "workspace:*",
|
"@blocksuite/inline": "workspace:*",
|
||||||
"@blocksuite/sync": "workspace:*",
|
"@blocksuite/sync": "workspace:*",
|
||||||
"@preact/signals-core": "^1.8.0",
|
"@preact/signals-core": "^1.8.0",
|
||||||
"@types/flexsearch": "^0.7.6",
|
|
||||||
"@types/lodash.ismatch": "^4.4.9",
|
"@types/lodash.ismatch": "^4.4.9",
|
||||||
"file-type": "^19.5.0",
|
"file-type": "^19.5.0",
|
||||||
"flexsearch": "0.7.43",
|
|
||||||
"lib0": "^0.2.97",
|
"lib0": "^0.2.97",
|
||||||
"lodash.clonedeep": "^4.5.0",
|
"lodash.clonedeep": "^4.5.0",
|
||||||
"lodash.ismatch": "^4.4.0",
|
"lodash.ismatch": "^4.4.0",
|
||||||
@@ -29,16 +27,12 @@
|
|||||||
"minimatch": "^10.0.1",
|
"minimatch": "^10.0.1",
|
||||||
"nanoid": "^5.0.7",
|
"nanoid": "^5.0.7",
|
||||||
"y-protocols": "^1.0.6",
|
"y-protocols": "^1.0.6",
|
||||||
|
"yjs": "^13.6.21",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/lodash.clonedeep": "^4.5.9",
|
"@types/lodash.clonedeep": "^4.5.9",
|
||||||
"@types/lodash.merge": "^4.6.9",
|
"@types/lodash.merge": "^4.6.9"
|
||||||
"lit": "^3.2.0",
|
|
||||||
"yjs": "^13.6.21"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"yjs": "*"
|
|
||||||
},
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
".": "./src/index.ts"
|
".": "./src/index.ts"
|
||||||
|
|||||||
@@ -436,7 +436,7 @@ describe('addBlock', () => {
|
|||||||
called = true;
|
called = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
collection.setDocMeta('doc:home', { favorite: true });
|
collection.meta.setDocMeta('doc:home', { favorite: true });
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
collection.meta.docMetas.map(({ id, title, favorite }) => ({
|
collection.meta.docMetas.map(({ id, title, favorite }) => ({
|
||||||
id,
|
id,
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
// oxlint-disable-next-line @typescript-eslint/triple-slash-reference
|
// oxlint-disable-next-line @typescript-eslint/triple-slash-reference
|
||||||
/// <reference path="../shim.d.ts" />
|
/// <reference path="../shim.d.ts" />
|
||||||
|
|
||||||
export type { Y };
|
|
||||||
export * from './adapter/index.js';
|
export * from './adapter/index.js';
|
||||||
export * from './reactive/index.js';
|
export * from './reactive/index.js';
|
||||||
export * from './schema/index.js';
|
export * from './schema/index.js';
|
||||||
@@ -11,8 +10,6 @@ export { type IdGenerator, nanoid, uuidv4 } from './utils/id-generator.js';
|
|||||||
export * as Utils from './utils/utils.js';
|
export * as Utils from './utils/utils.js';
|
||||||
export * from './yjs/index.js';
|
export * from './yjs/index.js';
|
||||||
|
|
||||||
import type * as Y from 'yjs';
|
|
||||||
|
|
||||||
const env =
|
const env =
|
||||||
typeof globalThis !== 'undefined'
|
typeof globalThis !== 'undefined'
|
||||||
? globalThis
|
? globalThis
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import {
|
|||||||
import clonedeep from 'lodash.clonedeep';
|
import clonedeep from 'lodash.clonedeep';
|
||||||
import merge from 'lodash.merge';
|
import merge from 'lodash.merge';
|
||||||
import { Awareness } from 'y-protocols/awareness.js';
|
import { Awareness } from 'y-protocols/awareness.js';
|
||||||
import * as Y from 'yjs';
|
|
||||||
|
|
||||||
import type { Schema } from '../schema/index.js';
|
import type { Schema } from '../schema/index.js';
|
||||||
import type { IdGenerator } from '../utils/id-generator.js';
|
import type { IdGenerator } from '../utils/id-generator.js';
|
||||||
@@ -27,7 +26,7 @@ import { BlockCollection, type GetDocOptions } from './doc/block-collection.js';
|
|||||||
import type { Doc, Query } from './doc/index.js';
|
import type { Doc, Query } from './doc/index.js';
|
||||||
import type { IdGeneratorType } from './id.js';
|
import type { IdGeneratorType } from './id.js';
|
||||||
import { pickIdGenerator } from './id.js';
|
import { pickIdGenerator } from './id.js';
|
||||||
import { DocCollectionMeta, type DocMeta } from './meta.js';
|
import { DocCollectionMeta } from './meta.js';
|
||||||
|
|
||||||
export type DocCollectionOptions = {
|
export type DocCollectionOptions = {
|
||||||
schema: Schema;
|
schema: Schema;
|
||||||
@@ -71,8 +70,6 @@ export interface StackItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class DocCollection {
|
export class DocCollection {
|
||||||
static Y = Y;
|
|
||||||
|
|
||||||
protected readonly _schema: Schema;
|
protected readonly _schema: Schema;
|
||||||
|
|
||||||
readonly awarenessStore: AwarenessStore;
|
readonly awarenessStore: AwarenessStore;
|
||||||
@@ -252,15 +249,6 @@ export class DocCollection {
|
|||||||
this.blockCollections.delete(docId);
|
this.blockCollections.delete(docId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Update doc meta state. Note that this intentionally does not mutate doc state. */
|
|
||||||
setDocMeta(
|
|
||||||
docId: string,
|
|
||||||
// You should not update subDocIds directly.
|
|
||||||
props: Partial<DocMeta>
|
|
||||||
) {
|
|
||||||
this.meta.setDocMeta(docId, props);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the data sync process
|
* Start the data sync process
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
IndexedDBBlobSource,
|
IndexedDBBlobSource,
|
||||||
IndexedDBDocSource,
|
IndexedDBDocSource,
|
||||||
} from '@blocksuite/sync';
|
} from '@blocksuite/sync';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import { WebSocketAwarenessSource } from '../../_common/sync/websocket/awareness';
|
import { WebSocketAwarenessSource } from '../../_common/sync/websocket/awareness';
|
||||||
import { WebSocketDocSource } from '../../_common/sync/websocket/doc';
|
import { WebSocketDocSource } from '../../_common/sync/websocket/doc';
|
||||||
@@ -93,7 +94,7 @@ export async function createDefaultDocCollection() {
|
|||||||
delete: (id: string) => collection.removeDoc(id),
|
delete: (id: string) => collection.removeDoc(id),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
window.Y = DocCollection.Y;
|
window.Y = Y;
|
||||||
|
|
||||||
return collection;
|
return collection;
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+2
-1
@@ -3,6 +3,7 @@ import type { TestUtils } from '@blocksuite/blocks';
|
|||||||
import type { AffineEditorContainer } from '@blocksuite/presets';
|
import type { AffineEditorContainer } from '@blocksuite/presets';
|
||||||
import type { BlockSchema, Doc, DocCollection, Job } from '@blocksuite/store';
|
import type { BlockSchema, Doc, DocCollection, Job } from '@blocksuite/store';
|
||||||
import type { z } from 'zod';
|
import type { z } from 'zod';
|
||||||
|
import type * as Y from 'yjs';
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
type HTMLTemplate = [
|
type HTMLTemplate = [
|
||||||
@@ -17,7 +18,7 @@ declare global {
|
|||||||
collection: DocCollection;
|
collection: DocCollection;
|
||||||
blockSchemas: z.infer<typeof BlockSchema>[];
|
blockSchemas: z.infer<typeof BlockSchema>[];
|
||||||
job: Job;
|
job: Job;
|
||||||
Y: typeof DocCollection.Y;
|
Y: typeof Y;
|
||||||
std: typeof std;
|
std: typeof std;
|
||||||
testUtils: TestUtils;
|
testUtils: TestUtils;
|
||||||
host: EditorHost;
|
host: EditorHost;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { DocCollection, Text } from '@blocksuite/store';
|
import { type DocCollection, Text } from '@blocksuite/store';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import type { InitFn } from './utils.js';
|
import type { InitFn } from './utils.js';
|
||||||
|
|
||||||
@@ -13,10 +14,10 @@ export const pendingStructs: InitFn = (
|
|||||||
const rootId = tempDoc.addBlock('affine:page', {
|
const rootId = tempDoc.addBlock('affine:page', {
|
||||||
title: new Text('Pending Structs'),
|
title: new Text('Pending Structs'),
|
||||||
});
|
});
|
||||||
const vec = DocCollection.Y.encodeStateVector(tempDoc.spaceDoc);
|
const vec = Y.encodeStateVector(tempDoc.spaceDoc);
|
||||||
|
|
||||||
// To avoid pending structs, uncomment the following line
|
// To avoid pending structs, uncomment the following line
|
||||||
// const update = DocCollection.Y.encodeStateAsUpdate(tempDoc.spaceDoc);
|
// const update = Y.encodeStateAsUpdate(tempDoc.spaceDoc);
|
||||||
|
|
||||||
tempDoc.addBlock('affine:surface', {}, rootId);
|
tempDoc.addBlock('affine:surface', {}, rootId);
|
||||||
// Add note block inside root block
|
// Add note block inside root block
|
||||||
@@ -28,11 +29,11 @@ export const pendingStructs: InitFn = (
|
|||||||
},
|
},
|
||||||
noteId
|
noteId
|
||||||
);
|
);
|
||||||
const diff = DocCollection.Y.encodeStateAsUpdate(tempDoc.spaceDoc, vec);
|
const diff = Y.encodeStateAsUpdate(tempDoc.spaceDoc, vec);
|
||||||
// To avoid pending structs, uncomment the following line
|
// To avoid pending structs, uncomment the following line
|
||||||
// DocCollection.Y.applyUpdate(doc.spaceDoc, update);
|
// Y.applyUpdate(doc.spaceDoc, update);
|
||||||
|
|
||||||
DocCollection.Y.applyUpdate(doc.spaceDoc, diff);
|
Y.applyUpdate(doc.spaceDoc, diff);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { Y } from '@blocksuite/store';
|
import type { DocCollection } from '@blocksuite/store';
|
||||||
import { DocCollection } from '@blocksuite/store';
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import type { InitFn } from './utils.js';
|
import type { InitFn } from './utils.js';
|
||||||
|
|
||||||
@@ -24,9 +24,9 @@ export const versionMismatch: InitFn = (
|
|||||||
const paragraph = blocks.get(paragraphId) as Y.Map<unknown>;
|
const paragraph = blocks.get(paragraphId) as Y.Map<unknown>;
|
||||||
paragraph.set('sys:version', (paragraph.get('sys:version') as number) + 1);
|
paragraph.set('sys:version', (paragraph.get('sys:version') as number) + 1);
|
||||||
|
|
||||||
const update = DocCollection.Y.encodeStateAsUpdate(tempDoc.spaceDoc);
|
const update = Y.encodeStateAsUpdate(tempDoc.spaceDoc);
|
||||||
|
|
||||||
DocCollection.Y.applyUpdate(doc.spaceDoc, update);
|
Y.applyUpdate(doc.spaceDoc, update);
|
||||||
doc.addBlock('affine:paragraph', {}, noteId);
|
doc.addBlock('affine:paragraph', {}, noteId);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import {
|
|||||||
IndexedDBBlobSource,
|
IndexedDBBlobSource,
|
||||||
MemoryBlobSource,
|
MemoryBlobSource,
|
||||||
} from '@blocksuite/sync';
|
} from '@blocksuite/sync';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import { MockServerBlobSource } from '../../_common/sync/blob/mock-server.js';
|
import { MockServerBlobSource } from '../../_common/sync/blob/mock-server.js';
|
||||||
import type { InitFn } from '../data/utils.js';
|
import type { InitFn } from '../data/utils.js';
|
||||||
@@ -92,7 +93,7 @@ export function createStarterDocCollection() {
|
|||||||
delete: (id: string) => collection.removeDoc(id),
|
delete: (id: string) => collection.removeDoc(id),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
window.Y = DocCollection.Y;
|
window.Y = Y;
|
||||||
window.testUtils = new TestUtils();
|
window.testUtils = new TestUtils();
|
||||||
|
|
||||||
return collection;
|
return collection;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
"@preact/signals-core": "^1.8.0",
|
"@preact/signals-core": "^1.8.0",
|
||||||
"@toeverything/theme": "^1.1.3",
|
"@toeverything/theme": "^1.1.3",
|
||||||
"lit": "^3.2.0",
|
"lit": "^3.2.0",
|
||||||
|
"yjs": "^13.6.21",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import {
|
|||||||
NoteDisplayMode,
|
NoteDisplayMode,
|
||||||
} from '@blocksuite/blocks';
|
} from '@blocksuite/blocks';
|
||||||
import { assertExists } from '@blocksuite/global/utils';
|
import { assertExists } from '@blocksuite/global/utils';
|
||||||
import { DocCollection } from '@blocksuite/store';
|
|
||||||
import { beforeEach, describe, expect, test } from 'vitest';
|
import { beforeEach, describe, expect, test } from 'vitest';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import { wait } from '../utils/common.js';
|
import { wait } from '../utils/common.js';
|
||||||
import { addNote, getDocRootBlock } from '../utils/edgeless.js';
|
import { addNote, getDocRootBlock } from '../utils/edgeless.js';
|
||||||
@@ -24,7 +24,7 @@ describe('group', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('group with no children will be removed automatically', () => {
|
test('group with no children will be removed automatically', () => {
|
||||||
const map = new DocCollection.Y.Map<boolean>();
|
const map = new Y.Map<boolean>();
|
||||||
const ids = Array.from({ length: 2 })
|
const ids = Array.from({ length: 2 })
|
||||||
.map(() => {
|
.map(() => {
|
||||||
const id = service.crud.addElement('shape', {
|
const id = service.crud.addElement('shape', {
|
||||||
@@ -62,7 +62,7 @@ describe('group', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('remove group should remove its children at the same time', () => {
|
test('remove group should remove its children at the same time', () => {
|
||||||
const map = new DocCollection.Y.Map<boolean>();
|
const map = new Y.Map<boolean>();
|
||||||
const doc = service.doc;
|
const doc = service.doc;
|
||||||
const noteId = addNote(doc);
|
const noteId = addNote(doc);
|
||||||
const shapeId = service.crud.addElement('shape', {
|
const shapeId = service.crud.addElement('shape', {
|
||||||
@@ -112,7 +112,7 @@ describe('group', () => {
|
|||||||
collapsedHeight: 100,
|
collapsedHeight: 100,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const children = new DocCollection.Y.Map<boolean>();
|
const children = new Y.Map<boolean>();
|
||||||
|
|
||||||
children.set(shape1, true);
|
children.set(shape1, true);
|
||||||
children.set(shape2, true);
|
children.set(shape2, true);
|
||||||
@@ -187,7 +187,7 @@ describe('group', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('empty group should have all zero xywh', () => {
|
test('empty group should have all zero xywh', () => {
|
||||||
const map = new DocCollection.Y.Map<boolean>();
|
const map = new Y.Map<boolean>();
|
||||||
const groupId = service.crud.addElement('group', { children: map });
|
const groupId = service.crud.addElement('group', { children: map });
|
||||||
assertExists(groupId);
|
assertExists(groupId);
|
||||||
const group = service.crud.getElementById(groupId) as GroupElementModel;
|
const group = service.crud.getElementById(groupId) as GroupElementModel;
|
||||||
@@ -201,7 +201,7 @@ describe('group', () => {
|
|||||||
test('descendant of group should not contain itself', () => {
|
test('descendant of group should not contain itself', () => {
|
||||||
const groupIds = [1, 2, 3].map(_ => {
|
const groupIds = [1, 2, 3].map(_ => {
|
||||||
return service.crud.addElement('group', {
|
return service.crud.addElement('group', {
|
||||||
children: new DocCollection.Y.Map<boolean>(),
|
children: new Y.Map<boolean>(),
|
||||||
}) as string;
|
}) as string;
|
||||||
});
|
});
|
||||||
const groups = groupIds.map(
|
const groups = groupIds.map(
|
||||||
|
|||||||
@@ -5,8 +5,9 @@ import type {
|
|||||||
GroupElementModel,
|
GroupElementModel,
|
||||||
NoteBlockModel,
|
NoteBlockModel,
|
||||||
} from '@blocksuite/blocks';
|
} from '@blocksuite/blocks';
|
||||||
import { type BlockModel, type Doc, DocCollection } from '@blocksuite/store';
|
import { type BlockModel, type Doc } from '@blocksuite/store';
|
||||||
import { beforeEach, describe, expect, test } from 'vitest';
|
import { beforeEach, describe, expect, test } from 'vitest';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import { wait } from '../utils/common.js';
|
import { wait } from '../utils/common.js';
|
||||||
import {
|
import {
|
||||||
@@ -409,7 +410,7 @@ describe('group related functionality', () => {
|
|||||||
service: EdgelessRootBlockComponent['service'],
|
service: EdgelessRootBlockComponent['service'],
|
||||||
childIds: string[]
|
childIds: string[]
|
||||||
) => {
|
) => {
|
||||||
const children = new DocCollection.Y.Map<boolean>();
|
const children = new Y.Map<boolean>();
|
||||||
childIds.forEach(id => children.set(id, true));
|
childIds.forEach(id => children.set(id, true));
|
||||||
|
|
||||||
return service.crud.addElement('group', {
|
return service.crud.addElement('group', {
|
||||||
@@ -574,7 +575,7 @@ describe('compare function', () => {
|
|||||||
childIds: string[]
|
childIds: string[]
|
||||||
// eslint-disable-next-line sonarjs/no-identical-functions
|
// eslint-disable-next-line sonarjs/no-identical-functions
|
||||||
) => {
|
) => {
|
||||||
const children = new DocCollection.Y.Map<boolean>();
|
const children = new Y.Map<boolean>();
|
||||||
childIds.forEach(id => children.set(id, true));
|
childIds.forEach(id => children.set(id, true));
|
||||||
|
|
||||||
return service.crud.addElement('group', {
|
return service.crud.addElement('group', {
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ import type { TextSelection } from '@blocksuite/block-std';
|
|||||||
import { ShadowlessElement } from '@blocksuite/block-std';
|
import { ShadowlessElement } from '@blocksuite/block-std';
|
||||||
import type { RichText } from '@blocksuite/blocks';
|
import type { RichText } from '@blocksuite/blocks';
|
||||||
import { WithDisposable } from '@blocksuite/global/utils';
|
import { WithDisposable } from '@blocksuite/global/utils';
|
||||||
import { DocCollection } from '@blocksuite/store';
|
|
||||||
import { css, html, nothing } from 'lit';
|
import { css, html, nothing } from 'lit';
|
||||||
import { property, query } from 'lit/decorators.js';
|
import { property, query } from 'lit/decorators.js';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import type { Comment, CommentManager } from './comment-manager.js';
|
import type { Comment, CommentManager } from './comment-manager.js';
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ export class CommentInput extends WithDisposable(ShadowlessElement) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const yText = new DocCollection.Y.Text();
|
const yText = new Y.Text();
|
||||||
yText.applyDelta(deltas);
|
yText.applyDelta(deltas);
|
||||||
const comment = this.manager.addComment(textSelection, {
|
const comment = this.manager.addComment(textSelection, {
|
||||||
author: 'Anonymous',
|
author: 'Anonymous',
|
||||||
@@ -82,7 +82,7 @@ export class CommentInput extends WithDisposable(ShadowlessElement) {
|
|||||||
|
|
||||||
const { quote } = parseResult;
|
const { quote } = parseResult;
|
||||||
|
|
||||||
const tmpYDoc = new DocCollection.Y.Doc();
|
const tmpYDoc = new Y.Doc();
|
||||||
const tmpYText = tmpYDoc.getText('comment');
|
const tmpYText = tmpYDoc.getText('comment');
|
||||||
|
|
||||||
return html`<div class="comment-input-container">
|
return html`<div class="comment-input-container">
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { EditorHost, TextSelection } from '@blocksuite/block-std';
|
import type { EditorHost, TextSelection } from '@blocksuite/block-std';
|
||||||
import { DocCollection, type Y } from '@blocksuite/store';
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
export interface CommentMeta {
|
export interface CommentMeta {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -53,10 +53,7 @@ export class CommentManager {
|
|||||||
quote,
|
quote,
|
||||||
...payload,
|
...payload,
|
||||||
};
|
};
|
||||||
this.commentsMap.set(
|
this.commentsMap.set(id, new Y.Map<unknown>(Object.entries(comment)));
|
||||||
id,
|
|
||||||
new DocCollection.Y.Map<unknown>(Object.entries(comment))
|
|
||||||
);
|
|
||||||
return comment;
|
return comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,17 +63,15 @@ export class CommentManager {
|
|||||||
const start = comment.get('start') as Comment['start'];
|
const start = comment.get('start') as Comment['start'];
|
||||||
const end = comment.get('end') as Comment['end'];
|
const end = comment.get('end') as Comment['end'];
|
||||||
|
|
||||||
const startIndex =
|
const startIndex = Y.createAbsolutePositionFromRelativePosition(
|
||||||
DocCollection.Y.createAbsolutePositionFromRelativePosition(
|
start.index,
|
||||||
start.index,
|
this.host.doc.spaceDoc
|
||||||
this.host.doc.spaceDoc
|
);
|
||||||
);
|
|
||||||
const startBlock = this.host.view.getBlock(start.id);
|
const startBlock = this.host.view.getBlock(start.id);
|
||||||
const endIndex =
|
const endIndex = Y.createAbsolutePositionFromRelativePosition(
|
||||||
DocCollection.Y.createAbsolutePositionFromRelativePosition(
|
end.index,
|
||||||
end.index,
|
this.host.doc.spaceDoc
|
||||||
this.host.doc.spaceDoc
|
);
|
||||||
);
|
|
||||||
const endBlock = this.host.view.getBlock(end.id);
|
const endBlock = this.host.view.getBlock(end.id);
|
||||||
|
|
||||||
if (!startIndex || !startBlock || !endIndex || !endBlock) {
|
if (!startIndex || !startBlock || !endIndex || !endBlock) {
|
||||||
@@ -122,11 +117,11 @@ export class CommentManager {
|
|||||||
const toBlockId = toBlock.model.id;
|
const toBlockId = toBlock.model.id;
|
||||||
if (!fromBlockText || !toBlockText) return null;
|
if (!fromBlockText || !toBlockText) return null;
|
||||||
|
|
||||||
const startIndex = DocCollection.Y.createRelativePositionFromTypeIndex(
|
const startIndex = Y.createRelativePositionFromTypeIndex(
|
||||||
fromBlockText.yText,
|
fromBlockText.yText,
|
||||||
from.index
|
from.index
|
||||||
);
|
);
|
||||||
const endIndex = DocCollection.Y.createRelativePositionFromTypeIndex(
|
const endIndex = Y.createRelativePositionFromTypeIndex(
|
||||||
toBlockText.yText,
|
toBlockText.yText,
|
||||||
to ? to.index + to.length : from.index + from.length
|
to ? to.index + to.length : from.index + from.length
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ export class DocTitle extends WithDisposable(ShadowlessElement) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private readonly _updateTitleInMeta = () => {
|
private readonly _updateTitleInMeta = () => {
|
||||||
this.doc.collection.setDocMeta(this.doc.id, {
|
this.doc.collection.meta.setDocMeta(this.doc.id, {
|
||||||
title: this._rootModel.title.toString(),
|
title: this._rootModel.title.toString(),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { ShadowlessElement } from '@blocksuite/block-std';
|
import { ShadowlessElement } from '@blocksuite/block-std';
|
||||||
import type { FrameBlockModel } from '@blocksuite/blocks';
|
import type { FrameBlockModel } from '@blocksuite/blocks';
|
||||||
import { DisposableGroup, WithDisposable } from '@blocksuite/global/utils';
|
import { DisposableGroup, WithDisposable } from '@blocksuite/global/utils';
|
||||||
import type { Y } from '@blocksuite/store';
|
|
||||||
import { css, html, type PropertyValues } from 'lit';
|
import { css, html, type PropertyValues } from 'lit';
|
||||||
import { property, query } from 'lit/decorators.js';
|
import { property, query } from 'lit/decorators.js';
|
||||||
|
import type * as Y from 'yjs';
|
||||||
|
|
||||||
import { FrameCardTitleEditor } from './frame-card-title-editor.js';
|
import { FrameCardTitleEditor } from './frame-card-title-editor.js';
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ import {
|
|||||||
uploadBlobForImage,
|
uploadBlobForImage,
|
||||||
} from '@blocksuite/affine/blocks';
|
} from '@blocksuite/affine/blocks';
|
||||||
import { Bound, getCommonBound } from '@blocksuite/affine/global/utils';
|
import { Bound, getCommonBound } from '@blocksuite/affine/global/utils';
|
||||||
import { type BlockProps, DocCollection, Text } from '@blocksuite/affine/store';
|
import { type BlockProps, Text } from '@blocksuite/affine/store';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import { getAIPanelWidget } from '../utils/ai-widgets';
|
import { getAIPanelWidget } from '../utils/ai-widgets';
|
||||||
import type { AffineNode, AIContext } from '../utils/context';
|
import type { AffineNode, AIContext } from '../utils/context';
|
||||||
@@ -262,7 +263,7 @@ function addSurfaceRefBlock(host: EditorHost, bound: Bound, place: Place) {
|
|||||||
const frame = host.doc.addBlock(
|
const frame = host.doc.addBlock(
|
||||||
'affine:frame',
|
'affine:frame',
|
||||||
{
|
{
|
||||||
title: new Text(new DocCollection.Y.Text('Frame')),
|
title: new Text(new Y.Text('Frame')),
|
||||||
xywh: bound.serialize(),
|
xywh: bound.serialize(),
|
||||||
index: LayerManager.INITIAL_INDEX,
|
index: LayerManager.INITIAL_INDEX,
|
||||||
},
|
},
|
||||||
|
|||||||
+1
-1
@@ -41,7 +41,7 @@ const BlockSuiteEditorImpl = ({
|
|||||||
}: EditorProps) => {
|
}: EditorProps) => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const disposable = page.slots.blockUpdated.once(() => {
|
const disposable = page.slots.blockUpdated.once(() => {
|
||||||
page.collection.setDocMeta(page.id, {
|
page.collection.meta.setDocMeta(page.id, {
|
||||||
updatedDate: Date.now(),
|
updatedDate: Date.now(),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import {
|
|||||||
useParams,
|
useParams,
|
||||||
useSearchParams,
|
useSearchParams,
|
||||||
} from 'react-router-dom';
|
} from 'react-router-dom';
|
||||||
|
import * as _Y from 'yjs';
|
||||||
|
|
||||||
import { AffineErrorBoundary } from '../../../components/affine/affine-error-boundary';
|
import { AffineErrorBoundary } from '../../../components/affine/affine-error-boundary';
|
||||||
import { WorkbenchRoot } from '../../../modules/workbench';
|
import { WorkbenchRoot } from '../../../modules/workbench';
|
||||||
@@ -46,11 +47,15 @@ declare global {
|
|||||||
var exportWorkspaceSnapshot: (docs?: string[]) => Promise<void>;
|
var exportWorkspaceSnapshot: (docs?: string[]) => Promise<void>;
|
||||||
// oxlint-disable-next-line no-var
|
// oxlint-disable-next-line no-var
|
||||||
var importWorkspaceSnapshot: () => Promise<void>;
|
var importWorkspaceSnapshot: () => Promise<void>;
|
||||||
|
// oxlint-disable-next-line no-var
|
||||||
|
var Y: typeof _Y;
|
||||||
interface WindowEventMap {
|
interface WindowEventMap {
|
||||||
'affine:workspace:change': CustomEvent<{ id: string }>;
|
'affine:workspace:change': CustomEvent<{ id: string }>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
globalThis.Y = _Y;
|
||||||
|
|
||||||
export const Component = (): ReactElement => {
|
export const Component = (): ReactElement => {
|
||||||
const {
|
const {
|
||||||
workspacesService,
|
workspacesService,
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ export class DocsStore extends Store {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setDocMeta(id: string, meta: Partial<DocMeta>) {
|
setDocMeta(id: string, meta: Partial<DocMeta>) {
|
||||||
this.workspaceService.workspace.docCollection.setDocMeta(id, meta);
|
this.workspaceService.workspace.docCollection.meta.setDocMeta(id, meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
setDocPrimaryModeSetting(id: string, mode: DocMode) {
|
setDocPrimaryModeSetting(id: string, mode: DocMode) {
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
// the adapter is to bridge the workspace rootdoc & native js bindings
|
// the adapter is to bridge the workspace rootdoc & native js bindings
|
||||||
import type { WorkspaceService } from '@affine/core/modules/workspace';
|
import type { WorkspaceService } from '@affine/core/modules/workspace';
|
||||||
import { createYProxy, type Y } from '@blocksuite/affine/store';
|
import { createYProxy } from '@blocksuite/affine/store';
|
||||||
import { LiveData, Service } from '@toeverything/infra';
|
import { LiveData, Service } from '@toeverything/infra';
|
||||||
import { defaultsDeep } from 'lodash-es';
|
import { defaultsDeep } from 'lodash-es';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
|
import type * as Y from 'yjs';
|
||||||
|
|
||||||
import type { FavoriteSupportTypeUnion } from '../../constant';
|
import type { FavoriteSupportTypeUnion } from '../../constant';
|
||||||
import type { FavoriteService } from '../favorite';
|
import type { FavoriteService } from '../favorite';
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ export class TagStore extends Store {
|
|||||||
};
|
};
|
||||||
|
|
||||||
updatePageTags = (pageId: string, tags: string[]) => {
|
updatePageTags = (pageId: string, tags: string[]) => {
|
||||||
this.workspaceService.workspace.docCollection.setDocMeta(pageId, {
|
this.workspaceService.workspace.docCollection.meta.setDocMeta(pageId, {
|
||||||
tags,
|
tags,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ test('newly created page shows empty history', async ({ page }) => {
|
|||||||
const pushCurrentPageUpdates = async (page: Page) => {
|
const pushCurrentPageUpdates = async (page: Page) => {
|
||||||
const [workspaceId, guid, updates, state] = await page.evaluate(() => {
|
const [workspaceId, guid, updates, state] = await page.evaluate(() => {
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
const Y = window.currentWorkspace.docCollection.constructor.Y;
|
const Y = window.Y;
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
const spaceDoc = window.currentEditor.page.spaceDoc;
|
const spaceDoc = window.currentEditor.page.spaceDoc;
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
|
|||||||
@@ -3379,6 +3379,7 @@ __metadata:
|
|||||||
date-fns: "npm:^4.0.0"
|
date-fns: "npm:^4.0.0"
|
||||||
lit: "npm:^3.2.0"
|
lit: "npm:^3.2.0"
|
||||||
minimatch: "npm:^10.0.1"
|
minimatch: "npm:^10.0.1"
|
||||||
|
yjs: "npm:^13.6.21"
|
||||||
zod: "npm:^3.23.8"
|
zod: "npm:^3.23.8"
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
@@ -3447,6 +3448,7 @@ __metadata:
|
|||||||
"@toeverything/theme": "npm:^1.1.3"
|
"@toeverything/theme": "npm:^1.1.3"
|
||||||
lit: "npm:^3.2.0"
|
lit: "npm:^3.2.0"
|
||||||
minimatch: "npm:^10.0.1"
|
minimatch: "npm:^10.0.1"
|
||||||
|
yjs: "npm:^13.6.21"
|
||||||
zod: "npm:^3.23.8"
|
zod: "npm:^3.23.8"
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
@@ -3633,6 +3635,7 @@ __metadata:
|
|||||||
lit: "npm:^3.2.0"
|
lit: "npm:^3.2.0"
|
||||||
lodash.chunk: "npm:^4.2.0"
|
lodash.chunk: "npm:^4.2.0"
|
||||||
nanoid: "npm:^5.0.7"
|
nanoid: "npm:^5.0.7"
|
||||||
|
yjs: "npm:^13.6.21"
|
||||||
zod: "npm:^3.23.8"
|
zod: "npm:^3.23.8"
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
@@ -3661,6 +3664,7 @@ __metadata:
|
|||||||
lit-html: "npm:^3.2.1"
|
lit-html: "npm:^3.2.1"
|
||||||
lodash.clonedeep: "npm:^4.5.0"
|
lodash.clonedeep: "npm:^4.5.0"
|
||||||
shiki: "npm:^1.12.0"
|
shiki: "npm:^1.12.0"
|
||||||
|
yjs: "npm:^13.6.21"
|
||||||
zod: "npm:^3.23.8"
|
zod: "npm:^3.23.8"
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
@@ -3674,6 +3678,7 @@ __metadata:
|
|||||||
"@blocksuite/inline": "workspace:*"
|
"@blocksuite/inline": "workspace:*"
|
||||||
"@blocksuite/store": "workspace:*"
|
"@blocksuite/store": "workspace:*"
|
||||||
fractional-indexing: "npm:^3.2.0"
|
fractional-indexing: "npm:^3.2.0"
|
||||||
|
yjs: "npm:^13.6.21"
|
||||||
zod: "npm:^3.23.8"
|
zod: "npm:^3.23.8"
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
@@ -3715,6 +3720,7 @@ __metadata:
|
|||||||
remark-parse: "npm:^11.0.0"
|
remark-parse: "npm:^11.0.0"
|
||||||
remark-stringify: "npm:^11.0.0"
|
remark-stringify: "npm:^11.0.0"
|
||||||
unified: "npm:^11.0.5"
|
unified: "npm:^11.0.5"
|
||||||
|
yjs: "npm:^13.6.21"
|
||||||
zod: "npm:^3.23.8"
|
zod: "npm:^3.23.8"
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
@@ -3819,6 +3825,7 @@ __metadata:
|
|||||||
rehype-parse: "npm:^9.0.0"
|
rehype-parse: "npm:^9.0.0"
|
||||||
unified: "npm:^11.0.5"
|
unified: "npm:^11.0.5"
|
||||||
w3c-keyname: "npm:^2.2.8"
|
w3c-keyname: "npm:^2.2.8"
|
||||||
|
yjs: "npm:^13.6.21"
|
||||||
zod: "npm:^3.23.8"
|
zod: "npm:^3.23.8"
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
@@ -3895,6 +3902,7 @@ __metadata:
|
|||||||
shiki: "npm:^1.14.1"
|
shiki: "npm:^1.14.1"
|
||||||
simple-xml-to-json: "npm:^1.2.2"
|
simple-xml-to-json: "npm:^1.2.2"
|
||||||
unified: "npm:^11.0.5"
|
unified: "npm:^11.0.5"
|
||||||
|
yjs: "npm:^13.6.21"
|
||||||
zod: "npm:^3.23.8"
|
zod: "npm:^3.23.8"
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
@@ -3916,6 +3924,7 @@ __metadata:
|
|||||||
"@toeverything/theme": "npm:^1.1.3"
|
"@toeverything/theme": "npm:^1.1.3"
|
||||||
date-fns: "npm:^4.0.0"
|
date-fns: "npm:^4.0.0"
|
||||||
lit: "npm:^3.2.0"
|
lit: "npm:^3.2.0"
|
||||||
|
yjs: "npm:^13.6.21"
|
||||||
zod: "npm:^3.23.8"
|
zod: "npm:^3.23.8"
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
@@ -3956,9 +3965,6 @@ __metadata:
|
|||||||
lit: "npm:^3.2.0"
|
lit: "npm:^3.2.0"
|
||||||
yjs: "npm:^13.6.21"
|
yjs: "npm:^13.6.21"
|
||||||
zod: "npm:^3.23.8"
|
zod: "npm:^3.23.8"
|
||||||
peerDependencies:
|
|
||||||
lit: ^3.2.0
|
|
||||||
yjs: "*"
|
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
@@ -4033,6 +4039,7 @@ __metadata:
|
|||||||
"@toeverything/theme": "npm:^1.1.3"
|
"@toeverything/theme": "npm:^1.1.3"
|
||||||
lit: "npm:^3.2.0"
|
lit: "npm:^3.2.0"
|
||||||
vitest: "npm:^2.1.8"
|
vitest: "npm:^2.1.8"
|
||||||
|
yjs: "npm:^13.6.21"
|
||||||
zod: "npm:^3.23.8"
|
zod: "npm:^3.23.8"
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
@@ -4045,14 +4052,11 @@ __metadata:
|
|||||||
"@blocksuite/inline": "workspace:*"
|
"@blocksuite/inline": "workspace:*"
|
||||||
"@blocksuite/sync": "workspace:*"
|
"@blocksuite/sync": "workspace:*"
|
||||||
"@preact/signals-core": "npm:^1.8.0"
|
"@preact/signals-core": "npm:^1.8.0"
|
||||||
"@types/flexsearch": "npm:^0.7.6"
|
|
||||||
"@types/lodash.clonedeep": "npm:^4.5.9"
|
"@types/lodash.clonedeep": "npm:^4.5.9"
|
||||||
"@types/lodash.ismatch": "npm:^4.4.9"
|
"@types/lodash.ismatch": "npm:^4.4.9"
|
||||||
"@types/lodash.merge": "npm:^4.6.9"
|
"@types/lodash.merge": "npm:^4.6.9"
|
||||||
file-type: "npm:^19.5.0"
|
file-type: "npm:^19.5.0"
|
||||||
flexsearch: "npm:0.7.43"
|
|
||||||
lib0: "npm:^0.2.97"
|
lib0: "npm:^0.2.97"
|
||||||
lit: "npm:^3.2.0"
|
|
||||||
lodash.clonedeep: "npm:^4.5.0"
|
lodash.clonedeep: "npm:^4.5.0"
|
||||||
lodash.ismatch: "npm:^4.4.0"
|
lodash.ismatch: "npm:^4.4.0"
|
||||||
lodash.merge: "npm:^4.6.2"
|
lodash.merge: "npm:^4.6.2"
|
||||||
@@ -4061,8 +4065,6 @@ __metadata:
|
|||||||
y-protocols: "npm:^1.0.6"
|
y-protocols: "npm:^1.0.6"
|
||||||
yjs: "npm:^13.6.21"
|
yjs: "npm:^13.6.21"
|
||||||
zod: "npm:^3.23.8"
|
zod: "npm:^3.23.8"
|
||||||
peerDependencies:
|
|
||||||
yjs: "*"
|
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
@@ -14300,13 +14302,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@types/flexsearch@npm:^0.7.6":
|
|
||||||
version: 0.7.6
|
|
||||||
resolution: "@types/flexsearch@npm:0.7.6"
|
|
||||||
checksum: 10/93aaed91f5847a0c85e19b339147067897c92385de842071c959bf3f1efb8c7095acce460385aa285c75c67022d78979b4cae6ecb754bdb74348bf4976160ae3
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@types/fs-extra@npm:9.0.13, @types/fs-extra@npm:^9.0.1, @types/fs-extra@npm:^9.0.11":
|
"@types/fs-extra@npm:9.0.13, @types/fs-extra@npm:^9.0.1, @types/fs-extra@npm:^9.0.11":
|
||||||
version: 9.0.13
|
version: 9.0.13
|
||||||
resolution: "@types/fs-extra@npm:9.0.13"
|
resolution: "@types/fs-extra@npm:9.0.13"
|
||||||
@@ -21563,13 +21558,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"flexsearch@npm:0.7.43":
|
|
||||||
version: 0.7.43
|
|
||||||
resolution: "flexsearch@npm:0.7.43"
|
|
||||||
checksum: 10/79c0bceee435bd40fd0a0d8ba72f1bd07f622374a73bd3ceb874f7c7dd9a0fe9863b5c66a4037c2fa534e726f718d010ac99377d1924e347823b51ce641180e5
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"flora-colossus@npm:^2.0.0":
|
"flora-colossus@npm:^2.0.0":
|
||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
resolution: "flora-colossus@npm:2.0.0"
|
resolution: "flora-colossus@npm:2.0.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user