Remove SharedObjectCore.is and .registerCore (#8841)

This commit is contained in:
Scarlett Lee 2022-02-01 14:09:37 -08:00 коммит произвёл GitHub
Родитель c5d35788a3
Коммит b71abddc66
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
32 изменённых файлов: 67 добавлений и 203 удалений

Просмотреть файл

@ -31,11 +31,11 @@ required parameter `retryInfo`.
- [`MessageType.Save` and code that handled it was removed](#messageType-save-and-code-that-handled-it-was-removed)
- [Removed `IOdspResolvedUrl.sharingLinkToRedeem`](#Removed-IOdspResolvedUrl.sharingLinkToRedeem)
- [Removed url from ICreateBlobResponse](#removed-url-from-ICreateBlobResponse)
- [`readonly` removed from `IDeltaManager`, `DeltaManager`, and `DeltaManagerProxy`](#readonly-removed-from-IDeltaManager-and-DeltaManager-DeltaManagerProxy)
- [Synthesize Decoupled from IFluidObject and Deprecations Removed](Synthesize-Decoupled-from-IFluidObject-and-Deprecations-Removed)
- [`readonly` removed from `IDeltaManager`, `DeltaManager`, and `DeltaManagerProxy`](#readonly-removed-from-IDeltaManager-and-DeltaManager-DeltaManagerProxy)(Synthesize-Decoupled-from-IFluidObject-and-Deprecations-Removed)
- [codeDetails removed from Container](#codeDetails-removed-from-Container)
- [wait() methods removed from map and directory](#wait-methods-removed-from-map-and-directory)
- [Removed containerPath from DriverPreCheckInfo](#removed-containerPath-from-DriverPreCheckInfo)
- [Removed SharedObject.is](#Removed-SharedObject.is)
### `MessageType.Save` and code that handled it was removed
The `Save` operation type was deprecated and has now been removed. This removes `MessageType.Save` from `protocol-definitions`, `save;${string}: ${string}` from `SummarizeReason` in the `container-runtime` package, and `MessageFactory.createSave()` from and `server-test-utils`.
@ -97,6 +97,9 @@ The `wait()` methods on `ISharedMap` and `IDirectory` were deprecated in 0.55 an
### Removed containerPath from DriverPreCheckInfo
The `containerPath` property of `DriverPreCheckInfo` was deprecated and has now been removed. To replace its functionality, use `Loader.request()`.
### Removed `SharedObject.is`
The `is` method is removed from SharedObject. This was being used to detect SharedObjects stored inside other SharedObjects (and then binding them), which should not be happening anymore. Instead, use handles to SharedObjects.
## 0.55 Breaking changes
- [`SharedObject` summary and GC API changes](#SharedObject-summary-and-GC-API-changes)
- [`IChannel.summarize` split into sync and async](#IChannel.summarize-split-into-sync-and-async)

Просмотреть файл

@ -47,7 +47,6 @@ export class SharedCell<T = any> extends SharedObject<ISharedCellEvents<T>> impl
protected loadCore(storage: IChannelStorageService): Promise<void>;
protected onDisconnect(): void;
protected processCore(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void;
protected registerCore(): void;
set(value: Serializable<T>): void;
protected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats;
}

Просмотреть файл

@ -39,8 +39,6 @@ export class SharedCounter extends SharedObject<ISharedCounterEvents> implements
protected onDisconnect(): void;
// @internal
protected processCore(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void;
// @internal (undocumented)
protected registerCore(): void;
// @internal
protected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats;
get value(): number;

Просмотреть файл

@ -92,8 +92,6 @@ export class Ink extends SharedObject<IInkEvents> implements IInk {
// (undocumented)
protected processCore(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void;
// (undocumented)
protected registerCore(): void;
// (undocumented)
protected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats;
}

Просмотреть файл

@ -191,8 +191,6 @@ export class SharedDirectory extends SharedObject<ISharedDirectoryEvents> implem
// @internal (undocumented)
protected processCore(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void;
// @internal (undocumented)
protected registerCore(): void;
// @internal (undocumented)
protected reSubmitCore(content: any, localOpMetadata: unknown): void;
set<T = any>(key: string, value: T): this;
get size(): number;
@ -227,8 +225,6 @@ export class SharedMap extends SharedObject<ISharedMapEvents> implements IShared
// @internal (undocumented)
protected processCore(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void;
// @internal (undocumented)
protected registerCore(): void;
// @internal (undocumented)
protected reSubmitCore(content: any, localOpMetadata: unknown): void;
set(key: string, value: any): this;
get size(): number;

Просмотреть файл

@ -77,8 +77,6 @@ export class SharedMatrix<T = any> extends SharedObject implements IMatrixProduc
protected processCore(rawMessage: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void;
protected processGCDataCore(serializer: SummarySerializer): void;
// (undocumented)
protected registerCore(): void;
// (undocumented)
removeCols(colStart: number, count: number): void;
// (undocumented)
removeRows(rowStart: number, count: number): void;

Просмотреть файл

@ -42,8 +42,6 @@ export class ConsensusOrderedCollection<T = any> extends SharedObject<IConsensus
// (undocumented)
protected processCore(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void;
// (undocumented)
protected registerCore(): void;
// (undocumented)
protected release(acquireId: string): void;
// (undocumented)
protected releaseCore(acquireId: string): void;

Просмотреть файл

@ -35,8 +35,6 @@ export class ConsensusRegisterCollection<T> extends SharedObject<IConsensusRegis
// (undocumented)
readVersions(key: string): T[] | undefined;
// (undocumented)
protected registerCore(): void;
// (undocumented)
protected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats;
write(key: string, value: T): Promise<boolean>;
}

Просмотреть файл

@ -419,8 +419,6 @@ export class SharedIntervalCollection<TInterval extends ISerializableInterval =
// (undocumented)
protected processCore(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void;
// (undocumented)
protected registerCore(): void;
// (undocumented)
protected reSubmitCore(content: any, localOpMetadata: unknown): void;
// (undocumented)
protected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats;
@ -567,8 +565,6 @@ export abstract class SharedSegmentSequence<T extends ISegment> extends SharedOb
protected processCore(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void;
protected processGCDataCore(serializer: SummarySerializer): void;
// (undocumented)
protected registerCore(): void;
// (undocumented)
removeLocalReference(lref: LocalReference): void;
// (undocumented)
removeRange(start: number, end: number): IMergeTreeRemoveMsg;

Просмотреть файл

@ -114,18 +114,12 @@ export abstract class SharedObjectCore<TEvent extends ISharedObjectEvents = ISha
readonly handle: IFluidHandle;
protected handleDecoded(decodedHandle: IFluidHandle): void;
// (undocumented)
get IChannel(): this;
// (undocumented)
id: string;
// (undocumented)
get IFluidLoadable(): this;
initializeLocal(): void;
protected initializeLocalCore(): void;
// (undocumented)
static is(obj: any): obj is SharedObjectCore;
isAttached(): boolean;
// (undocumented)
get ISharedObject(): this;
load(services: IChannelServices): Promise<void>;
protected abstract loadCore(services: IChannelStorageService): Promise<void>;
protected readonly logger: ITelemetryLogger;
@ -133,7 +127,6 @@ export abstract class SharedObjectCore<TEvent extends ISharedObjectEvents = ISha
protected onConnect(): void;
protected abstract onDisconnect(): any;
protected abstract processCore(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): any;
protected abstract registerCore(): any;
protected reSubmitCore(content: any, localOpMetadata: unknown): void;
// (undocumented)
protected runtime: IFluidDataStoreRuntime;

Просмотреть файл

@ -36,8 +36,6 @@ export class SharedSummaryBlock extends SharedObject implements ISharedSummaryBl
protected onDisconnect(): void;
// (undocumented)
protected processCore(message: ISequencedDocumentMessage, local: boolean): void;
// (undocumented)
protected registerCore(): void;
set<T>(key: string, value: Jsonable<T>): void;
// (undocumented)
protected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats;

Просмотреть файл

@ -97,8 +97,6 @@ export class TaskManager extends SharedObject<ITaskManagerEvents> implements ITa
protected processCore(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void;
// (undocumented)
queued(taskId: string): boolean;
// @internal (undocumented)
protected registerCore(): void;
// @internal
protected reSubmitCore(): void;
// @internal

Просмотреть файл

@ -548,7 +548,6 @@ export class SharedPropertyTree extends SharedObject {
}
}
protected registerCore() { }
protected onDisconnect() { }
private _applyLocalChangeSet(change: IPropertyTreeMessage) {

Просмотреть файл

@ -86,8 +86,6 @@ export abstract class SharedOT<TState, TOp> extends SharedObject {
this.global = this.local = this.serializer.parse(rawContent);
}
protected registerCore() {}
protected onDisconnect() { }
protected processCore(message: ISequencedDocumentMessage, local: boolean) {

Просмотреть файл

@ -512,13 +512,6 @@ export abstract class GenericSharedTree<TChange> extends SharedObject<ISharedTre
}
}
/**
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.registerCore}
*/
protected registerCore(): void {
// Do nothing
}
/**
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.onDisconnect}
*/

Просмотреть файл

@ -55,7 +55,5 @@ export class SharedXTree extends SharedObject
throw new Error("not implemented");
}
protected registerCore() { throw new Error("not implemented"); }
protected applyStashedOp() { throw new Error("not implemented"); }
}

Просмотреть файл

@ -146,10 +146,6 @@ export class SharedCell<T = any> extends SharedObject<ISharedCellEvents<T>>
* {@inheritDoc ISharedCell.set}
*/
public set(value: Serializable<T>) {
if (SharedObject.is(value)) {
throw new Error("SharedObject sets are no longer supported. Instead set the SharedObject handle.");
}
// Serialize the value if required.
const operationValue: ICellValue = {
value: this.serializer.encode(value, this.handle),
@ -221,15 +217,6 @@ export class SharedCell<T = any> extends SharedObject<ISharedCellEvents<T>>
this.data = undefined;
}
/**
* Process the cell value on register
*/
protected registerCore() {
if (SharedObject.is(this.data)) {
this.data.bindToContext();
}
}
/**
* Call back on disconnect
*/

Просмотреть файл

@ -144,13 +144,6 @@ export class SharedCounter extends SharedObject<ISharedCounterEvents> implements
this._value = content.value;
}
/**
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.registerCore}
* @internal
*/
protected registerCore() {
}
/**
* Called when the object has disconnected from the delta stream.
* @internal

Просмотреть файл

@ -214,13 +214,6 @@ export class Ink extends SharedObject<IInkEvents> implements IInk {
}
}
/**
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.registerCore}
*/
protected registerCore(): void {
return;
}
/**
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.onDisconnect}
*/

Просмотреть файл

@ -647,27 +647,6 @@ export class SharedDirectory extends SharedObject<ISharedDirectoryEvents> implem
}
}
/**
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.registerCore}
* @internal
*/
protected registerCore(): void {
const subdirsToRegisterFrom = new Array<SubDirectory>();
subdirsToRegisterFrom.push(this.root);
for (const currentSubDir of subdirsToRegisterFrom) {
for (const value of currentSubDir.values()) {
if (SharedObject.is(value)) {
value.bindToContext();
}
}
for (const [, subdir] of currentSubDir.subdirectories()) {
subdirsToRegisterFrom.push(subdir as SubDirectory);
}
}
}
/**
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.processCore}
* @internal

Просмотреть файл

@ -9,7 +9,6 @@ import {
ISerializedHandle,
parseHandles,
serializeHandles,
SharedObject,
ValueType,
} from "@fluidframework/shared-object-base";
import {
@ -128,10 +127,6 @@ export class LocalValueMaker {
* @returns An ILocalValue containing the value
*/
public fromInMemory(value: any): ILocalValue {
if (SharedObject.is(value)) {
throw new Error("SharedObject sets are no longer supported. Instead set the SharedObject handle.");
}
return new PlainLocalValue(value);
}
}

Просмотреть файл

@ -365,16 +365,4 @@ export class SharedMap extends SharedObject<ISharedMapEvents> implements IShared
this.kernel.tryProcessMessage(message.contents, local, localOpMetadata);
}
}
/**
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.registerCore}
* @internal
*/
protected registerCore() {
for (const value of this.values()) {
if (SharedObject.is(value)) {
value.bindToContext();
}
}
}
}

Просмотреть файл

@ -621,11 +621,6 @@ export class SharedMatrix<T = any>
}
}
protected registerCore() {
this.rows.startOrUpdateCollaboration(this.runtime.clientId, 0);
this.cols.startOrUpdateCollaboration(this.runtime.clientId, 0);
}
// Invoked by PermutationVector to notify IMatrixConsumers of row insertion/deletions.
private readonly onRowDelta = (position: number, removedCount: number, insertedCount: number) => {
for (const consumer of this.consumers) {

Просмотреть файл

@ -264,10 +264,6 @@ export class ConsensusOrderedCollection<T = any>
this.data.loadFrom(content2);
}
protected registerCore() {
return;
}
protected onDisconnect() {
for (const [, { value, clientId }] of this.jobTracking) {
if (clientId === this.runtime.clientId) {

Просмотреть файл

@ -204,8 +204,6 @@ export class ConsensusRegisterCollection<T>
}
}
protected registerCore() { }
protected onDisconnect() {}
protected processCore(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown) {

Просмотреть файл

@ -9,7 +9,6 @@ import {
ISerializedHandle,
parseHandles,
serializeHandles,
SharedObject,
ValueType,
} from "@fluidframework/shared-object-base";
import {
@ -219,10 +218,6 @@ export class LocalValueMaker {
* @returns An ILocalValue containing the value
*/
public fromInMemory(value: any): ILocalValue {
if (SharedObject.is(value)) {
throw new Error("SharedObject sets are no longer supported. Instead set the SharedObject handle.");
}
return new PlainLocalValue(value);
}

Просмотреть файл

@ -565,16 +565,6 @@ export abstract class SharedSegmentSequence<T extends ISegment>
}
}
protected registerCore() {
for (const value of this.intervalMapKernel.values()) {
if (SharedObject.is(value)) {
value.bindToContext();
}
}
this.client.startOrUpdateCollaboration(this.runtime.clientId);
}
protected didAttach() {
// If we are not local, and we've attached we need to start generating and sending ops
// so start collaboration and provide a default client id incase we are not connected

Просмотреть файл

@ -170,14 +170,6 @@ export class SharedIntervalCollection<TInterval extends ISerializableInterval =
}
}
protected registerCore() {
for (const value of this.intervalMapKernel.values()) {
if (SharedObject.is(value)) {
value.bindToContext();
}
}
}
/**
* Creates the full path of the intervalCollection label
* @param label - the incoming lable

Просмотреть файл

@ -31,16 +31,6 @@ import { ISharedObject, ISharedObjectEvents } from "./types";
*/
export abstract class SharedObjectCore<TEvent extends ISharedObjectEvents = ISharedObjectEvents>
extends EventEmitterWithErrorHandling<TEvent> implements ISharedObject<TEvent> {
/**
* @param obj - The thing to check if it is a SharedObject
* @returns Returns true if the thing is a SharedObject
*/
public static is(obj: any): obj is SharedObjectCore {
return obj?.ISharedObject !== undefined;
}
public get ISharedObject() { return this; }
public get IChannel() { return this; }
public get IFluidLoadable() { return this; }
/**
@ -191,9 +181,6 @@ export abstract class SharedObjectCore<TEvent extends ISharedObjectEvents = ISha
this._isBoundToContext = true;
// Allow derived classes to perform custom processing prior to registering this object
this.registerCore();
this.runtime.bindChannel(this);
}
@ -252,11 +239,6 @@ export abstract class SharedObjectCore<TEvent extends ISharedObjectEvents = ISha
return;
}
/**
* Allows the distributed data type the ability to perform custom processing once an attach has happened.
*/
protected abstract registerCore();
/**
* Allows the distributive data type the ability to perform custom processing once an attach has happened.
* Also called after non-local data type get loaded.

Просмотреть файл

@ -110,11 +110,6 @@ export class SharedSummaryBlock extends SharedObject implements ISharedSummaryBl
}
}
/**
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.registerCore}
*/
protected registerCore() { }
/**
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.onDisconnect}
*/

Просмотреть файл

@ -386,11 +386,6 @@ export class TaskManager extends SharedObject<ITaskManagerEvents> implements ITa
*/
protected initializeLocalCore() { }
/**
* @internal
*/
protected registerCore() { }
/**
* @internal
*/

Просмотреть файл

@ -13,26 +13,30 @@ import {
import {generatePairwiseOptions} from "@fluidframework/test-pairwise-generator";
import { describeFullCompat } from "@fluidframework/test-version-utils";
import { IResolvedUrl } from "@fluidframework/driver-definitions";
import { ISharedMap, IValueChanged, SharedMap } from "@fluidframework/map";
import { ISharedMap, IValueChanged } from "@fluidframework/map";
import { SequenceDeltaEvent, SharedString, SharedStringFactory } from "@fluidframework/sequence";
import { IFluidHandle } from "@fluidframework/core-interfaces";
import { AttachState } from "@fluidframework/container-definitions";
import { IChannelFactory } from "@fluidframework/datastore-definitions";
// during these point succeeding objects won't even exist locally
const ContainerCreated = 0
const DatastoreCreated = 1;
const MapCreated = 2
const DdsCreated = 2
//these points are after all objects at least exist locally
// these points are after all objects at least exist locally
const sharedPoints = [3, 4, 5];
const ddsKey = "string";
const testConfigs =
generatePairwiseOptions({
containerAttachPoint:[ContainerCreated, DatastoreCreated, ... sharedPoints],
containerSaveAfterAttach: [true, false],
datastoreAttachPoint: [DatastoreCreated, ... sharedPoints],
datastoreSaveAfterAttach: [true, false],
mapAttachPoint: [MapCreated, ... sharedPoints],
mapSaveAfterAttach: [true, false],
ddsAttachPoint: [DdsCreated, ... sharedPoints],
ddsSaveAfterAttach: [true, false],
});
describeFullCompat("Validate Attach lifecycle", (getTestObjectProvider) => {
@ -52,11 +56,14 @@ describeFullCompat("Validate Attach lifecycle", (getTestObjectProvider) => {
const provider = getTestObjectProvider();
const timeoutDurationMs = this.timeout() / 2;
let containerUrl: IResolvedUrl | undefined;
const oldRegistry: [string | undefined, IChannelFactory][] =
[[SharedStringFactory.Type, SharedString.getFactory()]];
const containerConfig = { registry: oldRegistry };
// act code block
{
const initLoader = createLoader(
[[provider.defaultCodeDetails, provider.createFluidEntryPoint()]],
[[provider.defaultCodeDetails, provider.createFluidEntryPoint(containerConfig)]],
provider.documentServiceFactory,
provider.urlResolver,
);
@ -71,7 +78,7 @@ describeFullCompat("Validate Attach lifecycle", (getTestObjectProvider) => {
if(testConfig.containerAttachPoint === ContainerCreated) {
// point 0 - at container create, datastore and dss don't exist
await attachContainer();
}
}
const initDataObject = await requestFluidObject<ITestFluidObject>(initContainer, "default");
@ -80,7 +87,7 @@ describeFullCompat("Validate Attach lifecycle", (getTestObjectProvider) => {
const attachDatastore = async ()=>{
initDataObject.root.set("ds", newDataObj.handle);
while(testConfig.datastoreSaveAfterAttach
&& initContainer.isDirty
&& initContainer.isDirty
&& initContainer.attachState !== AttachState.Detached){
await timeoutPromise<void>(
(resolve)=>initContainer.once("saved", ()=>resolve()),
@ -96,18 +103,18 @@ describeFullCompat("Validate Attach lifecycle", (getTestObjectProvider) => {
await attachContainer();
}
const newMap = SharedMap.create(newDataObj.runtime);
const attachDds= async()=>{
newDataObj.root.set("map",newMap.handle);
while(testConfig.mapSaveAfterAttach
&& initContainer.isDirty
const newString = SharedString.create(newDataObj.runtime);
const attachDds = async()=>{
newDataObj.root.set(ddsKey, newString.handle);
while(testConfig.ddsSaveAfterAttach
&& initContainer.isDirty
&& initContainer.attachState !== AttachState.Detached){
await timeoutPromise<void>(
(resolve)=>initContainer.once("saved", ()=>resolve()),
{durationMs: timeoutDurationMs,errorMsg:"ddsSaveAfterAttach timeout"});
}
}
if(testConfig.mapAttachPoint === 2) {
if(testConfig.ddsAttachPoint === 2) {
// point 2 - at dds create
await attachDds();
}
@ -117,7 +124,7 @@ describeFullCompat("Validate Attach lifecycle", (getTestObjectProvider) => {
for(const i of sharedPoints) {
// also send an op at these points
// we'll use these to validate
newMap.set(i.toString(),i);
newString.insertText(convertSharedPointToPos(i), i.toString());
if(testConfig.containerAttachPoint === i) {
await attachContainer();
@ -125,7 +132,7 @@ describeFullCompat("Validate Attach lifecycle", (getTestObjectProvider) => {
if(testConfig.datastoreAttachPoint === i) {
await attachDatastore()
}
if(testConfig.mapAttachPoint === i) {
if(testConfig.ddsAttachPoint === i) {
await attachDds();
}
}
@ -149,7 +156,7 @@ describeFullCompat("Validate Attach lifecycle", (getTestObjectProvider) => {
// validation code block
{
const validationLoader = createLoader(
[[provider.defaultCodeDetails, provider.createFluidEntryPoint()]],
[[provider.defaultCodeDetails, provider.createFluidEntryPoint(containerConfig)]],
provider.documentServiceFactory,
provider.urlResolver,
);
@ -161,36 +168,59 @@ describeFullCompat("Validate Attach lifecycle", (getTestObjectProvider) => {
const newDatastore =await (await waitKey<IFluidHandle<ITestFluidObject>>(
initDataObject.root,"ds", timeoutDurationMs)).get();
const newMap = await (await waitKey<IFluidHandle<ISharedMap>>(
newDatastore.root,"map", timeoutDurationMs)).get();
const newString = await (await waitKey<IFluidHandle<SharedString>>(
newDatastore.root, ddsKey, timeoutDurationMs)).get();
for(const i of sharedPoints) {
assert.equal(
await waitKey<number>(newMap, i.toString(), timeoutDurationMs),
i);
await waitChar(newString, convertSharedPointToPos(i), timeoutDurationMs),
i.toString(), `No match at {i}`);
}
}
});
}
});
function convertSharedPointToPos(i: number){
return i - sharedPoints[0];
}
async function waitChar(sharedString: SharedString, pos: number, timeoutDurationMs: number): Promise<string>{
return timeoutPromise<string>((resolve)=>{
const text = sharedString.getText();
if(text.length > pos){
resolve(text[pos]);
}
else{
const waitFunc = (event: SequenceDeltaEvent)=>{
const range = event.ranges.find((value) => value.position === pos);
if(range){
sharedString.off("sequenceDelta", waitFunc);
resolve(sharedString.getText()[pos]);
}
}
sharedString.on("sequenceDelta", waitFunc);
}
},
{durationMs: timeoutDurationMs, errorMsg:`${pos} not available before timeout`});
}
async function waitKey<T>(map: ISharedMap, key:string, timeoutDurationMs: number): Promise<T>{
return timeoutPromise<T>((resolve)=>{
if(map.has(key)){
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
resolve(map.get<T>(key)!)
}
const waitFunc = (changed: IValueChanged)=>{
if(changed.key === key){
map.off("valueChanged", waitFunc);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
resolve(map.get<T>(key)!);
}else{
const waitFunc = (changed: IValueChanged)=>{
if(changed.key === key){
map.off("valueChanged", waitFunc);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
resolve(map.get<T>(key)!);
}
}
map.on("valueChanged", waitFunc);
}
map.on("valueChanged", waitFunc);
},
{durationMs: timeoutDurationMs,errorMsg:`${key} not available before timeout`});
}
}