diff options
| author | Pinapelz <yukais@pinapelz.com> | 2025-06-28 17:26:46 -0700 |
|---|---|---|
| committer | Pinapelz <yukais@pinapelz.com> | 2025-06-28 17:43:56 -0700 |
| commit | e4fa1e69e7ebfb627c7198fd1a9881e9327ec4d4 (patch) | |
| tree | 06284a538a6008eca75051399e47db4e5d50301c /node_modules/rxjs/src/internal/observable/fromEventPattern.ts | |
initial commit: scaffolding
Diffstat (limited to 'node_modules/rxjs/src/internal/observable/fromEventPattern.ts')
| -rw-r--r-- | node_modules/rxjs/src/internal/observable/fromEventPattern.ts | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/node_modules/rxjs/src/internal/observable/fromEventPattern.ts b/node_modules/rxjs/src/internal/observable/fromEventPattern.ts new file mode 100644 index 0000000..6e700b1 --- /dev/null +++ b/node_modules/rxjs/src/internal/observable/fromEventPattern.ts @@ -0,0 +1,152 @@ +import { Observable } from '../Observable'; +import { isFunction } from '../util/isFunction'; +import { NodeEventHandler } from './fromEvent'; +import { mapOneOrManyArgs } from '../util/mapOneOrManyArgs'; + +/* tslint:disable:max-line-length */ +export function fromEventPattern<T>( + addHandler: (handler: NodeEventHandler) => any, + removeHandler?: (handler: NodeEventHandler, signal?: any) => void +): Observable<T>; +export function fromEventPattern<T>( + addHandler: (handler: NodeEventHandler) => any, + removeHandler?: (handler: NodeEventHandler, signal?: any) => void, + resultSelector?: (...args: any[]) => T +): Observable<T>; +/* tslint:enable:max-line-length */ + +/** + * Creates an Observable from an arbitrary API for registering event handlers. + * + * <span class="informal">When that method for adding event handler was something {@link fromEvent} + * was not prepared for.</span> + * + *  + * + * `fromEventPattern` allows you to convert into an Observable any API that supports registering handler functions + * for events. It is similar to {@link fromEvent}, but far + * more flexible. In fact, all use cases of {@link fromEvent} could be easily handled by + * `fromEventPattern` (although in slightly more verbose way). + * + * This operator accepts as a first argument an `addHandler` function, which will be injected with + * handler parameter. That handler is actually an event handler function that you now can pass + * to API expecting it. `addHandler` will be called whenever Observable + * returned by the operator is subscribed, so registering handler in API will not + * necessarily happen when `fromEventPattern` is called. + * + * After registration, every time an event that we listen to happens, + * Observable returned by `fromEventPattern` will emit value that event handler + * function was called with. Note that if event handler was called with more + * than one argument, second and following arguments will not appear in the Observable. + * + * If API you are using allows to unregister event handlers as well, you can pass to `fromEventPattern` + * another function - `removeHandler` - as a second parameter. It will be injected + * with the same handler function as before, which now you can use to unregister + * it from the API. `removeHandler` will be called when consumer of resulting Observable + * unsubscribes from it. + * + * In some APIs unregistering is actually handled differently. Method registering an event handler + * returns some kind of token, which is later used to identify which function should + * be unregistered or it itself has method that unregisters event handler. + * If that is the case with your API, make sure token returned + * by registering method is returned by `addHandler`. Then it will be passed + * as a second argument to `removeHandler`, where you will be able to use it. + * + * If you need access to all event handler parameters (not only the first one), + * or you need to transform them in any way, you can call `fromEventPattern` with optional + * third parameter - project function which will accept all arguments passed to + * event handler when it is called. Whatever is returned from project function will appear on + * resulting stream instead of usual event handlers first argument. This means + * that default project can be thought of as function that takes its first parameter + * and ignores the rest. + * + * ## Examples + * + * Emits clicks happening on the DOM document + * + * ```ts + * import { fromEventPattern } from 'rxjs'; + * + * function addClickHandler(handler) { + * document.addEventListener('click', handler); + * } + * + * function removeClickHandler(handler) { + * document.removeEventListener('click', handler); + * } + * + * const clicks = fromEventPattern( + * addClickHandler, + * removeClickHandler + * ); + * clicks.subscribe(x => console.log(x)); + * + * // Whenever you click anywhere in the browser, DOM MouseEvent + * // object will be logged. + * ``` + * + * Use with API that returns cancellation token + * + * ```ts + * import { fromEventPattern } from 'rxjs'; + * + * const token = someAPI.registerEventHandler(function() {}); + * someAPI.unregisterEventHandler(token); // this APIs cancellation method accepts + * // not handler itself, but special token. + * + * const someAPIObservable = fromEventPattern( + * function(handler) { return someAPI.registerEventHandler(handler); }, // Note that we return the token here... + * function(handler, token) { someAPI.unregisterEventHandler(token); } // ...to then use it here. + * ); + * ``` + * + * Use with project function + * + * ```ts + * import { fromEventPattern } from 'rxjs'; + * + * someAPI.registerEventHandler((eventType, eventMessage) => { + * console.log(eventType, eventMessage); // Logs 'EVENT_TYPE' 'EVENT_MESSAGE' to console. + * }); + * + * const someAPIObservable = fromEventPattern( + * handler => someAPI.registerEventHandler(handler), + * handler => someAPI.unregisterEventHandler(handler) + * (eventType, eventMessage) => eventType + ' --- ' + eventMessage // without that function only 'EVENT_TYPE' + * ); // would be emitted by the Observable + * + * someAPIObservable.subscribe(value => console.log(value)); + * + * // Logs: + * // 'EVENT_TYPE --- EVENT_MESSAGE' + * ``` + * + * @see {@link fromEvent} + * @see {@link bindCallback} + * @see {@link bindNodeCallback} + * + * @param addHandler A function that takes a `handler` function as argument and attaches it + * somehow to the actual source of events. + * @param removeHandler A function that takes a `handler` function as an argument and removes + * it from the event source. If `addHandler` returns some kind of token, `removeHandler` function + * will have it as a second parameter. + * @param resultSelector A function to transform results. It takes the arguments from the event + * handler and should return a single value. + * @return Observable which, when an event happens, emits first parameter passed to registered + * event handler. Alternatively it emits whatever project function returns at that moment. + */ +export function fromEventPattern<T>( + addHandler: (handler: NodeEventHandler) => any, + removeHandler?: (handler: NodeEventHandler, signal?: any) => void, + resultSelector?: (...args: any[]) => T +): Observable<T | T[]> { + if (resultSelector) { + return fromEventPattern<T>(addHandler, removeHandler).pipe(mapOneOrManyArgs(resultSelector)); + } + + return new Observable<T | T[]>((subscriber) => { + const handler = (...e: T[]) => subscriber.next(e.length === 1 ? e[0] : e); + const retValue = addHandler(handler); + return isFunction(removeHandler) ? () => removeHandler(handler, retValue) : undefined; + }); +} |
