Last active
June 5, 2023 13:01
-
-
Save lilBunnyRabbit/222cc5d5c48d1912bc46821c77cca947 to your computer and use it in GitHub Desktop.
React service | Brainstorming
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| export class ExampleService extends Service { | |
| readonly startExample = this.observable(this._startExample); | |
| private _startExample( | |
| observer: ServiceObserver<{ | |
| progress: number; | |
| }>, | |
| test: string | |
| ): string { | |
| observer.dispatch("progress", 1); | |
| return test; | |
| } | |
| readonly startAsyncExample = this.observable(this._startAsyncExample); | |
| private async _startAsyncExample( | |
| observer: ServiceObserver<{ | |
| progress: number; | |
| }>, | |
| test: string | |
| ): Promise<string> { | |
| observer.dispatch("progress", 1); | |
| return test; | |
| } | |
| } | |
| export default new ExampleService(); | |
| // Example usage | |
| // TS Playground: https://www.typescriptlang.org/play?#code/C4TwDgpgBAyhBOA3AlgYwgUURAdsAwgIYA2xARoagNYA8AKgHxQC8UAFBNngFxT4CuAZ2AB7ALZZcwegwCULJohHIAJgG4AsAChtEAB5gR8YFFTFCgwbAQp0AeTKCbCepLxX9wXCqsAlCKhGKjTC8Mg4AOYANFCEOCBMrP6B8MGh4dGx8QxMnt5WbsB0hPARECYA3tpQUAD0AFT11TX1UADiuAgkUAjwRlAAZv04IiaC-GCGxhAqUGLlABYiPgB0zVD1tc1gYYiEXlDC+2hQAHKjMBNTXioY8H3wbDiE87zpkTHwEGDm6PN4pxeEDewDCkXkVS0NRqX2A-HgOCgOAgAHcoHcHmx1tCAAYAIgAJBU4Eg0BAHE4kAgVs95gBfFZE2kQOl4qDIKwjMZXIw3FZQAAKxAgFmgQmghOJNjJFOc8BpQIZRK+P0oEH+wEB9LxKxx2NkmihUDp2maDSaRo2UDo4BmUBR8EIkwQg36OMKxVK5RWKg5YH2qAWhRxa0tm22-DIxBOvsE-uAgfoPT0XhwPigVAgIBEA2thUEDDYoEgvDoMRU5UIyGIpfzAG06ABdWS8MgiETCuJQSHQqCw+GI8aQeWx+OBwpPVF8ISiCRcYBF22xKzvTIVKAV4BV4jG2QG5omnRG83rVoAAQrOwC+ztAFozqNDjzpip+UKRU4oOKoDiSbZyY4co+n6AYLCGp5bEaIjYPcqjQKOoETgA+pwUi8IULZQG2HYioiPbQsACx9Gif4yoBVLyucwCXJMvIzBiRhFgsHLAXGiHzgq8wxIRLEIQmCycRA+5GoeZqNKe1q2rMDpOsOrrwD+HolGUwArIQKgqAAMhyqYIOBYaQTUYCRtGqCxBp2nCJ08BJnkaZWJm2a5nQ+aFtixbAtaUTYqgJDkJQVC8KR6CFEQpAUNQrjzoIDaNkwAA+SL8KQ3mWlAIhgMAyAiDgggAPytu2naIolACCGmFJZunwHYmXZblUCJfwaYQAM4QzM0mE8VY+E1EO1Lqbc85VdZi6QMuhyghkMS+eFAUTZVOnWTEGVZTlgjCb2-YIlA3WGjUonHuJYZQBe3xfL5NxQPeVFPrRL5vp2n7fr+0r2ORMFqRZS3IvA+nQuGUEwWEFbmUNUgjb9WJpUhHkgmC0TYkhs3+dQ6HDT9CB2PAi1Wb9DgAFYBCYiU4MlxCpb2SGrfV+WFThXZlRVGN41jdXrY1X4tW1yIqJ1vBKKo3buURIgkW9AGUp9VE0dc9H3Ix3VfeDeCQ9SzLccxgjK2r8rMptxqmkdFoA5JkDSY6zoKUMCnuvOnoqSsXxiNBmAs9V-0tIZUDGVGJzO67uu2Sm+QZlmOZ5tFblpXDXk+X5EWBdYpIhfOYWo7QLnRbFCVJSl2I0+tBVYUVuGc7j1W1WtDVNdz7V80aXVa8LaX9fKAfYBXo0eRNq4zQn80WOi7vLel7O5QbMLlAOu1a-thtHjUJ4nWdV6XXeD7cvdfKCk9Yqfq9KeS0BHcQLrnsbN7ruwaDp9d1DSOx33SMo4n6MQ5jNU4yP+NkETqAkzzhTJGhdcrF2wsVcuP82bVysLXCsPMOqNwFsoWYvVZ7EWTv+WUFEVgy2fDcBijwlZ32gXrIEmsWKn11oJA2h5Dr6GuKYcwlgsFkhbkZPoXgAF2hEB9QgUYIA0GxHQHBMFkypnTMFY+FFKbQjoKVUoHgQ72SyCAOsjY5E1DoP4cYxATB2XTM1KgIwUQlUFH0MQHIhHGNMTgBgzRCyvwCrwNgfCpYIFLGIhAMQVh+OUoIUsiiIgbQUNaXRyVgAQmxNtREbA-FqSUUEpR8hmBMHQTUQIuUTDuLlCwJEU5pHeMePIIe5wcCnHJgI4U9BikMHnr2LJwgoB7GIPwaArBnHUDcR9HxUAEkBMntCWJ3Z0q9PgDEVp7TjQNJmQebQDCDC8mYRYAoegXg-AgNIiRodtn4S+OpHKxAQCTRKMADA6yxCbPyUrXJSBqkQCYixJCRxjAXI2cKA2OxkB7AOC8rcbzLmbOhr2O5MEgoS2KTQDJPs+gRC+JYXgZMxBkAQLMukDAtG7QgMIeGGR+aTQRhw6EYLqR8UDGwPEOwRDwpxYIPEMQACMQyRleGEPPQ6U9Dk4GOac4wpVBAgBwKgd5VzhQ3K1isMFDynna3+WcgVQqRVAs+fPb5vzoAWCVVAeV-LBXCtFcCgu4yIVHyhTC6ltLEVJRRWi7EGKsVsuAHiyIBKBSWOsSEKakR0nGo8SOEC-FKWWoRfSplLLp47SdRyhZRtzSNATYmpNybE3ohVdAFNmas2NEgk0sYEt8nIjRIa4U0i2DCW0FLMkKxXnnPTZSvEsgpXjJ1p-YNcLQ0MvYOuTc25dxhKaThFYxAaVsBxO6mlobeBEl7dWOkOI9yGiregGtALgCKoNfWvEjaVhTIgCsQiuA2BsD3akpgg7hTDtHTiAAaiQdp06Kh7vnYuoAA | |
| const service = new ExampleService(); | |
| service.startExample("").observer.addListener("progress", ({ detail }) => console.log(`Progress: ${detail}`)); | |
| service.startAsyncExample("").value.then((value) => console.log(`Value: ${value}`)); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| export class Service { | |
| protected observable< | |
| TObserver extends ServiceObserver, | |
| TArgs extends any[], | |
| TResult extends unknown | Promise<unknown> | |
| >(callback: (observer: TObserver, ...args: TArgs) => TResult) { | |
| return (...args: TArgs) => { | |
| const observer = new ServiceObserver() as NonNullable<TObserver>; | |
| const value = callback(observer, ...args); | |
| return { observer, value }; | |
| }; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| type ServiceEventCallback<T> = (event: CustomEvent<T>) => void; | |
| export class ServiceObserver<TEvents extends Record<string, any> = Record<string, any>> extends EventTarget { | |
| /** | |
| * General error for not supported methods. | |
| */ | |
| private static NotSupportedError(name: string, replacementName: string) { | |
| return new Error( | |
| `"${ServiceObserver.name}.${name}" is not supported. Please use "${ServiceObserver.name}.${replacementName}".` | |
| ); | |
| } | |
| /** | |
| * Typed wrapper for `EventTarget.dispatchEvent`. | |
| */ | |
| public dispatch<T extends keyof TEvents>(type: T, detail: TEvents[T]): boolean { | |
| return super.dispatchEvent(new CustomEvent(type as string, { detail })); | |
| } | |
| /** | |
| * @deprecated - Not supported. Please use `ServiceObserver.dispatch`. | |
| */ | |
| override dispatchEvent(_event: Event): boolean { | |
| throw ServiceObserver.NotSupportedError(this.dispatchEvent.name, this.dispatch.name); | |
| } | |
| /** | |
| * Typed wrapper for `EventTarget.addListener`. | |
| */ | |
| public addListener<T extends keyof TEvents>( | |
| type: T, | |
| callback: ServiceEventCallback<TEvents[T]> | null, | |
| options?: boolean | AddEventListenerOptions | undefined | |
| ): this { | |
| super.addEventListener(type as string, callback as EventListener, options); | |
| return this; | |
| } | |
| /** | |
| * @deprecated - Not supported. Please use `ServiceObserver.addListener`. | |
| */ | |
| override addEventListener( | |
| _type: string, | |
| _callback: EventListenerOrEventListenerObject | null, | |
| _options?: boolean | AddEventListenerOptions | undefined | |
| ): void { | |
| throw ServiceObserver.NotSupportedError(this.addEventListener.name, this.addListener.name); | |
| } | |
| /** | |
| * Typed wrapper for `EventTarget.removeEventListener`. | |
| */ | |
| public removeListener<T extends keyof TEvents>( | |
| type: T, | |
| callback: ServiceEventCallback<TEvents[T]> | null, | |
| options?: boolean | EventListenerOptions | undefined | |
| ): this { | |
| super.removeEventListener(type as string, callback as EventListener, options); | |
| return this; | |
| } | |
| /** | |
| * @deprecated - Not supported. Please use `ServiceObserver.removeListener`. | |
| */ | |
| override removeEventListener( | |
| _type: string, | |
| _callback: EventListenerOrEventListenerObject | null, | |
| _options?: boolean | EventListenerOptions | undefined | |
| ): void { | |
| throw ServiceObserver.NotSupportedError(this.removeEventListener.name, this.removeListener.name); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment