From bdb032a32cecf472572ef0edb8e9977a9cea793b Mon Sep 17 00:00:00 2001 From: Nikodem Cyrzan <85363474+NikodemCyrzan@users.noreply.github.com> Date: Thu, 19 Sep 2024 11:55:58 +0200 Subject: [PATCH 1/2] feat: create copy of index.js --- index.ts | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 index.ts diff --git a/index.ts b/index.ts new file mode 100644 index 0000000..c0f3ec3 --- /dev/null +++ b/index.ts @@ -0,0 +1,127 @@ +class Observer { + constructor(handlers) { + this.handlers = handlers; + this.isUnsubscribed = false; + } + + next(value) { + if (this.handlers.next && !this.isUnsubscribed) { + this.handlers.next(value); + } + } + + error(error) { + if (!this.isUnsubscribed) { + if (this.handlers.error) { + this.handlers.error(error); + } + + this.unsubscribe(); + } + } + + complete() { + if (!this.isUnsubscribed) { + if (this.handlers.complete) { + this.handlers.complete(); + } + + this.unsubscribe(); + } + } + + unsubscribe() { + this.isUnsubscribed = true; + + if (this._unsubscribe) { + this._unsubscribe(); + } + } +} + +class Observable { + constructor(subscribe) { + this._subscribe = subscribe; + } + + static from(values) { + return new Observable((observer) => { + values.forEach((value) => observer.next(value)); + + observer.complete(); + + return () => { + console.log('unsubscribed'); + }; + }); + } + + subscribe(obs) { + const observer = new Observer(obs); + + observer._unsubscribe = this._subscribe(observer); + + return ({ + unsubscribe() { + observer.unsubscribe(); + } + }); + } +} + +const HTTP_POST_METHOD = 'POST'; +const HTTP_GET_METHOD = 'GET'; + +const HTTP_STATUS_OK = 200; +const HTTP_STATUS_INTERNAL_SERVER_ERROR = 500; + + +const userMock = { + name: 'User Name', + age: 26, + roles: [ + 'user', + 'admin' + ], + createdAt: new Date(), + isDeleated: false, +}; + +const requestsMock = [ + { + method: HTTP_POST_METHOD, + host: 'service.example', + path: 'user', + body: userMock, + params: {}, + }, + { + method: HTTP_GET_METHOD, + host: 'service.example', + path: 'user', + params: { + id: '3f5h67s4s' + }, + } +]; + +const handleRequest = (request) => { + // handling of request + return {status: HTTP_STATUS_OK}; +}; +const handleError = (error) => { + // handling of error + return {status: HTTP_STATUS_INTERNAL_SERVER_ERROR}; +}; + +const handleComplete = () => console.log('complete'); + +const requests$ = Observable.from(requestsMock); + +const subscription = requests$.subscribe({ + next: handleRequest, + error: handleError, + complete: handleComplete +}); + +subscription.unsubscribe(); From 04e3e5a4a43417fce926c9f314345dbaaee2b22d Mon Sep 17 00:00:00 2001 From: Nikodem Cyrzan <85363474+NikodemCyrzan@users.noreply.github.com> Date: Thu, 19 Sep 2024 11:56:44 +0200 Subject: [PATCH 2/2] feat: add types to index.ts --- index.ts | 140 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 91 insertions(+), 49 deletions(-) diff --git a/index.ts b/index.ts index c0f3ec3..3589840 100644 --- a/index.ts +++ b/index.ts @@ -1,16 +1,33 @@ -class Observer { - constructor(handlers) { - this.handlers = handlers; - this.isUnsubscribed = false; - } +interface ObserverStatus { + status: HttpStatus; +} + +interface ObserverError { + code: number; + text: string; +} + +interface ObserverHandlers { + next: (value: T) => ObserverStatus; + error: (value: ObserverError) => ObserverStatus; + complete: () => void; +} - next(value) { +type ObserverUnsubscriber = () => void; + +class Observer { + private isUnsubscribed = false; + unsubscribeHolder: ObserverUnsubscriber | undefined; + + constructor(private handlers: ObserverHandlers) {} + + next(value: T): void { if (this.handlers.next && !this.isUnsubscribed) { this.handlers.next(value); } } - error(error) { + error(error: ObserverError): void { if (!this.isUnsubscribed) { if (this.handlers.error) { this.handlers.error(error); @@ -20,7 +37,7 @@ class Observer { } } - complete() { + complete(): void { if (!this.isUnsubscribed) { if (this.handlers.complete) { this.handlers.complete(); @@ -30,98 +47,123 @@ class Observer { } } - unsubscribe() { + unsubscribe(): void { this.isUnsubscribed = true; - if (this._unsubscribe) { - this._unsubscribe(); + if (this.unsubscribeHolder) { + this.unsubscribeHolder(); } } } -class Observable { - constructor(subscribe) { - this._subscribe = subscribe; +type ObservableSubscriber = (observer: Observer) => ObserverUnsubscriber; + +class Observable { + private subscribeHolder: ObservableSubscriber; + + constructor(subscribe: ObservableSubscriber) { + this.subscribeHolder = subscribe; } - static from(values) { - return new Observable((observer) => { + static from(values: T[]): Observable { + return new Observable((observer) => { values.forEach((value) => observer.next(value)); observer.complete(); return () => { - console.log('unsubscribed'); + console.log("unsubscribed"); }; }); } - subscribe(obs) { + subscribe(obs: ObserverHandlers): { unsubscribe(): void } { const observer = new Observer(obs); - observer._unsubscribe = this._subscribe(observer); + observer.unsubscribeHolder = this.subscribeHolder(observer); - return ({ - unsubscribe() { + return { + unsubscribe(): void { observer.unsubscribe(); - } - }); + }, + }; } } -const HTTP_POST_METHOD = 'POST'; -const HTTP_GET_METHOD = 'GET'; +const HTTP_METHOD = { + post: "POST", + get: "GET", +} as const; + +type HttpMethod = (typeof HTTP_METHOD)[keyof typeof HTTP_METHOD]; + +const HTTP_STATUS = { + ok: 200, + internalServerError: 500, +} as const; + +type HttpStatus = (typeof HTTP_STATUS)[keyof typeof HTTP_STATUS]; -const HTTP_STATUS_OK = 200; -const HTTP_STATUS_INTERNAL_SERVER_ERROR = 500; +type User = { + name: string; + age: number; + roles: Array<"user" | "admin">; + createdAt: Date; + isDeleted: boolean; +}; +type HTTPRequest = { + method: HttpMethod; + host: string; + path: string; + body?: T; + params: Record; +}; -const userMock = { - name: 'User Name', +const userMock: User = { + name: "User Name", age: 26, - roles: [ - 'user', - 'admin' - ], + roles: ["user", "admin"], createdAt: new Date(), - isDeleated: false, + isDeleted: false, }; -const requestsMock = [ +const requestsMock: HTTPRequest[] = [ { - method: HTTP_POST_METHOD, - host: 'service.example', - path: 'user', + method: HTTP_METHOD.post, + host: "service.example", + path: "user", body: userMock, params: {}, }, { - method: HTTP_GET_METHOD, - host: 'service.example', - path: 'user', + method: HTTP_METHOD.get, + host: "service.example", + path: "user", params: { - id: '3f5h67s4s' + id: "3f5h67s4s", }, - } + }, ]; -const handleRequest = (request) => { +const handleRequest = (request: HTTPRequest): ObserverStatus => { // handling of request - return {status: HTTP_STATUS_OK}; + return { status: HTTP_STATUS.ok }; }; -const handleError = (error) => { + +const handleError = (error: ObserverError): ObserverStatus => { // handling of error - return {status: HTTP_STATUS_INTERNAL_SERVER_ERROR}; + return { status: HTTP_STATUS.internalServerError }; }; -const handleComplete = () => console.log('complete'); +const handleComplete = (): void => console.log("complete"); const requests$ = Observable.from(requestsMock); const subscription = requests$.subscribe({ next: handleRequest, error: handleError, - complete: handleComplete + complete: handleComplete, }); subscription.unsubscribe();