Skip to content

Instantly share code, notes, and snippets.

@lilBunnyRabbit
Last active June 5, 2023 18:13
Show Gist options
  • Select an option

  • Save lilBunnyRabbit/9bbd327d207a71a1f867d7ed86454a46 to your computer and use it in GitHub Desktop.

Select an option

Save lilBunnyRabbit/9bbd327d207a71a1f867d7ed86454a46 to your computer and use it in GitHub Desktop.
React Service 2 | Brainstorming
const service = new ExampleService();
const val1 = service.example("first", 1, true);
console.log("val1", val1);
const val2 = service.example.observe({
progress: (value) => console.log("progress:", value),
update: (value) => console.log("update:", value)
})("second", 2, false);
console.log("val2", val2);
const val3 = await service.asyncExample("third", 3, true);
console.log("val3", val3);
const val4 = await service.asyncExample.observe({
progress: (value) => console.log("progress:", value),
update: (value) => console.log("update:", value)
})("fourth", 4, false);
console.log("val4", val4);
class ExampleService {
readonly example = ServiceObserver.bind(this._example);
private _example(
observer: ServiceObserver<{
progress: number;
update: string;
}>,
arg1: string,
arg2: number,
arg3: boolean
): string {
observer.dispatch("progress", 0);
observer.dispatch("update", arg1);
observer.dispatch("progress", 1);
return `${arg1} - ${arg2} - ${arg3}`;
}
readonly asyncExample = ServiceObserver.bind(this._asyncExample);
private async _asyncExample(
observer: ServiceObserver<{
progress: number;
update: string;
}>,
arg1: string,
arg2: number,
arg3: boolean
): Promise<string> {
observer.dispatch("progress", 0);
observer.dispatch("update", arg1);
observer.dispatch("progress", 1);
return `${arg1} - ${arg2} - ${arg3}`;
}
}
type ServiceObserverListeners<TEvents extends Record<string, any>> = {
[K in keyof TEvents]: (value: TEvents[K]) => void;
};
interface ServiceObserverCallback<
TEvents extends Record<string, any>,
TArgs extends any[],
TResult extends unknown | Promise<unknown>
> {
(...args: TArgs): TResult;
observe(listeners: Partial<ServiceObserverListeners<TEvents>>): (...args: TArgs) => TResult;
}
class ServiceObserver<TEvents extends Record<string, any>> {
constructor(private listeners: Partial<ServiceObserverListeners<TEvents>> = {}) {}
static bind<
TEvents extends Record<string, any>,
TArgs extends any[],
TResult extends unknown | Promise<unknown>
>(callback: (observer: ServiceObserver<TEvents>, ...args: TArgs) => TResult) {
const serviceCallback = function (...args: TArgs): TResult {
return callback(new ServiceObserver<TEvents>(), ...args);
} as ServiceObserverCallback<TEvents, TArgs, TResult>;
serviceCallback.observe = function (listeners: Partial<ServiceObserverListeners<TEvents>>) {
return (...args: TArgs) => callback(new ServiceObserver<TEvents>(listeners), ...args);
};
return serviceCallback;
}
public dispatch<T extends keyof TEvents>(type: T, value: TEvents[T]): this {
this.listeners[type]?.(value);
return this;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment