mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 12:28:42 +00:00
docs(editor): improve documentation for store class (#10949)
This commit is contained in:
@@ -51,7 +51,7 @@ export function updateXYWH(
|
||||
bound.w = clamp(bound.w, NOTE_MIN_WIDTH * scale, Infinity);
|
||||
bound.h = clamp(bound.h, NOTE_MIN_HEIGHT * scale, Infinity);
|
||||
if (bound.h >= NOTE_MIN_HEIGHT * scale) {
|
||||
updateBlock(ele, () => {
|
||||
updateBlock.call(ele.doc, ele, () => {
|
||||
ele.props.edgeless.collapse = true;
|
||||
ele.props.edgeless.collapsedHeight = bound.h / scale;
|
||||
});
|
||||
|
||||
@@ -14,3 +14,4 @@
|
||||
## Store
|
||||
|
||||
- [Store](classes/Store.md)
|
||||
- [StoreSlots](interfaces/StoreSlots.md)
|
||||
|
||||
@@ -16,60 +16,6 @@ A store is a piece of data created from one or a part of a Y.Doc.
|
||||
|
||||
## Block CRUD
|
||||
|
||||
### updateBlock()
|
||||
|
||||
> **updateBlock**: \<`T`\>(`model`, `props`) => `void`(`model`, `callback`) => `void`
|
||||
|
||||
Updates a block's properties or executes a callback in a transaction
|
||||
|
||||
#### Type Parameters
|
||||
|
||||
##### T
|
||||
|
||||
`T` *extends* `Partial`\<`BlockProps`\>
|
||||
|
||||
#### Parameters
|
||||
|
||||
##### model
|
||||
|
||||
`string` | `BlockModel`\<`object`\>
|
||||
|
||||
##### props
|
||||
|
||||
`T`
|
||||
|
||||
#### Returns
|
||||
|
||||
`void`
|
||||
|
||||
#### Parameters
|
||||
|
||||
##### model
|
||||
|
||||
`string` | `BlockModel`\<`object`\>
|
||||
|
||||
##### callback
|
||||
|
||||
() => `void`
|
||||
|
||||
#### Returns
|
||||
|
||||
`void`
|
||||
|
||||
#### Param
|
||||
|
||||
The block model or block ID to update
|
||||
|
||||
#### Param
|
||||
|
||||
Either a callback function to execute or properties to update
|
||||
|
||||
#### Throws
|
||||
|
||||
When the block is not found or schema validation fails
|
||||
|
||||
***
|
||||
|
||||
### blockSize
|
||||
|
||||
#### Get Signature
|
||||
@@ -84,6 +30,92 @@ Get the number of blocks in the store
|
||||
|
||||
***
|
||||
|
||||
### isEmpty
|
||||
|
||||
#### Get Signature
|
||||
|
||||
> **get** **isEmpty**(): `boolean`
|
||||
|
||||
Check if there are no blocks in the store.
|
||||
|
||||
##### Returns
|
||||
|
||||
`boolean`
|
||||
|
||||
***
|
||||
|
||||
### isEmpty$
|
||||
|
||||
#### Get Signature
|
||||
|
||||
> **get** **isEmpty$**(): `ReadonlySignal`\<`boolean`\>
|
||||
|
||||
Get the signal for the empty state of the store.
|
||||
|
||||
##### Returns
|
||||
|
||||
`ReadonlySignal`\<`boolean`\>
|
||||
|
||||
***
|
||||
|
||||
### readonly
|
||||
|
||||
#### Get Signature
|
||||
|
||||
> **get** **readonly**(): `boolean`
|
||||
|
||||
Check if the store is readonly.
|
||||
|
||||
##### Returns
|
||||
|
||||
`boolean`
|
||||
|
||||
#### Set Signature
|
||||
|
||||
> **set** **readonly**(`value`): `void`
|
||||
|
||||
Set the readonly state of the store.
|
||||
|
||||
##### Parameters
|
||||
|
||||
###### value
|
||||
|
||||
`boolean`
|
||||
|
||||
##### Returns
|
||||
|
||||
`void`
|
||||
|
||||
***
|
||||
|
||||
### readonly$
|
||||
|
||||
#### Get Signature
|
||||
|
||||
> **get** **readonly$**(): `Signal`\<`boolean`\>
|
||||
|
||||
Get the signal for the readonly state of the store.
|
||||
|
||||
##### Returns
|
||||
|
||||
`Signal`\<`boolean`\>
|
||||
|
||||
***
|
||||
|
||||
### root
|
||||
|
||||
#### Get Signature
|
||||
|
||||
> **get** **root**(): `null` \| `BlockModel`\<`object`\>
|
||||
|
||||
Get the root block of the store.
|
||||
|
||||
##### Returns
|
||||
|
||||
`null` \| `BlockModel`\<`object`\>
|
||||
|
||||
***
|
||||
|
||||
### addBlock()
|
||||
|
||||
> **addBlock**(`flavour`, `blockProps`, `parent`?, `parentIndex`?): `string`
|
||||
@@ -530,6 +562,331 @@ Optional flag to insert before sibling
|
||||
|
||||
`void`
|
||||
|
||||
***
|
||||
|
||||
### updateBlock()
|
||||
|
||||
> **updateBlock**(`modelOrId`, `callBackOrProps`): `void`
|
||||
|
||||
Updates a block's properties or executes a callback in a transaction
|
||||
|
||||
#### Parameters
|
||||
|
||||
##### modelOrId
|
||||
|
||||
The block model or block ID to update
|
||||
|
||||
`string` | `BlockModel`\<`object`\>
|
||||
|
||||
##### callBackOrProps
|
||||
|
||||
Either a callback function to execute or properties to update
|
||||
|
||||
`Partial`\<`BlockProps`\> | () => `void`
|
||||
|
||||
#### Returns
|
||||
|
||||
`void`
|
||||
|
||||
#### Throws
|
||||
|
||||
When the block is not found or schema validation fails
|
||||
|
||||
## Extension
|
||||
|
||||
### get
|
||||
|
||||
#### Get Signature
|
||||
|
||||
> **get** **get**(): \<`T`\>(`identifier`, `options`?) => `T`
|
||||
|
||||
Get an extension instance from the store
|
||||
|
||||
##### Example
|
||||
|
||||
```ts
|
||||
const extension = store.get(SomeExtension);
|
||||
```
|
||||
|
||||
##### Returns
|
||||
|
||||
`Function`
|
||||
|
||||
The extension instance
|
||||
|
||||
###### Type Parameters
|
||||
|
||||
###### T
|
||||
|
||||
`T`
|
||||
|
||||
###### Parameters
|
||||
|
||||
###### identifier
|
||||
|
||||
`GeneralServiceIdentifier`\<`T`\>
|
||||
|
||||
###### options?
|
||||
|
||||
`ResolveOptions`
|
||||
|
||||
###### Returns
|
||||
|
||||
`T`
|
||||
|
||||
***
|
||||
|
||||
### getOptional
|
||||
|
||||
#### Get Signature
|
||||
|
||||
> **get** **getOptional**(): \<`T`\>(`identifier`, `options`?) => `null` \| `T`
|
||||
|
||||
Optional get an extension instance from the store.
|
||||
The major difference between `get` and `getOptional` is that `getOptional` will not throw an error if the extension is not found.
|
||||
|
||||
##### Example
|
||||
|
||||
```ts
|
||||
const extension = store.getOptional(SomeExtension);
|
||||
```
|
||||
|
||||
##### Returns
|
||||
|
||||
`Function`
|
||||
|
||||
The extension instance
|
||||
|
||||
###### Type Parameters
|
||||
|
||||
###### T
|
||||
|
||||
`T`
|
||||
|
||||
###### Parameters
|
||||
|
||||
###### identifier
|
||||
|
||||
`GeneralServiceIdentifier`\<`T`\>
|
||||
|
||||
###### options?
|
||||
|
||||
`ResolveOptions`
|
||||
|
||||
###### Returns
|
||||
|
||||
`null` \| `T`
|
||||
|
||||
***
|
||||
|
||||
### provider
|
||||
|
||||
#### Get Signature
|
||||
|
||||
> **get** **provider**(): `ServiceProvider`
|
||||
|
||||
Get the di provider for current store.
|
||||
|
||||
##### Returns
|
||||
|
||||
`ServiceProvider`
|
||||
|
||||
## History
|
||||
|
||||
### canRedo
|
||||
|
||||
#### Get Signature
|
||||
|
||||
> **get** **canRedo**(): `boolean`
|
||||
|
||||
Check if the store can redo
|
||||
|
||||
##### Returns
|
||||
|
||||
`boolean`
|
||||
|
||||
***
|
||||
|
||||
### canUndo
|
||||
|
||||
#### Get Signature
|
||||
|
||||
> **get** **canUndo**(): `boolean`
|
||||
|
||||
Check if the store can undo
|
||||
|
||||
##### Returns
|
||||
|
||||
`boolean`
|
||||
|
||||
***
|
||||
|
||||
### captureSync
|
||||
|
||||
#### Get Signature
|
||||
|
||||
> **get** **captureSync**(): () => `void`
|
||||
|
||||
Force the following history to be captured into a new stack.
|
||||
|
||||
##### Example
|
||||
|
||||
```ts
|
||||
op1();
|
||||
op2();
|
||||
store.captureSync();
|
||||
op3();
|
||||
|
||||
store.undo(); // undo op3
|
||||
store.undo(); // undo op1, op2
|
||||
```
|
||||
|
||||
##### Returns
|
||||
|
||||
`Function`
|
||||
|
||||
###### Returns
|
||||
|
||||
`void`
|
||||
|
||||
***
|
||||
|
||||
### history
|
||||
|
||||
#### Get Signature
|
||||
|
||||
> **get** **history**(): `UndoManager`
|
||||
|
||||
Get the Y.UndoManager instance for current store.
|
||||
|
||||
##### Returns
|
||||
|
||||
`UndoManager`
|
||||
|
||||
***
|
||||
|
||||
### redo
|
||||
|
||||
#### Get Signature
|
||||
|
||||
> **get** **redo**(): () => `void`
|
||||
|
||||
Redo the last undone transaction.
|
||||
|
||||
##### Returns
|
||||
|
||||
`Function`
|
||||
|
||||
###### Returns
|
||||
|
||||
`void`
|
||||
|
||||
***
|
||||
|
||||
### resetHistory
|
||||
|
||||
#### Get Signature
|
||||
|
||||
> **get** **resetHistory**(): () => `void`
|
||||
|
||||
Reset the history of the store.
|
||||
|
||||
##### Returns
|
||||
|
||||
`Function`
|
||||
|
||||
###### Returns
|
||||
|
||||
`void`
|
||||
|
||||
***
|
||||
|
||||
### transact
|
||||
|
||||
#### Get Signature
|
||||
|
||||
> **get** **transact**(): (`fn`, `shouldTransact`?) => `void`
|
||||
|
||||
Execute a transaction.
|
||||
|
||||
##### Example
|
||||
|
||||
```ts
|
||||
store.transact(() => {
|
||||
op1();
|
||||
op2();
|
||||
});
|
||||
```
|
||||
|
||||
##### Returns
|
||||
|
||||
`Function`
|
||||
|
||||
###### Parameters
|
||||
|
||||
###### fn
|
||||
|
||||
() => `void`
|
||||
|
||||
###### shouldTransact?
|
||||
|
||||
`boolean`
|
||||
|
||||
###### Returns
|
||||
|
||||
`void`
|
||||
|
||||
***
|
||||
|
||||
### undo
|
||||
|
||||
#### Get Signature
|
||||
|
||||
> **get** **undo**(): () => `void`
|
||||
|
||||
Undo the last transaction.
|
||||
|
||||
##### Returns
|
||||
|
||||
`Function`
|
||||
|
||||
###### Returns
|
||||
|
||||
`void`
|
||||
|
||||
***
|
||||
|
||||
### withoutTransact
|
||||
|
||||
#### Get Signature
|
||||
|
||||
> **get** **withoutTransact**(): (`fn`) => `void`
|
||||
|
||||
Execute a transaction without capturing the history.
|
||||
|
||||
##### Example
|
||||
|
||||
```ts
|
||||
store.withoutTransact(() => {
|
||||
op1();
|
||||
op2();
|
||||
});
|
||||
```
|
||||
|
||||
##### Returns
|
||||
|
||||
`Function`
|
||||
|
||||
###### Parameters
|
||||
|
||||
###### fn
|
||||
|
||||
() => `void`
|
||||
|
||||
###### Returns
|
||||
|
||||
`void`
|
||||
|
||||
## Store Lifecycle
|
||||
|
||||
### disposableGroup
|
||||
@@ -542,51 +899,61 @@ Group of disposable resources managed by the store
|
||||
|
||||
### slots
|
||||
|
||||
> `readonly` **slots**: `object` & `object`
|
||||
> `readonly` **slots**: [`StoreSlots`](../interfaces/StoreSlots.md)
|
||||
|
||||
Slots for receiving events from the store.
|
||||
All events are rxjs Subjects, you can subscribe to them like this:
|
||||
|
||||
#### Type declaration
|
||||
```ts
|
||||
store.slots.ready.subscribe(() => {
|
||||
console.log('store is ready');
|
||||
});
|
||||
```
|
||||
|
||||
##### historyUpdated
|
||||
You can also use rxjs operators to handle the events.
|
||||
|
||||
> **historyUpdated**: `Subject`\<`void`\>
|
||||
***
|
||||
|
||||
This fires when the doc history is updated.
|
||||
### id
|
||||
|
||||
##### yBlockUpdated
|
||||
#### Get Signature
|
||||
|
||||
> **yBlockUpdated**: `Subject`\<\{ `id`: `string`; `isLocal`: `boolean`; `type`: `"add"`; \} \| \{ `id`: `string`; `isLocal`: `boolean`; `type`: `"delete"`; \}\>
|
||||
> **get** **id**(): `string`
|
||||
|
||||
This fires when the doc yBlock is updated.
|
||||
Get the id of the store.
|
||||
|
||||
#### Type declaration
|
||||
##### Returns
|
||||
|
||||
##### blockUpdated
|
||||
`string`
|
||||
|
||||
> **blockUpdated**: `Subject`\<`BlockUpdatedPayload`\>
|
||||
***
|
||||
|
||||
This fires when a block is updated via API call or has just been updated from existing ydoc.
|
||||
### loaded
|
||||
|
||||
##### ready
|
||||
#### Get Signature
|
||||
|
||||
> **ready**: `Subject`\<`void`\>
|
||||
> **get** **loaded**(): `boolean`
|
||||
|
||||
This is always triggered after `doc.load` is called.
|
||||
Check if the store is loaded.
|
||||
|
||||
##### rootAdded
|
||||
##### Returns
|
||||
|
||||
> **rootAdded**: `Subject`\<`string`\>
|
||||
`boolean`
|
||||
|
||||
This fires when the root block is added via API call or has just been initialized from existing ydoc.
|
||||
useful for internal block UI components to start subscribing following up events.
|
||||
Note that at this moment, the whole block tree may not be fully initialized yet.
|
||||
***
|
||||
|
||||
##### rootDeleted
|
||||
### ready
|
||||
|
||||
> **rootDeleted**: `Subject`\<`string`\>
|
||||
#### Get Signature
|
||||
|
||||
This fires when the root block is deleted via API call or has just been removed from existing ydoc.
|
||||
> **get** **ready**(): `boolean`
|
||||
|
||||
Check if the store is ready.
|
||||
Which means the Y.Doc is loaded and the root block is added.
|
||||
|
||||
##### Returns
|
||||
|
||||
`boolean`
|
||||
|
||||
***
|
||||
|
||||
@@ -688,99 +1055,28 @@ Get the Doc instance for current store.
|
||||
|
||||
***
|
||||
|
||||
### get
|
||||
### schema
|
||||
|
||||
#### Get Signature
|
||||
|
||||
> **get** **get**(): \<`T`\>(`identifier`, `options`?) => `T`
|
||||
> **get** **schema**(): `Schema`
|
||||
|
||||
Get an extension instance from the store
|
||||
|
||||
##### Example
|
||||
|
||||
```ts
|
||||
const extension = store.get(SomeExtension);
|
||||
```
|
||||
Get the Schema instance of the store.
|
||||
|
||||
##### Returns
|
||||
|
||||
`Function`
|
||||
|
||||
The extension instance
|
||||
|
||||
###### Type Parameters
|
||||
|
||||
###### T
|
||||
|
||||
`T`
|
||||
|
||||
###### Parameters
|
||||
|
||||
###### identifier
|
||||
|
||||
`GeneralServiceIdentifier`\<`T`\>
|
||||
|
||||
###### options?
|
||||
|
||||
`ResolveOptions`
|
||||
|
||||
###### Returns
|
||||
|
||||
`T`
|
||||
`Schema`
|
||||
|
||||
***
|
||||
|
||||
### getOptional
|
||||
### workspace
|
||||
|
||||
#### Get Signature
|
||||
|
||||
> **get** **getOptional**(): \<`T`\>(`identifier`, `options`?) => `null` \| `T`
|
||||
> **get** **workspace**(): `Workspace`
|
||||
|
||||
Optional get an extension instance from the store.
|
||||
The major difference between `get` and `getOptional` is that `getOptional` will not throw an error if the extension is not found.
|
||||
|
||||
##### Example
|
||||
|
||||
```ts
|
||||
const extension = store.getOptional(SomeExtension);
|
||||
```
|
||||
Get the Workspace instance for current store.
|
||||
|
||||
##### Returns
|
||||
|
||||
`Function`
|
||||
|
||||
The extension instance
|
||||
|
||||
###### Type Parameters
|
||||
|
||||
###### T
|
||||
|
||||
`T`
|
||||
|
||||
###### Parameters
|
||||
|
||||
###### identifier
|
||||
|
||||
`GeneralServiceIdentifier`\<`T`\>
|
||||
|
||||
###### options?
|
||||
|
||||
`ResolveOptions`
|
||||
|
||||
###### Returns
|
||||
|
||||
`null` \| `T`
|
||||
|
||||
***
|
||||
|
||||
### provider
|
||||
|
||||
#### Get Signature
|
||||
|
||||
> **get** **provider**(): `ServiceProvider`
|
||||
|
||||
Get the di provider for current store.
|
||||
|
||||
##### Returns
|
||||
|
||||
`ServiceProvider`
|
||||
`Workspace`
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
[**@blocksuite/store**](../../../@blocksuite/store/README.md)
|
||||
|
||||
***
|
||||
|
||||
[BlockSuite API Documentation](../../../README.md) / [@blocksuite/store](../README.md) / StoreSlots
|
||||
|
||||
# Interface: StoreSlots
|
||||
|
||||
Slots for receiving events from the store.
|
||||
All events are rxjs Subjects, you can subscribe to them like this:
|
||||
|
||||
```ts
|
||||
store.slots.ready.subscribe(() => {
|
||||
console.log('store is ready');
|
||||
});
|
||||
```
|
||||
|
||||
You can also use rxjs operators to handle the events.
|
||||
|
||||
## Properties
|
||||
|
||||
### blockUpdated
|
||||
|
||||
> **blockUpdated**: `Subject`\<`StoreBlockUpdatedPayloads`\>
|
||||
|
||||
***
|
||||
|
||||
### historyUpdated
|
||||
|
||||
> **historyUpdated**: `Subject`\<`void`\>
|
||||
|
||||
This fires when the doc history is updated.
|
||||
|
||||
***
|
||||
|
||||
### ready
|
||||
|
||||
> **ready**: `Subject`\<`void`\>
|
||||
|
||||
This fires after `doc.load` is called.
|
||||
The Y.Doc is fully loaded and ready to use.
|
||||
|
||||
***
|
||||
|
||||
### rootAdded
|
||||
|
||||
> **rootAdded**: `Subject`\<`string`\>
|
||||
|
||||
This fires when the root block is added via API call or has just been initialized from existing ydoc.
|
||||
useful for internal block UI components to start subscribing following up events.
|
||||
Note that at this moment, the whole block tree may not be fully initialized yet.
|
||||
|
||||
***
|
||||
|
||||
### rootDeleted
|
||||
|
||||
> **rootDeleted**: `Subject`\<`string`\>
|
||||
|
||||
This fires when the root block is deleted via API call or has just been removed from existing ydoc.
|
||||
In most cases, you don't need to subscribe to this event.
|
||||
@@ -29,20 +29,14 @@ export interface Doc {
|
||||
*/
|
||||
historyUpdated: Subject<void>;
|
||||
/**
|
||||
* @internal
|
||||
* This fires when the doc yBlock is updated.
|
||||
*/
|
||||
yBlockUpdated: Subject<
|
||||
| {
|
||||
type: 'add';
|
||||
id: string;
|
||||
isLocal: boolean;
|
||||
}
|
||||
| {
|
||||
type: 'delete';
|
||||
id: string;
|
||||
isLocal: boolean;
|
||||
}
|
||||
>;
|
||||
yBlockUpdated: Subject<{
|
||||
type: 'add' | 'delete';
|
||||
id: string;
|
||||
isLocal: boolean;
|
||||
}>;
|
||||
};
|
||||
|
||||
get history(): Y.UndoManager;
|
||||
|
||||
@@ -34,30 +34,135 @@ export type StoreOptions = {
|
||||
extensions?: ExtensionType[];
|
||||
};
|
||||
|
||||
export type BlockUpdatedPayload =
|
||||
| {
|
||||
type: 'add';
|
||||
id: string;
|
||||
isLocal: boolean;
|
||||
init: boolean;
|
||||
flavour: string;
|
||||
model: BlockModel;
|
||||
}
|
||||
| {
|
||||
type: 'delete';
|
||||
id: string;
|
||||
isLocal: boolean;
|
||||
flavour: string;
|
||||
parent: string;
|
||||
model: BlockModel;
|
||||
}
|
||||
| {
|
||||
type: 'update';
|
||||
id: string;
|
||||
isLocal: boolean;
|
||||
flavour: string;
|
||||
props: { key: string };
|
||||
};
|
||||
type StoreBlockAddedPayload = {
|
||||
/**
|
||||
* The type of the event.
|
||||
*/
|
||||
type: 'add';
|
||||
/**
|
||||
* The id of the block.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Whether the event is triggered by local changes.
|
||||
*/
|
||||
isLocal: boolean;
|
||||
/**
|
||||
* The flavour of the block.
|
||||
*/
|
||||
flavour: string;
|
||||
/**
|
||||
* The model of the block.
|
||||
*/
|
||||
model: BlockModel;
|
||||
/**
|
||||
* @internal
|
||||
* Whether the event is triggered by initialization.
|
||||
* FIXME: This seems not working as expected now.
|
||||
*/
|
||||
init: boolean;
|
||||
};
|
||||
|
||||
type StoreBlockDeletedPayload = {
|
||||
/**
|
||||
* The type of the event.
|
||||
*/
|
||||
type: 'delete';
|
||||
/**
|
||||
* The id of the block.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Whether the event is triggered by local changes.
|
||||
*/
|
||||
isLocal: boolean;
|
||||
/**
|
||||
* The flavour of the block.
|
||||
*/
|
||||
flavour: string;
|
||||
/**
|
||||
* The parent id of the block.
|
||||
*/
|
||||
parent: string;
|
||||
/**
|
||||
* The model of the block.
|
||||
*/
|
||||
model: BlockModel;
|
||||
};
|
||||
|
||||
type StoreBlockUpdatedPayload = {
|
||||
/**
|
||||
* The type of the event.
|
||||
*/
|
||||
type: 'update';
|
||||
/**
|
||||
* The id of the block.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Whether the event is triggered by local changes.
|
||||
*/
|
||||
isLocal: boolean;
|
||||
/**
|
||||
* The flavour of the block.
|
||||
*/
|
||||
flavour: string;
|
||||
/**
|
||||
* The changed props of the block.
|
||||
*/
|
||||
props: { key: string };
|
||||
};
|
||||
|
||||
type StoreBlockUpdatedPayloads =
|
||||
| StoreBlockAddedPayload
|
||||
| StoreBlockDeletedPayload
|
||||
| StoreBlockUpdatedPayload;
|
||||
|
||||
/**
|
||||
* Slots for receiving events from the store.
|
||||
* All events are rxjs Subjects, you can subscribe to them like this:
|
||||
*
|
||||
* ```ts
|
||||
* store.slots.ready.subscribe(() => {
|
||||
* console.log('store is ready');
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* You can also use rxjs operators to handle the events.
|
||||
*
|
||||
* @interface
|
||||
* @category Store
|
||||
*/
|
||||
export type StoreSlots = Doc['slots'] & {
|
||||
/**
|
||||
* This fires after `doc.load` is called.
|
||||
* The Y.Doc is fully loaded and ready to use.
|
||||
*/
|
||||
ready: Subject<void>;
|
||||
/**
|
||||
* This fires when the root block is added via API call or has just been initialized from existing ydoc.
|
||||
* useful for internal block UI components to start subscribing following up events.
|
||||
* Note that at this moment, the whole block tree may not be fully initialized yet.
|
||||
*/
|
||||
rootAdded: Subject<string>;
|
||||
/**
|
||||
* This fires when the root block is deleted via API call or has just been removed from existing ydoc.
|
||||
* In most cases, you don't need to subscribe to this event.
|
||||
*/
|
||||
rootDeleted: Subject<string>;
|
||||
/**
|
||||
*
|
||||
* @summary
|
||||
* This fires when a block is updated via API call or has just been updated from existing ydoc.
|
||||
*
|
||||
* The payload can have three types:
|
||||
* - add: When a new block is added
|
||||
* - delete: When a block is removed
|
||||
* - update: When a block's properties are modified
|
||||
*
|
||||
*/
|
||||
blockUpdated: Subject<StoreBlockUpdatedPayloads>;
|
||||
};
|
||||
|
||||
const internalExtensions = [StoreSelectionExtension];
|
||||
|
||||
@@ -107,28 +212,20 @@ export class Store {
|
||||
private readonly _schema: Schema;
|
||||
|
||||
/**
|
||||
* Slots for receiving events from the store.
|
||||
* Get the id of the store.
|
||||
*
|
||||
* @category Store Lifecycle
|
||||
*/
|
||||
readonly slots: Doc['slots'] & {
|
||||
/** This is always triggered after `doc.load` is called. */
|
||||
ready: Subject<void>;
|
||||
/**
|
||||
* This fires when the root block is added via API call or has just been initialized from existing ydoc.
|
||||
* useful for internal block UI components to start subscribing following up events.
|
||||
* Note that at this moment, the whole block tree may not be fully initialized yet.
|
||||
*/
|
||||
rootAdded: Subject<string>;
|
||||
/**
|
||||
* This fires when the root block is deleted via API call or has just been removed from existing ydoc.
|
||||
*/
|
||||
rootDeleted: Subject<string>;
|
||||
/**
|
||||
* This fires when a block is updated via API call or has just been updated from existing ydoc.
|
||||
*/
|
||||
blockUpdated: Subject<BlockUpdatedPayload>;
|
||||
};
|
||||
get id() {
|
||||
return this._doc.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc StoreSlots}
|
||||
*
|
||||
* @category Store Lifecycle
|
||||
*/
|
||||
readonly slots: StoreSlots;
|
||||
|
||||
private get _yBlocks() {
|
||||
return this._doc.yBlocks;
|
||||
@@ -143,6 +240,8 @@ export class Store {
|
||||
|
||||
/**
|
||||
* Get the di provider for current store.
|
||||
*
|
||||
* @category Extension
|
||||
*/
|
||||
get provider() {
|
||||
return this._provider;
|
||||
@@ -178,6 +277,11 @@ export class Store {
|
||||
return Object.values(this._blocks.peek()).length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the store can redo
|
||||
*
|
||||
* @category History
|
||||
*/
|
||||
get canRedo() {
|
||||
if (this.readonly) {
|
||||
return false;
|
||||
@@ -185,6 +289,11 @@ export class Store {
|
||||
return this._doc.canRedo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the store can undo
|
||||
*
|
||||
* @category History
|
||||
*/
|
||||
get canUndo() {
|
||||
if (this.readonly) {
|
||||
return false;
|
||||
@@ -192,93 +301,11 @@ export class Store {
|
||||
return this._doc.canUndo;
|
||||
}
|
||||
|
||||
get captureSync() {
|
||||
return this._doc.captureSync.bind(this._doc);
|
||||
}
|
||||
|
||||
get clear() {
|
||||
return this._doc.clear.bind(this._doc);
|
||||
}
|
||||
|
||||
get workspace() {
|
||||
return this._doc.workspace;
|
||||
}
|
||||
|
||||
get history() {
|
||||
return this._doc.history;
|
||||
}
|
||||
|
||||
get id() {
|
||||
return this._doc.id;
|
||||
}
|
||||
|
||||
get isEmpty() {
|
||||
return this._isEmpty.peek();
|
||||
}
|
||||
|
||||
get isEmpty$() {
|
||||
return this._isEmpty;
|
||||
}
|
||||
|
||||
get loaded() {
|
||||
return this._doc.loaded;
|
||||
}
|
||||
|
||||
get meta() {
|
||||
return this._doc.meta;
|
||||
}
|
||||
|
||||
get readonly$() {
|
||||
return this._readonly;
|
||||
}
|
||||
|
||||
get readonly() {
|
||||
return this._readonly.value === true;
|
||||
}
|
||||
|
||||
set readonly(value: boolean) {
|
||||
this._readonly.value = value;
|
||||
}
|
||||
|
||||
get ready() {
|
||||
return this._doc.ready;
|
||||
}
|
||||
|
||||
get redo() {
|
||||
if (this.readonly) {
|
||||
return () => {
|
||||
console.error('cannot undo in readonly mode');
|
||||
};
|
||||
}
|
||||
return this._doc.redo.bind(this._doc);
|
||||
}
|
||||
|
||||
get resetHistory() {
|
||||
return this._doc.resetHistory.bind(this._doc);
|
||||
}
|
||||
|
||||
get root() {
|
||||
const rootId = this._crud.root;
|
||||
if (!rootId) return null;
|
||||
return this.getBlock(rootId)?.model ?? null;
|
||||
}
|
||||
|
||||
get rootDoc() {
|
||||
return this._doc.rootDoc;
|
||||
}
|
||||
|
||||
get schema() {
|
||||
return this._schema;
|
||||
}
|
||||
|
||||
get spaceDoc() {
|
||||
return this._doc.spaceDoc;
|
||||
}
|
||||
|
||||
get transact() {
|
||||
return this._doc.transact.bind(this._doc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Undo the last transaction.
|
||||
*
|
||||
* @category History
|
||||
*/
|
||||
get undo() {
|
||||
if (this.readonly) {
|
||||
return () => {
|
||||
@@ -288,12 +315,214 @@ export class Store {
|
||||
return this._doc.undo.bind(this._doc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redo the last undone transaction.
|
||||
*
|
||||
* @category History
|
||||
*/
|
||||
get redo() {
|
||||
if (this.readonly) {
|
||||
return () => {
|
||||
console.error('cannot undo in readonly mode');
|
||||
};
|
||||
}
|
||||
return this._doc.redo.bind(this._doc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the history of the store.
|
||||
*
|
||||
* @category History
|
||||
*/
|
||||
get resetHistory() {
|
||||
return this._doc.resetHistory.bind(this._doc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a transaction.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* store.transact(() => {
|
||||
* op1();
|
||||
* op2();
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @category History
|
||||
*/
|
||||
get transact() {
|
||||
return this._doc.transact.bind(this._doc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a transaction without capturing the history.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* store.withoutTransact(() => {
|
||||
* op1();
|
||||
* op2();
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @category History
|
||||
*/
|
||||
get withoutTransact() {
|
||||
return this._doc.withoutTransact.bind(this._doc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Force the following history to be captured into a new stack.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* op1();
|
||||
* op2();
|
||||
* store.captureSync();
|
||||
* op3();
|
||||
*
|
||||
* store.undo(); // undo op3
|
||||
* store.undo(); // undo op1, op2
|
||||
* ```
|
||||
*
|
||||
* @category History
|
||||
*/
|
||||
get captureSync() {
|
||||
return this._doc.captureSync.bind(this._doc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link Workspace} instance for current store.
|
||||
*/
|
||||
get workspace() {
|
||||
return this._doc.workspace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link Y.UndoManager} instance for current store.
|
||||
*
|
||||
* @category History
|
||||
*/
|
||||
get history() {
|
||||
return this._doc.history;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there are no blocks in the store.
|
||||
*
|
||||
* @category Block CRUD
|
||||
*/
|
||||
get isEmpty() {
|
||||
return this._isEmpty.peek();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the signal for the empty state of the store.
|
||||
*
|
||||
* @category Block CRUD
|
||||
*/
|
||||
get isEmpty$() {
|
||||
return this._isEmpty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the store is loaded.
|
||||
*
|
||||
* @category Store Lifecycle
|
||||
*/
|
||||
get loaded() {
|
||||
return this._doc.loaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the meta data of the store.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
get meta() {
|
||||
return this._doc.meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the store is readonly.
|
||||
*
|
||||
* @category Block CRUD
|
||||
*/
|
||||
get readonly() {
|
||||
return this._readonly.value === true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the signal for the readonly state of the store.
|
||||
*
|
||||
* @category Block CRUD
|
||||
*/
|
||||
get readonly$() {
|
||||
return this._readonly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the readonly state of the store.
|
||||
*
|
||||
* @category Block CRUD
|
||||
*/
|
||||
set readonly(value: boolean) {
|
||||
this._readonly.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the store is ready.
|
||||
* Which means the Y.Doc is loaded and the root block is added.
|
||||
*
|
||||
* @category Store Lifecycle
|
||||
*/
|
||||
get ready() {
|
||||
return this._doc.ready;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the root block of the store.
|
||||
*
|
||||
* @category Block CRUD
|
||||
*/
|
||||
get root() {
|
||||
const rootId = this._crud.root;
|
||||
if (!rootId) return null;
|
||||
return this.getBlock(rootId)?.model ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* Get the root Y.Doc of sub Y.Doc.
|
||||
* In the current design, store is on a sub Y.Doc, and all sub docs have the same root Y.Doc.
|
||||
*/
|
||||
get rootDoc() {
|
||||
return this._doc.rootDoc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link Schema} instance of the store.
|
||||
*/
|
||||
get schema() {
|
||||
return this._schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* Get the Y.Doc instance of the store.
|
||||
*/
|
||||
get spaceDoc() {
|
||||
return this._doc.spaceDoc;
|
||||
}
|
||||
|
||||
private _isDisposed = false;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* In most cases, you don't need to use the constructor directly.
|
||||
* The store is created by the {@link Doc} instance.
|
||||
*/
|
||||
constructor({ doc, readonly, query, provider, extensions }: StoreOptions) {
|
||||
this._doc = doc;
|
||||
this.slots = {
|
||||
@@ -587,13 +816,10 @@ export class Store {
|
||||
*
|
||||
* @category Block CRUD
|
||||
*/
|
||||
updateBlock: {
|
||||
<T extends Partial<BlockProps>>(model: BlockModel | string, props: T): void;
|
||||
(model: BlockModel | string, callback: () => void): void;
|
||||
} = (
|
||||
updateBlock(
|
||||
modelOrId: BlockModel | string,
|
||||
callBackOrProps: (() => void) | Partial<BlockProps>
|
||||
) => {
|
||||
) {
|
||||
if (this.readonly) {
|
||||
console.error('cannot modify data in readonly mode');
|
||||
return;
|
||||
@@ -657,7 +883,7 @@ export class Store {
|
||||
this._runQuery(block);
|
||||
return;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a block from the store
|
||||
@@ -919,6 +1145,8 @@ export class Store {
|
||||
* ```ts
|
||||
* const extension = store.get(SomeExtension);
|
||||
* ```
|
||||
*
|
||||
* @category Extension
|
||||
*/
|
||||
get get() {
|
||||
return this.provider.get.bind(this.provider);
|
||||
@@ -934,6 +1162,8 @@ export class Store {
|
||||
* ```ts
|
||||
* const extension = store.getOptional(SomeExtension);
|
||||
* ```
|
||||
*
|
||||
* @category Extension
|
||||
*/
|
||||
get getOptional() {
|
||||
return this.provider.getOptional.bind(this.provider);
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { InitFn } from './utils.js';
|
||||
|
||||
export const embed: InitFn = (collection: Workspace, id: string) => {
|
||||
const doc = collection.getDoc(id) ?? collection.createDoc({ id });
|
||||
doc.clear();
|
||||
doc.doc.clear();
|
||||
|
||||
doc.load(() => {
|
||||
// Add root block and surface block at root level
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { InitFn } from './utils.js';
|
||||
|
||||
export const empty: InitFn = (collection: Workspace, id: string) => {
|
||||
const doc = collection.getDoc(id) ?? collection.createDoc({ id });
|
||||
doc.clear();
|
||||
doc.doc.clear();
|
||||
|
||||
doc.load(() => {
|
||||
// Add root block and surface block at root level
|
||||
|
||||
@@ -11,9 +11,9 @@ export const linked: InitFn = (collection: Workspace, id: string) => {
|
||||
const docCId = 'doc:linked-edgeless';
|
||||
const docC = collection.createDoc({ id: docCId });
|
||||
|
||||
docA.clear();
|
||||
docB.clear();
|
||||
docC.clear();
|
||||
docA.doc.clear();
|
||||
docB.doc.clear();
|
||||
docC.doc.clear();
|
||||
|
||||
docB.load(() => {
|
||||
const rootId = docB.addBlock('affine:page', {
|
||||
|
||||
@@ -20,9 +20,9 @@ export const synced: InitFn = (collection: Workspace, id: string) => {
|
||||
const docSyncedEdgelessId = 'doc:synced-edgeless';
|
||||
const docSyncedEdgeless = collection.createDoc({ id: docSyncedEdgelessId });
|
||||
|
||||
docMain.clear();
|
||||
docSyncedPage.clear();
|
||||
docSyncedEdgeless.clear();
|
||||
docMain.doc.clear();
|
||||
docSyncedPage.doc.clear();
|
||||
docSyncedEdgeless.doc.clear();
|
||||
|
||||
docSyncedPage.load(() => {
|
||||
// Add root block and surface block at root level
|
||||
|
||||
Reference in New Issue
Block a user