refactor(core): refactor editor query string selector (#8058)

The editor selector is the information for locating a block, which can automatically focus on a certain content when a user opens a document.

```
export type EditorSelector = {
  blockIds?: string[];
  elementIds?: string[];
};
```

The selector can be set from multiple places, such as passing it in the center peek parameter, or passing it in the query part of the URL.

This pr decoupled the selector from the query string and now available at `editorService.editor.selector$`
This commit is contained in:
EYHN
2024-09-03 06:37:58 +00:00
parent f9d0a348c4
commit a6484018ef
14 changed files with 240 additions and 131 deletions

View File

@@ -23,6 +23,8 @@ import {
throttleTime,
} from 'rxjs';
import { shallowEqual } from '../utils/shallow-equal';
const logger = new DebugLogger('livedata');
/**
@@ -334,6 +336,32 @@ export class LiveData<T = unknown>
return sub$;
}
/**
* same as map, but do shallow equal check before emit
*/
selector<R>(selector: (v: T) => R): LiveData<R> {
const sub$ = LiveData.from(
new Observable<R>(subscriber => {
let last: any = undefined;
return this.subscribe({
next: v => {
const data = selector(v);
if (!shallowEqual(last, data)) {
subscriber.next(data);
}
last = data;
},
complete: () => {
sub$.complete();
},
});
}),
undefined as R // is safe
);
return sub$;
}
distinctUntilChanged(comparator?: (previous: T, current: T) => boolean) {
return LiveData.from(
this.pipe(distinctUntilChanged(comparator)),

View File

@@ -0,0 +1,34 @@
// credit: https://github.com/facebook/fbjs/blob/main/packages/fbjs/src/core/shallowEqual.js
export function shallowEqual(objA: any, objB: any) {
if (Object.is(objA, objB)) {
return true;
}
if (
typeof objA !== 'object' ||
objA === null ||
typeof objB !== 'object' ||
objB === null
) {
return false;
}
const keysA = Object.keys(objA);
const keysB = Object.keys(objB);
if (keysA.length !== keysB.length) {
return false;
}
// Test for A's keys different from B.
for (const key of keysA) {
if (
!Object.prototype.hasOwnProperty.call(objB, key) ||
!Object.is(objA[key], objB[key])
) {
return false;
}
}
return true;
}