Skip to content

Commit

Permalink
Add beforeRequest decorator for ui sdk (#1983)
Browse files Browse the repository at this point in the history
  • Loading branch information
jhoncool authored Dec 26, 2024
1 parent 0a1bb78 commit 5b08a4f
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
66 changes: 66 additions & 0 deletions src/ui/libs/schematic-sdk/decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import type {SdkConfig} from '@gravity-ui/sdk';
import {CancellablePromise} from '@gravity-ui/sdk';

const CANCEL_REQUEST_EVENT = 'sdk_cancel_request';

type ConcurrentId = string | undefined;

class SdkEvent extends EventTarget {
cancelRequest(concurrentId: ConcurrentId) {
this.dispatchEvent(new CustomEvent(CANCEL_REQUEST_EVENT, {detail: {concurrentId}}));
}
}
const instance = new SdkEvent();

function subscribeCancelRequest(cb: (concurrentId: ConcurrentId) => void) {
function subscribe(event: Event) {
const customEvent = event as CustomEvent<{concurrentId: ConcurrentId}>;
cb(customEvent.detail.concurrentId);
}
instance.addEventListener(CANCEL_REQUEST_EVENT, subscribe);
function unsubscribe() {
instance.removeEventListener(CANCEL_REQUEST_EVENT, subscribe);
}
return unsubscribe;
}

export function emitCancelRequest(concurrentId: ConcurrentId) {
instance.cancelRequest(concurrentId);
}

export function initBeforeRequestDecorator(
beforeRequest: () => Promise<unknown>,
): SdkConfig['decorator'] {
return (sdkActionFunc) =>
(...sdkActionFuncArgs) => {
const requestOptions = sdkActionFuncArgs[1];
const concurrentId = requestOptions?.concurrentId;
let cancelled = false;
let actionPromise: ReturnType<typeof sdkActionFunc>;
let unsubscribe: ReturnType<typeof subscribeCancelRequest>;
if (concurrentId) {
unsubscribe = subscribeCancelRequest((emittedConcurrentId) => {
if (emittedConcurrentId === concurrentId) {
cancelled = true;
}
});
}
return new CancellablePromise(
beforeRequest().then(() => {
unsubscribe?.();
actionPromise = sdkActionFunc(...sdkActionFuncArgs);
if (cancelled) {
actionPromise.cancel();
}
return actionPromise;
}),
() => {
unsubscribe?.();
actionPromise?.cancel();
cancelled = true;
},
).finally(() => {
unsubscribe?.();
});
};
}
9 changes: 9 additions & 0 deletions src/ui/libs/schematic-sdk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {DL} from '../../constants';
import {registry} from '../../registry';
import Utils from '../../utils';

import {emitCancelRequest} from './decorator';
import type {OperationError, SdkError} from './parse-error';
import {handleRequestError, isOperationError, isSdkError} from './parse-error';

Expand Down Expand Up @@ -60,6 +61,7 @@ const sdkConfig: SdkConfig = {
},
};
},
// decorator: initBeforeRequestDecorator(...),
};

export const initSdk = () => {
Expand Down Expand Up @@ -97,8 +99,15 @@ export const initSdk = () => {
return sdk;
};

// TODO: return object with sdk and cancelRequest
export const getSdk = () => {
return registry.libs.schematicSdk.get() as DatalensSdk<{
root: typeof schema;
}>;
};

// Use it instead of sdk.cancelRequest
export function cancelRequest(concurrentId: string) {
emitCancelRequest(concurrentId);
getSdk().cancelRequest(concurrentId);
}

0 comments on commit 5b08a4f

Please sign in to comment.