Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@blocksuite/store

Package Overview
Dependencies
Maintainers
0
Versions
1250
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@blocksuite/store - npm Package Compare versions

Comparing version 0.0.0-canary-20241014001453 to 0.0.0-canary-20241015001406

8

CHANGELOG.md
# @blocksuite/store
## 0.0.0-canary-20241014001453
## 0.0.0-canary-20241015001406

@@ -9,5 +9,5 @@ ### Patch Changes

- Updated dependencies
- @blocksuite/global@0.0.0-canary-20241014001453
- @blocksuite/inline@0.0.0-canary-20241014001453
- @blocksuite/sync@0.0.0-canary-20241014001453
- @blocksuite/global@0.0.0-canary-20241015001406
- @blocksuite/inline@0.0.0-canary-20241015001406
- @blocksuite/sync@0.0.0-canary-20241015001406

@@ -14,0 +14,0 @@ ## 0.17.18

@@ -46,3 +46,3 @@ import type { Doc } from '../store/index.js';

constructor(job: Job);
fromBlock(mode: DraftModel): Promise<FromBlockSnapshotResult<AdapterTarget> | undefined>;
fromBlock(model: DraftModel): Promise<FromBlockSnapshotResult<AdapterTarget> | undefined>;
abstract fromBlockSnapshot(payload: FromBlockSnapshotPayload): Promise<FromBlockSnapshotResult<AdapterTarget>> | FromBlockSnapshotResult<AdapterTarget>;

@@ -49,0 +49,0 @@ fromDoc(doc: Doc): Promise<FromDocSnapshotResult<AdapterTarget> | undefined>;

