mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
feat: fractional indexing (#7359)
* Introducing fractional indices as part of `element.index` * Ensuring invalid fractional indices are always synchronized with the array order * Simplifying reconciliation based on the fractional indices * Moving reconciliation inside the `@excalidraw/excalidraw` package --------- Co-authored-by: Marcel Mraz <marcel@excalidraw.com> Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
This commit is contained in:
parent
bbdcd30a73
commit
32df5502ae
50 changed files with 3640 additions and 2047 deletions
|
@ -55,6 +55,7 @@ export type ElementConstructorOpts = MarkOptional<
|
|||
| "angle"
|
||||
| "groupIds"
|
||||
| "frameId"
|
||||
| "index"
|
||||
| "boundElements"
|
||||
| "seed"
|
||||
| "version"
|
||||
|
@ -89,6 +90,7 @@ const _newElementBase = <T extends ExcalidrawElement>(
|
|||
angle = 0,
|
||||
groupIds = [],
|
||||
frameId = null,
|
||||
index = null,
|
||||
roundness = null,
|
||||
boundElements = null,
|
||||
link = null,
|
||||
|
@ -114,6 +116,7 @@ const _newElementBase = <T extends ExcalidrawElement>(
|
|||
opacity,
|
||||
groupIds,
|
||||
frameId,
|
||||
index,
|
||||
roundness,
|
||||
seed: rest.seed ?? randomInteger(),
|
||||
version: rest.version || 1,
|
||||
|
|
|
@ -1454,7 +1454,7 @@ describe("textWysiwyg", () => {
|
|||
strokeWidth: 2,
|
||||
type: "rectangle",
|
||||
updated: 1,
|
||||
version: 1,
|
||||
version: 2,
|
||||
width: 610,
|
||||
x: 15,
|
||||
y: 25,
|
||||
|
|
|
@ -24,6 +24,7 @@ export type TextAlign = typeof TEXT_ALIGN[keyof typeof TEXT_ALIGN];
|
|||
|
||||
type VerticalAlignKeys = keyof typeof VERTICAL_ALIGN;
|
||||
export type VerticalAlign = typeof VERTICAL_ALIGN[VerticalAlignKeys];
|
||||
export type FractionalIndex = string & { _brand: "franctionalIndex" };
|
||||
|
||||
type _ExcalidrawElementBase = Readonly<{
|
||||
id: string;
|
||||
|
@ -50,6 +51,11 @@ type _ExcalidrawElementBase = Readonly<{
|
|||
Used for deterministic reconciliation of updates during collaboration,
|
||||
in case the versions (see above) are identical. */
|
||||
versionNonce: number;
|
||||
/** String in a fractional form defined by https://github.com/rocicorp/fractional-indexing.
|
||||
Used for ordering in multiplayer scenarios, such as during reconciliation or undo / redo.
|
||||
Always kept in sync with the array order by `syncMovedIndices` and `syncInvalidIndices`.
|
||||
Could be null, i.e. for new elements which were not yet assigned to the scene. */
|
||||
index: FractionalIndex | null;
|
||||
isDeleted: boolean;
|
||||
/** List of groups the element belongs to.
|
||||
Ordered from deepest to shallowest. */
|
||||
|
@ -164,6 +170,12 @@ export type ExcalidrawElement =
|
|||
| ExcalidrawIframeElement
|
||||
| ExcalidrawEmbeddableElement;
|
||||
|
||||
export type Ordered<TElement extends ExcalidrawElement> = TElement & {
|
||||
index: FractionalIndex;
|
||||
};
|
||||
|
||||
export type OrderedExcalidrawElement = Ordered<ExcalidrawElement>;
|
||||
|
||||
export type NonDeleted<TElement extends ExcalidrawElement> = TElement & {
|
||||
isDeleted: boolean;
|
||||
};
|
||||
|
@ -275,7 +287,10 @@ export type NonDeletedElementsMap = Map<
|
|||
* Map of all excalidraw Scene elements, including deleted.
|
||||
* Not a subset. Use this type when you need access to current Scene elements.
|
||||
*/
|
||||
export type SceneElementsMap = Map<ExcalidrawElement["id"], ExcalidrawElement> &
|
||||
export type SceneElementsMap = Map<
|
||||
ExcalidrawElement["id"],
|
||||
Ordered<ExcalidrawElement>
|
||||
> &
|
||||
MakeBrand<"SceneElementsMap">;
|
||||
|
||||
/**
|
||||
|
@ -284,7 +299,7 @@ export type SceneElementsMap = Map<ExcalidrawElement["id"], ExcalidrawElement> &
|
|||
*/
|
||||
export type NonDeletedSceneElementsMap = Map<
|
||||
ExcalidrawElement["id"],
|
||||
NonDeletedExcalidrawElement
|
||||
Ordered<NonDeletedExcalidrawElement>
|
||||
> &
|
||||
MakeBrand<"NonDeletedSceneElementsMap">;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue