mirror of
https://github.com/codex-team/editor.js
synced 2024-05-02 14:52:57 +02:00
chore(api): blocks.update(id, data) method improved (#2443)
* add custom Chai assertion "be.calledWithBatchedEvents" for testing onchange * chore(api): blocks.update(id, data) method improved - `blocks.update(id, data)` now can accept partial data object — it will update only passed properties, others will remain the same. - `blocks.update(id, data)` now will trigger onChange with only `block-change` event. - `blocks.update(id, data)` will return a promise with BlockAPI object of changed block. * fix tests * Update blocks.cy.ts
This commit is contained in:
parent
b39996616c
commit
922dfd8741
|
@ -3,8 +3,8 @@
|
|||
### 2.28.0
|
||||
|
||||
- `New` - Block ids now displayed in DOM via a data-id attribute. Could be useful for plugins that want access a Block's element by id.
|
||||
- `New` - The `blocks.convert(blockId, newType)` API method added. It allows to convert existed Block to a Block of another type.
|
||||
- `New` - The `blocks.insertMany()` API method added. It allows to insert several Blocks to specified index.
|
||||
- `New` - The `blocks.convert(blockId, newType)` API method added. It allows to convert existing Block to a Block of another type.
|
||||
- `New` - The `blocks.insertMany()` API method added. It allows to insert several Blocks to the specified index.
|
||||
- `Improvement` - The Delete keydown at the end of the Block will now work opposite a Backspace at the start. Next Block will be removed (if empty) or merged with the current one.
|
||||
- `Improvement` - The Delete keydown will work like a Backspace when several Blocks are selected.
|
||||
- `Improvement` - If we have two empty Blocks, and press Backspace at the start of the second one, the previous will be removed instead of current.
|
||||
|
@ -17,7 +17,11 @@
|
|||
- `Improvement` - "I'm ready" log removed
|
||||
- `Improvement` - The stub-block style simplified.
|
||||
- `Improvement` - If some Block's tool will throw an error during construction, we will show Stub block instead of skipping it during render
|
||||
- `Improvement` - Call of `blocks.clear()` now will trigger onChange will "block-removed" event for all removed blocks.
|
||||
- `Improvement` - Call of `blocks.clear()` now will trigger onChange with "block-removed" event for all removed blocks.
|
||||
- `Improvement` - `BlockMutationType` and `BlockMutationEvent` types exported
|
||||
- `Improvement` - `blocks.update(id, data)` now can accept partial data object — it will update only passed properties, others will remain the same.
|
||||
- `Improvement` - `blocks.update(id, data)` now will trigger onChange with only `block-change` event.
|
||||
- `Improvement` - `blocks.update(id, data)` will return a promise with BlockAPI object of changed block.
|
||||
|
||||
### 2.27.2
|
||||
|
||||
|
|
|
@ -220,6 +220,24 @@ export default class Blocks {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces block under passed index with passed block
|
||||
*
|
||||
* @param index - index of existed block
|
||||
* @param block - new block
|
||||
*/
|
||||
public replace(index: number, block: Block): void {
|
||||
if (this.blocks[index] === undefined) {
|
||||
throw Error('Incorrect index');
|
||||
}
|
||||
|
||||
const prevBlock = this.blocks[index];
|
||||
|
||||
prevBlock.holder.replaceWith(block.holder);
|
||||
|
||||
this.blocks[index] = block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts several blocks at once
|
||||
*
|
||||
|
|
|
@ -297,26 +297,19 @@ export default class BlocksAPI extends Module {
|
|||
* @param id - id of the block to update
|
||||
* @param data - the new data
|
||||
*/
|
||||
public update = (id: string, data: BlockToolData): void => {
|
||||
public update = async (id: string, data: Partial<BlockToolData>): Promise<BlockAPIInterface> => {
|
||||
const { BlockManager } = this.Editor;
|
||||
const block = BlockManager.getBlockById(id);
|
||||
|
||||
if (!block) {
|
||||
_.log('blocks.update(): Block with passed id was not found', 'warn');
|
||||
|
||||
return;
|
||||
if (block === undefined) {
|
||||
throw new Error(`Block with id "${id}" not found`);
|
||||
}
|
||||
|
||||
const blockIndex = BlockManager.getBlockIndex(block);
|
||||
const updatedBlock = await BlockManager.update(block, data);
|
||||
|
||||
BlockManager.insert({
|
||||
id: block.id,
|
||||
tool: block.name,
|
||||
data,
|
||||
index: blockIndex,
|
||||
replace: true,
|
||||
tunes: block.tunes,
|
||||
});
|
||||
// we cast to any because our BlockAPI has no "new" signature
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return new (BlockAPI as any)(updatedBlock);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -333,6 +333,36 @@ export default class BlockManager extends Module {
|
|||
this._blocks.insertMany(blocks, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Block data.
|
||||
*
|
||||
* Currently we don't have an 'update' method in the Tools API, so we just create a new block with the same id and type
|
||||
* Should not trigger 'block-removed' or 'block-added' events
|
||||
*
|
||||
* @param block - block to update
|
||||
* @param data - new data
|
||||
*/
|
||||
public async update(block: Block, data: Partial<BlockToolData>): Promise<Block> {
|
||||
const existingData = await block.data;
|
||||
|
||||
const newBlock = this.composeBlock({
|
||||
id: block.id,
|
||||
tool: block.name,
|
||||
data: Object.assign({}, existingData, data),
|
||||
tunes: block.tunes,
|
||||
});
|
||||
|
||||
const blockIndex = this.getBlockIndex(block);
|
||||
|
||||
this._blocks.replace(blockIndex, newBlock);
|
||||
|
||||
this.blockDidMutated(BlockChangedMutationType, newBlock, {
|
||||
index: blockIndex,
|
||||
});
|
||||
|
||||
return newBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace passed Block with the new one with specified Tool and data
|
||||
*
|
||||
|
|
16
test/cypress/fixtures/types/PartialBlockMutationEvent.ts
Normal file
16
test/cypress/fixtures/types/PartialBlockMutationEvent.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { BlockMutationEvent, BlockMutationType } from '../../../../types';
|
||||
|
||||
/**
|
||||
* Simplified version of the BlockMutationEvent with optional fields that could be used in tests
|
||||
*/
|
||||
export default interface PartialBlockMutationEvent {
|
||||
/**
|
||||
* Event type
|
||||
*/
|
||||
type?: BlockMutationType,
|
||||
|
||||
/**
|
||||
* Details with partial properties
|
||||
*/
|
||||
detail?: Partial<BlockMutationEvent['detail']>
|
||||
}
|
59
test/cypress/support/e2e.ts
Normal file
59
test/cypress/support/e2e.ts
Normal file
|
@ -0,0 +1,59 @@
|
|||
|
||||
/* global chai */
|
||||
// because this file is imported from cypress/support/e2e.js
|
||||
// that means all other spec files will have this assertion plugin
|
||||
// available to them because the supportFile is bundled and served
|
||||
// prior to any spec files loading
|
||||
|
||||
import PartialBlockMutationEvent from '../fixtures/types/PartialBlockMutationEvent';
|
||||
|
||||
/**
|
||||
* Chai plugin for checking if passed onChange method is called with an array of passed events
|
||||
*
|
||||
* @param _chai - Chai instance
|
||||
*/
|
||||
const beCalledWithBatchedEvents = (_chai): void => {
|
||||
/**
|
||||
* Check if passed onChange method is called with an array of passed events
|
||||
*
|
||||
* @param expectedEvents - batched events to check
|
||||
*/
|
||||
function assertToBeCalledWithBatchedEvents(expectedEvents: PartialBlockMutationEvent[]): void {
|
||||
/**
|
||||
* EditorJS API is passed as the first parameter of the onChange callback
|
||||
*/
|
||||
const EditorJSApiMock = Cypress.sinon.match.any;
|
||||
const $onChange = this._obj;
|
||||
|
||||
this.assert(
|
||||
$onChange.calledOnce,
|
||||
'expected #{this} to be called once',
|
||||
'expected #{this} to not be called once'
|
||||
);
|
||||
|
||||
this.assert(
|
||||
$onChange.calledWithMatch(
|
||||
EditorJSApiMock,
|
||||
Cypress.sinon.match((events: PartialBlockMutationEvent[]) => {
|
||||
expect(events).to.be.an('array');
|
||||
|
||||
return events.every((event, index) => {
|
||||
const eventToCheck = expectedEvents[index];
|
||||
|
||||
return expect(event).to.containSubset(eventToCheck);
|
||||
});
|
||||
})
|
||||
),
|
||||
'expected #{this} to be called with #{exp}, but it was called with #{act}',
|
||||
'expected #{this} to not be called with #{exp}, but it was called with #{act} ',
|
||||
expectedEvents
|
||||
);
|
||||
}
|
||||
|
||||
_chai.Assertion.addMethod('calledWithBatchedEvents', assertToBeCalledWithBatchedEvents);
|
||||
};
|
||||
|
||||
/**
|
||||
* registers our assertion function "beCalledWithBatchedEvents" with Chai
|
||||
*/
|
||||
chai.use(beCalledWithBatchedEvents);
|
29
test/cypress/support/index.d.ts
vendored
29
test/cypress/support/index.d.ts
vendored
|
@ -1,9 +1,9 @@
|
|||
// in cypress/support/index.d.ts
|
||||
// load type definitions that come with Cypress module
|
||||
/// <reference types="cypress" />
|
||||
|
||||
import type { EditorConfig, OutputData } from './../../../types/index';
|
||||
import type EditorJS from '../../../types/index'
|
||||
import PartialBlockMutationEvent from '../fixtures/types/PartialBlockMutationEvent';
|
||||
|
||||
declare global {
|
||||
namespace Cypress {
|
||||
|
@ -65,6 +65,22 @@ declare global {
|
|||
interface ApplicationWindow {
|
||||
EditorJS: typeof EditorJS
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends Cypress assertion Chainer interface with the new assertion methods
|
||||
*/
|
||||
interface Chainer<Subject> {
|
||||
/**
|
||||
* Custom Chai assertion that checks if given onChange method is called with an array of passed events
|
||||
*
|
||||
* @example
|
||||
* ```
|
||||
* cy.get('@onChange').should('be.calledWithBatchedEvents', [{ type: 'block-added', detail: { index: 0 }}])
|
||||
* expect(onChange).to.be.calledWithBatchedEvents([{ type: 'block-added', detail: { index: 0 }}])
|
||||
* ```
|
||||
*/
|
||||
(chainer: 'be.calledWithBatchedEvents', expectedEvents: PartialBlockMutationEvent[]): Chainable<Subject>;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,6 +92,17 @@ declare global {
|
|||
* "containSubset" object properties matcher
|
||||
*/
|
||||
containSubset(subset: any): Assertion;
|
||||
|
||||
/**
|
||||
* Custom Chai assertion that checks if given onChange method is called with an array of passed events
|
||||
*
|
||||
* @example
|
||||
* ```
|
||||
* cy.get('@onChange').should('be.calledWithBatchedEvents', [{ type: 'block-added', detail: { index: 0 }}])
|
||||
* expect(onChange).to.be.calledWithBatchedEvents([{ type: 'block-added', detail: { index: 0 }}])
|
||||
* ```
|
||||
*/
|
||||
calledWithBatchedEvents(expectedEvents: PartialBlockMutationEvent[]): Assertion;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,11 @@ installLogsCollector();
|
|||
*/
|
||||
import './commands';
|
||||
|
||||
/**
|
||||
* File with custom assertions
|
||||
*/
|
||||
import './e2e';
|
||||
|
||||
import chaiSubset from 'chai-subset';
|
||||
|
||||
/**
|
||||
|
|
|
@ -114,13 +114,17 @@ describe('api.blocks', () => {
|
|||
text: 'Updated text',
|
||||
};
|
||||
|
||||
editor.blocks.update(idToUpdate, newBlockData);
|
||||
|
||||
cy.get('[data-cy=editorjs]')
|
||||
.get('div.ce-block')
|
||||
.invoke('text')
|
||||
.then(blockText => {
|
||||
expect(blockText).to.be.eq(firstBlock.data.text);
|
||||
editor.blocks.update(idToUpdate, newBlockData)
|
||||
.catch(error => {
|
||||
expect(error.message).to.be.eq(`Block with id "${idToUpdate}" not found`);
|
||||
})
|
||||
.finally(() => {
|
||||
cy.get('[data-cy=editorjs]')
|
||||
.get('div.ce-block')
|
||||
.invoke('text')
|
||||
.then(blockText => {
|
||||
expect(blockText).to.be.eq(firstBlock.data.text);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -161,7 +165,7 @@ describe('api.blocks', () => {
|
|||
{
|
||||
type: 'paragraph',
|
||||
data: { text: 'first block' },
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
}).then((editor) => {
|
||||
|
|
|
@ -7,32 +7,11 @@ import { BlockRemovedMutationType } from '../../../types/events/block/BlockRemov
|
|||
import { BlockMovedMutationType } from '../../../types/events/block/BlockMoved';
|
||||
import type EditorJS from '../../../types/index';
|
||||
|
||||
|
||||
/**
|
||||
* EditorJS API is passed as the first parameter of the onChange callback
|
||||
*/
|
||||
const EditorJSApiMock = Cypress.sinon.match.any;
|
||||
|
||||
/**
|
||||
* Check if passed onChange method is called with an array of passed events
|
||||
*
|
||||
* @param $onChange - editor onChange spy
|
||||
* @param expectedEvents - batched events to check
|
||||
*/
|
||||
function beCalledWithBatchedEvents($onChange, expectedEvents): void {
|
||||
expect($onChange).to.be.calledOnce;
|
||||
expect($onChange).to.be.calledWithMatch(
|
||||
EditorJSApiMock,
|
||||
Cypress.sinon.match((events) => {
|
||||
return events.every((event, index) => {
|
||||
const eventToCheck = expectedEvents[index];
|
||||
|
||||
return expect(event).to.containSubset(eventToCheck);
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Add checks that correct block API object is passed to onChange
|
||||
* @todo Add cases for native inputs changes
|
||||
|
@ -105,22 +84,20 @@ describe('onChange callback', () => {
|
|||
.type('change')
|
||||
.type('{enter}');
|
||||
|
||||
cy.get('@onChange').should(($callback) => {
|
||||
return beCalledWithBatchedEvents($callback, [
|
||||
{
|
||||
type: BlockChangedMutationType,
|
||||
detail: {
|
||||
index: 0,
|
||||
},
|
||||
cy.get('@onChange').should('be.calledWithBatchedEvents', [
|
||||
{
|
||||
type: BlockChangedMutationType,
|
||||
detail: {
|
||||
index: 0,
|
||||
},
|
||||
{
|
||||
type: BlockAddedMutationType,
|
||||
detail: {
|
||||
index: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
type: BlockAddedMutationType,
|
||||
detail: {
|
||||
index: 1,
|
||||
},
|
||||
]);
|
||||
});
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should filter out similar events on batching', () => {
|
||||
|
@ -243,37 +220,35 @@ describe('onChange callback', () => {
|
|||
.get('div.ce-popover-item[data-item-name=delimiter]')
|
||||
.click();
|
||||
|
||||
cy.get('@onChange').should(($callback) => {
|
||||
return beCalledWithBatchedEvents($callback, [
|
||||
{
|
||||
type: BlockRemovedMutationType,
|
||||
detail: {
|
||||
index: 0,
|
||||
target: {
|
||||
name: 'paragraph',
|
||||
},
|
||||
cy.get('@onChange').should('be.calledWithBatchedEvents', [
|
||||
{
|
||||
type: BlockRemovedMutationType,
|
||||
detail: {
|
||||
index: 0,
|
||||
target: {
|
||||
name: 'paragraph',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: BlockAddedMutationType,
|
||||
detail: {
|
||||
index: 0,
|
||||
target: {
|
||||
name: 'delimiter',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: BlockAddedMutationType,
|
||||
detail: {
|
||||
index: 0,
|
||||
target: {
|
||||
name: 'delimiter',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: BlockAddedMutationType,
|
||||
detail: {
|
||||
index: 1,
|
||||
target: {
|
||||
name: 'paragraph',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: BlockAddedMutationType,
|
||||
detail: {
|
||||
index: 1,
|
||||
target: {
|
||||
name: 'paragraph',
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should be fired on block replacement for both of blocks', () => {
|
||||
|
@ -291,28 +266,26 @@ describe('onChange callback', () => {
|
|||
.get('div.ce-popover-item[data-item-name=header]')
|
||||
.click();
|
||||
|
||||
cy.get('@onChange').should(($callback) => {
|
||||
return beCalledWithBatchedEvents($callback, [
|
||||
{
|
||||
type: BlockRemovedMutationType,
|
||||
detail: {
|
||||
index: 0,
|
||||
target: {
|
||||
name: 'paragraph',
|
||||
},
|
||||
cy.get('@onChange').should('be.calledWithBatchedEvents', [
|
||||
{
|
||||
type: BlockRemovedMutationType,
|
||||
detail: {
|
||||
index: 0,
|
||||
target: {
|
||||
name: 'paragraph',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: BlockAddedMutationType,
|
||||
detail: {
|
||||
index: 0,
|
||||
target: {
|
||||
name: 'header',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: BlockAddedMutationType,
|
||||
detail: {
|
||||
index: 0,
|
||||
target: {
|
||||
name: 'header',
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should be fired on tune modifying', () => {
|
||||
|
@ -375,28 +348,26 @@ describe('onChange callback', () => {
|
|||
.get('div[data-item-name=delete]')
|
||||
.click();
|
||||
|
||||
cy.get('@onChange').should(($callback) => {
|
||||
return beCalledWithBatchedEvents($callback, [
|
||||
/**
|
||||
* "block-removed" fired since we have deleted a block
|
||||
*/
|
||||
{
|
||||
type: BlockRemovedMutationType,
|
||||
detail: {
|
||||
index: 0,
|
||||
},
|
||||
cy.get('@onChange').should('be.calledWithBatchedEvents', [
|
||||
/**
|
||||
* "block-removed" fired since we have deleted a block
|
||||
*/
|
||||
{
|
||||
type: BlockRemovedMutationType,
|
||||
detail: {
|
||||
index: 0,
|
||||
},
|
||||
/**
|
||||
* "block-added" fired since we have deleted the last block, so the new one is created
|
||||
*/
|
||||
{
|
||||
type: BlockAddedMutationType,
|
||||
detail: {
|
||||
index: 0,
|
||||
},
|
||||
},
|
||||
/**
|
||||
* "block-added" fired since we have deleted the last block, so the new one is created
|
||||
*/
|
||||
{
|
||||
type: BlockAddedMutationType,
|
||||
detail: {
|
||||
index: 0,
|
||||
},
|
||||
]);
|
||||
});
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should be fired when block is moved', () => {
|
||||
|
@ -594,19 +565,17 @@ describe('onChange callback', () => {
|
|||
cy.wrap(editor.blocks.clear());
|
||||
});
|
||||
|
||||
cy.get('@onChange').should(($callback) => {
|
||||
return beCalledWithBatchedEvents($callback, [
|
||||
{
|
||||
type: BlockRemovedMutationType,
|
||||
},
|
||||
{
|
||||
type: BlockRemovedMutationType,
|
||||
},
|
||||
{
|
||||
type: BlockAddedMutationType,
|
||||
},
|
||||
]);
|
||||
});
|
||||
cy.get('@onChange').should('be.calledWithBatchedEvents', [
|
||||
{
|
||||
type: BlockRemovedMutationType,
|
||||
},
|
||||
{
|
||||
type: BlockRemovedMutationType,
|
||||
},
|
||||
{
|
||||
type: BlockAddedMutationType,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should be called on blocks.render() on non-empty editor with removed blocks', () => {
|
||||
|
@ -639,15 +608,52 @@ describe('onChange callback', () => {
|
|||
}));
|
||||
});
|
||||
|
||||
cy.get('@onChange').should(($callback) => {
|
||||
return beCalledWithBatchedEvents($callback, [
|
||||
{
|
||||
type: BlockRemovedMutationType,
|
||||
},
|
||||
{
|
||||
type: BlockRemovedMutationType,
|
||||
},
|
||||
]);
|
||||
});
|
||||
cy.get('@onChange').should('be.calledWithBatchedEvents', [
|
||||
{
|
||||
type: BlockRemovedMutationType,
|
||||
},
|
||||
{
|
||||
type: BlockRemovedMutationType,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should be called on blocks.update() with "block-changed" event', () => {
|
||||
const block = {
|
||||
id: 'bwnFX5LoX7',
|
||||
type: 'paragraph',
|
||||
data: {
|
||||
text: 'The first block mock.',
|
||||
},
|
||||
};
|
||||
const config = {
|
||||
data: {
|
||||
blocks: [
|
||||
block,
|
||||
],
|
||||
},
|
||||
onChange: (api, event): void => {
|
||||
console.log('something changed', event);
|
||||
},
|
||||
};
|
||||
|
||||
cy.spy(config, 'onChange').as('onChange');
|
||||
|
||||
cy.createEditor(config)
|
||||
.then((editor) => {
|
||||
editor.blocks.update(block.id, {
|
||||
text: 'Updated text',
|
||||
});
|
||||
|
||||
cy.get('@onChange').should('be.calledWithMatch', EditorJSApiMock, Cypress.sinon.match({
|
||||
type: BlockChangedMutationType,
|
||||
detail: {
|
||||
index: 0,
|
||||
target: {
|
||||
id: block.id,
|
||||
},
|
||||
},
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
4
types/api/blocks.d.ts
vendored
4
types/api/blocks.d.ts
vendored
|
@ -134,9 +134,9 @@ export interface Blocks {
|
|||
* Updates block data by id
|
||||
*
|
||||
* @param id - id of the block to update
|
||||
* @param data - the new data
|
||||
* @param data - the new data. Can be partial.
|
||||
*/
|
||||
update(id: string, data: BlockToolData): void;
|
||||
update(id: string, data: Partial<BlockToolData>): Promise<BlockAPI>;
|
||||
|
||||
/**
|
||||
* Converts block to another type. Both blocks should provide the conversionConfig.
|
||||
|
|
4
types/index.d.ts
vendored
4
types/index.d.ts
vendored
|
@ -31,7 +31,7 @@ import {
|
|||
} from './api';
|
||||
|
||||
import { OutputData } from './data-formats';
|
||||
import { BlockMutationEventMap } from './events/block';
|
||||
import { BlockMutationEvent, BlockMutationEventMap, BlockMutationType } from './events/block';
|
||||
import { BlockAddedMutationType, BlockAddedEvent } from './events/block/BlockAdded';
|
||||
import { BlockChangedMutationType, BlockChangedEvent } from './events/block/BlockChanged';
|
||||
import { BlockMovedMutationType, BlockMovedEvent } from './events/block/BlockMoved';
|
||||
|
@ -85,6 +85,8 @@ export { OutputData, OutputBlockData} from './data-formats/output-data';
|
|||
export { BlockId } from './data-formats/block-id';
|
||||
export { BlockAPI } from './api'
|
||||
export {
|
||||
BlockMutationType,
|
||||
BlockMutationEvent,
|
||||
BlockMutationEventMap,
|
||||
BlockAddedMutationType,
|
||||
BlockAddedEvent,
|
||||
|
|
Loading…
Reference in a new issue