@@ -10,5 +10,5 @@ import { assertEquals } from '@blocksuite/global/utils';

}
async fromBlock(mode) {
async fromBlock(model) {
try {
const blockSnapshot = await this.job.blockToSnapshot(mode);
const blockSnapshot = await this.job.blockToSnapshot(model);
if (!blockSnapshot)

@@ -15,0 +15,0 @@ return;

@@ -15,3 +15,3 @@ import type { BlockModel, InternalPrimitives } from '../schema/index.js';

};
export type SnapshotReturn<Props extends object> = {
export type SnapshotNode<Props extends object> = {
id: string;

@@ -28,3 +28,3 @@ flavour: string;

};
fromSnapshot({ json, }: FromSnapshotPayload): Promise<SnapshotReturn<Props>> | SnapshotReturn<Props>;
fromSnapshot({ json, }: FromSnapshotPayload): Promise<SnapshotNode<Props>> | SnapshotNode<Props>;
toSnapshot({ model, }: ToSnapshotPayload<Props>): Promise<BlockSnapshotLeaf> | BlockSnapshotLeaf;

@@ -31,0 +31,0 @@ }

import type { BlockModel } from '../schema/index.js';
import type { Doc, DocCollection } from '../store/index.js';
import type { DraftModel } from './draft.js';
import type { JobMiddleware } from './middleware.js';
import type { BlockSnapshot, CollectionInfoSnapshot, DocSnapshot, SliceSnapshot } from './type.js';
import { AssetsManager } from './assets.js';
import { type DraftModel } from './draft.js';
import { Slice } from './slice.js';

@@ -15,7 +15,4 @@ export type JobConfig = {

private readonly _assetsManager;
private _batchCounter;
private readonly _collection;
private readonly _pendingOperations;
private readonly _slots;
private _unblockTimer?;
blockToSnapshot: (model: DraftModel) => Promise<BlockSnapshot | undefined>;

@@ -27,3 +24,3 @@ collectionInfoToSnapshot: () => CollectionInfoSnapshot | undefined;

snapshotToDoc: (snapshot: DocSnapshot) => Promise<Doc | undefined>;
snapshotToModelData: (snapshot: BlockSnapshot) => Promise<import("./base.js").SnapshotReturn<object> | undefined>;
snapshotToModelData: (snapshot: BlockSnapshot) => Promise<import("./base.js").SnapshotNode<object> | undefined>;
snapshotToSlice: (snapshot: SliceSnapshot, doc: Doc, parent?: string, index?: number) => Promise<Slice | undefined>;

@@ -36,11 +33,16 @@ walk: (snapshot: DocSnapshot, callback: (block: BlockSnapshot) => void) => void;

constructor({ collection, middlewares }: JobConfig);
private _batchSnapshotToBlock;
private _blockToSnapshot;
private _convertFlatSnapshots;
private _convertSnapshotToDraftModel;
private _exportDocMeta;
private _flattenSnapshot;
private _getCollectionMeta;
private _getSchema;
private _getTransformer;
private _insertBlockTree;
private _rebuildBlockTree;
private _snapshotToBlock;
private _triggerBeforeImportEvent;
reset(): void;
}
//# sourceMappingURL=job.d.ts.map

@@ -5,5 +5,19 @@ import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';

import { BaseBlockTransformer } from './base.js';
import { toDraftModel } from './draft.js';
import { Slice } from './slice.js';
import { BlockSnapshotSchema, CollectionInfoSnapshotSchema, DocSnapshotSchema, SliceSnapshotSchema, } from './type.js';
async function nextTick() {
// @ts-ignore
if ('scheduler' in window && 'yield' in window.scheduler) {
// @ts-ignore
return window.scheduler.yield();
}
else if (typeof requestIdleCallback !== 'undefined') {
return new Promise(resolve => requestIdleCallback(resolve));
}
else {
return new Promise(resolve => setTimeout(resolve, 0));
}
}
// The number of blocks to insert in one batch
const BATCH_SIZE = 100;
export class Job {

@@ -24,4 +38,2 @@ get adapterConfigs() {

this._adapterConfigs = new Map();
this._batchCounter = 0;
this._pendingOperations = [];
this._slots = {

@@ -143,3 +155,5 @@ beforeImport: new Slot(),

BlockSnapshotSchema.parse(snapshot);
const model = await this._batchSnapshotToBlock(snapshot, doc, parent, index);
const model = await this._snapshotToBlock(snapshot, doc, parent, index);
if (!model)
return;
return model;

@@ -201,2 +215,3 @@ }

this.snapshotToSlice = async (snapshot, doc, parent, index) => {
SliceSnapshotSchema.parse(snapshot);
try {

@@ -207,10 +222,23 @@ this._slots.beforeImport.emit({

});
SliceSnapshotSchema.parse(snapshot);
const { content, pageVersion, workspaceVersion, workspaceId, pageId } = snapshot;
const contentBlocks = [];
for (const [i, block] of content.entries()) {
contentBlocks.push(await this._batchSnapshotToBlock(block, doc, parent, (index ?? 0) + i));
// Create a temporary root snapshot to encompass all content blocks
const tmpRootSnapshot = {
id: 'temporary-root',
flavour: 'affine:page',
props: {},
type: 'block',
children: content,
};
for (const block of content) {
this._triggerBeforeImportEvent(block, parent, index);
}
const flatSnapshots = [];
this._flattenSnapshot(tmpRootSnapshot, flatSnapshots, parent, index);
const blockTree = await this._convertFlatSnapshots(flatSnapshots);
await this._insertBlockTree(blockTree.children, doc, parent, index);
const contentBlocks = blockTree.children
.map(tree => doc.getBlockById(tree.draft.id))
.filter(Boolean);
const slice = new Slice({
content: contentBlocks.map(block => toDraftModel(block)),
content: contentBlocks,
pageVersion,

@@ -260,33 +288,2 @@ workspaceVersion,

}
_batchSnapshotToBlock(snapshot, doc, parent, index) {
return new Promise(resolve => {
if (this._batchCounter < 100) {
resolve(this._snapshotToBlock(snapshot, doc, parent, index));
}
else {
// This will block the caller function
// so that no further operations can be added to the queue.
// Example:
// for (const snapshot of snapshots) {
// // Block here as it is waiting for the promise to resolve.
// await job.snapshotToBlock(snapshot, doc, id);
// }
this._pendingOperations.push(() => resolve(this._snapshotToBlock(snapshot, doc, parent, index)));
}
this._batchCounter++;
const unblock = () => {
// There should only be one operation in the queue
// as we should create new jobs for each events.
// However, we still need to loop through the list
// to avoid potential bugs.
while (this._pendingOperations.length > 0) {
this._pendingOperations.shift()?.();
}
this._unblockTimer = undefined;
this._batchCounter = 0;
};
clearTimeout(this._unblockTimer);
this._unblockTimer = setTimeout(unblock, 10);
});
}
async _blockToSnapshot(model) {

@@ -318,2 +315,51 @@ this._slots.beforeExport.emit({

}
async _convertFlatSnapshots(flatSnapshots) {
// Phase 1: Convert snapshots to draft models in series
// This is not time-consuming, this is faster than Promise.all
const draftModels = [];
for (const flat of flatSnapshots) {
const draft = await this._convertSnapshotToDraftModel(flat);
if (draft) {
draft.id = flat.snapshot.id;
}
draftModels.push({
draft,
snapshot: flat.snapshot,
parentId: flat.parentId,
index: flat.index,
});
}
// Phase 2: Filter out the models that failed to convert
const validDraftModels = draftModels.filter(item => !!item.draft);
// Phase 3: Rebuild the block trees
const blockTree = this._rebuildBlockTree(validDraftModels);
return blockTree;
}
async _convertSnapshotToDraftModel(flat) {
try {
const { children, flavour } = flat.snapshot;
const schema = this._getSchema(flavour);
const transformer = this._getTransformer(schema);
const { props } = await transformer.fromSnapshot({
json: {
id: flat.snapshot.id,
flavour: flat.snapshot.flavour,
props: flat.snapshot.props,
},
assets: this._assetsManager,
children,
});
return {
id: flat.snapshot.id,
flavour: flat.snapshot.flavour,
children: [],
...props,
};
}
catch (error) {
console.error(`Error when transforming snapshot to model data:`);
console.error(error);
return;
}
}
_exportDocMeta(doc) {

@@ -331,2 +377,10 @@ const docMeta = doc.meta;

}
_flattenSnapshot(snapshot, flatSnapshots, parentId, index) {
flatSnapshots.push({ snapshot, parentId, index });
if (snapshot.children) {
snapshot.children.forEach((child, idx) => {
this._flattenSnapshot(child, flatSnapshots, snapshot.id, idx);
});
}
}
_getCollectionMeta() {

@@ -361,43 +415,76 @@ const { meta } = this._collection;

}
async _snapshotToBlock(snapshot, doc, parent, index) {
this._slots.beforeImport.emit({
type: 'block',
snapshot,
parent,
index,
async _insertBlockTree(nodes, doc, parentId, startIndex, counter = 0) {
for (let index = 0; index < nodes.length; index++) {
const node = nodes[index];
const { draft } = node;
const { id, flavour } = draft;
const actualIndex = startIndex !== undefined ? startIndex + index : undefined;
doc.addBlock(flavour, draft, parentId, actualIndex);
const model = doc.getBlockById(id);
if (!model) {
throw new BlockSuiteError(ErrorCode.TransformerError, `Block not found by id ${id}`);
}
this._slots.afterImport.emit({
type: 'block',
model,
snapshot: node.snapshot,
});
counter++;
if (counter % BATCH_SIZE === 0) {
await nextTick();
}
if (node.children.length > 0) {
counter = await this._insertBlockTree(node.children, doc, id, undefined, counter);
}
}
return counter;
}
_rebuildBlockTree(draftModels) {
const nodeMap = new Map();
// First pass: create nodes and add them to the map
draftModels.forEach(({ draft, snapshot }) => {
nodeMap.set(draft.id, { draft, snapshot, children: [] });
});
const { children, flavour, props, id } = snapshot;
const schema = this._getSchema(flavour);
const snapshotLeaf = {
id,
flavour,
props,
};
const transformer = this._getTransformer(schema);
const modelData = await transformer.fromSnapshot({
json: snapshotLeaf,
assets: this._assetsManager,
children,
const root = nodeMap.get(draftModels[0].draft.id);
// Second pass: build the tree structure
draftModels.forEach(({ draft, parentId, index }) => {
const node = nodeMap.get(draft.id);
if (!node)
return;
if (parentId) {
const parentNode = nodeMap.get(parentId);
if (parentNode && index !== undefined) {
parentNode.children[index] = node;
}
}
});
const nextTick = typeof window !== 'undefined'
? window.requestAnimationFrame
: setImmediate;
await new Promise(resolve => nextTick(() => resolve(undefined)));
doc.addBlock(modelData.flavour, { ...modelData.props, id: modelData.id }, parent, index);
for (const [index, child] of children.entries()) {
await this._batchSnapshotToBlock(child, doc, id, index);
if (!root) {
throw new Error('No root node found in the tree');
}
const model = doc.getBlockById(id);
if (!model) {
throw new BlockSuiteError(ErrorCode.TransformerError, `Block not found by id ${id}`);
}
this._slots.afterImport.emit({
type: 'block',
snapshot,
model,
parent,
index,
});
return model;
return root;
}
async _snapshotToBlock(snapshot, doc, parent, index) {
this._triggerBeforeImportEvent(snapshot, parent, index);
const flatSnapshots = [];
this._flattenSnapshot(snapshot, flatSnapshots, parent, index);
const blockTree = await this._convertFlatSnapshots(flatSnapshots);
await this._insertBlockTree([blockTree], doc, parent, index);
return doc.getBlockById(snapshot.id) || null;
}
_triggerBeforeImportEvent(snapshot, parent, index) {
const traverseAndTrigger = (node, parent, index) => {
this._slots.beforeImport.emit({
type: 'block',
snapshot: node,
parent: parent,
index: index,
});
if (node.children) {
node.children.forEach((child, idx) => {
traverseAndTrigger(child, node.id, idx);
});
}
};
traverseAndTrigger(snapshot, parent, index);
}
reset() {

@@ -404,0 +491,0 @@ this._assetsManager.cleanup();

{
"name": "@blocksuite/store",
"version": "0.0.0-canary-20241014001453",
"version": "0.0.0-canary-20241015001406",
"description": "BlockSuite data store built for general purpose state management.",

@@ -23,5 +23,5 @@ "type": "module",

"dependencies": {
"@blocksuite/global": "0.0.0-canary-20241014001453",
"@blocksuite/inline": "0.0.0-canary-20241014001453",
"@blocksuite/sync": "0.0.0-canary-20241014001453",
"@blocksuite/global": "0.0.0-canary-20241015001406",
"@blocksuite/inline": "0.0.0-canary-20241015001406",
"@blocksuite/sync": "0.0.0-canary-20241015001406",
"@preact/signals-core": "^1.8.0",

@@ -28,0 +28,0 @@ "@types/flexsearch": "^0.7.6",

@@ -62,5 +62,5 @@ import { assertEquals } from '@blocksuite/global/utils';

async fromBlock(mode: DraftModel) {
async fromBlock(model: DraftModel) {
try {
const blockSnapshot = await this.job.blockToSnapshot(mode);
const blockSnapshot = await this.job.blockToSnapshot(model);
if (!blockSnapshot) return;

@@ -67,0 +67,0 @@ return await this.fromBlockSnapshot({

@@ -25,3 +25,3 @@ import type { BlockModel, InternalPrimitives } from '../schema/index.js';

export type SnapshotReturn<Props extends object> = {
export type SnapshotNode<Props extends object> = {
id: string;

@@ -55,5 +55,3 @@ flavour: string;

json,
}: FromSnapshotPayload):
| Promise<SnapshotReturn<Props>>
| SnapshotReturn<Props> {
}: FromSnapshotPayload): Promise<SnapshotNode<Props>> | SnapshotNode<Props> {
const { flavour, id, version, props: _props } = json;

@@ -60,0 +58,0 @@

@@ -6,2 +6,3 @@ import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';

import type { Doc, DocCollection, DocMeta } from '../store/index.js';
import type { DraftModel } from './draft.js';
import type {

@@ -23,3 +24,2 @@ BeforeExportPayload,

import { BaseBlockTransformer } from './base.js';
import { type DraftModel, toDraftModel } from './draft.js';
import { Slice } from './slice.js';

@@ -38,2 +38,29 @@ import {

interface FlatSnapshot {
snapshot: BlockSnapshot;
parentId?: string;
index?: number;
}
interface DraftBlockTreeNode {
draft: DraftModel;
snapshot: BlockSnapshot;
children: Array<DraftBlockTreeNode>;
}
async function nextTick() {
// @ts-ignore
if ('scheduler' in window && 'yield' in window.scheduler) {
// @ts-ignore
return window.scheduler.yield();
} else if (typeof requestIdleCallback !== 'undefined') {
return new Promise(resolve => requestIdleCallback(resolve));
} else {
return new Promise(resolve => setTimeout(resolve, 0));
}
}
// The number of blocks to insert in one batch
const BATCH_SIZE = 100;
export class Job {

@@ -44,8 +71,4 @@ private readonly _adapterConfigs = new Map<string, string>();

private _batchCounter = 0;
private readonly _collection: DocCollection;
private readonly _pendingOperations: (() => void)[] = [];
private readonly _slots: JobSlots = {

@@ -58,4 +81,2 @@ beforeImport: new Slot<BeforeImportPayload>(),

private _unblockTimer?: ReturnType<typeof setTimeout>;
blockToSnapshot = async (

@@ -188,9 +209,4 @@ model: DraftModel

BlockSnapshotSchema.parse(snapshot);
const model = await this._batchSnapshotToBlock(
snapshot,
doc,
parent,
index
);
const model = await this._snapshotToBlock(snapshot, doc, parent, index);
if (!model) return;
return model;

@@ -260,2 +276,3 @@ } catch (error) {

): Promise<Slice | undefined> => {
SliceSnapshotSchema.parse(snapshot);
try {

@@ -266,13 +283,31 @@ this._slots.beforeImport.emit({

});
SliceSnapshotSchema.parse(snapshot);
const { content, pageVersion, workspaceVersion, workspaceId, pageId } =
snapshot;
const contentBlocks: BlockModel[] = [];
for (const [i, block] of content.entries()) {
contentBlocks.push(
await this._batchSnapshotToBlock(block, doc, parent, (index ?? 0) + i)
);
// Create a temporary root snapshot to encompass all content blocks
const tmpRootSnapshot: BlockSnapshot = {
id: 'temporary-root',
flavour: 'affine:page',
props: {},
type: 'block',
children: content,
};
for (const block of content) {
this._triggerBeforeImportEvent(block, parent, index);
}
const flatSnapshots: FlatSnapshot[] = [];
this._flattenSnapshot(tmpRootSnapshot, flatSnapshots, parent, index);
const blockTree = await this._convertFlatSnapshots(flatSnapshots);
await this._insertBlockTree(blockTree.children, doc, parent, index);
const contentBlocks = blockTree.children
.map(tree => doc.getBlockById(tree.draft.id))
.filter(Boolean) as DraftModel[];
const slice = new Slice({
content: contentBlocks.map(block => toDraftModel(block)),
content: contentBlocks,
pageVersion,

@@ -283,2 +318,3 @@ workspaceVersion,

});
this._slots.afterImport.emit({

@@ -345,40 +381,2 @@ type: 'slice',

private _batchSnapshotToBlock(
snapshot: BlockSnapshot,
doc: Doc,
parent?: string,
index?: number
) {
return new Promise<BlockModel>(resolve => {
if (this._batchCounter < 100) {
resolve(this._snapshotToBlock(snapshot, doc, parent, index));
} else {
// This will block the caller function
// so that no further operations can be added to the queue.
// Example:
// for (const snapshot of snapshots) {
// // Block here as it is waiting for the promise to resolve.
// await job.snapshotToBlock(snapshot, doc, id);
// }
this._pendingOperations.push(() =>
resolve(this._snapshotToBlock(snapshot, doc, parent, index))
);
}
this._batchCounter++;
const unblock = () => {
// There should only be one operation in the queue
// as we should create new jobs for each events.
// However, we still need to loop through the list
// to avoid potential bugs.
while (this._pendingOperations.length > 0) {
this._pendingOperations.shift()?.();
}
this._unblockTimer = undefined;
this._batchCounter = 0;
};
clearTimeout(this._unblockTimer);
this._unblockTimer = setTimeout(unblock, 10);
});
}
private async _blockToSnapshot(model: DraftModel): Promise<BlockSnapshot> {

@@ -414,2 +412,62 @@ this._slots.beforeExport.emit({

private async _convertFlatSnapshots(flatSnapshots: FlatSnapshot[]) {
// Phase 1: Convert snapshots to draft models in series
// This is not time-consuming, this is faster than Promise.all
const draftModels = [];
for (const flat of flatSnapshots) {
const draft = await this._convertSnapshotToDraftModel(flat);
if (draft) {
draft.id = flat.snapshot.id;
}
draftModels.push({
draft,
snapshot: flat.snapshot,
parentId: flat.parentId,
index: flat.index,
});
}
// Phase 2: Filter out the models that failed to convert
const validDraftModels = draftModels.filter(item => !!item.draft) as {
draft: DraftModel;
snapshot: BlockSnapshot;
parentId?: string;
index?: number;
}[];
// Phase 3: Rebuild the block trees
const blockTree = this._rebuildBlockTree(validDraftModels);
return blockTree;
}
private async _convertSnapshotToDraftModel(
flat: FlatSnapshot
): Promise<DraftModel | undefined> {
try {
const { children, flavour } = flat.snapshot;
const schema = this._getSchema(flavour);
const transformer = this._getTransformer(schema);
const { props } = await transformer.fromSnapshot({
json: {
id: flat.snapshot.id,
flavour: flat.snapshot.flavour,
props: flat.snapshot.props,
},
assets: this._assetsManager,
children,
});
return {
id: flat.snapshot.id,
flavour: flat.snapshot.flavour,
children: [],
...props,
} as DraftModel;
} catch (error) {
console.error(`Error when transforming snapshot to model data:`);
console.error(error);
return;
}
}
private _exportDocMeta(doc: Doc): DocSnapshot['meta'] {

@@ -432,2 +490,16 @@ const docMeta = doc.meta;

private _flattenSnapshot(
snapshot: BlockSnapshot,
flatSnapshots: FlatSnapshot[],
parentId?: string,
index?: number
) {
flatSnapshots.push({ snapshot, parentId, index });
if (snapshot.children) {
snapshot.children.forEach((child, idx) => {
this._flattenSnapshot(child, flatSnapshots, snapshot.id, idx);
});
}
}
private _getCollectionMeta() {

@@ -474,2 +546,86 @@ const { meta } = this._collection;

private async _insertBlockTree(
nodes: DraftBlockTreeNode[],
doc: Doc,
parentId?: string,
startIndex?: number,
counter: number = 0
) {
for (let index = 0; index < nodes.length; index++) {
const node = nodes[index];
const { draft } = node;
const { id, flavour } = draft;
const actualIndex =
startIndex !== undefined ? startIndex + index : undefined;
doc.addBlock(flavour as BlockSuite.Flavour, draft, parentId, actualIndex);
const model = doc.getBlockById(id);
if (!model) {
throw new BlockSuiteError(
ErrorCode.TransformerError,
`Block not found by id ${id}`
);
}
this._slots.afterImport.emit({
type: 'block',
model,
snapshot: node.snapshot,
});
counter++;
if (counter % BATCH_SIZE === 0) {
await nextTick();
}
if (node.children.length > 0) {
counter = await this._insertBlockTree(
node.children,
doc,
id,
undefined,
counter
);
}
}
return counter;
}
private _rebuildBlockTree(
draftModels: {
draft: DraftModel;
snapshot: BlockSnapshot;
parentId?: string;
index?: number;
}[]
): DraftBlockTreeNode {
const nodeMap = new Map<string, DraftBlockTreeNode>();
// First pass: create nodes and add them to the map
draftModels.forEach(({ draft, snapshot }) => {
nodeMap.set(draft.id, { draft, snapshot, children: [] });
});
const root = nodeMap.get(draftModels[0].draft.id) as DraftBlockTreeNode;
// Second pass: build the tree structure
draftModels.forEach(({ draft, parentId, index }) => {
const node = nodeMap.get(draft.id);
if (!node) return;
if (parentId) {
const parentNode = nodeMap.get(parentId);
if (parentNode && index !== undefined) {
parentNode.children[index] = node;
}
}
});
if (!root) {
throw new Error('No root node found in the tree');
}
return root;
}
private async _snapshotToBlock(

@@ -480,56 +636,38 @@ snapshot: BlockSnapshot,

index?: number
) {
this._slots.beforeImport.emit({
type: 'block',
snapshot,
parent,
index,
});
const { children, flavour, props, id } = snapshot;
): Promise<BlockModel | null> {
this._triggerBeforeImportEvent(snapshot, parent, index);
const schema = this._getSchema(flavour);
const snapshotLeaf = {
id,
flavour,
props,
};
const transformer = this._getTransformer(schema);
const modelData = await transformer.fromSnapshot({
json: snapshotLeaf,
assets: this._assetsManager,
children,
});
const flatSnapshots: FlatSnapshot[] = [];
this._flattenSnapshot(snapshot, flatSnapshots, parent, index);
const nextTick =
typeof window !== 'undefined'
? window.requestAnimationFrame
: setImmediate;
await new Promise(resolve => nextTick(() => resolve(undefined)));
doc.addBlock(
modelData.flavour as BlockSuite.Flavour,
{ ...modelData.props, id: modelData.id },
parent,
index
);
const blockTree = await this._convertFlatSnapshots(flatSnapshots);
for (const [index, child] of children.entries()) {
await this._batchSnapshotToBlock(child, doc, id, index);
}
await this._insertBlockTree([blockTree], doc, parent, index);
const model = doc.getBlockById(id);
if (!model) {
throw new BlockSuiteError(
ErrorCode.TransformerError,
`Block not found by id ${id}`
);
}
this._slots.afterImport.emit({
type: 'block',
snapshot,
model,
parent,
index,
});
return doc.getBlockById(snapshot.id) || null;
}
return model;
private _triggerBeforeImportEvent(
snapshot: BlockSnapshot,
parent?: string,
index?: number
) {
const traverseAndTrigger = (
node: BlockSnapshot,
parent?: string,
index?: number
) => {
this._slots.beforeImport.emit({
type: 'block',
snapshot: node,
parent: parent,
index: index,
});
if (node.children) {
node.children.forEach((child, idx) => {
traverseAndTrigger(child, node.id, idx);
});
}
};
traverseAndTrigger(snapshot, parent, index);
}

@@ -536,0 +674,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc