Odoo GraphQL Subscription using Node, Express JS for Sample
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1 lines
17 KiB

{"version":3,"file":"Concast.js","sourceRoot":"","sources":["../../../src/utilities/observables/Concast.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n Observer,\n ObservableSubscription,\n Subscriber,\n} from \"./Observable.js\";\nimport { Observable } from \"./Observable.js\";\nimport { iterateObserversSafely } from \"./iteration.js\";\nimport { fixObservableSubclass } from \"./subclassing.js\";\n\ntype MaybeAsync<T> = T | PromiseLike<T>;\n\nfunction isPromiseLike<T>(value: MaybeAsync<T>): value is PromiseLike<T> {\n return value && typeof (value as any).then === \"function\";\n}\n\n// Any individual Source<T> can be an Observable<T> or a promise for one.\ntype Source<T> = MaybeAsync<Observable<T>>;\n\nexport type ConcastSourcesIterable<T> = Iterable<Source<T>>;\nexport type ConcastSourcesArray<T> = Array<Source<T>>;\n\n// A Concast<T> observable concatenates the given sources into a single\n// non-overlapping sequence of Ts, automatically unwrapping any promises,\n// and broadcasts the T elements of that sequence to any number of\n// subscribers, all without creating a bunch of intermediary Observable\n// wrapper objects.\n//\n// Even though any number of observers can subscribe to the Concast, each\n// source observable is guaranteed to receive at most one subscribe call,\n// and the results are multicast to all observers.\n//\n// In addition to broadcasting every next/error message to this.observers,\n// the Concast stores the most recent message using this.latest, so any\n// new observers can immediately receive the latest message, even if it\n// was originally delivered in the past. This behavior means we can assume\n// every active observer in this.observers has received the same most\n// recent message.\n//\n// With the exception of this.latest replay, a Concast is a \"hot\"\n// observable in the sense that it does not replay past results from the\n// beginning of time for each new observer.\n//\n// Could we have used some existing RxJS class instead? Concast<T> is\n// similar to a BehaviorSubject<T>, because it is multicast and redelivers\n// the latest next/error message to new subscribers. Unlike Subject<T>,\n// Concast<T> does not expose an Observer<T> interface (this.handlers is\n// intentionally private), since Concast<T> gets its inputs from the\n// concatenated sources. If we ever switch to RxJS, there may be some\n// value in reusing their code, but for now we use zen-observable, which\n// does not contain any Subject implementations.\nexport class Concast<T> extends Observable<T> {\n // Active observers receiving broadcast messages. Thanks to this.latest,\n // we can assume all observers in this Set have received the same most\n // recent message, though possibly at different times in the past.\n private observers = new Set<Observer<T>>();\n\n // This property starts off undefined to indicate the initial\n // subscription has not yet begun, then points to each source\n // subscription in turn, and finally becomes null after the sources have\n // been exhausted. After that, it stays null.\n private sub?: ObservableSubscription | null;\n\n // Not only can the individual elements of the iterable be promises, but\n // also the iterable itself can be wrapped in a promise.\n constructor(sources: MaybeAsync<ConcastSourcesIterable<T>> | Subscriber<T>) {\n super((observer) => {\n this.addObserver(observer);\n return () => this.removeObserver(observer);\n });\n\n // Suppress rejection warnings for this.promise, since it's perfectly\n // acceptable to pay no attention to this.promise if you're consuming\n // the results through the normal observable API.\n this.promise.catch((_) => {});\n\n // If someone accidentally tries to create a Concast using a subscriber\n // function, recover by creating an Observable from that subscriber and\n // using it as the source.\n if (typeof sources === \"function\") {\n sources = [new Observable(sources)];\n }\n\n if (isPromiseLike(sources)) {\n sources.then((iterable) => this.start(iterable), this.handlers.error);\n } else {\n this.start(sources);\n }\n }\n\n // A consumable array of source observables, incrementally consumed each time\n // this.handlers.complete is called. This private field is not initialized\n // until the concast.start method is called, which can happen asynchronously\n // if a Promise is passed to the Concast constructor, so undefined is a\n // possible value for this.sources before concast.start is called.\n private sources: Source<T>[] | undefined;\n\n private start(sources: ConcastSourcesIterable<T>) {\n if (this.sub !== void 0) return;\n\n // In practice, sources is most often simply an Array of observables.\n // TODO Consider using sources[Symbol.iterator]() to take advantage\n // of the laziness of non-Array iterables.\n this.sources = Array.from(sources);\n\n // Calling this.handlers.complete() kicks off consumption of the first\n // source observable. It's tempting to do this step lazily in\n // addObserver, but this.promise can be accessed without calling\n // addObserver, so consumption needs to begin eagerly.\n this.handlers.complete();\n }\n\n private deliverLastMessage(observer: Observer<T>) {\n if (this.latest) {\n const nextOrError = this.latest[0];\n const method = observer[nextOrError];\n if (method) {\n method.call(observer, this.latest[1]);\n }\n // If the subscription is already closed, and the last message was\n // a 'next' message, simulate delivery of the final 'complete'\n // message again.\n if (this.sub === null && nextOrError === \"next\" && observer.complete) {\n observer.complete();\n }\n }\n }\n\n public addObserver(observer: Observer<T>) {\n if (!this.observers.has(observer)) {\n // Immediately deliver the most recent message, so we can always\n // be sure all observers have the latest information.\n this.deliverLastMessage(observer);\n this.observers.add(observer);\n }\n }\n\n public removeObserver(observer: Observer<T>) {\n if (this.observers.delete(observer) && this.observers.size < 1) {\n // In case there are still any listeners in this.nextResultListeners, and\n // no error or completion has been broadcast yet, make sure those\n // observers have a chance to run and then remove themselves from\n // this.observers.\n this.handlers.complete();\n }\n }\n\n // Any Concast object can be trivially converted to a Promise, without\n // having to create a new wrapper Observable. This promise provides an\n // easy way to observe the final state of the Concast.\n private resolve!: (result?: T | PromiseLike<T>) => void;\n private reject!: (reason: any) => void;\n public readonly promise = new Promise<T | undefined>((resolve, reject) => {\n this.resolve = resolve;\n this.reject = reject;\n });\n\n // Name and argument of the most recently invoked observer method, used\n // to deliver latest results immediately to new observers.\n private latest?: [\"next\", T] | [\"error\", any];\n\n // Bound handler functions that can be reused for every internal\n // subscription.\n private handlers = {\n next: (result: T) => {\n if (this.sub !== null) {\n this.latest = [\"next\", result];\n this.notify(\"next\", result);\n iterateObserversSafely(this.observers, \"next\", result);\n }\n },\n\n error: (error: any) => {\n const { sub } = this;\n if (sub !== null) {\n // Delay unsubscribing from the underlying subscription slightly,\n // so that immediately subscribing another observer can keep the\n // subscription active.\n if (sub) setTimeout(() => sub.unsubscribe());\n this.sub = null;\n this.latest = [\"error\", error];\n this.reject(error);\n this.notify(\"error\", error);\n iterateObserversSafely(this.observers, \"error\", error);\n }\n },\n\n complete: () => {\n const { sub, sources = [] } = this;\n if (sub !== null) {\n // If complete is called before concast.start, this.sources may be\n // undefined, so we use a default value of [] for sources. That works\n // here because it falls into the if (!value) {...} block, which\n // appropriately terminates the Concast, even if this.sources might\n // eventually have been initialized to a non-empty array.\n const value = sources.shift();\n if (!value) {\n if (sub) setTimeout(() => sub.unsubscribe());\n this.sub = null;\n if (this.latest && this.latest[0] === \"next\") {\n this.resolve(this.latest[1]);\n } else {\n this.resolve();\n }\n this.notify(\"complete\");\n // We do not store this.latest = [\"complete\"], because doing so\n // discards useful information about the previous next (or\n // error) message. Instead, if new observers subscribe after\n // this Concast has completed, they will receive the final\n // 'next' message (unless there was an error) immediately\n // followed by a 'complete' message (see addObserver).\n iterateObserversSafely(this.observers, \"complete\");\n } else if (isPromiseLike(value)) {\n value.then(\n (obs) => (this.sub = obs.subscribe(this.handlers)),\n this.handlers.error\n );\n } else {\n this.sub = value.subscribe(this.handlers);\n }\n }\n },\n };\n\n private nextResultListeners = new Set<NextResultListener>();\n\n private notify(\n method: Parameters<NextResultListener>[0],\n arg?: Parameters<NextResultListener>[1]\n ) {\n const { nextResultListeners } = this;\n if (nextResultListeners.size) {\n // Replacing this.nextResultListeners first ensures it does not grow while\n // we are iterating over it, potentially leading to infinite loops.\n this.nextResultListeners = new Set();\n nextResultListeners.forEach((listener) => listener(method, arg));\n }\n }\n\n // We need a way to run callbacks just *before* the next result (or error or\n // completion) is delivered by this Concast, so we can be sure any code that\n // runs as a result of delivering that result/error observes the effects of\n // running the callback(s). It was tempting to reuse the Observer type instead\n // of introducing NextResultListener, but that messes with the sizing and\n // maintenance of this.observers, and ends up being more code overall.\n beforeNext(callback: NextResultListener) {\n let called = false;\n this.nextResultListeners.add((method, arg) => {\n if (!called) {\n called = true;\n callback(method, arg);\n }\n });\n }\n\n // A public way to abort observation and broadcast.\n public cancel = (reason: any) => {\n this.reject(reason);\n this.sources = [];\n this.handlers.complete();\n };\n}\n\ntype NextResultListener = (\n method: \"next\" | \"error\" | \"complete\",\n arg?: any\n) => any;\n\n// Necessary because the Concast constructor has a different signature\n// than the Observable constructor.\nfixObservableSubclass(Concast);\n"]}