@mindignited/continuum-client 2.14.6 → 2.14.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/continuum.cjs +2 -2
- package/dist/continuum.cjs.map +1 -1
- package/dist/continuum.js +129 -127
- package/dist/continuum.js.map +1 -1
- package/package.json +16 -17
package/dist/continuum.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"continuum.js","sources":["../src/api/ConnectionInfo.ts","../src/api/errors/ContinuumError.ts","../src/core/api/IEventBus.ts","../src/core/api/StompConnectionManager.ts","../src/core/api/EventBus.ts","../src/core/api/DefaultCRI.ts","../src/core/api/CRI.ts","../src/internal/core/api/ArgumentResolver.ts","../src/internal/core/api/EventUtil.ts","../src/internal/core/api/ReturnValueConverter.ts","../src/internal/core/api/Logger.ts","../src/core/api/ServiceIdentifier.ts","../src/api/ContinuumDecorators.ts","../src/internal/core/api/ServiceInvocationSupervisor.ts","../src/core/api/ServiceRegistry.ts","../src/core/api/crud/AbstractIterablePage.ts","../src/internal/core/api/crud/FindAllIterablePage.ts","../src/internal/core/api/crud/SearchIterablePage.ts","../src/core/api/crud/CrudServiceProxy.ts","../src/core/api/crud/CrudServiceProxyFactory.ts","../src/api/Continuum.ts","../src/api/ILogManager.ts","../src/api/LogManager.ts","../src/api/errors/AuthenticationError.ts","../src/api/errors/AuthorizationError.ts","../src/api/security/ConnectedInfo.ts","../src/api/security/Participant.ts","../src/api/security/ParticipantConstants.ts","../src/core/api/StreamData.ts","../src/core/api/crud/FunctionalIterablePage.ts","../src/core/api/crud/IDataSource.ts","../src/core/api/crud/Pageable.ts","../src/core/api/crud/Sort.ts"],"sourcesContent":["/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * ConnectHeaders to use during connection to the continuum server\n * These headers will be sent as part of the STOMP CONNECT frame\n * This is typically used for authentication information, but any data can be sent\n */\nexport class ConnectHeaders {\n [key: string]: string\n}\n\nexport class ServerInfo {\n host!: string\n port?: number | null\n useSSL?: boolean | null\n}\n\n/**\n * ConnectionInfo provides the information needed to connect to the continuum server\n */\nexport class ConnectionInfo extends ServerInfo {\n /**\n * The headers to send during the connection to the continuum server.\n * If a function is provided, it will be called to get the headers each time the connection is established.\n * This is useful for providing dynamic headers, such as a JWT token that expires.\n */\n connectHeaders?: ConnectHeaders | (() => Promise<ConnectHeaders>)\n\n /**\n * The maximum number of connection attempts to make during the {@link IEventBus} initial connection request.\n * If the limit is reached the {@link IEventBus} will return an error to the caller of {@link IEventBus#connect}\n * Set to 0, undefined, or null to try forever\n */\n maxConnectionAttempts?: number | null\n\n /**\n * If true, the session will not be kept alive after the connection is established and then disrupted.\n * If false, the session will be kept alive after the connection is established and then disrupted, for a period of time.\n */\n disableStickySession?: boolean | null\n\n}\n\n\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Base error class for all Continuum errors\n */\nexport class ContinuumError extends Error {\n\n constructor(message: string) {\n super(message);\n Object.setPrototypeOf(this, ContinuumError.prototype);\n }\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Optional } from 'typescript-optional'\nimport { Observable } from 'rxjs'\nimport {ConnectedInfo} from '@/api/security/ConnectedInfo'\nimport {ContinuumError} from '@/api/errors/ContinuumError'\nimport {ConnectionInfo, ServerInfo} from '@/api/ConnectionInfo'\n\n/**\n * Part of the low level portion of continuum representing data to be processed\n *\n * This is similar to a Stomp Frame but with more required information and no control plane semantics.\n *\n *\n * Created by Navid Mitchell on 2019-01-04.\n */\nexport interface IEvent {\n\n /**\n * The cri that specifies where the event should be routed\n */\n cri: string\n\n /**\n * Any headers defined for this event.\n * This will usually contain all the fields above as well since they are typically wrappers around expected header values.\n */\n headers: Map<string, string>\n\n /**\n * The event payload. The payload depends on the type the payload is encoded into a media format which is specified by the contentType attribute (e.g. application/json).\n */\n data: Optional<Uint8Array>\n\n /**\n * @return the data property as a UTF-8 encoded string\n */\n getDataString(): string\n\n /**\n * Gets the value for the header with the given key\n * @param key to get the header value for\n * @return the header value or undefined if there is no header for the key\n */\n getHeader(key: string): string | undefined\n\n /**\n * Tests if a header for the given key exists\n * @param key to check if exists as a header\n * @return true if the header for the key exists false if not\n */\n hasHeader(key: string): boolean\n\n /**\n * Removes the header from the headers map\n * @param key to remove\n * @return true if an element in the headers map object existed and has been removed, or false if the element does not exist\n */\n removeHeader(key: string): boolean\n\n /**\n * Sets the data property from the given string value\n * @param data\n */\n setDataString(data: string): void\n\n /**\n * Sets the header into the headers map\n * @param key the key to use\n * @param value the value to use\n */\n setHeader(key: string, value: string): void\n\n}\n\n/**\n * Part of the low level portion of continuum representing a connection to a continuum server\n * This is similar to a Stomp Client but with more required information and no control plane semantics.\n *\n * Created by Navid Mitchell on 2019-01-04.\n */\nexport interface IEventBus {\n\n /**\n * Any errors emitted by this observable will be fatal and the connection will be closed.\n * You will need to resolve the problem and reconnect.\n */\n fatalErrors: Observable<ContinuumError>\n\n /**\n * The {@link ServerInfo} used when connecting, if connected or null\n */\n serverInfo: ServerInfo | null\n\n /**\n * Requests a connection to the given Stomp url\n * @param connectionInfo provides the information needed to connect to the continuum server\n * @return Promise containing the result of the initial connection attempt\n */\n connect(connectionInfo: ConnectionInfo): Promise<ConnectedInfo>\n\n /**\n * Disconnects the client from the server\n * This will clear any subscriptions and close the connection\n * @param force if true then the connection will be closed immediately without sending a disconnect frame\n * When this mode is used, the actual Websocket may linger for a while\n * and the broker may not realize that the connection is no longer in use.\n *\n * @return Promise containing the result of the disconnect attempt\n */\n disconnect(force?: boolean): Promise<void>\n\n /**\n * Determines if the connection is connected.\n * This means that there is an open connection to the Continuum server\n * @return true if the connection is active false if not\n */\n isConnected(): boolean\n\n /**\n * Determines if the connection is active.\n * This means {@link IEventBus#connect()} was called and was successful. The underlying connection may not be established yet.\n * If this is true and {@link IEventBus#isConnected} is false messages sent will be queued\n * @return true if the connection is active false if not\n */\n isConnectionActive(): boolean\n\n /**\n * Creates a subscription for all {@link IEvent}'s for the given destination\n * @param cri to subscribe to\n */\n observe(cri: string): Observable<IEvent>\n\n /**\n * Sends an {@link IEvent} expecting a response\n * All response correlation will be handled internally\n * @param event to send as the request\n * @return a Promise that will resolve when the response is received\n */\n request(event: IEvent): Promise<IEvent>\n\n /**\n * Sends an {@link IEvent} expecting multiple responses\n * All response correlation will be handled internally\n * @param event to send as the request\n * @param sendControlEvents if true then control events will be sent to the server when changes to the returned to Observable are requested\n * @return an {@link Observable<IEvent} that will provide the response stream\n * NOTE: the naming here is similar to RSocket https://www.baeldung.com/rsocket#3-requeststream\n */\n requestStream(event: IEvent, sendControlEvents: boolean): Observable<IEvent>\n\n /**\n * Send a single {@link IEvent} to the connected server\n * @param event to send\n */\n send(event: IEvent): void\n\n}\n\n/**\n * Constants used within {@link IEvent}'s to control the flow of events\n * Header that start with __ will always be persisted between messages\n */\nexport enum EventConstants {\n CONTENT_TYPE_HEADER = 'content-type',\n CONTENT_LENGTH_HEADER = 'content-length',\n REPLY_TO_HEADER = 'reply-to',\n\n /**\n * This is the replyToId that will be supplied by the client, which will be used when sending replies to the client.\n */\n REPLY_TO_ID_HEADER = 'reply-to-id',\n\n /**\n * Header provided by the sever on connection to represent the user's session id\n */\n SESSION_HEADER = 'session',\n\n /**\n * Header provided by the server on connection to provide the {@link ConnectionInfo} as a JSON string\n */\n CONNECTED_INFO_HEADER = 'connected-info',\n\n /**\n * Header provided by the client on connection request to represent that the server\n * should not keep the session alive after any network disconnection.\n */\n DISABLE_STICKY_SESSION_HEADER = \"disable-sticky-session\",\n\n /**\n * Correlates a response with a given request\n * Headers that start with __ will always be persisted between messages\n */\n CORRELATION_ID_HEADER = '__correlation-id',\n\n /**\n * Denotes that something caused an error. Will contain a brief message about the error\n */\n ERROR_HEADER = 'error',\n\n /**\n * Denotes the completion of an event stream. The value typically will contain the reason for completion.\n */\n COMPLETE_HEADER = 'complete',\n\n /**\n * Denotes the event is a control plane event. These are used for internal coordination.\n */\n CONTROL_HEADER = 'control',\n\n /**\n * Stream is complete, no further values will be sent.\n */\n CONTROL_VALUE_COMPLETE = 'complete',\n\n CONTROL_VALUE_CANCEL = 'cancel',\n\n CONTROL_VALUE_SUSPEND = 'suspend',\n\n CONTROL_VALUE_RESUME = 'resume',\n\n SERVICE_DESTINATION_PREFIX = 'srv://',\n SERVICE_DESTINATION_SCHEME = \"srv\",\n STREAM_DESTINATION_PREFIX = 'stream://',\n STREAM_DESTINATION_SCHEME = \"stream\",\n\n CONTENT_JSON = 'application/json',\n CONTENT_TEXT = 'text/plain',\n\n /**\n * The traceparent HTTP header field identifies the incoming request in a tracing system. It has four fields:\n *\n * version\n * trace-id\n * parent-id\n * trace-flags\n * @see https://www.w3.org/TR/trace-context/#traceparent-header\n */\n TRACEPARENT_HEADER = 'traceparent',\n\n /**\n * The main purpose of the tracestate header is to provide additional vendor-specific trace identification information across different distributed tracing systems and is a companion header for the traceparent field. It also conveys information about the request’s position in multiple distributed tracing graphs.\n * @see https://www.w3.org/TR/trace-context/#tracestate-header\n */\n TRACESTATE_HEADER = 'tracestate'\n}\n","import {ConnectionInfo} from '@/api/ConnectionInfo'\nimport {ConnectedInfo} from '@/api/security/ConnectedInfo'\nimport {EventConstants} from '@/core/api/IEventBus'\nimport {IFrame, RxStomp, RxStompConfig, StompHeaders} from '@stomp/rx-stomp'\nimport {ReconnectionTimeMode} from '@stomp/stompjs'\nimport {Subscription} from 'rxjs'\nimport {v4 as uuidv4} from 'uuid'\nimport debug from 'debug'\n\n/**\n * Creates a new RxStomp client and manages it\n * This is here to simplify the logic needed for connection management and the usage of the client.\n */\nexport class StompConnectionManager {\n\n public lastWebsocketError: Event | null = null\n /**\n * This will return true if a {@link ConnectionInfo#maxConnectionAttempts} threshold was set and was reached\n */\n public maxConnectionAttemptsReached: boolean = false\n public rxStomp: RxStomp | null = null\n private readonly INITIAL_RECONNECT_DELAY: number = 2000\n private readonly MAX_RECONNECT_DELAY: number = 120000 // 2 mins\n private readonly JITTER_MAX: number = 5000\n private connectionAttempts: number = 0\n private initialConnectionSuccessful: boolean = false\n private debugLogger = debug('continuum:stomp')\n private replyToId = uuidv4()\n public readonly replyToCri = EventConstants.SERVICE_DESTINATION_PREFIX + this.replyToId + ':' + uuidv4() + '@continuum.js.EventBus/replyHandler'\n public deactivationHandler: (() => void) | null = null\n\n /**\n * @return true if this {@link StompConnectionManager} is actively trying to maintain a connection to the Stomp server, false if not.\n */\n public get active(): boolean {\n if(this.rxStomp){\n return true\n }else{\n return false\n }\n }\n\n /**\n * return true if this {@link StompConnectionManager} is active and has a connection to the stomp server\n */\n public get connected(): boolean {\n return this.rxStomp != null\n && this.rxStomp.connected()\n }\n\n public activate(connectionInfo: ConnectionInfo): Promise<ConnectedInfo> {\n return new Promise((resolve, reject): void => {\n // Validate state and short circuit\n if(!connectionInfo){\n reject('You must supply a valid connectionInfo object')\n return\n }\n\n if (!(connectionInfo.host)) {\n reject('No host provided')\n return\n }\n\n if(this.rxStomp) {\n reject('Stomp connection already active')\n return\n }\n\n // we reset most state here so, it will persist on a connection failure\n this.connectionAttempts = 0\n this.initialConnectionSuccessful = false\n this.lastWebsocketError = null\n this.maxConnectionAttemptsReached = false\n\n const url = 'ws' + (connectionInfo.useSSL ? 's' : '')\n + '://' + connectionInfo.host\n + (connectionInfo.port ? ':' + connectionInfo.port : '') + '/v1'\n\n this.rxStomp = new RxStomp()\n\n let connectHeadersInternal: StompHeaders = (typeof connectionInfo.connectHeaders !== 'function' && connectionInfo.connectHeaders != null ? connectionInfo.connectHeaders : {})\n\n const stompConfig: RxStompConfig = {\n brokerURL: url,\n connectHeaders: connectHeadersInternal,\n heartbeatIncoming: 120000,\n heartbeatOutgoing: 30000,\n reconnectDelay: this.INITIAL_RECONNECT_DELAY,\n beforeConnect: async (): Promise<void> => {\n\n if(typeof connectionInfo.connectHeaders === 'function'){\n const headers = await connectionInfo.connectHeaders()\n for(const key in headers) {\n connectHeadersInternal[key] = headers[key]\n }\n }\n\n if(connectionInfo.disableStickySession){\n connectHeadersInternal[EventConstants.DISABLE_STICKY_SESSION_HEADER] = 'true'\n }\n connectHeadersInternal[EventConstants.REPLY_TO_ID_HEADER] = this.replyToId\n\n // If max connections are set then make sure we have not exceeded that threshold\n if(connectionInfo?.maxConnectionAttempts){\n this.connectionAttempts++\n\n if(this.connectionAttempts > connectionInfo.maxConnectionAttempts){\n\n // Reached threshold give up\n this.maxConnectionAttemptsReached = true\n await this.deactivate()\n\n // If we have not made an initial connection, the promise is not yet resolved\n if(!this.initialConnectionSuccessful) {\n let message = (this.lastWebsocketError as any)?.message ? (this.lastWebsocketError as any)?.message : 'UNKNOWN'\n reject(`Max number of reconnection attempts reached. Last WS Error ${message}`)\n }\n }else{\n await this.connectionJitterDelay();\n }\n }else{\n await this.connectionJitterDelay();\n }\n }\n }\n\n if(this.debugLogger.enabled){\n stompConfig.debug = (msg: string): void => {\n this.debugLogger(msg)\n }\n }\n\n //*** Begin Block that handles backoff ***\n this.rxStomp.configure(stompConfig)\n\n // Set values that are only accessible from the stompClient\n this.rxStomp.stompClient.maxReconnectDelay = this.MAX_RECONNECT_DELAY\n this.rxStomp.stompClient.reconnectTimeMode = ReconnectionTimeMode.EXPONENTIAL\n\n // Handles Websocket Errors\n this.rxStomp.webSocketErrors$.subscribe(value => {\n this.lastWebsocketError = value\n })\n\n // Handles Successful Connections\n const connectedSubscription: Subscription = this.rxStomp.connected$.subscribe(() =>{\n connectedSubscription.unsubscribe()\n // Successful Connection\n if(!this.initialConnectionSuccessful){\n this.initialConnectionSuccessful = true\n }\n })\n\n // This subscription is to handle any errors that occur during connection\n const errorSubscription: Subscription = this.rxStomp.stompErrors$.subscribe((value: IFrame) => {\n errorSubscription.unsubscribe()\n const message = value.headers['message']\n this.rxStomp?.deactivate()\n this.rxStomp = null\n reject(message)\n })\n\n // This is triggered when the server sends a CONNECTED frame.\n const serverHeadersSubscription: Subscription = this.rxStomp.serverHeaders$.subscribe((value: StompHeaders) => {\n let connectedInfoJson: string | undefined = value[EventConstants.CONNECTED_INFO_HEADER]\n if (connectedInfoJson != null) {\n\n const connectedInfo: ConnectedInfo = JSON.parse(connectedInfoJson)\n\n if(!connectionInfo.disableStickySession){\n\n serverHeadersSubscription.unsubscribe()\n\n if (connectedInfo.sessionId != null && connectedInfo.replyToId != null) {\n\n // Remove all information originally sent from the connect headers\n if (connectionInfo.connectHeaders != null) {\n for (let key in connectHeadersInternal) {\n delete connectHeadersInternal[key]\n }\n }\n\n connectHeadersInternal[EventConstants.SESSION_HEADER] = connectedInfo.sessionId\n\n resolve(connectedInfo)\n } else {\n reject('Server did not return proper data for successful login')\n }\n\n }else if(typeof connectionInfo.connectHeaders === 'function'){\n // If the connect headers are supplied by a function we remove all the header values since they will be recreated on next connect\n for (let key in connectHeadersInternal) {\n delete connectHeadersInternal[key]\n }\n if(!this.initialConnectionSuccessful) {\n resolve(connectedInfo)\n }\n }else if(typeof connectionInfo.connectHeaders === 'object'){\n // static object we must leave intact for reuse\n serverHeadersSubscription.unsubscribe()\n resolve(connectedInfo)\n }\n } else {\n reject('Server did not return proper data for successful login')\n }\n })\n\n this.rxStomp.activate()\n })\n }\n\n public async deactivate(force?: boolean): Promise<void> {\n if(this.rxStomp){\n await this.rxStomp.deactivate({force: force})\n if(this.deactivationHandler){\n this.deactivationHandler()\n }\n this.rxStomp = null\n }\n return\n }\n\n /**\n * Make sure clients don't all try to reconnect at the same time.\n */\n private async connectionJitterDelay(): Promise<void> {\n if(this.initialConnectionSuccessful) {\n const randomJitter = Math.random() * this.JITTER_MAX;\n this.debugLogger(`Adding ${randomJitter}ms of jitter delay`)\n return new Promise(resolve => setTimeout(resolve, randomJitter));\n }\n }\n\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\")\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {ConnectionInfo, ServerInfo} from '@/api/ConnectionInfo'\nimport {ContinuumError} from '@/api/errors/ContinuumError'\nimport {ConnectedInfo} from '@/api/security/ConnectedInfo'\nimport {StompConnectionManager} from '@/core/api/StompConnectionManager'\nimport {context, propagation} from '@opentelemetry/api';\nimport {IFrame, IMessage} from '@stomp/rx-stomp'\nimport {ConnectableObservable, firstValueFrom, Observable, Subject, Subscription, throwError, Unsubscribable} from 'rxjs'\nimport {filter, map, multicast} from 'rxjs/operators'\nimport {Optional} from 'typescript-optional'\nimport {v4 as uuidv4} from 'uuid'\nimport {EventConstants, IEvent, IEventBus} from './IEventBus'\n\n/**\n * Default IEvent implementation\n */\nexport class Event implements IEvent {\n\n public cri: string\n public headers: Map<string, string>\n public data: Optional<Uint8Array>\n\n constructor(cri: string,\n headers?: Map<string, string>,\n data?: Uint8Array) {\n\n this.cri = cri\n\n if (headers !== undefined) {\n this.headers = headers\n } else {\n this.headers = new Map<string, string>()\n }\n\n this.data = Optional.ofNullable(data)\n }\n\n public getHeader(key: string): string | undefined {\n return this.headers.get(key)\n }\n\n public hasHeader(key: string): boolean {\n return this.headers.has(key)\n }\n\n public setHeader(key: string, value: string): void {\n this.headers.set(key, value)\n }\n\n public removeHeader(key: string): boolean {\n return this.headers.delete(key)\n }\n\n public setDataString(data: string): void {\n const uint8Array = new TextEncoder().encode(data)\n this.data = Optional.ofNonNull(uint8Array)\n }\n\n public getDataString(): string {\n let ret = ''\n this.data.ifPresent(( value ) => ret = new TextDecoder().decode(value))\n return ret\n }\n}\n\ninterface Carrier {\n traceparent?: string;\n tracestate?: string;\n}\n\n/**\n * Default implementation of {@link IEventBus}\n */\nexport class EventBus implements IEventBus {\n\n public fatalErrors: Observable<Error>\n public serverInfo: ServerInfo | null = null\n private stompConnectionManager: StompConnectionManager = new StompConnectionManager()\n private replyToCri: string | null = null\n private requestRepliesObservable: ConnectableObservable<IEvent> | null = null\n private requestRepliesSubject: Subject<IEvent> | null = null\n private requestRepliesSubscription: Subscription | null = null\n private errorSubject: Subject<IFrame> = new Subject<IFrame>()\n private errorSubjectSubscription: Subscription | null | undefined = null\n\n constructor() {\n this.fatalErrors = this.errorSubject\n .pipe(map<IFrame, Error>((frame: IFrame): Error => {\n this.disconnect()\n .catch((error: string) => {\n if(console){\n console.error('Error disconnecting from Stomp: ' + error)\n }\n })\n // TODO: map to continuum error\n return new ContinuumError(frame.headers['message'])\n }))\n this.stompConnectionManager.deactivationHandler = () => {\n this.cleanup()\n }\n }\n\n public isConnectionActive(): boolean{\n return this.stompConnectionManager.active\n }\n\n public isConnected(): boolean {\n return this.stompConnectionManager.connected\n }\n\n public async connect(connectionInfo: ConnectionInfo): Promise<ConnectedInfo> {\n if(!this.stompConnectionManager.active){\n\n // reset state in case connection ended due to max connection attempts\n this.cleanup()\n\n const connectedInfo = await this.stompConnectionManager.activate(connectionInfo)\n // manually copy so we don't store any sensitive info\n this.serverInfo = new ServerInfo()\n this.serverInfo.host = connectionInfo.host\n this.serverInfo.port = connectionInfo.port\n this.serverInfo.useSSL = connectionInfo.useSSL\n\n // FIXME: a reply should not need a reply, therefore a replyCri probably should not be a EventConstants.SERVICE_DESTINATION_PREFIX\n this.replyToCri = this.stompConnectionManager.replyToCri\n\n this.errorSubjectSubscription = this.stompConnectionManager.rxStomp?.stompErrors$.subscribe(this.errorSubject)\n\n return connectedInfo\n }else{\n throw new Error('Event Bus connection already active')\n }\n }\n\n public async disconnect(force?: boolean): Promise<void> {\n await this.stompConnectionManager.deactivate(force)\n\n this.cleanup()\n }\n\n public send(event: IEvent): void {\n if(this.stompConnectionManager.rxStomp){\n const headers: any = {}\n\n for (const [key, value] of event.headers.entries()) {\n headers[key] = value\n }\n\n const carrier: Carrier = {}\n propagation.inject(context.active(), carrier)\n if(carrier.traceparent){\n headers[EventConstants.TRACEPARENT_HEADER] = carrier.traceparent\n }\n if(carrier.tracestate){\n headers[EventConstants.TRACESTATE_HEADER] = carrier.tracestate\n }\n\n // send data over stomp\n this.stompConnectionManager.rxStomp.publish({\n destination: event.cri,\n headers,\n binaryBody: event.data.orUndefined()\n })\n }else{\n throw this.createSendUnavailableError()\n }\n }\n\n public request(event: IEvent): Promise<IEvent> {\n return firstValueFrom(this.requestStream(event, false))\n }\n\n public requestStream(event: IEvent, sendControlEvents: boolean = true): Observable<IEvent> {\n if(this.stompConnectionManager?.rxStomp){\n return new Observable<IEvent>((subscriber) => {\n\n if (this.requestRepliesObservable == null) {\n this.requestRepliesSubject = new Subject<IEvent>()\n this.requestRepliesObservable = this._observe(this.replyToCri as string)\n .pipe(multicast(this.requestRepliesSubject)) as ConnectableObservable<IEvent>\n this.requestRepliesSubscription = this.requestRepliesObservable.connect()\n }\n\n let serverSignaledCompletion = false\n const correlationId = uuidv4()\n const defaultMessagesSubscription: Unsubscribable\n = this.requestRepliesObservable\n .pipe(filter((value: IEvent): boolean => {\n return value.headers.get(EventConstants.CORRELATION_ID_HEADER) === correlationId\n })).subscribe({\n next(value: IEvent): void {\n\n if (value.hasHeader(EventConstants.CONTROL_HEADER)) {\n\n if (value.headers.get(EventConstants.CONTROL_HEADER) === 'complete') {\n serverSignaledCompletion = true\n subscriber.complete()\n } else {\n throw new Error('Control Header ' + value.headers.get(EventConstants.CONTROL_HEADER) + ' is not supported')\n }\n\n } else if (value.hasHeader(EventConstants.ERROR_HEADER)) {\n\n // TODO: add custom error type that contains error detail as well if provided by server, this would be the event body\n serverSignaledCompletion = true\n subscriber.error(new Error(value.getHeader(EventConstants.ERROR_HEADER)))\n\n } else {\n\n subscriber.next(value)\n\n }\n },\n error(err: any): void {\n subscriber.error(err)\n },\n complete(): void {\n subscriber.complete()\n }\n })\n\n subscriber.add(defaultMessagesSubscription)\n\n event.setHeader(EventConstants.REPLY_TO_HEADER, this.replyToCri as string)\n event.setHeader(EventConstants.CORRELATION_ID_HEADER, correlationId)\n\n this.send(event)\n\n return () => {\n if (sendControlEvents && !serverSignaledCompletion) {\n // create control event to cancel long-running request\n const controlEvent: Event = new Event(event.cri)\n controlEvent.setHeader(EventConstants.CONTROL_HEADER, EventConstants.CONTROL_VALUE_CANCEL)\n controlEvent.setHeader(EventConstants.CORRELATION_ID_HEADER, correlationId)\n this.send(controlEvent)\n }\n }\n })\n }else{\n return throwError(() => this.createSendUnavailableError())\n }\n }\n\n public observe(cri: string): Observable<IEvent> {\n return this._observe(cri)\n }\n\n private cleanup(): void{\n if (this.requestRepliesSubject != null) {\n\n // This will be sent to any client waiting on an Event\n this.requestRepliesSubject.error(new Error('Connection disconnected'))\n\n if (this.requestRepliesSubscription != null) {\n this.requestRepliesSubscription.unsubscribe()\n this.requestRepliesSubscription = null\n }\n\n this.requestRepliesSubject = null;\n this.requestRepliesObservable = null\n }\n\n if (this.errorSubjectSubscription) {\n this.errorSubjectSubscription.unsubscribe()\n this.errorSubjectSubscription = null\n }\n\n this.serverInfo = null\n }\n\n /**\n * Creates the proper error to return if this.stompConnectionManager?.rxStomp is not available on a send request\n */\n private createSendUnavailableError(): Error {\n let ret: string = 'You must call connect on the event bus before sending any request'\n if(this.stompConnectionManager.maxConnectionAttemptsReached){\n ret = 'Max connection attempts reached event bus is not available'\n }\n return new Error(ret)\n }\n\n /**\n * This is internal impl of observe that creates a cold observable.\n * The public variants transform this to some type of hot observable depending on the need\n * @param cri to observe\n * @return the cold {@link Observable<IEvent>} for the given destination\n */\n private _observe(cri: string): Observable<IEvent> {\n if(this.stompConnectionManager?.rxStomp) {\n return this.stompConnectionManager\n .rxStomp\n .watch(cri)\n .pipe(map<IMessage, IEvent>((message: IMessage): IEvent => {\n\n // We translate all IMessage objects to IEvent objects\n const headers: Map<string, string> = new Map<string, string>()\n let destination: string = ''\n for (const prop of Object.keys(message.headers)) {\n if (prop === 'destination') {\n destination = message.headers[prop]\n }else{\n headers.set(prop, message.headers[prop])\n }\n }\n\n return new Event(destination, headers, message.binaryBody)\n }))\n }else{\n return throwError(() => this.createSendUnavailableError())\n }\n }\n\n}\n\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\")\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CRI } from \"./CRI\"\n\n/**\n * Default implementation of the `CRI` interface.\n *\n * @author Navid Mitchell\n * @since 3/25/25\n */\nexport class DefaultCRI implements CRI {\n private readonly _scheme: string\n private readonly _scope: string | null\n private readonly _resourceName: string\n private readonly _path: string | null\n private readonly _version: string | null\n private readonly _raw: string\n\n constructor(rawCRI: string)\n constructor(scheme: string, scope: string | null, resourceName: string, path: string | null, version: string | null)\n constructor(...args: any[]) {\n if (args.length === 1) {\n const rawURC = args[0]\n if (typeof rawURC !== \"string\") {\n throw new Error(\"Raw URI must be a string\")\n }\n const parsed = DefaultCRI.parseRaw(rawURC)\n this._scheme = parsed.scheme\n this._scope = parsed.scope\n this._resourceName = parsed.resourceName\n this._path = parsed.path\n this._version = parsed.version\n this._raw = rawURC\n } else if (args.length === 5) {\n const [scheme, scope, resourceName, path, version] = args\n this._scheme = scheme\n this._scope = scope\n this._resourceName = resourceName\n this._path = path\n this._version = version\n this._raw = DefaultCRI.buildRaw(scheme, scope, resourceName, path, version)\n } else {\n throw new Error(\"Invalid constructor arguments for DefaultCRI\")\n }\n\n if (!this._scheme || !this._resourceName) {\n throw new Error(`Invalid CRI: scheme and resourceName are required. Got: ${this._raw}`)\n }\n }\n\n public scheme(): string {\n return this._scheme\n }\n\n public scope(): string | null {\n return this._scope\n }\n\n public hasScope(): boolean {\n return this._scope !== null\n }\n\n public resourceName(): string {\n return this._resourceName\n }\n\n public version(): string | null {\n return this._version\n }\n\n public hasVersion(): boolean {\n return this._version !== null\n }\n\n public path(): string | null {\n return this._path\n }\n\n public hasPath(): boolean {\n return this._path !== null\n }\n\n public baseResource(): string {\n let result = `${this._scheme}://`\n if (this.hasScope()) {\n result += `${this._scope}@`\n }\n result += this._resourceName\n return result\n }\n\n public raw(): string {\n return this._raw\n }\n\n public equals(other: any): boolean {\n if (this === other) return true\n if (!(other instanceof DefaultCRI)) return false\n return this._raw === other.raw()\n }\n\n public hashCode(): number {\n let hash = 17\n hash = hash * 37 + this._raw.split(\"\").reduce((a, c) => a + c.charCodeAt(0), 0)\n return hash\n }\n\n public toString(): string {\n return this._raw\n }\n\n // Helper to parse a raw CRI string\n private static parseRaw(raw: string): {\n scheme: string\n scope: string | null\n resourceName: string\n path: string | null\n version: string | null\n } {\n const regex = /^([^:]+):\\/\\/(?:([^@]+)@)?([^\\/#]+)(\\/[^#]*)?(?:#(.+))?$/;\n const match = raw.match(regex)\n if (!match) {\n throw new Error(`Invalid CRI format: ${raw}`)\n }\n\n const [, scheme, scope, resourceName, path, version] = match\n return {\n scheme,\n scope: scope || null,\n resourceName,\n path: path ? path.substring(1) : null,\n version: version || null,\n }\n }\n\n // Helper to build a raw CRI string\n private static buildRaw(\n scheme: string,\n scope: string | null,\n resourceName: string,\n path: string | null,\n version: string | null\n ): string {\n let result = `${scheme}://`\n if (scope) {\n result += `${scope}@`\n }\n result += resourceName\n if (path) {\n result += `/${path}`\n }\n if (version) {\n result += `#${version}`\n }\n return result\n }\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\")\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {DefaultCRI} from './DefaultCRI.js'\n\n/**\n * `CRI` is a Continuum Resource Identifier used by Continuum to route requests appropriately.\n *\n * The `CRI` is a URI where the parts are named differently for clarity as to their purpose within Continuum.\n *\n * Will be in a format as follows where anything surrounded with `[]` is optional:\n *\n * scheme://[scope@]resourceName[/path][#version]\n *\n * NOTE: If scope needs to be used to identify a sub-scope, it will follow the form `scope = scope:sub-scope`.\n *\n * This format can have varied meanings based upon the scheme used.\n *\n * @author Navid Mitchell\n * @since 3/25/25\n */\nexport interface CRI {\n /**\n * The scheme for this `CRI`.\n *\n * @returns a string containing the scheme\n */\n scheme(): string\n\n /**\n * The scope for this `CRI` or `null` if not provided.\n *\n * This is useful to narrow down the `CRI`. This could be something like a user id, device id, or a node id.\n *\n * @returns a string containing the scope if provided or `null` if not set\n */\n scope(): string | null\n\n /**\n * @returns `true` if the `scope` is set\n */\n hasScope(): boolean\n\n /**\n * The name of the resource represented by this `CRI`.\n *\n * In the case of a `srv` `CRI`, this will be the service name.\n * In the case of a `stream` `CRI`, this will be the name of the event type that the stream expects.\n *\n * For the following CRI, `resourceName` would be the portion specified by `resourceName`:\n *\n * `scheme://[scope@]resourceName/path`\n *\n * @returns the string containing the name of this resource\n */\n resourceName(): string\n\n /**\n * This is a version for the resource or `null` if not provided.\n *\n * @returns a string containing the version if provided or `null` if not set\n */\n version(): string | null\n\n /**\n * @returns `true` if the `version` is set\n */\n hasVersion(): boolean\n\n /**\n * The path for this `CRI`, without a leading `/`.\n *\n * For the following CRI, `path` would be the portion specified by `path`:\n *\n * `scheme://[scope@]resourceName/path`\n *\n * @returns the path string if provided or `null` if not set\n */\n path(): string | null\n\n /**\n * @returns `true` if the `path` is set\n */\n hasPath(): boolean\n\n /**\n * Base Resource is a portion of the fully qualified `CRI` containing the following:\n *\n * `scheme://[scope@]resourceName`\n *\n * @returns string containing the baseResource\n */\n baseResource(): string\n\n /**\n * The fully qualified value for this `CRI`.\n *\n * @returns the fully qualified `CRI` as a string\n */\n raw(): string\n}\n\n/**\n * Creates a new `CRI` from a raw string.\n *\n * @param rawUrc the raw string\n * @returns the newly created `CRI`\n */\nexport function createCRI(rawUrc: string): CRI;\n\n/**\n * Creates a new `CRI` from scheme and resourceName.\n *\n * @param scheme the scheme\n * @param resourceName the resource name\n * @returns the newly created `CRI`\n */\nexport function createCRI(scheme: string, resourceName: string): CRI;\n/**\n * Creates a new `CRI` from scheme, scope, and resourceName.\n *\n * @param scheme the scheme\n * @param scope the scope\n * @param resourceName the resource name\n * @returns the newly created `CRI`\n */\nexport function createCRI(scheme: string, scope: string | null, resourceName: string): CRI;\n/**\n * Creates a new `CRI` from all provided values.\n *\n * @param scheme the scheme\n * @param scope the scope\n * @param resourceName the resource name\n * @param path the path\n * @param version the version\n * @returns the newly created `CRI`\n */\nexport function createCRI(scheme: string, scope: string | null, resourceName: string, path: string | null, version: string | null): CRI;\n\n// Implementation of the overloaded createCRI function\nexport function createCRI(...args: any[]): CRI {\n if (args.length === 1) return new DefaultCRI(args[0]);\n if (args.length === 2) return new DefaultCRI(args[0], null, args[1], null, null);\n if (args.length === 3) return new DefaultCRI(args[0], args[1], args[2], null, null);\n if (args.length === 5) return new DefaultCRI(args[0], args[1], args[2], args[3], args[4]);\n throw new Error(\"Invalid arguments for createCRI\");\n}\n","/*\n * Copyright 2008-2021 Kinotic and the original author or authors.\n * Licensed under the Apache License, Version 2.0 (the \"License\")\n * See https://www.apache.org/licenses/LICENSE-2.0\n */\n\n\nimport {EventConstants, IEvent} from '@/core/api/IEventBus.js'\n\n/**\n * Argument resolution utilities for service invocation.\n *\n * @author Navid Mitchell 🤝Grok\n * @since 3/25/2025\n */\nexport interface ArgumentResolver {\n resolveArguments(event: IEvent): any[]\n}\n\nexport class JsonArgumentResolver implements ArgumentResolver {\n resolveArguments(event: IEvent): any[] {\n if (this.containsJsonContent(event)) {\n const data = event.getDataString()\n return data ? JSON.parse(data) : []\n }else{\n throw new Error(\"Currently only JSON content is supported\")\n }\n }\n\n protected containsJsonContent(event: IEvent): boolean {\n const contentType = event.getHeader(EventConstants.CONTENT_TYPE_HEADER)\n return contentType != null && contentType !== \"\" && contentType === \"application/json\"\n }\n}\n","/*\n * Copyright 2008-2021 Kinotic and the original author or authors.\n * Licensed under the Apache License, Version 2.0 (the \"License\")\n * See https://www.apache.org/licenses/LICENSE-2.0\n */\n\n\nimport {EventConstants, IEvent} from '@/core/api/IEventBus.js'\nimport {Event} from '@/core/api/EventBus.js'\n\n/**\n * Utility functions for working with events in the Continuum framework.\n *\n * @author Navid Mitchell 🤝Grok\n * @since 3/25/2025\n */\nexport class EventUtil {\n\n public static createReplyEvent(\n incomingHeaders: Map<string, string>,\n headers?: Map<string, string>,\n body?: Uint8Array\n ): IEvent {\n if (!incomingHeaders) {\n throw new Error(\"incomingHeaders cannot be null\")\n }\n\n const replyCRI = incomingHeaders.get(EventConstants.REPLY_TO_HEADER)\n if (!replyCRI || replyCRI.trim() === \"\") {\n throw new Error(\"No reply-to header found, cannot create outgoing message\")\n }\n\n const newHeaders = new Map<string, string>()\n for (const [key, value] of incomingHeaders) {\n if (key.startsWith(\"__\")) {\n newHeaders.set(key, value)\n }\n }\n\n if (headers) {\n for (const [key, value] of headers) {\n newHeaders.set(key, value)\n }\n }\n\n return new Event(replyCRI, newHeaders, body || undefined)\n }\n}\n","/*\n * Copyright 2008-2021 Kinotic and the original author or authors.\n * Licensed under the Apache License, Version 2.0 (the \"License\")\n * See https://www.apache.org/licenses/LICENSE-2.0\n */\n\nimport {EventConstants, IEvent} from '@/core/api/IEventBus.js'\nimport {EventUtil} from '@/internal/core/api/EventUtil.js'\n\n/**\n * Return value conversion utilities for service responses.\n *\n * @author Navid Mitchell 🤝Grok\n * @since 3/25/2025\n */\nexport interface ReturnValueConverter {\n convert(incomingMetadata: Map<string, string>, returnValue: any): IEvent\n}\n\nexport class BasicReturnValueConverter implements ReturnValueConverter {\n convert(incomingMetadata: Map<string, string>, returnValue: any): IEvent {\n return EventUtil.createReplyEvent(\n incomingMetadata,\n new Map([[EventConstants.CONTENT_TYPE_HEADER, \"application/json\"]]),\n new TextEncoder().encode(JSON.stringify(returnValue))\n )\n }\n}\n","/*\n * Copyright 2008-2021 Kinotic and the original author or authors.\n * Licensed under the Apache License, Version 2.0 (the \"License\")\n * See https://www.apache.org/licenses/LICENSE-2.0\n */\n\n/**\n * Logging utilities for the Continuum library.\n *\n * @author Navid Mitchell 🤝Grok\n * @since 3/25/2025\n */\nexport interface Logger {\n trace(message: string, ...args: any[]): void\n debug(message: string, ...args: any[]): void\n info(message: string, ...args: any[]): void\n warn(message: string, ...args: any[]): void\n error(message: string, ...args: any[]): void\n}\n\nexport class NoOpLogger implements Logger {\n trace(_message: string, ..._args: any[]): void {}\n debug(_message: string, ..._args: any[]): void {}\n info(_message: string, ..._args: any[]): void {}\n warn(_message: string, ..._args: any[]): void {}\n error(_message: string, ..._args: any[]): void {}\n}\n\nexport function createDebugLogger(namespace: string): Logger {\n let debug: any\n try {\n debug = require(\"debug\")(namespace)\n } catch (e) {\n debug = (...args: any[]) => console.debug(`[${namespace}]`, ...args)\n }\n\n return {\n trace: (...args) => debug(\"TRACE\", ...args),\n debug: (...args) => debug(\"DEBUG\", ...args),\n info: (...args) => debug(\"INFO\", ...args),\n warn: (...args) => debug(\"WARN\", ...args),\n error: (...args) => debug(\"ERROR\", ...args),\n }\n}\n","import {createCRI, CRI} from '@/core/api/CRI.js'\nimport {EventConstants} from '@/core/api/IEventBus.js'\n\nexport class ServiceIdentifier {\n\n public namespace: string\n public name: string\n public scope?: string\n public version?: string\n private _cri: CRI | null = null\n\n\n constructor(namespace: string, name: string) {\n this.namespace = namespace\n this.name = name\n }\n\n /**\n * Returns the qualified name for this {@link ServiceIdentifier}\n * This is the namespace.name\n * @return string containing the qualified name\n */\n public qualifiedName(): string{\n return this.namespace + \".\" + this.name;\n }\n\n /**\n * The {@link CRI} that represents this {@link ServiceIdentifier}\n * @return the cri for this {@link ServiceIdentifier}\n */\n public cri(): CRI {\n if(this._cri == null) {\n this._cri = createCRI(\n EventConstants.SERVICE_DESTINATION_SCHEME, // scheme\n this.scope || null, // scope\n this.qualifiedName(), // resourceName\n null, // path (null as per your example)\n this.version || null // version\n );\n }\n return this._cri;\n }\n}\n","/*\n * Copyright 2008-2021 Kinotic and the original author or authors.\n * Licensed under the Apache License, Version 2.0 (the 'License')\n * See https://www.apache.org/licenses/LICENSE-2.0\n */\n\nimport 'reflect-metadata'\nimport { Continuum } from '@/api/Continuum.js'\nimport { ServiceIdentifier } from '@/core/api/ServiceIdentifier.js'\n\n/**\n * Decorator for registering services with the Continuum ServiceRegistry.\n *\n * @author Navid Mitchell 🤝Grok\n * @since 3/25/2025\n */\nconst SCOPE_METADATA_KEY = Symbol('scope')\nconst VERSION_METADATA_KEY = Symbol('version')\nexport const CONTEXT_METADATA_KEY = Symbol('context')\n\n//@ts-ignore\nexport function Scope(target: any, propertyKey: string, descriptor?: PropertyDescriptor) {\n Reflect.defineMetadata(SCOPE_METADATA_KEY, propertyKey, target)\n}\n\nexport function Version(version: string) {\n if (!/^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9]+)?$/.test(version)) {\n throw new Error(`Invalid semantic version: ${version}. Must follow X.Y.Z[-optional] format.`)\n }\n return function (target: Function) {\n Reflect.defineMetadata(VERSION_METADATA_KEY, version, target)\n }\n}\n\nexport function Context() {\n return function (target: any, propertyKey: string, parameterIndex: number) {\n const existingContexts = Reflect.getMetadata(CONTEXT_METADATA_KEY, target, propertyKey) || [];\n existingContexts.push(parameterIndex);\n Reflect.defineMetadata(CONTEXT_METADATA_KEY, existingContexts, target, propertyKey);\n }\n}\n\nexport function Publish(namespace: string, name?: string) {\n return function (target: Function) {\n const original = target\n const serviceIdentifier = new ServiceIdentifier(namespace, name || target.name)\n\n const version = Reflect.getMetadata(VERSION_METADATA_KEY, target)\n if (version) {\n serviceIdentifier.version = version\n }\n\n const newConstructor: any = function (this: any, ...args: any[]) {\n const instance = Reflect.construct(original, args)\n\n const scopeProperty = Reflect.getMetadata(SCOPE_METADATA_KEY, target.prototype)\n if (scopeProperty) {\n const scopeValue = instance[scopeProperty]\n serviceIdentifier.scope = typeof scopeValue === 'function' ? scopeValue.call(instance) : scopeValue\n }\n\n // Register with the singleton Continuum's ServiceRegistry\n Continuum.serviceRegistry.register(serviceIdentifier, instance)\n\n return instance\n }\n\n newConstructor.prototype = original.prototype\n return newConstructor as any\n }\n}\n","/*\n * Copyright 2008-2021 Kinotic and the original author or authors.\n * Licensed under the Apache License, Version 2.0 (the \"License\")\n * See https://www.apache.org/licenses/LICENSE-2.0\n */\n\nimport { createCRI } from '@/core/api/CRI.js'\nimport { EventConstants, IEvent, IEventBus } from '@/core/api/IEventBus.js'\nimport { ServiceIdentifier } from '@/core/api/ServiceIdentifier.js'\nimport { ArgumentResolver, JsonArgumentResolver } from './ArgumentResolver.js'\nimport { EventUtil } from './EventUtil.js'\nimport { BasicReturnValueConverter, ReturnValueConverter } from './ReturnValueConverter.js'\nimport { Subscription } from \"rxjs\"\nimport { createDebugLogger, Logger } from \"./Logger.js\"\nimport { ContextInterceptor, ServiceContext } from '@/core/api/ContextInterceptor.js'\nimport { CONTEXT_METADATA_KEY } from '@/api/ContinuumDecorators.js'\n\n/**\n * Handles invoking services registered with Continuum in TypeScript.\n *\n * @author Navid Mitchell 🤝Grok\n * @since 3/25/2025\n */\nexport class ServiceInvocationSupervisor {\n private readonly log: Logger\n private active: boolean = false\n private readonly eventBusService: IEventBus\n private readonly interceptorProvider: () => ContextInterceptor<any> | null\n private readonly argumentResolver: ArgumentResolver\n private readonly returnValueConverter: ReturnValueConverter\n private readonly serviceIdentifier: ServiceIdentifier\n private readonly serviceInstance: any\n private methodSubscription: Subscription | null = null\n private readonly methodMap: Record<string, (...args: any[]) => any>\n\n constructor(\n serviceIdentifier: ServiceIdentifier,\n serviceInstance: any,\n eventBusService: IEventBus,\n interceptorProvider: () => ContextInterceptor<any> | null,\n options: {\n logger?: Logger\n argumentResolver?: ArgumentResolver\n returnValueConverter?: ReturnValueConverter\n } = {}\n ) {\n if (!serviceIdentifier) throw new Error(\"ServiceIdentifier must not be null\")\n if (!serviceInstance) throw new Error(\"Service instance must not be null\")\n if (!eventBusService) throw new Error(\"EventBusService must not be null\")\n if (!interceptorProvider) throw new Error(\"interceptorProvider must not be null\")\n\n this.serviceIdentifier = serviceIdentifier\n this.serviceInstance = serviceInstance\n this.eventBusService = eventBusService\n this.interceptorProvider = interceptorProvider\n\n this.log = options.logger || createDebugLogger(\"continuum:ServiceInvocationSupervisor\")\n this.argumentResolver = options.argumentResolver || new JsonArgumentResolver()\n this.returnValueConverter = options.returnValueConverter || new BasicReturnValueConverter()\n\n this.methodMap = this.buildMethodMap(serviceInstance)\n }\n\n public isActive(): boolean {\n return this.active\n }\n\n public start(): void {\n if (this.active) {\n throw new Error(\"Service already started\")\n }\n this.active = true\n\n const criBase = this.serviceIdentifier.cri().baseResource()\n this.methodSubscription = this.eventBusService\n .observe(criBase)\n .subscribe({\n next: async (event: IEvent) => {\n await this.processEvent(event);\n },\n error: (error: Error) => {\n this.log.error(\"Event listener error\", error)\n this.active = false\n },\n complete: () => {\n this.log.error(\"Event listener stopped unexpectedly. Setting supervisor inactive.\")\n this.active = false\n },\n })\n\n this.log.info(`ServiceInvocationSupervisor started for ${criBase}`)\n }\n\n public stop(): void {\n if (!this.active) {\n throw new Error(\"Service already stopped\")\n }\n this.active = false\n\n if (this.methodSubscription) {\n this.methodSubscription.unsubscribe()\n this.methodSubscription = null\n }\n\n this.log.info(\"ServiceInvocationSupervisor stopped\")\n }\n\n private buildMethodMap(serviceInstance: any): Record<string, (...args: any[]) => any> {\n const methodMap: Record<string, (...args: any[]) => any> = {}\n for (const key of Object.getOwnPropertyNames(Object.getPrototypeOf(serviceInstance))) {\n const method = serviceInstance[key]\n if (typeof method === \"function\" && key !== \"constructor\") {\n methodMap[key] = method.bind(serviceInstance)\n }\n }\n return methodMap\n }\n\n private async processEvent(event: IEvent): Promise<void> {\n const isControl = event.hasHeader(EventConstants.CONTROL_HEADER)\n this.log.trace(`Service ${isControl ? \"Control\" : \"Invocation\"} requested for ${event.cri}`)\n\n try {\n if (isControl) {\n this.processControlPlaneRequest(event)\n } else {\n if (this.validateReplyTo(event)) {\n await this.processInvocationRequest(event)\n } else {\n this.log.error(`ReplyTo header missing or invalid. Ignoring event: ${JSON.stringify(event)}`)\n }\n }\n } catch (e) {\n this.log.debug(`Exception processing service request: ${JSON.stringify(event)}`, e)\n this.handleException(event, e)\n }\n }\n\n private processControlPlaneRequest(event: IEvent): void {\n const correlationId = event.getHeader(EventConstants.CORRELATION_ID_HEADER)\n if (!correlationId) {\n throw new Error(\"Streaming control plane messages require a CORRELATION_ID_HEADER\")\n }\n this.log.trace(`Processing control event for correlationId: ${correlationId}`)\n }\n\n private async processInvocationRequest(event: IEvent): Promise<void> {\n const path = createCRI(event.cri).path()\n if (!path) {\n throw new Error(\"The methodId must not be blank\")\n }\n\n const handlerMethod = this.methodMap[path]\n if (!handlerMethod) {\n throw new Error(`No method resolved for methodId ${path}`)\n }\n\n const methodName = path;\n const args = this.argumentResolver.resolveArguments(event)\n const contextIndices: number[] = Reflect.getMetadata(CONTEXT_METADATA_KEY, this.serviceInstance, methodName) || [];\n\n // Create context using interceptor\n let context: ServiceContext = {};\n const interceptor = this.interceptorProvider();\n if (interceptor) {\n try {\n context = await interceptor.intercept(event, context);\n } catch (e) {\n this.log.error(`Interceptor failed to create context for event: ${JSON.stringify(event)}`, e)\n this.handleException(event, new Error(\"Internal server error\"))\n return\n }\n }\n\n // Inject context into arguments where @Context is used\n for (const index of contextIndices) {\n args[index] = context;\n }\n\n const expectedArgsCount = handlerMethod.length\n if (args.length !== expectedArgsCount) {\n throw new Error(`Argument count mismatch for method ${path}: expected ${expectedArgsCount}, got ${args.length}`)\n }\n\n let result: any\n try {\n result = handlerMethod(...args)\n if (result instanceof Promise) {\n result.then(\n (resolved) => this.processMethodInvocationResult(event, resolved),\n (error) => this.handleException(event, error)\n )\n } else {\n this.processMethodInvocationResult(event, result)\n }\n } catch (e) {\n this.handleException(event, e)\n }\n }\n\n private processMethodInvocationResult(event: IEvent, result: any): void {\n const outgoingEvent = this.returnValueConverter.convert(event.headers, result)\n this.eventBusService.send(outgoingEvent)\n }\n\n private handleException(event: IEvent, error: any): void {\n const errorEvent = EventUtil.createReplyEvent(\n event.headers,\n new Map([\n [EventConstants.ERROR_HEADER, error.message || \"Unknown error\"],\n [EventConstants.CONTENT_TYPE_HEADER, \"application/json\"]\n ]),\n new TextEncoder().encode(JSON.stringify({ message: error.message }))\n )\n this.eventBusService.send(errorEvent)\n }\n\n private validateReplyTo(event: IEvent): boolean {\n const replyTo = event.getHeader(EventConstants.REPLY_TO_HEADER)\n if (!replyTo) {\n this.log.warn(\"No reply-to header found in event\")\n return false\n }\n if (replyTo.trim() === \"\") {\n this.log.warn(\"Reply-to header must not be blank\")\n return false\n }\n if (!replyTo.startsWith(`${EventConstants.SERVICE_DESTINATION_SCHEME}:`)) {\n this.log.warn(\"Reply-to header must be a valid service destination\")\n return false\n }\n return true\n }\n}\n","/*\n * Copyright 2008-2021 Kinotic and the original author or authors.\n * Licensed under the Apache License, Version 2.0 (the \"License\")\n * See https://www.apache.org/licenses/LICENSE-2.0\n */\n\nimport { ContinuumContextStack } from '@/api/Continuum'\nimport { ServiceIdentifier } from './ServiceIdentifier.js'\nimport { ServiceInvocationSupervisor } from '@/internal/core/api/ServiceInvocationSupervisor.js'\nimport opentelemetry, { SpanKind, SpanStatusCode, Tracer } from '@opentelemetry/api'\nimport {\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n} from '@opentelemetry/semantic-conventions'\nimport { Observable } from 'rxjs'\nimport { first, map } from 'rxjs/operators'\nimport info from '../../../package.json' assert { type: 'json' }\nimport { Event } from './EventBus'\nimport { EventConstants, IEvent, IEventBus } from './IEventBus'\nimport { IEventFactory, IServiceProxy, IServiceRegistry } from './IServiceRegistry'\nimport { ContextInterceptor, ServiceContext } from './ContextInterceptor'\n\n/**\n * An implementation of a {@link IEventFactory} which uses JSON content\n */\nexport class JsonEventFactory implements IEventFactory {\n create(cri: string, args: any[] | null | undefined): IEvent {\n const event: Event = new Event(cri)\n event.setHeader(EventConstants.CONTENT_TYPE_HEADER, EventConstants.CONTENT_JSON)\n if (args != null) {\n event.setDataString(JSON.stringify(args))\n }\n return event\n }\n}\n\n/**\n * An implementation of a {@link IEventFactory} which uses text content\n */\nexport class TextEventFactory implements IEventFactory {\n create(cri: string, args: any[] | null | undefined): IEvent {\n const event: Event = new Event(cri)\n event.setHeader(EventConstants.CONTENT_TYPE_HEADER, EventConstants.CONTENT_TEXT)\n if (args != null) {\n let data: string = ''\n let i = 0\n for (const arg of args) {\n if (i > 0) {\n data = data + '\\n'\n }\n data = data + arg\n i++\n }\n if (data.length > 0) {\n event.setDataString(data)\n }\n }\n return event\n }\n}\n\n/**\n * The default implementation of {@link IServiceRegistry}\n */\nexport class ServiceRegistry implements IServiceRegistry {\n private readonly eventBus: IEventBus\n private readonly supervisors: Map<string, ServiceInvocationSupervisor> = new Map()\n private contextInterceptor: ContextInterceptor<any> | null = null\n\n constructor(eventBus: IEventBus) {\n this.eventBus = eventBus\n }\n\n public serviceProxy(serviceIdentifier: string): IServiceProxy {\n return new ServiceProxy(serviceIdentifier, this.eventBus)\n }\n\n public register(serviceIdentifier: ServiceIdentifier, service: any): void {\n const criString = serviceIdentifier.cri().raw()\n if (!this.supervisors.has(criString)) {\n const supervisor = new ServiceInvocationSupervisor(\n serviceIdentifier,\n service,\n this.eventBus,\n () => this.contextInterceptor\n )\n this.supervisors.set(criString, supervisor)\n supervisor.start()\n }\n }\n\n public unRegister(serviceIdentifier: ServiceIdentifier): void {\n const criString = serviceIdentifier.cri().raw()\n const supervisor = this.supervisors.get(criString)\n if (supervisor) {\n supervisor.stop()\n this.supervisors.delete(criString)\n }\n }\n\n public registerContextInterceptor<T extends ServiceContext>(interceptor: ContextInterceptor<T> | null): void {\n this.contextInterceptor = interceptor\n }\n}\n\n/**\n * The default implementation of {@link IEventFactory} which uses JSON content\n */\nconst defaultEventFactory: IEventFactory = new JsonEventFactory()\n\n/**\n * For internal use only should not be instantiated directly\n */\nclass ServiceProxy implements IServiceProxy {\n public readonly serviceIdentifier: string\n private readonly eventBus: IEventBus\n private tracer: Tracer\n\n constructor(serviceIdentifier: string, eventBus: IEventBus) {\n if (typeof serviceIdentifier === 'undefined' || serviceIdentifier.length === 0) {\n throw new Error('The serviceIdentifier provided must contain a value')\n }\n this.serviceIdentifier = serviceIdentifier\n this.eventBus = eventBus\n this.tracer = opentelemetry.trace.getTracer(\n 'continuum.client',\n info.version\n )\n }\n\n invoke(methodIdentifier: string,\n args?: any[] | null | undefined,\n scope?: string | null | undefined,\n eventFactory?: IEventFactory | null | undefined): Promise<any> {\n return this.tracer.startActiveSpan(\n `${this.serviceIdentifier}/${methodIdentifier}`,\n {\n kind: SpanKind.CLIENT\n },\n async (span) => {\n if (scope) {\n span.setAttribute('continuum.scope', scope)\n }\n span.setAttribute('rpc.system', 'continuum')\n span.setAttribute('rpc.service', this.serviceIdentifier)\n span.setAttribute('rpc.method', methodIdentifier)\n\n return this.__invokeStream(false, methodIdentifier, args, scope, eventFactory)\n .pipe(first())\n .toPromise()\n .then(\n async (value) => {\n span.end()\n return value\n },\n async (ex) => {\n span.recordException(ex)\n span.setStatus({ code: SpanStatusCode.ERROR })\n span.end()\n throw ex\n })\n })\n }\n\n invokeStream(methodIdentifier: string,\n args?: any[] | null | undefined,\n scope?: string | null | undefined,\n eventFactory?: IEventFactory | null | undefined): Observable<any> {\n return this.__invokeStream(true, methodIdentifier, args, scope, eventFactory)\n }\n\n private __invokeStream(sendControlEvents: boolean,\n methodIdentifier: string,\n args?: any[] | null | undefined,\n scope?: string | null | undefined,\n eventFactory?: IEventFactory | null | undefined): Observable<any> {\n const cri: string = EventConstants.SERVICE_DESTINATION_PREFIX + (scope != null ? scope + '@' : '') + this.serviceIdentifier + '/' + methodIdentifier\n let eventFactoryToUse = defaultEventFactory\n if (eventFactory) {\n eventFactoryToUse = eventFactory\n } else if (ContinuumContextStack.getEventFactory()) {\n eventFactoryToUse = ContinuumContextStack.getEventFactory()!\n }\n\n let eventBusToUse = this.eventBus\n if (ContinuumContextStack.getContinuumInstance()) {\n eventBusToUse = ContinuumContextStack.getContinuumInstance()!.eventBus\n }\n\n // store additional attribute if there is an active span\n const span = opentelemetry.trace.getActiveSpan()\n if (span) {\n span.setAttribute(ATTR_SERVER_ADDRESS, eventBusToUse.serverInfo?.host || 'unknown')\n span.setAttribute(ATTR_SERVER_PORT, eventBusToUse.serverInfo?.port || 'unknown')\n }\n\n let event: IEvent = eventFactoryToUse.create(cri, args)\n\n return eventBusToUse.requestStream(event, sendControlEvents)\n .pipe(map<IEvent, any>((value: IEvent): any => {\n const contentType: string | undefined = value.getHeader(EventConstants.CONTENT_TYPE_HEADER)\n if (contentType !== undefined) {\n if (contentType === 'application/json') {\n return JSON.parse(value.getDataString())\n } else if (contentType === 'text/plain') {\n return value.getDataString()\n } else {\n throw new Error('Content Type ' + contentType + ' is not supported')\n }\n } else {\n return null\n }\n }))\n }\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {IterablePage} from '@/core/api/crud/IterablePage'\nimport {Page} from '@/core/api/crud/Page'\nimport {CursorPageable, OffsetPageable, Pageable} from '@/core/api/crud/Pageable'\n\nexport abstract class AbstractIterablePage<T> implements IterablePage<T> {\n\n private readonly pageable: Pageable\n private currentPage: Page<T>\n private firstPage: boolean = true\n\n protected constructor(pageable: Pageable,\n page: Page<T>) {\n this.pageable = pageable\n this.currentPage = page\n }\n\n /**\n * Finds the next page of results based on the given pageable\n * @param pageable to use to find the next page\n * @return the next page of results\n */\n protected abstract findNext(pageable: Pageable): Promise<Page<T>>;\n\n async next(): Promise<IteratorResult<IterablePage<T>>> {\n let ret: IteratorResult<IterablePage<T>>\n\n if(this.firstPage) {\n this.firstPage = false\n // Check has content in case this is an empty page\n // Such as when querying entities with no results\n ret = {done: !this.hasContent(), value: this}\n } else {\n if(this.isOffsetPageable()){\n\n const offsetPageable = this.pageable as OffsetPageable\n offsetPageable.pageNumber++\n\n // ignoring undefined should be fine since OffsetPageable should always have totalElements\n const numPages = Math.ceil(this.totalElements as number / this.pageable.pageSize)\n\n // Check if we are still less than the number of pages\n if(offsetPageable.pageNumber < numPages){\n this.currentPage = await this.findNext(this.pageable)\n ret = {done: false, value: this}\n }else{\n ret = {done: true, value: this}\n }\n }else{\n\n const cursorPageable = this.pageable as CursorPageable\n cursorPageable.cursor = this.currentPage.cursor as string || null\n\n this.currentPage = await this.findNext(this.pageable)\n\n // The last page will have a null cursor, so this will work correctly\n ret = {done: this.isLastPage(), value: this}\n }\n }\n return ret\n }\n\n [Symbol.asyncIterator](): AsyncIterableIterator<IterablePage<T>> {\n return this\n }\n\n hasContent(): boolean {\n return this.currentPage.content !== null && this.currentPage.content !== undefined && this.currentPage.content.length > 0\n }\n\n isLastPage(): boolean {\n let ret: boolean\n if (this.isOffsetPageable()) {\n // ignoring undefined should be fine since OffsetPageable should always have totalElements\n const numPages = Math.ceil(this.totalElements as number / this.pageable.pageSize)\n ret = numPages === (this.pageable as OffsetPageable).pageNumber + 1\n }else{\n ret = !this.firstPage && this.currentPage.cursor === null\n }\n return ret\n }\n\n private isOffsetPageable(): boolean {\n return (this.pageable as OffsetPageable).pageNumber !== undefined\n }\n\n get totalElements(): number | null | undefined {\n return this.currentPage.totalElements\n }\n\n get cursor(): string | null | undefined {\n return this.currentPage.cursor\n }\n\n get content(): T[] | null | undefined {\n return this.currentPage.content\n }\n\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {Identifiable} from '@/api/Identifiable'\nimport {AbstractIterablePage} from '@/core/api/crud/AbstractIterablePage'\nimport {CrudServiceProxy} from '@/core/api/crud/CrudServiceProxy'\nimport {Page} from '@/core/api/crud/Page'\nimport {Pageable} from '@/core/api/crud/Pageable'\n\n/**\n * {@link IterablePage} for use when finding all\n */\nexport class FindAllIterablePage<T extends Identifiable<string>> extends AbstractIterablePage<T> {\n\n private readonly crudServiceProxy: CrudServiceProxy<T>\n\n constructor(pageable: Pageable,\n page: Page<T>,\n crudServiceProxy: CrudServiceProxy<T>) {\n super(pageable, page)\n this.crudServiceProxy = crudServiceProxy\n }\n\n protected findNext(pageable: Pageable): Promise<Page<T>> {\n return this.crudServiceProxy.findAllSinglePage(pageable)\n }\n\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {Identifiable} from '@/api/Identifiable'\nimport {AbstractIterablePage} from '@/core/api/crud/AbstractIterablePage'\nimport {CrudServiceProxy} from '@/core/api/crud/CrudServiceProxy'\nimport {Page} from '@/core/api/crud/Page'\nimport {Pageable} from '@/core/api/crud/Pageable'\n\n/**\n * {@link IterablePage} for use when searching\n */\nexport class SearchIterablePage<T extends Identifiable<string>> extends AbstractIterablePage<T> {\n\n private readonly searchText: string\n private readonly crudServiceProxy: CrudServiceProxy<T>\n\n constructor(pageable: Pageable,\n page: Page<T>,\n searchText: string,\n crudServiceProxy: CrudServiceProxy<T>) {\n super(pageable, page)\n this.searchText = searchText\n this.crudServiceProxy = crudServiceProxy\n }\n\n protected findNext(pageable: Pageable): Promise<Page<T>> {\n return this.crudServiceProxy.searchSinglePage(this.searchText, pageable)\n }\n\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {FindAllIterablePage} from '@/internal/core/api/crud/FindAllIterablePage'\nimport {SearchIterablePage} from '@/internal/core/api/crud/SearchIterablePage'\nimport { ICrudServiceProxy } from './ICrudServiceProxy'\nimport { IServiceProxy } from '../IServiceRegistry'\nimport {Identifiable, IterablePage} from '@/index'\nimport { Page } from './Page'\nimport { Pageable } from './Pageable'\n\nexport class CrudServiceProxy<T extends Identifiable<string>> implements ICrudServiceProxy<T> {\n\n protected serviceProxy: IServiceProxy\n\n constructor(serviceProxy: IServiceProxy) {\n this.serviceProxy = serviceProxy\n }\n\n public count(): Promise<number> {\n return this.serviceProxy.invoke('count')\n }\n\n public create(entity: T): Promise<T> {\n return this.serviceProxy.invoke('create', [entity])\n }\n\n public deleteById(id: string): Promise<void> {\n return this.serviceProxy.invoke('deleteById', [id])\n }\n\n public async findAll(pageable: Pageable): Promise<IterablePage<T>> {\n const page = await this.findAllSinglePage(pageable)\n return new FindAllIterablePage(pageable, page, this)\n }\n\n public findAllSinglePage(pageable: Pageable): Promise<Page<T>> {\n return this.serviceProxy.invoke('findAll', [pageable])\n }\n\n public findById(id: string): Promise<T> {\n return this.serviceProxy.invoke('findById', [id])\n }\n\n public save(entity: T): Promise<T> {\n return this.serviceProxy.invoke('save', [entity])\n }\n\n public findByIdNotIn(ids: string[], page: Pageable): Promise<Page<Identifiable<string>>> {\n return (this.serviceProxy as IServiceProxy).invoke('findByIdNotIn', [ids, page])\n }\n\n public async search(searchText: string, pageable: Pageable): Promise<IterablePage<T>> {\n const page = await this.searchSinglePage(searchText, pageable)\n return new SearchIterablePage(pageable, page, searchText, this)\n }\n\n public searchSinglePage(searchText: string, pageable: Pageable): Promise<Page<T>> {\n return this.serviceProxy.invoke('search', [searchText, pageable])\n }\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ICrudServiceProxyFactory } from './ICrudServiceProxyFactory'\nimport { ICrudServiceProxy } from './ICrudServiceProxy'\nimport { CrudServiceProxy } from './CrudServiceProxy'\nimport { Identifiable } from '@/index'\nimport { IServiceRegistry } from '@/core/api/IServiceRegistry'\n\n\n/**\n * Default implementation of {@link ICrudServiceProxyFactory}\n */\nexport class CrudServiceProxyFactory implements ICrudServiceProxyFactory {\n\n private serviceRegistry: IServiceRegistry\n\n constructor(serviceRegistry: IServiceRegistry) {\n this.serviceRegistry = serviceRegistry\n }\n\n public crudServiceProxy<T extends Identifiable<string>>(serviceIdentifier: string): ICrudServiceProxy<T> {\n if ( typeof serviceIdentifier === 'undefined' || serviceIdentifier.length === 0 ) {\n throw new Error('The serviceIdentifier provided must contain a value')\n }\n return new CrudServiceProxy<T>(this.serviceRegistry.serviceProxy(serviceIdentifier))\n }\n\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { EventBus } from '@/core/api/EventBus'\nimport {IEventBus} from '@/core/api/IEventBus'\nimport { ServiceRegistry } from '@/core/api/ServiceRegistry'\nimport {IEventFactory, IServiceProxy} from '@/core/api/IServiceRegistry'\nimport {Identifiable} from '@/api/Identifiable'\nimport {ICrudServiceProxy} from '@/core/api/crud/ICrudServiceProxy'\nimport {CrudServiceProxyFactory} from '@/core/api/crud/CrudServiceProxyFactory'\nimport {ConnectedInfo} from '@/api/security/ConnectedInfo'\nimport {ConnectionInfo} from '@/api/ConnectionInfo'\n\n\n/**\n * Provides a way to store the current {@link ContinuumSingleton} and {@link IEventFactory} instances\n * This allows the {@link IServiceProxy} instances to dynamically switch between different {@link ContinuumSingleton} and {@link IEventFactory} instances\n */\ntype ContinuumContext = {\n instance?: ContinuumSingleton\n eventFactory?: IEventFactory\n}\n\n/**\n * Interface that defines the methods needed to manage the current {@link ContinuumContext} instance\n */\ninterface IContinuumContextStack {\n /**\n * Returns the current Continuum instance to use for all {@link IServiceProxy} instances invoked with {@link ContinuumContext.execute}\n */\n getContinuumInstance(): ContinuumSingleton | undefined\n\n /**\n * Returns the current event factory to use for all {@link IServiceProxy} instances invoked with {@link ContinuumContext.execute}\n */\n getEventFactory(): IEventFactory | undefined\n}\n\n/**\n * Provides a way to store the current {@link ContinuumContext} instance\n * This is used to allow for {@link IServiceProxy} instances to dynamically switch between different {@link ContinuumSingleton} instances\n */\nclass ContinuumContextStackClass implements IContinuumContextStack {\n\n private continuumOverride: ContinuumContext[] = []\n\n getContinuumInstance(): ContinuumSingleton | undefined {\n return this.continuumOverride[this.continuumOverride.length - 1]?.instance\n }\n\n getEventFactory(): IEventFactory | undefined{\n return this.continuumOverride[this.continuumOverride.length - 1]?.eventFactory\n }\n\n /**\n * Sets the current {@link ContinuumContext} instance to use for all {@link IServiceProxy} instances invoked with {@link ContinuumContext.execute}\n * @param continuumContext\n */\n push(continuumContext: ContinuumContext): void {\n this.continuumOverride.push(continuumContext)\n }\n\n /**\n * Removes the current {@link ContinuumContext} from the stack\n */\n pop(): void {\n this.continuumOverride.pop()\n }\n}\n\n/**\n * The default {@link ContinuumContextStackClass} instance that can be used to manage the current {@link ContinuumContext} instance\n */\nexport const ContinuumContextStack: IContinuumContextStack = new ContinuumContextStackClass()\n\n/**\n * Provides a simplified way to connect to Continuum and access services.\n * All methods use a single connection to the Continuum Services\n */\nexport class ContinuumSingleton {\n /**\n * The {@link IEventBus} that is used to communicate with the Continuum server\n */\n public readonly eventBus!: IEventBus\n /**\n * The {@link ServiceRegistry} that is used to manage the services that are available\n */\n public readonly serviceRegistry!: ServiceRegistry\n /**\n * The {@link CrudServiceProxyFactory} that is used to create {@link ICrudServiceProxy} instances\n */\n public readonly crudServiceProxyFactory!: CrudServiceProxyFactory\n\n constructor() {\n this.eventBus = new EventBus()\n this.serviceRegistry = new ServiceRegistry(this.eventBus)\n this.crudServiceProxyFactory = new CrudServiceProxyFactory(this.serviceRegistry)\n }\n\n /**\n * Requests a connection to the given Stomp url\n * @param connectionInfo provides the information needed to connect to the continuum server\n * @return Promise containing the result of the initial connection attempt\n */\n public connect(connectionInfo: ConnectionInfo): Promise<ConnectedInfo> {\n return this.eventBus.connect(connectionInfo)\n }\n\n /**\n * Disconnects the client from the server\n * This will clear any subscriptions and close the connection\n */\n public disconnect(force?: boolean): Promise<void> {\n return this.eventBus.disconnect(force)\n }\n\n /**\n * Creates a new service proxy that can be used to access the desired service.\n * @param serviceIdentifier the identifier of the service to be accessed\n * @return the {@link IServiceProxy} that can be used to access the service\n */\n public serviceProxy(serviceIdentifier: string): IServiceProxy {\n return this.serviceRegistry.serviceProxy(serviceIdentifier)\n }\n\n /**\n * Returns a {@link ICrudServiceProxy} for the given service identifier\n * @param serviceIdentifier the identifier of the service to be accessed\n */\n public crudServiceProxy<T extends Identifiable<string>>(serviceIdentifier: string): ICrudServiceProxy<T> {\n return this.crudServiceProxyFactory.crudServiceProxy<T>(serviceIdentifier)\n }\n\n /**\n * Allows for the execution of a function that requires a connection to the Continuum server\n * When the function is executed any calls using an {@link IServiceProxy} will be executed using the connection defined by this {@link ContinuumSingleton}\n * @param toExecute the function to execute\n * @param eventFactory an optional {@link IEventFactory} to use for the duration of the execution\n * @return the result of the function that was executed\n * @deprecated we have decided to deprecate this method as it is not thread safe and can cause issues when used in async operations\n * NOTE: this method is experimental and does not work well across multiple threads / async operations\n */\n public async execute(toExecute: () => Promise<any>, eventFactory?: IEventFactory): Promise<any> {\n const stack = ContinuumContextStack as ContinuumContextStackClass\n stack.push({instance: this, eventFactory: eventFactory})\n\n let ret: any\n try {\n ret = await toExecute()\n } finally {\n stack.pop()\n }\n\n return ret\n }\n}\n\n/**\n * The default {@link ContinuumSingleton} instance that can be used to access Continuum services\n */\nexport const Continuum = new ContinuumSingleton()\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport enum LogLevel {\n TRACE = 'TRACE',\n DEBUG = 'DEBUG',\n INFO = 'INFO',\n WARN = 'WARN',\n ERROR = 'ERROR',\n FATAL = 'FATAL',\n OFF = 'OFF'\n}\n\nexport class LoggerLevelsDescriptor {\n public configuredLevel?: LogLevel;\n}\n\nexport class GroupLoggerLevelsDescriptor extends LoggerLevelsDescriptor {\n public members: string[] = [];\n}\n\nexport class SingleLoggerLevelsDescriptor extends LoggerLevelsDescriptor {\n public effectiveLevel?: LogLevel;\n}\n\n/**\n * Description of loggers\n */\nexport class LoggersDescriptor {\n public levels: LogLevel[] = []\n public loggerLevels: Map<string, SingleLoggerLevelsDescriptor> = new Map()\n public groups: Map<string, GroupLoggerLevelsDescriptor> = new Map()\n}\n\n/**\n * Provides the ability to manage loggers\n */\nexport interface ILogManager {\n\n /**\n * @param nodeId the continuum node to get the LoggersDescriptor from\n * @return a {@link LoggersDescriptor} containing all the loggers and their levels\n */\n loggers(nodeId: string): Promise<LoggersDescriptor>\n\n /**\n * @param nodeId the continuum node to get the LoggerLevelsDescriptor from\n * @param name the name of the logger to get\n * @return a {@link LoggerLevelsDescriptor} containing the logger and its levels\n */\n loggerLevels(nodeId: string, name: string): Promise<LoggerLevelsDescriptor>\n\n /**\n * Configures the log level for the logger with the given name\n * @param nodeId the continuum node to set the log level on\n * @param name the name of the logger to set\n * @param level the {@link LogLevel} to set for the logger with the given name\n */\n configureLogLevel(nodeId: string, name: string, level: LogLevel): Promise<void>\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ILogManager,\n LogLevel,\n LoggersDescriptor,\n LoggerLevelsDescriptor,\n SingleLoggerLevelsDescriptor,\n GroupLoggerLevelsDescriptor} from './ILogManager'\nimport { IServiceProxy } from '@/core/api/IServiceRegistry'\nimport { Continuum } from '@/api/Continuum'\n\nexport class LogManager implements ILogManager {\n private readonly serviceProxy: IServiceProxy\n\n constructor() {\n this.serviceProxy = Continuum.serviceProxy('org.kinotic.continuum.api.log.LogManager')\n }\n\n loggers(nodeId: string): Promise<LoggersDescriptor> {\n return this.serviceProxy.invoke('loggers', null, nodeId)\n }\n\n async loggerLevels(nodeId: string, name: string): Promise<LoggerLevelsDescriptor> {\n const data: any = await this.serviceProxy.invoke('loggerLevels', [name], nodeId)\n let ret: LoggerLevelsDescriptor | null = null;\n if(data.hasOwnProperty('members')) {\n ret = new GroupLoggerLevelsDescriptor()\n }else if(data.hasOwnProperty('effectiveLevel')) {\n ret = new SingleLoggerLevelsDescriptor()\n }else{\n ret = new LoggerLevelsDescriptor()\n }\n Object.assign(ret, data)\n return ret\n }\n\n configureLogLevel(nodeId: string, name: string, level: LogLevel): Promise<void> {\n return this.serviceProxy.invoke('configureLogLevel', [name, level], nodeId)\n }\n}\n\nexport const logManager = new LogManager()\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ContinuumError } from './ContinuumError'\n\nexport class AuthenticationError extends ContinuumError {\n\n constructor(message: string) {\n super(message);\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ContinuumError } from './ContinuumError'\n\nexport class AuthorizationError extends ContinuumError {\n\n constructor(message: string) {\n super(message);\n Object.setPrototypeOf(this, AuthorizationError.prototype);\n }\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {Participant} from '@/api/security/Participant'\n\n/**\n * Contains\n */\nexport class ConnectedInfo {\n\n public sessionId!: string;\n\n public replyToId!: string;\n\n public participant!: Participant;\n\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { IParticipant } from './IParticipant'\n\n/**\n * Created by Navid Mitchell on 6/2/20\n */\nexport class Participant implements IParticipant {\n\n public id: string;\n\n public tenantId?: string | null;\n\n public metadata: Map<string, string>;\n\n public roles: string[];\n\n constructor(id: string,\n tenantId?: string,\n metadata?: Map<string, string>,\n roles?: string[]) {\n this.id = id\n this.tenantId = tenantId;\n this.metadata = metadata || new Map();\n this.roles = roles || [];\n }\n\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Some common constants used for the {@link Participant} and {@link Participant#getMetadata()}\n * Created by navid on 2/3/20\n */\nexport class ParticipantConstants {\n static readonly PARTICIPANT_TYPE_METADATA_KEY: string = 'type'\n static readonly PARTICIPANT_TYPE_DEVICE: string = 'device'\n static readonly PARTICIPANT_TYPE_CLI: string = 'cli'\n static readonly PARTICIPANT_TYPE_USER: string = 'user'\n static readonly PARTICIPANT_TYPE_NODE: string = 'node'\n static readonly CLI_PARTICIPANT_ID: string = '-42-Continuum-CLI-42-'\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Identifiable } from '@/index'\n\nexport enum StreamOperation {\n EXISTING = 'EXISTING',\n UPDATE = 'UPDATE',\n REMOVE = 'REMOVE'\n}\n\n/**\n * Holder for domain objects that will be returned as a stream of changes to a data set\n *\n * Created by Navid Mitchell on 6/3/20\n */\nexport class StreamData<I, T> implements Identifiable<I> {\n\n public streamOperation: StreamOperation\n\n public id: I\n\n public value: T\n\n constructor(streamOperation: StreamOperation, id: I, value: T) {\n this.streamOperation = streamOperation\n this.id = id\n this.value = value\n }\n\n public isSet(): boolean {\n return this.value !== null && this.value !== undefined\n }\n\n}\n","import {AbstractIterablePage} from \"./AbstractIterablePage\"\nimport {Page} from \"./Page\"\nimport {Pageable} from \"./Pageable\"\n\nexport class FunctionalIterablePage<T> extends AbstractIterablePage<T> {\n\n private readonly pageFunction: (pageable: Pageable) => Promise<Page<T>>\n\n constructor(pageable: Pageable,\n page: Page<T>,\n pageFunction: (pageable: Pageable) => Promise<Page<T>>) {\n super(pageable, page)\n this.pageFunction = pageFunction\n }\n\n protected findNext(pageable: Pageable): Promise<Page<T>> {\n return this.pageFunction(pageable)\n }\n\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the 'License')\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an 'AS IS' BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {Pageable} from './Pageable'\nimport {Page} from './Page'\nimport {Identifiable, IterablePage} from '@/index'\n\n/**\n * {@link IDataSource} provides an abstract way to retrieve data from various sources\n */\nexport interface IDataSource<T> {\n\n /**\n * Returns a {@link Page} of entities meeting the paging restriction provided in the {@code Pageable} object.\n *\n * @param pageable the page settings to be used\n * @return a {@link Promise} emitting the page of entities\n */\n findAll(pageable: Pageable): Promise<IterablePage<T>>\n\n /**\n * Returns a {@link Page} of entities matching the search text and paging restriction provided in the {@code Pageable} object.\n *\n * @param searchText the text to search for entities for\n * @param pageable the page settings to be used\n * @return a {@link Promise} emitting the page of entities\n */\n search(searchText: string, pageable: Pageable): Promise<IterablePage<T>>\n\n}\n\n\nexport interface IEditableDataSource<T extends Identifiable<string>> extends IDataSource<T>{\n\n /**\n * Creates a new entity if one does not already exist for the given id\n * @param entity to create if one does not already exist\n * @return a {@link Promise} containing the new entity or an error if an exception occurred\n */\n create(entity: T): Promise<T>\n\n /**\n * Saves a given entity. Use the returned instance for further operations as the save operation might have changed the\n * entity instance completely.\n *\n * @param entity must not be {@literal null}.\n * @return a {@link Promise} emitting the saved entity.\n * @throws Error in case the given {@literal entity} is {@literal null}.\n */\n save(entity: T): Promise<T>\n\n /**\n * Retrieves an entity by its id.\n *\n * @param id must not be {@literal null}.\n * @return a {@link Promise} emitting the entity with the given id or {@link Promise#empty()} if none found.\n * @throws IllegalArgumentException in case the given {@literal identity} is {@literal null}.\n */\n findById(id: string): Promise<T>\n\n /**\n * Deletes the entity with the given id.\n *\n * @param id must not be {@literal null}.\n * @return a {@link Promise} signaling when operation has completed.\n * @throws IllegalArgumentException in case the given {@literal identity} is {@literal null}.\n */\n deleteById(id: string): Promise<void>\n\n /**\n * Returns a {@link Page} of entities not in the ids list and meeting the paging restriction provided in the {@code Pageable} object.\n *\n * @param ids not to be returned in the Page\n * @param pageable the page settings to be used\n * @return a {@link Promise} emitting the page of entities\n */\n findByIdNotIn(ids: string[], pageable: Pageable): Promise<Page<Identifiable<string>>>\n}\n\n\nexport class DataSourceUtils {\n\n public static instanceOfEditableDataSource(datasource: IDataSource<any> | IEditableDataSource<any>): datasource is IEditableDataSource<any> {\n return 'create' in datasource\n }\n\n}\n","/*\n * Copyright 2008-2019 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {Sort} from './Sort'\n\n/**\n * Abstract interface for pagination information.\n *\n * Adapted from the Spring Data Commons Package\n *\n * @author Oliver Gierke\n * @author Navid Mitchell\n */\nexport abstract class Pageable {\n\n /**\n * Returns the sorting parameters (optional).\n */\n sort?: Sort | null | undefined = null\n\n /**\n * Returns the number of items to be returned.\n */\n pageSize: number = 25\n\n /**\n * Creates a {@link Pageable} that uses Offset based pagination.\n * @param pageNumber zero based page index.\n * @param pageSize the size of the page to be returned.\n * @param sort the sorting parameters (optional).\n */\n public static create(pageNumber: number, pageSize: number, sort?: Sort | null): OffsetPageable {\n return new OffsetPageable(pageNumber, pageSize, sort)\n }\n\n /**\n * Creates a {@link Pageable} that uses Cursor based pagination.\n * @param cursor the cursor to be used for subsequent retrieval of data, or null if this is the first page.\n * @param pageSize the size of the page to be returned.\n * @param sort the sorting parameters (optional).\n */\n public static createWithCursor(cursor: string | null, pageSize: number, sort?: Sort | null): CursorPageable {\n return new CursorPageable(cursor, pageSize, sort)\n }\n}\n\n/**\n * Implementation of {@link Pageable} that uses Offset based pagination.\n */\nexport class OffsetPageable extends Pageable {\n /**\n * Returns the page to be returned.\n */\n pageNumber: number = 0\n\n /**\n * Creates a {@link Pageable} that uses Offset based pagination.\n * @param pageNumber zero based page index.\n * @param pageSize the size of the page to be returned.\n * @param sort the sorting parameters (optional).\n */\n constructor(pageNumber: number, pageSize: number, sort?: Sort | null) {\n super()\n this.pageNumber = pageNumber\n this.pageSize = pageSize\n this.sort = sort\n }\n}\n\n/**\n * Implementation of {@link Pageable} that uses Cursor based pagination.\n */\nexport class CursorPageable extends Pageable {\n /**\n * The cursor to be used for subsequent retrieval of data, or null if this is the first page.\n */\n cursor: string | null\n\n /**\n * Creates a {@link Pageable} that uses Cursor based pagination.\n * @param cursor the cursor to be used for subsequent retrieval of data, or null if this is the first page.\n * @param pageSize the size of the page to be returned.\n * @param sort the sorting parameters (optional).\n */\n constructor(cursor: string | null, pageSize: number, sort?: Sort | null) {\n super()\n this.cursor = cursor\n this.pageSize = pageSize\n this.sort = sort\n }\n}\n","/*\n * Copyright 2008-2019 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Enumeration for sort directions.\n *\n * Adapted from the Spring Data Commons Package\n *\n * @author Oliver Gierke\n * @author Navid Mitchell\n */\nexport enum Direction {\n ASC = 'ASC',\n DESC = 'DESC'\n}\n\n/**\n * Enumeration for null handling hints that can be used in {@link Order} expressions.\n *\n * Adapted from the Spring Data Commons Package\n *\n * @author Thomas Darimont\n * @author Navid Mitchell\n * @since 1.8\n */\nexport enum NullHandling {\n\n /**\n * Lets the data store decide what to do with nulls.\n */\n NATIVE = 'NATIVE',\n\n /**\n * A hint to the used data store to order entries with null values before non-null entries.\n */\n NULLS_FIRST = 'NULLS_FIRST',\n\n /**\n * A hint to the used data store to order entries with null values after non-null entries.\n */\n NULLS_LAST = 'NULLS_LAST'\n}\n\nexport class Order {\n public property: string\n public direction: Direction = Direction.ASC\n public nullHandling: NullHandling = NullHandling.NATIVE\n\n constructor(property: string, direction: Direction | null) {\n this.property = property\n if (direction !== null) {\n this.direction = direction\n }\n }\n\n /**\n * Returns whether sorting for this property shall be ascending.\n */\n public isAscending(): boolean {\n return this.direction === Direction.ASC\n }\n\n /**\n * Returns whether sorting for this property shall be descending.\n */\n public isDescending(): boolean {\n return this.direction === Direction.DESC\n }\n\n}\n\n/**\n * Sort option for queries. You have to provide at least a list of properties to sort for that must not include\n * {@literal null} or empty strings. The direction defaults to {@link Sort#DEFAULT_DIRECTION}.\n *\n * Adapted from the Spring Data Commons Package\n *\n * @author Oliver Gierke\n * @author Thomas Darimont\n * @author Mark Paluch\n * @author Navid Mitchell\n */\nexport class Sort {\n\n public orders: Order[] = []\n\n}\n"],"names":["ConnectHeaders","ServerInfo","ConnectionInfo","ContinuumError","message","EventConstants","StompConnectionManager","debug","uuidv4","connectionInfo","resolve","reject","url","RxStomp","connectHeadersInternal","stompConfig","headers","key","msg","ReconnectionTimeMode","value","connectedSubscription","errorSubscription","serverHeadersSubscription","connectedInfoJson","connectedInfo","force","randomJitter","Event","cri","data","Optional","uint8Array","ret","EventBus","Subject","map","frame","error","event","carrier","propagation","context","firstValueFrom","sendControlEvents","Observable","subscriber","multicast","serverSignaledCompletion","correlationId","defaultMessagesSubscription","filter","err","controlEvent","throwError","destination","prop","DefaultCRI","args","rawURC","parsed","scheme","scope","resourceName","path","version","result","other","hash","a","c","raw","regex","match","createCRI","JsonArgumentResolver","contentType","EventUtil","incomingHeaders","body","replyCRI","newHeaders","BasicReturnValueConverter","incomingMetadata","returnValue","createDebugLogger","namespace","ServiceIdentifier","name","SCOPE_METADATA_KEY","VERSION_METADATA_KEY","CONTEXT_METADATA_KEY","Scope","target","propertyKey","descriptor","Version","Context","parameterIndex","existingContexts","Publish","original","serviceIdentifier","newConstructor","instance","scopeProperty","scopeValue","Continuum","ServiceInvocationSupervisor","serviceInstance","eventBusService","interceptorProvider","options","criBase","methodMap","method","isControl","e","handlerMethod","methodName","contextIndices","interceptor","index","expectedArgsCount","resolved","outgoingEvent","errorEvent","replyTo","JsonEventFactory","TextEventFactory","arg","ServiceRegistry","eventBus","ServiceProxy","service","criString","supervisor","defaultEventFactory","opentelemetry","info","methodIdentifier","eventFactory","SpanKind","span","first","ex","SpanStatusCode","eventFactoryToUse","ContinuumContextStack","eventBusToUse","ATTR_SERVER_ADDRESS","ATTR_SERVER_PORT","AbstractIterablePage","pageable","page","offsetPageable","numPages","cursorPageable","FindAllIterablePage","crudServiceProxy","SearchIterablePage","searchText","CrudServiceProxy","serviceProxy","entity","id","ids","CrudServiceProxyFactory","serviceRegistry","ContinuumContextStackClass","continuumContext","ContinuumSingleton","toExecute","stack","LogLevel","LoggerLevelsDescriptor","GroupLoggerLevelsDescriptor","SingleLoggerLevelsDescriptor","LoggersDescriptor","LogManager","nodeId","level","logManager","AuthenticationError","AuthorizationError","ConnectedInfo","Participant","tenantId","metadata","roles","ParticipantConstants","StreamOperation","StreamData","streamOperation","FunctionalIterablePage","pageFunction","DataSourceUtils","datasource","Pageable","pageNumber","pageSize","sort","OffsetPageable","cursor","CursorPageable","Direction","NullHandling","Order","property","direction","Sort"],"mappings":";;;;;;;;;;AAsBO,MAAMA,GAAe;AAE5B;AAEO,MAAMC,EAAW;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AACJ;AAKO,MAAMC,WAAuBD,EAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA;AAEJ;ACpCO,MAAME,UAAuB,MAAM;AAAA,EAEtC,YAAYC,GAAiB;AACzB,UAAMA,CAAO,GACb,OAAO,eAAe,MAAMD,EAAe,SAAS;AAAA,EACxD;AACJ;ACwJO,IAAKE,sBAAAA,OACRA,EAAA,sBAAsB,gBACtBA,EAAA,wBAAwB,kBACxBA,EAAA,kBAAkB,YAKlBA,EAAA,qBAAqB,eAKrBA,EAAA,iBAAiB,WAKjBA,EAAA,wBAAwB,kBAMxBA,EAAA,gCAAgC,0BAMhCA,EAAA,wBAAwB,oBAKxBA,EAAA,eAAe,SAKfA,EAAA,kBAAkB,YAKlBA,EAAA,iBAAiB,WAKjBA,EAAA,yBAAyB,YAEzBA,EAAA,uBAAuB,UAEvBA,EAAA,wBAAwB,WAExBA,EAAA,uBAAuB,UAEvBA,EAAA,6BAA6B,UAC7BA,EAAA,6BAA6B,OAC7BA,EAAA,4BAA6B,aAC7BA,EAAA,4BAA4B,UAE5BA,EAAA,eAAe,oBACfA,EAAA,eAAe,cAWfA,EAAA,qBAAqB,eAMrBA,EAAA,oBAAoB,cAjFZA,IAAAA,KAAA,CAAA,CAAA;ACrKL,MAAMC,EAAuB;AAAA,EAEzB,qBAAmC;AAAA;AAAA;AAAA;AAAA,EAInC,+BAAwC;AAAA,EACxC,UAA0B;AAAA,EAChB,0BAAkC;AAAA,EAClC,sBAA8B;AAAA;AAAA,EAC9B,aAAqB;AAAA,EAC9B,qBAA6B;AAAA,EAC7B,8BAAuC;AAAA,EACvC,cAAcC,EAAM,iBAAiB;AAAA,EACrC,YAAYC,EAAA;AAAA,EACJ,aAAcH,EAAe,6BAA6B,KAAK,YAAY,MAAMG,MAAW;AAAA,EACrG,sBAA2C;AAAA;AAAA;AAAA;AAAA,EAKlD,IAAW,SAAkB;AACzB,WAAG,OAAK;AAAA,EAKZ;AAAA;AAAA;AAAA;AAAA,EAKA,IAAW,YAAqB;AAC5B,WAAO,KAAK,WAAW,QAChB,KAAK,QAAQ,UAAA;AAAA,EACxB;AAAA,EAEO,SAASC,GAAwD;AACpE,WAAO,IAAI,QAAQ,CAACC,GAASC,MAAiB;AAE1C,UAAG,CAACF,GAAe;AACf,QAAAE,EAAO,+CAA+C;AACtD;AAAA,MACJ;AAEA,UAAI,CAAEF,EAAe,MAAO;AACxB,QAAAE,EAAO,kBAAkB;AACzB;AAAA,MACJ;AAEA,UAAG,KAAK,SAAS;AACb,QAAAA,EAAO,iCAAiC;AACxC;AAAA,MACJ;AAGA,WAAK,qBAAqB,GAC1B,KAAK,8BAA8B,IACnC,KAAK,qBAAqB,MAC1B,KAAK,+BAA+B;AAEpC,YAAMC,IAAM,QAAQH,EAAe,SAAS,MAAM,MAC5C,QAAQA,EAAe,QACtBA,EAAe,OAAO,MAAMA,EAAe,OAAO,MAAM;AAE/D,WAAK,UAAU,IAAII,EAAA;AAEnB,UAAIC,IAAwC,OAAOL,EAAe,kBAAmB,cAAcA,EAAe,kBAAkB,OAAOA,EAAe,iBAAiB,CAAA;AAE3K,YAAMM,IAA6B;AAAA,QAC/B,WAAWH;AAAA,QACX,gBAAgBE;AAAA,QAChB,mBAAmB;AAAA,QACnB,mBAAmB;AAAA,QACnB,gBAAgB,KAAK;AAAA,QACrB,eAAe,YAA2B;AAEtC,cAAG,OAAOL,EAAe,kBAAmB,YAAW;AACnD,kBAAMO,IAAU,MAAMP,EAAe,eAAA;AACrC,uBAAUQ,KAAOD;AACb,cAAAF,EAAuBG,CAAG,IAAID,EAAQC,CAAG;AAAA,UAEjD;AAQA,cANGR,EAAe,yBACdK,EAAuBT,EAAe,6BAA6B,IAAI,SAE3ES,EAAuBT,EAAe,kBAAkB,IAAI,KAAK,WAG9DI,GAAgB;AAGhB,gBAFC,KAAK,sBAEH,KAAK,qBAAqBA,EAAe;AAOxC,kBAJA,KAAK,+BAA+B,IACpC,MAAM,KAAK,WAAA,GAGR,CAAC,KAAK,6BAA6B;AAClC,oBAAIL,IAAW,KAAK,oBAA4B,UAAW,KAAK,oBAA4B,UAAU;AACtG,gBAAAO,EAAO,8DAA8DP,CAAO,EAAE;AAAA,cAClF;AAAA;AAEA,oBAAM,KAAK,sBAAA;AAAA;AAGd,kBAAM,KAAK,sBAAA;AAAA,QAEpB;AAAA,MAAA;AAGH,MAAG,KAAK,YAAY,YAChBW,EAAY,QAAQ,CAACG,MAAsB;AACvC,aAAK,YAAYA,CAAG;AAAA,MACxB,IAIJ,KAAK,QAAQ,UAAUH,CAAW,GAGlC,KAAK,QAAQ,YAAY,oBAAoB,KAAK,qBAClD,KAAK,QAAQ,YAAY,oBAAoBI,EAAqB,aAGlE,KAAK,QAAQ,iBAAiB,UAAU,CAAAC,MAAS;AAC7C,aAAK,qBAAqBA;AAAA,MAC9B,CAAC;AAGD,YAAMC,IAAsC,KAAK,QAAQ,WAAW,UAAU,MAAK;AAC/E,QAAAA,EAAsB,YAAA,GAElB,KAAK,gCACL,KAAK,8BAA8B;AAAA,MAE3C,CAAC,GAGKC,IAAkC,KAAK,QAAQ,aAAa,UAAU,CAACF,MAAkB;AAC3F,QAAAE,EAAkB,YAAA;AAClB,cAAMlB,IAAUgB,EAAM,QAAQ;AAC9B,aAAK,SAAS,WAAA,GACd,KAAK,UAAU,MACfT,EAAOP,CAAO;AAAA,MAClB,CAAC,GAGKmB,IAA0C,KAAK,QAAQ,eAAe,UAAU,CAACH,MAAwB;AAC3G,YAAII,IAAwCJ,EAAMf,EAAe,qBAAqB;AACtF,YAAImB,KAAqB,MAAM;AAE3B,gBAAMC,IAA+B,KAAK,MAAMD,CAAiB;AAEjE,cAAIf,EAAe;AAoBnB,gBAAS,OAAOA,EAAe,kBAAmB,YAAW;AAEzD,uBAASQ,KAAOH;AACZ,uBAAOA,EAAuBG,CAAG;AAErC,cAAI,KAAK,+BACLP,EAAQe,CAAa;AAAA,YAE7B,MAAA,CAAS,OAAOhB,EAAe,kBAAmB,aAE9Cc,EAA0B,YAAA,GAC1Bb,EAAQe,CAAa;AAAA,mBA7BrBF,EAA0B,YAAA,GAEtBE,EAAc,aAAa,QAAQA,EAAc,aAAa,MAAM;AAGpE,gBAAIhB,EAAe,kBAAkB;AACjC,uBAASQ,KAAOH;AACZ,uBAAOA,EAAuBG,CAAG;AAIzC,YAAAH,EAAuBT,EAAe,cAAc,IAAIoB,EAAc,WAEtEf,EAAQe,CAAa;AAAA,UACzB;AACI,YAAAd,EAAO,wDAAwD;AAAA,QAgB3E;AACI,UAAAA,EAAO,wDAAwD;AAAA,MAEvE,CAAC;AAED,WAAK,QAAQ,SAAA;AAAA,IACjB,CAAC;AAAA,EACL;AAAA,EAEA,MAAa,WAAWe,GAAgC;AACpD,IAAG,KAAK,YACJ,MAAM,KAAK,QAAQ,WAAW,EAAC,OAAAA,GAAa,GACzC,KAAK,uBACJ,KAAK,oBAAA,GAET,KAAK,UAAU;AAAA,EAGvB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,wBAAuC;AACjD,QAAG,KAAK,6BAA6B;AACjC,YAAMC,IAAe,KAAK,OAAA,IAAW,KAAK;AAC1C,kBAAK,YAAY,UAAUA,CAAY,oBAAoB,GACpD,IAAI,QAAQ,CAAAjB,MAAW,WAAWA,GAASiB,CAAY,CAAC;AAAA,IACnE;AAAA,EACJ;AAEJ;ACzMO,MAAMC,EAAwB;AAAA,EAE1B;AAAA,EACA;AAAA,EACA;AAAA,EAEP,YAAYC,GACAb,GACAc,GAAmB;AAE3B,SAAK,MAAMD,GAEPb,MAAY,SACZ,KAAK,UAAUA,IAEf,KAAK,8BAAc,IAAA,GAGvB,KAAK,OAAOe,EAAS,WAAWD,CAAI;AAAA,EACxC;AAAA,EAEO,UAAUb,GAAiC;AAC9C,WAAO,KAAK,QAAQ,IAAIA,CAAG;AAAA,EAC/B;AAAA,EAEO,UAAUA,GAAsB;AACnC,WAAO,KAAK,QAAQ,IAAIA,CAAG;AAAA,EAC/B;AAAA,EAEO,UAAUA,GAAaG,GAAqB;AAC/C,SAAK,QAAQ,IAAIH,GAAKG,CAAK;AAAA,EAC/B;AAAA,EAEO,aAAaH,GAAsB;AACtC,WAAO,KAAK,QAAQ,OAAOA,CAAG;AAAA,EAClC;AAAA,EAEO,cAAca,GAAoB;AACrC,UAAME,IAAa,IAAI,cAAc,OAAOF,CAAI;AAChD,SAAK,OAAOC,EAAS,UAAUC,CAAU;AAAA,EAC7C;AAAA,EAEO,gBAAwB;AAC3B,QAAIC,IAAM;AACV,gBAAK,KAAK,UAAU,CAAEb,MAAWa,IAAM,IAAI,YAAA,EAAc,OAAOb,CAAK,CAAC,GAC/Da;AAAA,EACX;AACJ;AAUO,MAAMC,EAA8B;AAAA,EAEhC;AAAA,EACA,aAAgC;AAAA,EAC/B,yBAAiD,IAAI5B,EAAA;AAAA,EACrD,aAA6B;AAAA,EAC7B,2BAAiE;AAAA,EACjE,wBAAgD;AAAA,EAChD,6BAAkD;AAAA,EAClD,eAAgC,IAAI6B,EAAA;AAAA,EACpC,2BAA4D;AAAA,EAEpE,cAAc;AACV,SAAK,cAAc,KAAK,aACA,KAAKC,EAAmB,CAACC,OACtB,KAAK,WAAA,EACA,MAAM,CAACC,MAAkB;AACtB,MAAG,WACC,QAAQ,MAAM,qCAAqCA,CAAK;AAAA,IAEhE,CAAC,GAEE,IAAInC,EAAekC,EAAM,QAAQ,OAAU,EACrD,CAAC,GACzB,KAAK,uBAAuB,sBAAsB,MAAM;AACpD,WAAK,QAAA;AAAA,IACT;AAAA,EACJ;AAAA,EAEO,qBAA6B;AAChC,WAAO,KAAK,uBAAuB;AAAA,EACvC;AAAA,EAEO,cAAuB;AAC1B,WAAO,KAAK,uBAAuB;AAAA,EACvC;AAAA,EAEA,MAAa,QAAQ5B,GAAwD;AACzE,QAAI,KAAK,uBAAuB;AAmB5B,YAAM,IAAI,MAAM,qCAAqC;AAnBlB;AAGnC,WAAK,QAAA;AAEL,YAAMgB,IAAgB,MAAM,KAAK,uBAAuB,SAAShB,CAAc;AAE/E,kBAAK,aAAa,IAAIR,EAAA,GACtB,KAAK,WAAW,OAAOQ,EAAe,MACtC,KAAK,WAAW,OAAOA,EAAe,MACtC,KAAK,WAAW,SAASA,EAAe,QAGxC,KAAK,aAAa,KAAK,uBAAuB,YAE9C,KAAK,2BAA2B,KAAK,uBAAuB,SAAS,aAAa,UAAU,KAAK,YAAY,GAEtGgB;AAAA,IACX;AAAA,EAGJ;AAAA,EAEA,MAAa,WAAWC,GAAgC;AACpD,UAAM,KAAK,uBAAuB,WAAWA,CAAK,GAElD,KAAK,QAAA;AAAA,EACT;AAAA,EAEO,KAAKa,GAAqB;AAC7B,QAAG,KAAK,uBAAuB,SAAQ;AACnC,YAAMvB,IAAe,CAAA;AAErB,iBAAW,CAACC,GAAKG,CAAK,KAAKmB,EAAM,QAAQ;AACrC,QAAAvB,EAAQC,CAAG,IAAIG;AAGnB,YAAMoB,IAAmB,CAAA;AACzB,MAAAC,EAAY,OAAOC,EAAQ,OAAA,GAAUF,CAAO,GACzCA,EAAQ,gBACPxB,EAAQX,EAAe,kBAAkB,IAAImC,EAAQ,cAEtDA,EAAQ,eACPxB,EAAQX,EAAe,iBAAiB,IAAImC,EAAQ,aAIxD,KAAK,uBAAuB,QAAQ,QAAQ;AAAA,QACI,aAAaD,EAAM;AAAA,QACnB,SAAAvB;AAAA,QACA,YAAYuB,EAAM,KAAK,YAAA;AAAA,MAAY,CACtC;AAAA,IACjD;AACI,YAAM,KAAK,2BAAA;AAAA,EAEnB;AAAA,EAEO,QAAQA,GAAgC;AAC3C,WAAOI,EAAe,KAAK,cAAcJ,GAAO,EAAK,CAAC;AAAA,EAC1D;AAAA,EAEO,cAAcA,GAAeK,IAA6B,IAA0B;AACvF,WAAG,KAAK,wBAAwB,UACrB,IAAIC,EAAmB,CAACC,MAAe;AAE1C,MAAI,KAAK,4BAA4B,SACjC,KAAK,wBAAwB,IAAIX,EAAA,GACjC,KAAK,2BAA2B,KAAK,SAAS,KAAK,UAAoB,EAClC,KAAKY,EAAU,KAAK,qBAAqB,CAAC,GAC/E,KAAK,6BAA6B,KAAK,yBAAyB,QAAA;AAGpE,UAAIC,IAA2B;AAC/B,YAAMC,IAAgBzC,EAAA,GAChB0C,IACM,KAAK,yBACA,KAAKC,EAAO,CAAC/B,MACHA,EAAM,QAAQ,IAAIf,EAAe,qBAAqB,MAAM4C,CACtE,CAAC,EAAE,UAAU;AAAA,QACI,KAAK7B,GAAqB;AAEtB,cAAIA,EAAM,UAAUf,EAAe,cAAc;AAE7C,gBAAIe,EAAM,QAAQ,IAAIf,EAAe,cAAc,MAAM;AACrD,cAAA2C,IAA2B,IAC3BF,EAAW,SAAA;AAAA;AAEX,oBAAM,IAAI,MAAM,oBAAoB1B,EAAM,QAAQ,IAAIf,EAAe,cAAc,IAAI,mBAAmB;AAAA,cAGlH,CAAWe,EAAM,UAAUf,EAAe,YAAY,KAGlD2C,IAA2B,IAC3BF,EAAW,MAAM,IAAI,MAAM1B,EAAM,UAAUf,EAAe,YAAY,CAAC,CAAC,KAIxEyC,EAAW,KAAK1B,CAAK;AAAA,QAG7B;AAAA,QACA,MAAMgC,GAAgB;AAClB,UAAAN,EAAW,MAAMM,CAAG;AAAA,QACxB;AAAA,QACA,WAAiB;AACb,UAAAN,EAAW,SAAA;AAAA,QACf;AAAA,MAAA,CACH;AAE/B,aAAAA,EAAW,IAAII,CAA2B,GAE1CX,EAAM,UAAUlC,EAAe,iBAAiB,KAAK,UAAoB,GACzEkC,EAAM,UAAUlC,EAAe,uBAAuB4C,CAAa,GAEnE,KAAK,KAAKV,CAAK,GAER,MAAM;AACT,YAAIK,KAAqB,CAACI,GAA0B;AAEhD,gBAAMK,IAAsB,IAAIzB,EAAMW,EAAM,GAAG;AAC/C,UAAAc,EAAa,UAAUhD,EAAe,gBAAgBA,EAAe,oBAAoB,GACzFgD,EAAa,UAAUhD,EAAe,uBAAuB4C,CAAa,GAC1E,KAAK,KAAKI,CAAY;AAAA,QAC1B;AAAA,MACJ;AAAA,IACJ,CAAC,IAEMC,EAAW,MAAM,KAAK,4BAA4B;AAAA,EAEjE;AAAA,EAEO,QAAQzB,GAAiC;AAC5C,WAAO,KAAK,SAASA,CAAG;AAAA,EAC5B;AAAA,EAEQ,UAAe;AACnB,IAAI,KAAK,yBAAyB,SAG9B,KAAK,sBAAsB,MAAM,IAAI,MAAM,yBAAyB,CAAC,GAEjE,KAAK,8BAA8B,SACnC,KAAK,2BAA2B,YAAA,GAChC,KAAK,6BAA6B,OAGtC,KAAK,wBAAwB,MAC7B,KAAK,2BAA2B,OAGhC,KAAK,6BACL,KAAK,yBAAyB,YAAA,GAC9B,KAAK,2BAA2B,OAGpC,KAAK,aAAa;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKQ,6BAAoC;AACxC,QAAII,IAAc;AAClB,WAAG,KAAK,uBAAuB,iCAC3BA,IAAM,+DAEH,IAAI,MAAMA,CAAG;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,SAASJ,GAAiC;AAC9C,WAAG,KAAK,wBAAwB,UACrB,KAAK,uBACA,QACA,MAAMA,CAAG,EACT,KAAKO,EAAsB,CAAChC,MAA8B;AAGvD,YAAMY,wBAAmC,IAAA;AACzC,UAAIuC,IAAsB;AAC1B,iBAAWC,KAAQ,OAAO,KAAKpD,EAAQ,OAAO;AAC1C,QAAIoD,MAAS,gBACTD,IAAcnD,EAAQ,QAAQoD,CAAI,IAElCxC,EAAQ,IAAIwC,GAAMpD,EAAQ,QAAQoD,CAAI,CAAC;AAI/C,aAAO,IAAI5B,EAAM2B,GAAavC,GAASZ,EAAQ,UAAU;AAAA,IAC7D,CAAC,CAAC,IAENkD,EAAW,MAAM,KAAK,4BAA4B;AAAA,EAEjE;AAEJ;AC/SO,MAAMG,EAA0B;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAIjB,eAAeC,GAAa;AACxB,QAAIA,EAAK,WAAW,GAAG;AACnB,YAAMC,IAASD,EAAK,CAAC;AACrB,UAAI,OAAOC,KAAW;AAClB,cAAM,IAAI,MAAM,0BAA0B;AAE9C,YAAMC,IAASH,EAAW,SAASE,CAAM;AACzC,WAAK,UAAUC,EAAO,QACtB,KAAK,SAASA,EAAO,OACrB,KAAK,gBAAgBA,EAAO,cAC5B,KAAK,QAAQA,EAAO,MACpB,KAAK,WAAWA,EAAO,SACvB,KAAK,OAAOD;AAAA,IAChB,WAAWD,EAAK,WAAW,GAAG;AAC1B,YAAM,CAACG,GAAQC,GAAOC,GAAcC,GAAMC,CAAO,IAAIP;AACrD,WAAK,UAAUG,GACf,KAAK,SAASC,GACd,KAAK,gBAAgBC,GACrB,KAAK,QAAQC,GACb,KAAK,WAAWC,GAChB,KAAK,OAAOR,EAAW,SAASI,GAAQC,GAAOC,GAAcC,GAAMC,CAAO;AAAA,IAC9E;AACI,YAAM,IAAI,MAAM,8CAA8C;AAGlE,QAAI,CAAC,KAAK,WAAW,CAAC,KAAK;AACvB,YAAM,IAAI,MAAM,2DAA2D,KAAK,IAAI,EAAE;AAAA,EAE9F;AAAA,EAEO,SAAiB;AACpB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEO,QAAuB;AAC1B,WAAO,KAAK;AAAA,EAChB;AAAA,EAEO,WAAoB;AACvB,WAAO,KAAK,WAAW;AAAA,EAC3B;AAAA,EAEO,eAAuB;AAC1B,WAAO,KAAK;AAAA,EAChB;AAAA,EAEO,UAAyB;AAC5B,WAAO,KAAK;AAAA,EAChB;AAAA,EAEO,aAAsB;AACzB,WAAO,KAAK,aAAa;AAAA,EAC7B;AAAA,EAEO,OAAsB;AACzB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEO,UAAmB;AACtB,WAAO,KAAK,UAAU;AAAA,EAC1B;AAAA,EAEO,eAAuB;AAC1B,QAAIC,IAAS,GAAG,KAAK,OAAO;AAC5B,WAAI,KAAK,eACLA,KAAU,GAAG,KAAK,MAAM,MAE5BA,KAAU,KAAK,eACRA;AAAA,EACX;AAAA,EAEO,MAAc;AACjB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEO,OAAOC,GAAqB;AAC/B,WAAI,SAASA,IAAc,KACrBA,aAAiBV,IAChB,KAAK,SAASU,EAAM,IAAA,IADgB;AAAA,EAE/C;AAAA,EAEO,WAAmB;AACtB,QAAIC,IAAO;AACX,WAAAA,IAAOA,IAAO,KAAK,KAAK,KAAK,MAAM,EAAE,EAAE,OAAO,CAACC,GAAGC,MAAMD,IAAIC,EAAE,WAAW,CAAC,GAAG,CAAC,GACvEF;AAAA,EACX;AAAA,EAEO,WAAmB;AACtB,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA,EAGA,OAAe,SAASG,GAMtB;AACE,UAAMC,IAAQ,4DACRC,IAAQF,EAAI,MAAMC,CAAK;AAC7B,QAAI,CAACC;AACD,YAAM,IAAI,MAAM,uBAAuBF,CAAG,EAAE;AAGhD,UAAM,CAAA,EAAGV,GAAQC,GAAOC,GAAcC,GAAMC,CAAO,IAAIQ;AACvD,WAAO;AAAA,MACH,QAAAZ;AAAA,MACA,OAAOC,KAAS;AAAA,MAChB,cAAAC;AAAA,MACA,MAAMC,IAAOA,EAAK,UAAU,CAAC,IAAI;AAAA,MACjC,SAASC,KAAW;AAAA,IAAA;AAAA,EAE5B;AAAA;AAAA,EAGA,OAAe,SACXJ,GACAC,GACAC,GACAC,GACAC,GACM;AACN,QAAIC,IAAS,GAAGL,CAAM;AACtB,WAAIC,MACAI,KAAU,GAAGJ,CAAK,MAEtBI,KAAUH,GACNC,MACAE,KAAU,IAAIF,CAAI,KAElBC,MACAC,KAAU,IAAID,CAAO,KAElBC;AAAA,EACX;AACJ;ACjBO,SAASQ,KAAahB,GAAkB;AAC3C,MAAIA,EAAK,WAAW,EAAG,QAAO,IAAID,EAAWC,EAAK,CAAC,CAAC;AACpD,MAAIA,EAAK,WAAW,EAAG,QAAO,IAAID,EAAWC,EAAK,CAAC,GAAG,MAAMA,EAAK,CAAC,GAAG,MAAM,IAAI;AAC/E,MAAIA,EAAK,WAAW,EAAG,QAAO,IAAID,EAAWC,EAAK,CAAC,GAAGA,EAAK,CAAC,GAAGA,EAAK,CAAC,GAAG,MAAM,IAAI;AAClF,MAAIA,EAAK,WAAW,EAAG,QAAO,IAAID,EAAWC,EAAK,CAAC,GAAGA,EAAK,CAAC,GAAGA,EAAK,CAAC,GAAGA,EAAK,CAAC,GAAGA,EAAK,CAAC,CAAC;AACxF,QAAM,IAAI,MAAM,iCAAiC;AACrD;AC7IO,MAAMiB,EAAiD;AAAA,EAC1D,iBAAiBpC,GAAsB;AACnC,QAAI,KAAK,oBAAoBA,CAAK,GAAG;AACjC,YAAMT,IAAOS,EAAM,cAAA;AACnB,aAAOT,IAAO,KAAK,MAAMA,CAAI,IAAI,CAAA;AAAA,IACrC;AACI,YAAM,IAAI,MAAM,0CAA0C;AAAA,EAElE;AAAA,EAEU,oBAAoBS,GAAwB;AAClD,UAAMqC,IAAcrC,EAAM,UAAUlC,EAAe,mBAAmB;AACtE,WAAOuE,KAAe,QAAQA,MAAgB,MAAMA,MAAgB;AAAA,EACxE;AACJ;ACjBO,MAAMC,EAAU;AAAA,EAEnB,OAAc,iBACVC,GACA9D,GACA+D,GACM;AACN,QAAI,CAACD;AACD,YAAM,IAAI,MAAM,gCAAgC;AAGpD,UAAME,IAAWF,EAAgB,IAAIzE,EAAe,eAAe;AACnE,QAAI,CAAC2E,KAAYA,EAAS,KAAA,MAAW;AACjC,YAAM,IAAI,MAAM,0DAA0D;AAG9E,UAAMC,wBAAiB,IAAA;AACvB,eAAW,CAAChE,GAAKG,CAAK,KAAK0D;AACvB,MAAI7D,EAAI,WAAW,IAAI,KACnBgE,EAAW,IAAIhE,GAAKG,CAAK;AAIjC,QAAIJ;AACA,iBAAW,CAACC,GAAKG,CAAK,KAAKJ;AACvB,QAAAiE,EAAW,IAAIhE,GAAKG,CAAK;AAIjC,WAAO,IAAIQ,EAAMoD,GAAUC,GAAYF,KAAQ,MAAS;AAAA,EAC5D;AACJ;AC5BO,MAAMG,GAA0D;AAAA,EACnE,QAAQC,GAAuCC,GAA0B;AACrE,WAAOP,EAAU;AAAA,MACbM;AAAA,MACA,oBAAI,IAAI,CAAC,CAAC9E,EAAe,qBAAqB,kBAAkB,CAAC,CAAC;AAAA,MAClE,IAAI,YAAA,EAAc,OAAO,KAAK,UAAU+E,CAAW,CAAC;AAAA,IAAA;AAAA,EAE5D;AACJ;ACCO,SAASC,GAAkBC,GAA2B;AACzD,MAAI/E;AACJ,MAAI;AACA,IAAAA,IAAQ,QAAQ,OAAO,EAAE+E,CAAS;AAAA,EACtC,QAAY;AACR,IAAA/E,IAAQ,IAAImD,MAAgB,QAAQ,MAAM,IAAI4B,CAAS,KAAK,GAAG5B,CAAI;AAAA,EACvE;AAEA,SAAO;AAAA,IACH,OAAO,IAAIA,MAASnD,EAAM,SAAS,GAAGmD,CAAI;AAAA,IAC1C,OAAO,IAAIA,MAASnD,EAAM,SAAS,GAAGmD,CAAI;AAAA,IAC1C,MAAM,IAAIA,MAASnD,EAAM,QAAQ,GAAGmD,CAAI;AAAA,IACxC,MAAM,IAAIA,MAASnD,EAAM,QAAQ,GAAGmD,CAAI;AAAA,IACxC,OAAO,IAAIA,MAASnD,EAAM,SAAS,GAAGmD,CAAI;AAAA,EAAA;AAElD;ACxCO,MAAM6B,GAAkB;AAAA,EAEpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACC,OAAmB;AAAA,EAG3B,YAAYD,GAAmBE,GAAc;AACzC,SAAK,YAAYF,GACjB,KAAK,OAAOE;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,gBAAuB;AAC1B,WAAO,KAAK,YAAY,MAAM,KAAK;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,MAAW;AACd,WAAG,KAAK,QAAQ,SACZ,KAAK,OAAOd;AAAA,MACRrE,EAAe;AAAA;AAAA,MACf,KAAK,SAAS;AAAA;AAAA,MACd,KAAK,cAAA;AAAA;AAAA,MACL;AAAA;AAAA,MACA,KAAK,WAAW;AAAA;AAAA,IAAA,IAGjB,KAAK;AAAA,EAChB;AACJ;AC1BA,MAAMoF,2BAA4B,OAAO,GACnCC,2BAA8B,SAAS,GAChCC,2BAA8B,SAAS;AAG7C,SAASC,GAAMC,GAAaC,GAAqBC,GAAiC;AACrF,UAAQ,eAAeN,GAAoBK,GAAaD,CAAM;AAClE;AAEO,SAASG,GAAQ/B,GAAiB;AACrC,MAAI,CAAC,kCAAkC,KAAKA,CAAO;AAC/C,UAAM,IAAI,MAAM,6BAA6BA,CAAO,wCAAwC;AAEhG,SAAO,SAAU4B,GAAkB;AAC/B,YAAQ,eAAeH,GAAsBzB,GAAS4B,CAAM;AAAA,EAChE;AACJ;AAEO,SAASI,KAAU;AACtB,SAAO,SAAUJ,GAAaC,GAAqBI,GAAwB;AACvE,UAAMC,IAAmB,QAAQ,YAAYR,GAAsBE,GAAQC,CAAW,KAAK,CAAA;AAC3F,IAAAK,EAAiB,KAAKD,CAAc,GACpC,QAAQ,eAAeP,GAAsBQ,GAAkBN,GAAQC,CAAW;AAAA,EACtF;AACJ;AAEO,SAASM,GAAQd,GAAmBE,GAAe;AACtD,SAAO,SAAUK,GAAkB;AAC/B,UAAMQ,IAAWR,GACXS,IAAoB,IAAIf,GAAkBD,GAAWE,KAAQK,EAAO,IAAI,GAExE5B,IAAU,QAAQ,YAAYyB,GAAsBG,CAAM;AAChE,IAAI5B,MACAqC,EAAkB,UAAUrC;AAGhC,UAAMsC,IAAsB,YAAwB7C,GAAa;AAC7D,YAAM8C,IAAW,QAAQ,UAAUH,GAAU3C,CAAI,GAE3C+C,IAAgB,QAAQ,YAAYhB,GAAoBI,EAAO,SAAS;AAC9E,UAAIY,GAAe;AACf,cAAMC,IAAaF,EAASC,CAAa;AACzC,QAAAH,EAAkB,QAAQ,OAAOI,KAAe,aAAaA,EAAW,KAAKF,CAAQ,IAAIE;AAAA,MAC7F;AAGA,aAAAC,EAAU,gBAAgB,SAASL,GAAmBE,CAAQ,GAEvDA;AAAA,IACX;AAEA,WAAAD,EAAe,YAAYF,EAAS,WAC7BE;AAAA,EACX;AACJ;AC/CO,MAAMK,GAA4B;AAAA,EACpB;AAAA,EACT,SAAkB;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACT,qBAA0C;AAAA,EACjC;AAAA,EAEjB,YACIN,GACAO,GACAC,GACAC,GACAC,IAII,IACN;AACE,QAAI,CAACV,EAAmB,OAAM,IAAI,MAAM,oCAAoC;AAC5E,QAAI,CAACO,EAAiB,OAAM,IAAI,MAAM,mCAAmC;AACzE,QAAI,CAACC,EAAiB,OAAM,IAAI,MAAM,kCAAkC;AACxE,QAAI,CAACC,EAAqB,OAAM,IAAI,MAAM,sCAAsC;AAEhF,SAAK,oBAAoBT,GACzB,KAAK,kBAAkBO,GACvB,KAAK,kBAAkBC,GACvB,KAAK,sBAAsBC,GAE3B,KAAK,MAAMC,EAAQ,UAAU3B,GAAkB,uCAAuC,GACtF,KAAK,mBAAmB2B,EAAQ,oBAAoB,IAAIrC,EAAA,GACxD,KAAK,uBAAuBqC,EAAQ,wBAAwB,IAAI9B,GAAA,GAEhE,KAAK,YAAY,KAAK,eAAe2B,CAAe;AAAA,EACxD;AAAA,EAEO,WAAoB;AACvB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEO,QAAc;AACjB,QAAI,KAAK;AACL,YAAM,IAAI,MAAM,yBAAyB;AAE7C,SAAK,SAAS;AAEd,UAAMI,IAAU,KAAK,kBAAkB,IAAA,EAAM,aAAA;AAC7C,SAAK,qBAAqB,KAAK,gBACA,QAAQA,CAAO,EACf,UAAU;AAAA,MACI,MAAM,OAAO1E,MAAkB;AAC3B,cAAM,KAAK,aAAaA,CAAK;AAAA,MACjC;AAAA,MACA,OAAO,CAACD,MAAiB;AACrB,aAAK,IAAI,MAAM,wBAAwBA,CAAK,GAC5C,KAAK,SAAS;AAAA,MAClB;AAAA,MACA,UAAU,MAAM;AACZ,aAAK,IAAI,MAAM,mEAAmE,GAClF,KAAK,SAAS;AAAA,MAClB;AAAA,IAAA,CACH,GAE1C,KAAK,IAAI,KAAK,2CAA2C2E,CAAO,EAAE;AAAA,EACtE;AAAA,EAEO,OAAa;AAChB,QAAI,CAAC,KAAK;AACN,YAAM,IAAI,MAAM,yBAAyB;AAE7C,SAAK,SAAS,IAEV,KAAK,uBACL,KAAK,mBAAmB,YAAA,GACxB,KAAK,qBAAqB,OAG9B,KAAK,IAAI,KAAK,qCAAqC;AAAA,EACvD;AAAA,EAEQ,eAAeJ,GAA+D;AAClF,UAAMK,IAAqD,CAAA;AAC3D,eAAWjG,KAAO,OAAO,oBAAoB,OAAO,eAAe4F,CAAe,CAAC,GAAG;AAClF,YAAMM,IAASN,EAAgB5F,CAAG;AAClC,MAAI,OAAOkG,KAAW,cAAclG,MAAQ,kBACxCiG,EAAUjG,CAAG,IAAIkG,EAAO,KAAKN,CAAe;AAAA,IAEpD;AACA,WAAOK;AAAA,EACX;AAAA,EAEA,MAAc,aAAa3E,GAA8B;AACrD,UAAM6E,IAAY7E,EAAM,UAAUlC,EAAe,cAAc;AAC/D,SAAK,IAAI,MAAM,WAAW+G,IAAY,YAAY,YAAY,kBAAkB7E,EAAM,GAAG,EAAE;AAE3F,QAAI;AACA,MAAI6E,IACA,KAAK,2BAA2B7E,CAAK,IAEjC,KAAK,gBAAgBA,CAAK,IAC1B,MAAM,KAAK,yBAAyBA,CAAK,IAEzC,KAAK,IAAI,MAAM,sDAAsD,KAAK,UAAUA,CAAK,CAAC,EAAE;AAAA,IAGxG,SAAS8E,GAAG;AACR,WAAK,IAAI,MAAM,yCAAyC,KAAK,UAAU9E,CAAK,CAAC,IAAI8E,CAAC,GAClF,KAAK,gBAAgB9E,GAAO8E,CAAC;AAAA,IACjC;AAAA,EACJ;AAAA,EAEQ,2BAA2B9E,GAAqB;AACpD,UAAMU,IAAgBV,EAAM,UAAUlC,EAAe,qBAAqB;AAC1E,QAAI,CAAC4C;AACD,YAAM,IAAI,MAAM,kEAAkE;AAEtF,SAAK,IAAI,MAAM,+CAA+CA,CAAa,EAAE;AAAA,EACjF;AAAA,EAEA,MAAc,yBAAyBV,GAA8B;AACjE,UAAMyB,IAAOU,EAAUnC,EAAM,GAAG,EAAE,KAAA;AAClC,QAAI,CAACyB;AACD,YAAM,IAAI,MAAM,gCAAgC;AAGpD,UAAMsD,IAAgB,KAAK,UAAUtD,CAAI;AACzC,QAAI,CAACsD;AACD,YAAM,IAAI,MAAM,mCAAmCtD,CAAI,EAAE;AAG7D,UAAMuD,IAAavD,GACbN,IAAO,KAAK,iBAAiB,iBAAiBnB,CAAK,GACnDiF,IAA2B,QAAQ,YAAY7B,GAAsB,KAAK,iBAAiB4B,CAAU,KAAK,CAAA;AAGhH,QAAI7E,IAA0B,CAAA;AAC9B,UAAM+E,IAAc,KAAK,oBAAA;AACzB,QAAIA;AACA,UAAI;AACA,QAAA/E,IAAU,MAAM+E,EAAY,UAAUlF,GAAOG,CAAO;AAAA,MACxD,SAAS2E,GAAG;AACR,aAAK,IAAI,MAAM,mDAAmD,KAAK,UAAU9E,CAAK,CAAC,IAAI8E,CAAC,GAC5F,KAAK,gBAAgB9E,GAAO,IAAI,MAAM,uBAAuB,CAAC;AAC9D;AAAA,MACJ;AAIJ,eAAWmF,KAASF;AAChB,MAAA9D,EAAKgE,CAAK,IAAIhF;AAGlB,UAAMiF,IAAoBL,EAAc;AACxC,QAAI5D,EAAK,WAAWiE;AAChB,YAAM,IAAI,MAAM,sCAAsC3D,CAAI,cAAc2D,CAAiB,SAASjE,EAAK,MAAM,EAAE;AAGnH,QAAIQ;AACJ,QAAI;AACA,MAAAA,IAASoD,EAAc,GAAG5D,CAAI,GAC1BQ,aAAkB,UAClBA,EAAO;AAAA,QACH,CAAC0D,MAAa,KAAK,8BAA8BrF,GAAOqF,CAAQ;AAAA,QAChE,CAACtF,MAAU,KAAK,gBAAgBC,GAAOD,CAAK;AAAA,MAAA,IAGhD,KAAK,8BAA8BC,GAAO2B,CAAM;AAAA,IAExD,SAASmD,GAAG;AACR,WAAK,gBAAgB9E,GAAO8E,CAAC;AAAA,IACjC;AAAA,EACJ;AAAA,EAEQ,8BAA8B9E,GAAe2B,GAAmB;AACpE,UAAM2D,IAAgB,KAAK,qBAAqB,QAAQtF,EAAM,SAAS2B,CAAM;AAC7E,SAAK,gBAAgB,KAAK2D,CAAa;AAAA,EAC3C;AAAA,EAEQ,gBAAgBtF,GAAeD,GAAkB;AACrD,UAAMwF,IAAajD,EAAU;AAAA,MACzBtC,EAAM;AAAA,0BACF,IAAI;AAAA,QACI,CAAClC,EAAe,cAAciC,EAAM,WAAW,eAAe;AAAA,QAC9D,CAACjC,EAAe,qBAAqB,kBAAkB;AAAA,MAAA,CAC1D;AAAA,MACT,IAAI,YAAA,EAAc,OAAO,KAAK,UAAU,EAAE,SAASiC,EAAM,SAAS,CAAC;AAAA,IAAA;AAEvE,SAAK,gBAAgB,KAAKwF,CAAU;AAAA,EACxC;AAAA,EAEQ,gBAAgBvF,GAAwB;AAC5C,UAAMwF,IAAUxF,EAAM,UAAUlC,EAAe,eAAe;AAC9D,WAAK0H,IAIDA,EAAQ,KAAA,MAAW,MACnB,KAAK,IAAI,KAAK,mCAAmC,GAC1C,MAENA,EAAQ,WAAW,GAAG1H,EAAe,0BAA0B,GAAG,IAIhE,MAHH,KAAK,IAAI,KAAK,qDAAqD,GAC5D,OATP,KAAK,IAAI,KAAK,mCAAmC,GAC1C;AAAA,EAWf;AACJ;;;;AChNO,MAAM2H,GAA0C;AAAA,EACnD,OAAOnG,GAAa6B,GAAwC;AACxD,UAAMnB,IAAe,IAAIX,EAAMC,CAAG;AAClC,WAAAU,EAAM,UAAUlC,EAAe,qBAAqBA,EAAe,YAAY,GAC3EqD,KAAQ,QACRnB,EAAM,cAAc,KAAK,UAAUmB,CAAI,CAAC,GAErCnB;AAAA,EACX;AACJ;AAKO,MAAM0F,GAA0C;AAAA,EACnD,OAAOpG,GAAa6B,GAAwC;AACxD,UAAMnB,IAAe,IAAIX,EAAMC,CAAG;AAElC,QADAU,EAAM,UAAUlC,EAAe,qBAAqBA,EAAe,YAAY,GAC3EqD,KAAQ,MAAM;AACd,UAAI5B,IAAe,IACf,IAAI;AACR,iBAAWoG,KAAOxE;AACd,QAAI,IAAI,MACJ5B,IAAOA,IAAO;AAAA,IAElBA,IAAOA,IAAOoG,GACd;AAEJ,MAAIpG,EAAK,SAAS,KACdS,EAAM,cAAcT,CAAI;AAAA,IAEhC;AACA,WAAOS;AAAA,EACX;AACJ;AAKO,MAAM4F,GAA4C;AAAA,EACpC;AAAA,EACA,kCAA4D,IAAA;AAAA,EACrE,qBAAqD;AAAA,EAE7D,YAAYC,GAAqB;AAC7B,SAAK,WAAWA;AAAA,EACpB;AAAA,EAEO,aAAa9B,GAA0C;AAC1D,WAAO,IAAI+B,GAAa/B,GAAmB,KAAK,QAAQ;AAAA,EAC5D;AAAA,EAEO,SAASA,GAAsCgC,GAAoB;AACtE,UAAMC,IAAYjC,EAAkB,IAAA,EAAM,IAAA;AAC1C,QAAI,CAAC,KAAK,YAAY,IAAIiC,CAAS,GAAG;AAClC,YAAMC,IAAa,IAAI5B;AAAA,QACnBN;AAAA,QACAgC;AAAA,QACA,KAAK;AAAA,QACL,MAAM,KAAK;AAAA,MAAA;AAEf,WAAK,YAAY,IAAIC,GAAWC,CAAU,GAC1CA,EAAW,MAAA;AAAA,IACf;AAAA,EACJ;AAAA,EAEO,WAAWlC,GAA4C;AAC1D,UAAMiC,IAAYjC,EAAkB,IAAA,EAAM,IAAA,GACpCkC,IAAa,KAAK,YAAY,IAAID,CAAS;AACjD,IAAIC,MACAA,EAAW,KAAA,GACX,KAAK,YAAY,OAAOD,CAAS;AAAA,EAEzC;AAAA,EAEO,2BAAqDd,GAAiD;AACzG,SAAK,qBAAqBA;AAAA,EAC9B;AACJ;AAKA,MAAMgB,KAAqC,IAAIT,GAAA;AAK/C,MAAMK,GAAsC;AAAA,EACxB;AAAA,EACC;AAAA,EACT;AAAA,EAER,YAAY/B,GAA2B8B,GAAqB;AACxD,QAAI,OAAO9B,IAAsB,OAAeA,EAAkB,WAAW;AACzE,YAAM,IAAI,MAAM,qDAAqD;AAEzE,SAAK,oBAAoBA,GACzB,KAAK,WAAW8B,GAChB,KAAK,SAASM,EAAc,MAAM;AAAA,MAC9B;AAAA,MACAC,GAAK;AAAA,IAAA;AAAA,EAEb;AAAA,EAEA,OAAOC,GACAlF,GACAI,GACA+E,GAA+D;AAClE,WAAO,KAAK,OAAO;AAAA,MACf,GAAG,KAAK,iBAAiB,IAAID,CAAgB;AAAA,MAC7C;AAAA,QACI,MAAME,EAAS;AAAA,MAAA;AAAA,MAEnB,OAAOC,OACCjF,KACAiF,EAAK,aAAa,mBAAmBjF,CAAK,GAE9CiF,EAAK,aAAa,cAAc,WAAW,GAC3CA,EAAK,aAAa,eAAe,KAAK,iBAAiB,GACvDA,EAAK,aAAa,cAAcH,CAAgB,GAEzC,KAAK,eAAe,IAAOA,GAAkBlF,GAAMI,GAAO+E,CAAY,EACjE,KAAKG,EAAA,CAAO,EACZ,YACA;AAAA,QACG,OAAO5H,OACH2H,EAAK,IAAA,GACE3H;AAAA,QAEX,OAAO6H,MAAO;AACV,gBAAAF,EAAK,gBAAgBE,CAAE,GACvBF,EAAK,UAAU,EAAE,MAAMG,EAAe,OAAO,GAC7CH,EAAK,IAAA,GACCE;AAAA,QACV;AAAA,MAAA;AAAA,IACnB;AAAA,EACR;AAAA,EAEA,aAAaL,GACAlF,GACAI,GACA+E,GAAkE;AAC3E,WAAO,KAAK,eAAe,IAAMD,GAAkBlF,GAAMI,GAAO+E,CAAY;AAAA,EAChF;AAAA,EAEQ,eAAejG,GACAgG,GACAlF,GACAI,GACA+E,GAAkE;AACrF,UAAMhH,IAAcxB,EAAe,8BAA8ByD,KAAS,OAAOA,IAAQ,MAAM,MAAM,KAAK,oBAAoB,MAAM8E;AACpI,QAAIO,IAAoBV;AACxB,IAAII,IACAM,IAAoBN,IACbO,EAAsB,sBAC7BD,IAAoBC,EAAsB,gBAAA;AAG9C,QAAIC,IAAgB,KAAK;AACzB,IAAID,EAAsB,2BACtBC,IAAgBD,EAAsB,uBAAwB;AAIlE,UAAML,IAAOL,EAAc,MAAM,cAAA;AACjC,IAAIK,MACAA,EAAK,aAAaO,GAAqBD,EAAc,YAAY,QAAQ,SAAS,GAClFN,EAAK,aAAaQ,GAAkBF,EAAc,YAAY,QAAQ,SAAS;AAGnF,QAAI9G,IAAgB4G,EAAkB,OAAOtH,GAAK6B,CAAI;AAEtD,WAAO2F,EAAc,cAAc9G,GAAOK,CAAiB,EACtC,KAAKR,EAAiB,CAAChB,MAAuB;AAC3C,YAAMwD,IAAkCxD,EAAM,UAAUf,EAAe,mBAAmB;AAC1F,UAAIuE,MAAgB,QAAW;AAC3B,YAAIA,MAAgB;AAChB,iBAAO,KAAK,MAAMxD,EAAM,cAAA,CAAe;AAC3C,YAAWwD,MAAgB;AACvB,iBAAOxD,EAAM,cAAA;AAEb,cAAM,IAAI,MAAM,kBAAkBwD,IAAc,mBAAmB;AAAA,MAE3E;AACI,eAAO;AAAA,IAEf,CAAC,CAAC;AAAA,EAC1B;AACJ;ACjMO,MAAe4E,EAAmD;AAAA,EAEpD;AAAA,EACT;AAAA,EACA,YAAqB;AAAA,EAEnB,YAAYC,GACAC,GAAe;AACjC,SAAK,WAAWD,GAChB,KAAK,cAAcC;AAAA,EACvB;AAAA,EASA,MAAM,OAAiD;AACnD,QAAIzH;AAEJ,QAAG,KAAK;AACJ,WAAK,YAAY,IAGjBA,IAAM,EAAC,MAAM,CAAC,KAAK,WAAA,GAAc,OAAO,KAAA;AAAA,aAErC,KAAK,oBAAmB;AAEvB,YAAM0H,IAAiB,KAAK;AAC5B,MAAAA,EAAe;AAGf,YAAMC,IAAW,KAAK,KAAK,KAAK,gBAA0B,KAAK,SAAS,QAAQ;AAGhF,MAAGD,EAAe,aAAaC,KAC3B,KAAK,cAAc,MAAM,KAAK,SAAS,KAAK,QAAQ,GACpD3H,IAAM,EAAC,MAAM,IAAO,OAAO,KAAA,KAE3BA,IAAM,EAAC,MAAM,IAAM,OAAO,KAAA;AAAA,IAElC,OAAK;AAED,YAAM4H,IAAiB,KAAK;AAC5B,MAAAA,EAAe,SAAS,KAAK,YAAY,UAAoB,MAE7D,KAAK,cAAc,MAAM,KAAK,SAAS,KAAK,QAAQ,GAGpD5H,IAAM,EAAC,MAAM,KAAK,WAAA,GAAc,OAAO,KAAA;AAAA,IAC3C;AAEJ,WAAOA;AAAA,EACX;AAAA,EAEA,CAAC,OAAO,aAAa,IAA4C;AAC7D,WAAO;AAAA,EACX;AAAA,EAEA,aAAsB;AAClB,WAAO,KAAK,YAAY,YAAY,QAAQ,KAAK,YAAY,YAAY,UAAa,KAAK,YAAY,QAAQ,SAAS;AAAA,EAC5H;AAAA,EAEA,aAAsB;AAClB,QAAIA;AACJ,WAAI,KAAK,qBAGLA,IADiB,KAAK,KAAK,KAAK,gBAA0B,KAAK,SAAS,QAAQ,MAC5D,KAAK,SAA4B,aAAa,IAElEA,IAAM,CAAC,KAAK,aAAa,KAAK,YAAY,WAAW,MAElDA;AAAA,EACX;AAAA,EAEQ,mBAA4B;AAChC,WAAQ,KAAK,SAA4B,eAAe;AAAA,EAC5D;AAAA,EAEA,IAAI,gBAA2C;AAC3C,WAAO,KAAK,YAAY;AAAA,EAC5B;AAAA,EAEA,IAAI,SAAoC;AACpC,WAAO,KAAK,YAAY;AAAA,EAC5B;AAAA,EAEA,IAAI,UAAkC;AAClC,WAAO,KAAK,YAAY;AAAA,EAC5B;AAEJ;ACxFO,MAAM6H,WAA4DN,EAAwB;AAAA,EAE5E;AAAA,EAEjB,YAAYC,GACAC,GACAK,GAAuC;AAC/C,UAAMN,GAAUC,CAAI,GACpB,KAAK,mBAAmBK;AAAA,EAC5B;AAAA,EAEU,SAASN,GAAsC;AACrD,WAAO,KAAK,iBAAiB,kBAAkBA,CAAQ;AAAA,EAC3D;AAEJ;ACfO,MAAMO,WAA2DR,EAAwB;AAAA,EAE3E;AAAA,EACA;AAAA,EAEjB,YAAYC,GACAC,GACAO,GACAF,GAAuC;AAC/C,UAAMN,GAAUC,CAAI,GACpB,KAAK,aAAaO,GAClB,KAAK,mBAAmBF;AAAA,EAC5B;AAAA,EAEU,SAASN,GAAsC;AACrD,WAAO,KAAK,iBAAiB,iBAAiB,KAAK,YAAYA,CAAQ;AAAA,EAC3E;AAEJ;ACnBO,MAAMS,GAAiF;AAAA,EAEhF;AAAA,EAEV,YAAYC,GAA6B;AACrC,SAAK,eAAeA;AAAA,EACxB;AAAA,EAEO,QAAyB;AAC5B,WAAO,KAAK,aAAa,OAAO,OAAO;AAAA,EAC3C;AAAA,EAEO,OAAOC,GAAuB;AACjC,WAAO,KAAK,aAAa,OAAO,UAAU,CAACA,CAAM,CAAC;AAAA,EACtD;AAAA,EAEO,WAAWC,GAA2B;AACzC,WAAO,KAAK,aAAa,OAAO,cAAc,CAACA,CAAE,CAAC;AAAA,EACtD;AAAA,EAEA,MAAa,QAAQZ,GAA8C;AAC/D,UAAMC,IAAO,MAAM,KAAK,kBAAkBD,CAAQ;AAClD,WAAO,IAAIK,GAAoBL,GAAUC,GAAM,IAAI;AAAA,EACvD;AAAA,EAEO,kBAAkBD,GAAsC;AAC3D,WAAO,KAAK,aAAa,OAAO,WAAW,CAACA,CAAQ,CAAC;AAAA,EACzD;AAAA,EAEO,SAASY,GAAwB;AACpC,WAAO,KAAK,aAAa,OAAO,YAAY,CAACA,CAAE,CAAC;AAAA,EACpD;AAAA,EAEO,KAAKD,GAAuB;AAC/B,WAAO,KAAK,aAAa,OAAO,QAAQ,CAACA,CAAM,CAAC;AAAA,EACpD;AAAA,EAEO,cAAcE,GAAeZ,GAAqD;AACrF,WAAQ,KAAK,aAA+B,OAAO,iBAAiB,CAACY,GAAKZ,CAAI,CAAC;AAAA,EACnF;AAAA,EAEA,MAAa,OAAOO,GAAoBR,GAA8C;AAClF,UAAMC,IAAO,MAAM,KAAK,iBAAiBO,GAAYR,CAAQ;AAC7D,WAAO,IAAIO,GAAmBP,GAAUC,GAAMO,GAAY,IAAI;AAAA,EAClE;AAAA,EAEO,iBAAiBA,GAAoBR,GAAsC;AAC9E,WAAO,KAAK,aAAa,OAAO,UAAU,CAACQ,GAAYR,CAAQ,CAAC;AAAA,EACpE;AACJ;AC/CO,MAAMc,GAA4D;AAAA,EAE7D;AAAA,EAER,YAAYC,GAAmC;AAC3C,SAAK,kBAAkBA;AAAA,EAC3B;AAAA,EAEO,iBAAiDlE,GAAiD;AACrG,QAAK,OAAOA,IAAsB,OAAeA,EAAkB,WAAW;AAC1E,YAAM,IAAI,MAAM,qDAAqD;AAEzE,WAAO,IAAI4D,GAAoB,KAAK,gBAAgB,aAAa5D,CAAiB,CAAC;AAAA,EACvF;AAEJ;ACcA,MAAMmE,GAA6D;AAAA,EAEvD,oBAAwC,CAAA;AAAA,EAEhD,uBAAuD;AACnD,WAAO,KAAK,kBAAkB,KAAK,kBAAkB,SAAS,CAAC,GAAG;AAAA,EACtE;AAAA,EAEA,kBAA4C;AACxC,WAAO,KAAK,kBAAkB,KAAK,kBAAkB,SAAS,CAAC,GAAG;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAKC,GAA0C;AAC3C,SAAK,kBAAkB,KAAKA,CAAgB;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAY;AACR,SAAK,kBAAkB,IAAA;AAAA,EAC3B;AACJ;AAKO,MAAMtB,IAAgD,IAAIqB,GAAA;AAM1D,MAAME,GAAmB;AAAA;AAAA;AAAA;AAAA,EAIZ;AAAA;AAAA;AAAA;AAAA,EAIA;AAAA;AAAA;AAAA;AAAA,EAIA;AAAA,EAEhB,cAAc;AACV,SAAK,WAAW,IAAIzI,EAAA,GACpB,KAAK,kBAAkB,IAAIiG,GAAgB,KAAK,QAAQ,GACxD,KAAK,0BAA0B,IAAIoC,GAAwB,KAAK,eAAe;AAAA,EACnF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,QAAQ9J,GAAwD;AACpE,WAAO,KAAK,SAAS,QAAQA,CAAc;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,WAAWiB,GAAgC;AAC9C,WAAO,KAAK,SAAS,WAAWA,CAAK;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,aAAa4E,GAA0C;AAC1D,WAAO,KAAK,gBAAgB,aAAaA,CAAiB;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,iBAAiDA,GAAiD;AACrG,WAAO,KAAK,wBAAwB,iBAAoBA,CAAiB;AAAA,EAC7E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAa,QAAQsE,GAA+B/B,GAA4C;AAC5F,UAAMgC,IAAQzB;AACd,IAAAyB,EAAM,KAAK,EAAC,UAAU,MAAM,cAAAhC,GAA2B;AAEvD,QAAI5G;AACJ,QAAI;AACA,MAAAA,IAAM,MAAM2I,EAAA;AAAA,IAChB,UAAA;AACI,MAAAC,EAAM,IAAA;AAAA,IACV;AAEA,WAAO5I;AAAA,EACX;AACJ;AAKO,MAAM0E,IAAY,IAAIgE,GAAA;AC7JtB,IAAKG,uBAAAA,OACRA,EAAA,QAAQ,SACRA,EAAA,QAAQ,SACRA,EAAA,OAAO,QACPA,EAAA,OAAO,QACPA,EAAA,QAAQ,SACRA,EAAA,QAAQ,SACRA,EAAA,MAAM,OAPEA,IAAAA,MAAA,CAAA,CAAA;AAUL,MAAMC,EAAuB;AAAA,EACzB;AACX;AAEO,MAAMC,WAAoCD,EAAuB;AAAA,EAC7D,UAAoB,CAAA;AAC/B;AAEO,MAAME,WAAqCF,EAAuB;AAAA,EAC9D;AACX;AAKO,MAAMG,GAAkB;AAAA,EACpB,SAAqB,CAAA;AAAA,EACrB,mCAA8D,IAAA;AAAA,EAC9D,6BAAuD,IAAA;AAClE;ACpBO,MAAMC,GAAkC;AAAA,EAC1B;AAAA,EAEjB,cAAc;AACV,SAAK,eAAexE,EAAU,aAAa,0CAA0C;AAAA,EACzF;AAAA,EAEA,QAAQyE,GAA4C;AAChD,WAAO,KAAK,aAAa,OAAO,WAAW,MAAMA,CAAM;AAAA,EAC3D;AAAA,EAEA,MAAM,aAAaA,GAAgB5F,GAA+C;AAC9E,UAAM1D,IAAY,MAAM,KAAK,aAAa,OAAO,gBAAgB,CAAC0D,CAAI,GAAG4F,CAAM;AAC/E,QAAInJ,IAAqC;AACzC,WAAGH,EAAK,eAAe,SAAS,IAC5BG,IAAM,IAAI+I,GAAA,IACLlJ,EAAK,eAAe,gBAAgB,IACzCG,IAAM,IAAIgJ,GAAA,IAEVhJ,IAAM,IAAI8I,EAAA,GAEd,OAAO,OAAO9I,GAAKH,CAAI,GAChBG;AAAA,EACX;AAAA,EAEA,kBAAkBmJ,GAAgB5F,GAAc6F,GAAgC;AAC5E,WAAO,KAAK,aAAa,OAAO,qBAAqB,CAAC7F,GAAM6F,CAAK,GAAGD,CAAM;AAAA,EAC9E;AACJ;AAEO,MAAME,KAAa,IAAIH,GAAA;ACrCvB,MAAMI,UAA4BpL,EAAe;AAAA,EAEpD,YAAYC,GAAiB;AACzB,UAAMA,CAAO,GACb,OAAO,eAAe,MAAMmL,EAAoB,SAAS;AAAA,EAC7D;AACJ;ACNO,MAAMC,UAA2BrL,EAAe;AAAA,EAEnD,YAAYC,GAAiB;AACzB,UAAMA,CAAO,GACb,OAAO,eAAe,MAAMoL,EAAmB,SAAS;AAAA,EAC5D;AACJ;ACHO,MAAMC,GAAc;AAAA,EAEhB;AAAA,EAEA;AAAA,EAEA;AAEX;ACRO,MAAMC,GAAoC;AAAA,EAEtC;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEP,YAAYrB,GACAsB,GACAC,GACAC,GAAkB;AAC1B,SAAK,KAAKxB,GACV,KAAK,WAAWsB,GAChB,KAAK,WAAWC,KAAY,oBAAI,IAAA,GAChC,KAAK,QAAQC,KAAS,CAAA;AAAA,EAC1B;AAEJ;ACrBO,MAAMC,GAAqB;AAAA,EAC9B,OAAgB,gCAAwC;AAAA,EACxD,OAAgB,0BAAkC;AAAA,EAClD,OAAgB,uBAA+B;AAAA,EAC/C,OAAgB,wBAAgC;AAAA,EAChD,OAAgB,wBAAgC;AAAA,EAChD,OAAgB,qBAA6B;AACjD;ACTO,IAAKC,uBAAAA,OACRA,EAAA,WAAW,YACXA,EAAA,SAAS,UACTA,EAAA,SAAS,UAHDA,IAAAA,MAAA,CAAA,CAAA;AAWL,MAAMC,GAA4C;AAAA,EAE9C;AAAA,EAEA;AAAA,EAEA;AAAA,EAEP,YAAYC,GAAkC5B,GAAOjJ,GAAU;AAC3D,SAAK,kBAAkB6K,GACvB,KAAK,KAAK5B,GACV,KAAK,QAAQjJ;AAAA,EACjB;AAAA,EAEO,QAAiB;AACpB,WAAO,KAAK,UAAU,QAAQ,KAAK,UAAU;AAAA,EACjD;AAEJ;AC5CO,MAAM8K,WAAkC1C,EAAwB;AAAA,EAElD;AAAA,EAEjB,YAAYC,GACAC,GACAyC,GAAwD;AAChE,UAAM1C,GAAUC,CAAI,GACpB,KAAK,eAAeyC;AAAA,EACxB;AAAA,EAEU,SAAS1C,GAAsC;AACrD,WAAO,KAAK,aAAaA,CAAQ;AAAA,EACrC;AAEJ;AC2EO,MAAM2C,GAAgB;AAAA,EAEzB,OAAc,6BAA6BC,GAAiG;AACxI,WAAO,YAAYA;AAAA,EACvB;AAEJ;AC1EO,MAAeC,EAAS;AAAA;AAAA;AAAA;AAAA,EAK3B,OAAiC;AAAA;AAAA;AAAA;AAAA,EAKjC,WAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQnB,OAAc,OAAOC,GAAoBC,GAAkBC,GAAoC;AAC3F,WAAO,IAAIC,GAAeH,GAAYC,GAAUC,CAAI;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAc,iBAAiBE,GAAuBH,GAAkBC,GAAoC;AACxG,WAAO,IAAIG,GAAeD,GAAQH,GAAUC,CAAI;AAAA,EACpD;AACJ;AAKO,MAAMC,WAAuBJ,EAAS;AAAA;AAAA;AAAA;AAAA,EAIzC,aAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQrB,YAAYC,GAAoBC,GAAkBC,GAAoB;AAClE,UAAA,GACA,KAAK,aAAaF,GAClB,KAAK,WAAWC,GAChB,KAAK,OAAOC;AAAA,EAChB;AACJ;AAKO,MAAMG,WAAuBN,EAAS;AAAA;AAAA;AAAA;AAAA,EAIzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,YAAYK,GAAuBH,GAAkBC,GAAoB;AACrE,UAAA,GACA,KAAK,SAASE,GACd,KAAK,WAAWH,GAChB,KAAK,OAAOC;AAAA,EAChB;AACJ;AC/EO,IAAKI,uBAAAA,OACRA,EAAA,MAAM,OACNA,EAAA,OAAO,QAFCA,IAAAA,MAAA,CAAA,CAAA,GAcAC,uBAAAA,OAKRA,EAAA,SAAS,UAKTA,EAAA,cAAc,eAKdA,EAAA,aAAa,cAfLA,IAAAA,MAAA,CAAA,CAAA;AAkBL,MAAMC,GAAM;AAAA,EACR;AAAA,EACA,YAAuB;AAAA,EACvB,eAA6B;AAAA,EAEpC,YAAYC,GAAkBC,GAA6B;AACvD,SAAK,WAAWD,GACZC,MAAc,SACf,KAAK,YAAYA;AAAA,EAExB;AAAA;AAAA;AAAA;AAAA,EAKO,cAAuB;AAC1B,WAAO,KAAK,cAAc;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKO,eAAwB;AAC3B,WAAO,KAAK,cAAc;AAAA,EAC9B;AAEJ;AAaO,MAAMC,GAAK;AAAA,EAEP,SAAkB,CAAA;AAE7B;"}
|
|
1
|
+
{"version":3,"file":"continuum.js","sources":["../src/api/ConnectionInfo.ts","../src/api/errors/ContinuumError.ts","../src/core/api/IEventBus.ts","../src/core/api/StompConnectionManager.ts","../src/core/api/EventBus.ts","../src/core/api/DefaultCRI.ts","../src/core/api/CRI.ts","../src/internal/core/api/ArgumentResolver.ts","../src/internal/core/api/EventUtil.ts","../src/internal/core/api/ReturnValueConverter.ts","../src/internal/core/api/Logger.ts","../src/core/api/ServiceIdentifier.ts","../src/api/ContinuumDecorators.ts","../src/internal/core/api/ServiceInvocationSupervisor.ts","../src/core/api/ServiceRegistry.ts","../src/core/api/crud/AbstractIterablePage.ts","../src/internal/core/api/crud/FindAllIterablePage.ts","../src/internal/core/api/crud/SearchIterablePage.ts","../src/core/api/crud/CrudServiceProxy.ts","../src/core/api/crud/CrudServiceProxyFactory.ts","../src/api/Continuum.ts","../src/api/ILogManager.ts","../src/api/LogManager.ts","../src/api/errors/AuthenticationError.ts","../src/api/errors/AuthorizationError.ts","../src/api/security/ConnectedInfo.ts","../src/api/security/Participant.ts","../src/api/security/ParticipantConstants.ts","../src/core/api/StreamData.ts","../src/core/api/crud/FunctionalIterablePage.ts","../src/core/api/crud/IDataSource.ts","../src/core/api/crud/Pageable.ts","../src/core/api/crud/Sort.ts"],"sourcesContent":["/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * ConnectHeaders to use during connection to the continuum server\n * These headers will be sent as part of the STOMP CONNECT frame\n * This is typically used for authentication information, but any data can be sent\n */\nexport class ConnectHeaders {\n [key: string]: string\n}\n\nexport class ServerInfo {\n host!: string\n port?: number | null\n useSSL?: boolean | null\n}\n\n/**\n * ConnectionInfo provides the information needed to connect to the continuum server\n */\nexport class ConnectionInfo extends ServerInfo {\n /**\n * The headers to send during the connection to the continuum server.\n * If a function is provided, it will be called to get the headers each time the connection is established.\n * This is useful for providing dynamic headers, such as a JWT token that expires.\n */\n connectHeaders?: ConnectHeaders | (() => Promise<ConnectHeaders>)\n\n /**\n * The maximum number of connection attempts to make during the {@link IEventBus} initial connection request.\n * If the limit is reached the {@link IEventBus} will return an error to the caller of {@link IEventBus#connect}\n * Set to 0, undefined, or null to try forever\n */\n maxConnectionAttempts?: number | null\n\n /**\n * If true, the session will not be kept alive after the connection is established and then disrupted.\n * If false, the session will be kept alive after the connection is established and then disrupted, for a period of time.\n */\n disableStickySession?: boolean | null\n\n}\n\n\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Base error class for all Continuum errors\n */\nexport class ContinuumError extends Error {\n\n constructor(message: string) {\n super(message);\n Object.setPrototypeOf(this, ContinuumError.prototype);\n }\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Optional } from 'typescript-optional'\nimport { Observable } from 'rxjs'\nimport {ConnectedInfo} from '@/api/security/ConnectedInfo'\nimport {ContinuumError} from '@/api/errors/ContinuumError'\nimport {ConnectionInfo, ServerInfo} from '@/api/ConnectionInfo'\n\n/**\n * Part of the low level portion of continuum representing data to be processed\n *\n * This is similar to a Stomp Frame but with more required information and no control plane semantics.\n *\n *\n * Created by Navid Mitchell on 2019-01-04.\n */\nexport interface IEvent {\n\n /**\n * The cri that specifies where the event should be routed\n */\n cri: string\n\n /**\n * Any headers defined for this event.\n * This will usually contain all the fields above as well since they are typically wrappers around expected header values.\n */\n headers: Map<string, string>\n\n /**\n * The event payload. The payload depends on the type the payload is encoded into a media format which is specified by the contentType attribute (e.g. application/json).\n */\n data: Optional<Uint8Array>\n\n /**\n * @return the data property as a UTF-8 encoded string\n */\n getDataString(): string\n\n /**\n * Gets the value for the header with the given key\n * @param key to get the header value for\n * @return the header value or undefined if there is no header for the key\n */\n getHeader(key: string): string | undefined\n\n /**\n * Tests if a header for the given key exists\n * @param key to check if exists as a header\n * @return true if the header for the key exists false if not\n */\n hasHeader(key: string): boolean\n\n /**\n * Removes the header from the headers map\n * @param key to remove\n * @return true if an element in the headers map object existed and has been removed, or false if the element does not exist\n */\n removeHeader(key: string): boolean\n\n /**\n * Sets the data property from the given string value\n * @param data\n */\n setDataString(data: string): void\n\n /**\n * Sets the header into the headers map\n * @param key the key to use\n * @param value the value to use\n */\n setHeader(key: string, value: string): void\n\n}\n\n/**\n * Part of the low level portion of continuum representing a connection to a continuum server\n * This is similar to a Stomp Client but with more required information and no control plane semantics.\n *\n * Created by Navid Mitchell on 2019-01-04.\n */\nexport interface IEventBus {\n\n /**\n * Any errors emitted by this observable will be fatal and the connection will be closed.\n * You will need to resolve the problem and reconnect.\n */\n fatalErrors: Observable<ContinuumError>\n\n /**\n * The {@link ServerInfo} used when connecting, if connected or null\n */\n serverInfo: ServerInfo | null\n\n /**\n * Requests a connection to the given Stomp url\n * @param connectionInfo provides the information needed to connect to the continuum server\n * @return Promise containing the result of the initial connection attempt\n */\n connect(connectionInfo: ConnectionInfo): Promise<ConnectedInfo>\n\n /**\n * Disconnects the client from the server\n * This will clear any subscriptions and close the connection\n * @param force if true then the connection will be closed immediately without sending a disconnect frame\n * When this mode is used, the actual Websocket may linger for a while\n * and the broker may not realize that the connection is no longer in use.\n *\n * @return Promise containing the result of the disconnect attempt\n */\n disconnect(force?: boolean): Promise<void>\n\n /**\n * Determines if the connection is connected.\n * This means that there is an open connection to the Continuum server\n * @return true if the connection is active false if not\n */\n isConnected(): boolean\n\n /**\n * Determines if the connection is active.\n * This means {@link IEventBus#connect()} was called and was successful. The underlying connection may not be established yet.\n * If this is true and {@link IEventBus#isConnected} is false messages sent will be queued\n * @return true if the connection is active false if not\n */\n isConnectionActive(): boolean\n\n /**\n * Creates a subscription for all {@link IEvent}'s for the given destination\n * @param cri to subscribe to\n */\n observe(cri: string): Observable<IEvent>\n\n /**\n * Sends an {@link IEvent} expecting a response\n * All response correlation will be handled internally\n * @param event to send as the request\n * @return a Promise that will resolve when the response is received\n */\n request(event: IEvent): Promise<IEvent>\n\n /**\n * Sends an {@link IEvent} expecting multiple responses\n * All response correlation will be handled internally\n * @param event to send as the request\n * @param sendControlEvents if true then control events will be sent to the server when changes to the returned to Observable are requested\n * @return an {@link Observable<IEvent} that will provide the response stream\n * NOTE: the naming here is similar to RSocket https://www.baeldung.com/rsocket#3-requeststream\n */\n requestStream(event: IEvent, sendControlEvents: boolean): Observable<IEvent>\n\n /**\n * Send a single {@link IEvent} to the connected server\n * @param event to send\n */\n send(event: IEvent): void\n\n}\n\n/**\n * Constants used within {@link IEvent}'s to control the flow of events\n * Header that start with __ will always be persisted between messages\n */\nexport enum EventConstants {\n CONTENT_TYPE_HEADER = 'content-type',\n CONTENT_LENGTH_HEADER = 'content-length',\n REPLY_TO_HEADER = 'reply-to',\n\n /**\n * This is the replyToId that will be supplied by the client, which will be used when sending replies to the client.\n */\n REPLY_TO_ID_HEADER = 'reply-to-id',\n\n /**\n * Header provided by the sever on connection to represent the user's session id\n */\n SESSION_HEADER = 'session',\n\n /**\n * Header provided by the server on connection to provide the {@link ConnectionInfo} as a JSON string\n */\n CONNECTED_INFO_HEADER = 'connected-info',\n\n /**\n * Header provided by the client on connection request to represent that the server\n * should not keep the session alive after any network disconnection.\n */\n DISABLE_STICKY_SESSION_HEADER = \"disable-sticky-session\",\n\n /**\n * Correlates a response with a given request\n * Headers that start with __ will always be persisted between messages\n */\n CORRELATION_ID_HEADER = '__correlation-id',\n\n /**\n * Denotes that something caused an error. Will contain a brief message about the error\n */\n ERROR_HEADER = 'error',\n\n /**\n * Denotes the completion of an event stream. The value typically will contain the reason for completion.\n */\n COMPLETE_HEADER = 'complete',\n\n /**\n * Denotes the event is a control plane event. These are used for internal coordination.\n */\n CONTROL_HEADER = 'control',\n\n /**\n * Stream is complete, no further values will be sent.\n */\n CONTROL_VALUE_COMPLETE = 'complete',\n\n CONTROL_VALUE_CANCEL = 'cancel',\n\n CONTROL_VALUE_SUSPEND = 'suspend',\n\n CONTROL_VALUE_RESUME = 'resume',\n\n SERVICE_DESTINATION_PREFIX = 'srv://',\n SERVICE_DESTINATION_SCHEME = \"srv\",\n STREAM_DESTINATION_PREFIX = 'stream://',\n STREAM_DESTINATION_SCHEME = \"stream\",\n\n CONTENT_JSON = 'application/json',\n CONTENT_TEXT = 'text/plain',\n\n /**\n * The traceparent HTTP header field identifies the incoming request in a tracing system. It has four fields:\n *\n * version\n * trace-id\n * parent-id\n * trace-flags\n * @see https://www.w3.org/TR/trace-context/#traceparent-header\n */\n TRACEPARENT_HEADER = 'traceparent',\n\n /**\n * The main purpose of the tracestate header is to provide additional vendor-specific trace identification information across different distributed tracing systems and is a companion header for the traceparent field. It also conveys information about the request’s position in multiple distributed tracing graphs.\n * @see https://www.w3.org/TR/trace-context/#tracestate-header\n */\n TRACESTATE_HEADER = 'tracestate'\n}\n","import {ConnectionInfo} from '@/api/ConnectionInfo'\nimport {ConnectedInfo} from '@/api/security/ConnectedInfo'\nimport {EventConstants} from '@/core/api/IEventBus'\nimport {IFrame, RxStomp, RxStompConfig, StompHeaders} from '@stomp/rx-stomp'\nimport {ReconnectionTimeMode} from '@stomp/stompjs'\nimport {Subscription} from 'rxjs'\nimport {v4 as uuidv4} from 'uuid'\nimport debug from 'debug'\n\n/**\n * Creates a new RxStomp client and manages it\n * This is here to simplify the logic needed for connection management and the usage of the client.\n */\nexport class StompConnectionManager {\n\n public lastWebsocketError: Event | null = null\n /**\n * This will return true if a {@link ConnectionInfo#maxConnectionAttempts} threshold was set and was reached\n */\n public maxConnectionAttemptsReached: boolean = false\n public rxStomp: RxStomp | null = null\n private readonly INITIAL_RECONNECT_DELAY: number = 2000\n private readonly MAX_RECONNECT_DELAY: number = 120000 // 2 mins\n private readonly JITTER_MAX: number = 5000\n private connectionAttempts: number = 0\n private initialConnectionSuccessful: boolean = false\n private debugLogger = debug('continuum:stomp')\n private replyToId = uuidv4()\n public readonly replyToCri = EventConstants.SERVICE_DESTINATION_PREFIX + this.replyToId + ':' + uuidv4() + '@continuum.js.EventBus/replyHandler'\n public deactivationHandler: (() => void) | null = null\n\n /**\n * @return true if this {@link StompConnectionManager} is actively trying to maintain a connection to the Stomp server, false if not.\n */\n public get active(): boolean {\n if(this.rxStomp){\n return true\n }else{\n return false\n }\n }\n\n /**\n * return true if this {@link StompConnectionManager} is active and has a connection to the stomp server\n */\n public get connected(): boolean {\n return this.rxStomp != null\n && this.rxStomp.connected()\n }\n\n public activate(connectionInfo: ConnectionInfo): Promise<ConnectedInfo> {\n return new Promise((resolve, reject): void => {\n // Validate state and short circuit\n if(!connectionInfo){\n reject('You must supply a valid connectionInfo object')\n return\n }\n\n if (!(connectionInfo.host)) {\n reject('No host provided')\n return\n }\n\n if(this.rxStomp) {\n reject('Stomp connection already active')\n return\n }\n\n // we reset most state here so, it will persist on a connection failure\n this.connectionAttempts = 0\n this.initialConnectionSuccessful = false\n this.lastWebsocketError = null\n this.maxConnectionAttemptsReached = false\n\n const url = 'ws' + (connectionInfo.useSSL ? 's' : '')\n + '://' + connectionInfo.host\n + (connectionInfo.port ? ':' + connectionInfo.port : '') + '/v1'\n\n this.rxStomp = new RxStomp()\n\n let connectHeadersInternal: StompHeaders = (typeof connectionInfo.connectHeaders !== 'function' && connectionInfo.connectHeaders != null ? connectionInfo.connectHeaders : {})\n\n const stompConfig: RxStompConfig = {\n brokerURL: url,\n connectHeaders: connectHeadersInternal,\n heartbeatIncoming: 120000,\n heartbeatOutgoing: 30000,\n reconnectDelay: this.INITIAL_RECONNECT_DELAY,\n beforeConnect: async (): Promise<void> => {\n\n if(typeof connectionInfo.connectHeaders === 'function'){\n const headers = await connectionInfo.connectHeaders()\n for(const key in headers) {\n connectHeadersInternal[key] = headers[key]\n }\n }\n\n if(connectionInfo.disableStickySession){\n connectHeadersInternal[EventConstants.DISABLE_STICKY_SESSION_HEADER] = 'true'\n }\n\n // use replyToId if provided in connectionInfo, otherwise set it\n if(connectHeadersInternal[EventConstants.REPLY_TO_ID_HEADER]){\n this.replyToId = connectHeadersInternal[EventConstants.REPLY_TO_ID_HEADER]\n }else{\n connectHeadersInternal[EventConstants.REPLY_TO_ID_HEADER] = this.replyToId\n }\n\n // If max connections are set then make sure we have not exceeded that threshold\n if(connectionInfo?.maxConnectionAttempts){\n this.connectionAttempts++\n\n if(this.connectionAttempts > connectionInfo.maxConnectionAttempts){\n\n // Reached threshold give up\n this.maxConnectionAttemptsReached = true\n await this.deactivate()\n\n // If we have not made an initial connection, the promise is not yet resolved\n if(!this.initialConnectionSuccessful) {\n let message = (this.lastWebsocketError as any)?.message ? (this.lastWebsocketError as any)?.message : 'UNKNOWN'\n reject(`Max number of reconnection attempts reached. Last WS Error ${message}`)\n }\n }else{\n await this.connectionJitterDelay();\n }\n }else{\n await this.connectionJitterDelay();\n }\n }\n }\n\n if(this.debugLogger.enabled){\n stompConfig.debug = (msg: string): void => {\n this.debugLogger(msg)\n }\n }\n\n //*** Begin Block that handles backoff ***\n this.rxStomp.configure(stompConfig)\n\n // Set values that are only accessible from the stompClient\n this.rxStomp.stompClient.maxReconnectDelay = this.MAX_RECONNECT_DELAY\n this.rxStomp.stompClient.reconnectTimeMode = ReconnectionTimeMode.EXPONENTIAL\n\n // Handles Websocket Errors\n this.rxStomp.webSocketErrors$.subscribe(value => {\n this.lastWebsocketError = value\n })\n\n // Handles Successful Connections\n const connectedSubscription: Subscription = this.rxStomp.connected$.subscribe(() =>{\n connectedSubscription.unsubscribe()\n // Successful Connection\n if(!this.initialConnectionSuccessful){\n this.initialConnectionSuccessful = true\n }\n })\n\n // This subscription is to handle any errors that occur during connection\n const errorSubscription: Subscription = this.rxStomp.stompErrors$.subscribe((value: IFrame) => {\n errorSubscription.unsubscribe()\n const message = value.headers['message']\n this.rxStomp?.deactivate()\n this.rxStomp = null\n reject(message)\n })\n\n // This is triggered when the server sends a CONNECTED frame.\n const serverHeadersSubscription: Subscription = this.rxStomp.serverHeaders$.subscribe((value: StompHeaders) => {\n let connectedInfoJson: string | undefined = value[EventConstants.CONNECTED_INFO_HEADER]\n if (connectedInfoJson != null) {\n\n const connectedInfo: ConnectedInfo = JSON.parse(connectedInfoJson)\n\n if(!connectionInfo.disableStickySession){\n\n serverHeadersSubscription.unsubscribe()\n\n if (connectedInfo.sessionId != null && connectedInfo.replyToId != null) {\n\n // Remove all information originally sent from the connect headers\n if (connectionInfo.connectHeaders != null) {\n for (let key in connectHeadersInternal) {\n delete connectHeadersInternal[key]\n }\n }\n\n connectHeadersInternal[EventConstants.SESSION_HEADER] = connectedInfo.sessionId\n\n resolve(connectedInfo)\n } else {\n reject('Server did not return proper data for successful login')\n }\n\n }else if(typeof connectionInfo.connectHeaders === 'function'){\n // If the connect headers are supplied by a function we remove all the header values since they will be recreated on next connect\n for (let key in connectHeadersInternal) {\n delete connectHeadersInternal[key]\n }\n if(!this.initialConnectionSuccessful) {\n resolve(connectedInfo)\n }\n }else if(typeof connectionInfo.connectHeaders === 'object'){\n // static object we must leave intact for reuse\n serverHeadersSubscription.unsubscribe()\n resolve(connectedInfo)\n }\n } else {\n reject('Server did not return proper data for successful login')\n }\n })\n\n this.rxStomp.activate()\n })\n }\n\n public async deactivate(force?: boolean): Promise<void> {\n if(this.rxStomp){\n await this.rxStomp.deactivate({force: force})\n if(this.deactivationHandler){\n this.deactivationHandler()\n }\n this.rxStomp = null\n }\n return\n }\n\n /**\n * Make sure clients don't all try to reconnect at the same time.\n */\n private async connectionJitterDelay(): Promise<void> {\n if(this.initialConnectionSuccessful) {\n const randomJitter = Math.random() * this.JITTER_MAX;\n this.debugLogger(`Adding ${randomJitter}ms of jitter delay`)\n return new Promise(resolve => setTimeout(resolve, randomJitter));\n }\n }\n\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\")\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {ConnectionInfo, ServerInfo} from '@/api/ConnectionInfo'\nimport {ContinuumError} from '@/api/errors/ContinuumError'\nimport {ConnectedInfo} from '@/api/security/ConnectedInfo'\nimport {StompConnectionManager} from '@/core/api/StompConnectionManager'\nimport {context, propagation} from '@opentelemetry/api';\nimport {IFrame, IMessage} from '@stomp/rx-stomp'\nimport {ConnectableObservable, firstValueFrom, Observable, Subject, Subscription, throwError, Unsubscribable} from 'rxjs'\nimport {filter, map, multicast} from 'rxjs/operators'\nimport {Optional} from 'typescript-optional'\nimport {v4 as uuidv4} from 'uuid'\nimport {EventConstants, IEvent, IEventBus} from './IEventBus'\n\n/**\n * Default IEvent implementation\n */\nexport class Event implements IEvent {\n\n public cri: string\n public headers: Map<string, string>\n public data: Optional<Uint8Array>\n\n constructor(cri: string,\n headers?: Map<string, string>,\n data?: Uint8Array) {\n\n this.cri = cri\n\n if (headers !== undefined) {\n this.headers = headers\n } else {\n this.headers = new Map<string, string>()\n }\n\n this.data = Optional.ofNullable(data)\n }\n\n public getHeader(key: string): string | undefined {\n return this.headers.get(key)\n }\n\n public hasHeader(key: string): boolean {\n return this.headers.has(key)\n }\n\n public setHeader(key: string, value: string): void {\n this.headers.set(key, value)\n }\n\n public removeHeader(key: string): boolean {\n return this.headers.delete(key)\n }\n\n public setDataString(data: string): void {\n const uint8Array = new TextEncoder().encode(data)\n this.data = Optional.ofNonNull(uint8Array)\n }\n\n public getDataString(): string {\n let ret = ''\n this.data.ifPresent(( value ) => ret = new TextDecoder().decode(value))\n return ret\n }\n}\n\ninterface Carrier {\n traceparent?: string;\n tracestate?: string;\n}\n\n/**\n * Default implementation of {@link IEventBus}\n */\nexport class EventBus implements IEventBus {\n\n public fatalErrors: Observable<Error>\n public serverInfo: ServerInfo | null = null\n private stompConnectionManager: StompConnectionManager = new StompConnectionManager()\n private replyToCri: string | null = null\n private requestRepliesObservable: ConnectableObservable<IEvent> | null = null\n private requestRepliesSubject: Subject<IEvent> | null = null\n private requestRepliesSubscription: Subscription | null = null\n private errorSubject: Subject<IFrame> = new Subject<IFrame>()\n private errorSubjectSubscription: Subscription | null | undefined = null\n\n constructor() {\n this.fatalErrors = this.errorSubject\n .pipe(map<IFrame, Error>((frame: IFrame): Error => {\n this.disconnect()\n .catch((error: string) => {\n if(console){\n console.error('Error disconnecting from Stomp: ' + error)\n }\n })\n // TODO: map to continuum error\n return new ContinuumError(frame.headers['message'])\n }))\n this.stompConnectionManager.deactivationHandler = () => {\n this.cleanup()\n }\n }\n\n public isConnectionActive(): boolean{\n return this.stompConnectionManager.active\n }\n\n public isConnected(): boolean {\n return this.stompConnectionManager.connected\n }\n\n public async connect(connectionInfo: ConnectionInfo): Promise<ConnectedInfo> {\n if(!this.stompConnectionManager.active){\n\n // reset state in case connection ended due to max connection attempts\n this.cleanup()\n\n const connectedInfo = await this.stompConnectionManager.activate(connectionInfo)\n // manually copy so we don't store any sensitive info\n this.serverInfo = new ServerInfo()\n this.serverInfo.host = connectionInfo.host\n this.serverInfo.port = connectionInfo.port\n this.serverInfo.useSSL = connectionInfo.useSSL\n\n // FIXME: a reply should not need a reply, therefore a replyCri probably should not be a EventConstants.SERVICE_DESTINATION_PREFIX\n this.replyToCri = this.stompConnectionManager.replyToCri\n\n this.errorSubjectSubscription = this.stompConnectionManager.rxStomp?.stompErrors$.subscribe(this.errorSubject)\n\n return connectedInfo\n }else{\n throw new Error('Event Bus connection already active')\n }\n }\n\n public async disconnect(force?: boolean): Promise<void> {\n await this.stompConnectionManager.deactivate(force)\n\n this.cleanup()\n }\n\n public send(event: IEvent): void {\n if(this.stompConnectionManager.rxStomp){\n const headers: any = {}\n\n for (const [key, value] of event.headers.entries()) {\n headers[key] = value\n }\n\n const carrier: Carrier = {}\n propagation.inject(context.active(), carrier)\n if(carrier.traceparent){\n headers[EventConstants.TRACEPARENT_HEADER] = carrier.traceparent\n }\n if(carrier.tracestate){\n headers[EventConstants.TRACESTATE_HEADER] = carrier.tracestate\n }\n\n // send data over stomp\n this.stompConnectionManager.rxStomp.publish({\n destination: event.cri,\n headers,\n binaryBody: event.data.orUndefined()\n })\n }else{\n throw this.createSendUnavailableError()\n }\n }\n\n public request(event: IEvent): Promise<IEvent> {\n return firstValueFrom(this.requestStream(event, false))\n }\n\n public requestStream(event: IEvent, sendControlEvents: boolean = true): Observable<IEvent> {\n if(this.stompConnectionManager?.rxStomp){\n return new Observable<IEvent>((subscriber) => {\n\n if (this.requestRepliesObservable == null) {\n this.requestRepliesSubject = new Subject<IEvent>()\n this.requestRepliesObservable = this._observe(this.replyToCri as string)\n .pipe(multicast(this.requestRepliesSubject)) as ConnectableObservable<IEvent>\n this.requestRepliesSubscription = this.requestRepliesObservable.connect()\n }\n\n let serverSignaledCompletion = false\n const correlationId = uuidv4()\n const defaultMessagesSubscription: Unsubscribable\n = this.requestRepliesObservable\n .pipe(filter((value: IEvent): boolean => {\n return value.headers.get(EventConstants.CORRELATION_ID_HEADER) === correlationId\n })).subscribe({\n next(value: IEvent): void {\n\n if (value.hasHeader(EventConstants.CONTROL_HEADER)) {\n\n if (value.headers.get(EventConstants.CONTROL_HEADER) === 'complete') {\n serverSignaledCompletion = true\n subscriber.complete()\n } else {\n throw new Error('Control Header ' + value.headers.get(EventConstants.CONTROL_HEADER) + ' is not supported')\n }\n\n } else if (value.hasHeader(EventConstants.ERROR_HEADER)) {\n\n // TODO: add custom error type that contains error detail as well if provided by server, this would be the event body\n serverSignaledCompletion = true\n subscriber.error(new Error(value.getHeader(EventConstants.ERROR_HEADER)))\n\n } else {\n\n subscriber.next(value)\n\n }\n },\n error(err: any): void {\n subscriber.error(err)\n },\n complete(): void {\n subscriber.complete()\n }\n })\n\n subscriber.add(defaultMessagesSubscription)\n\n event.setHeader(EventConstants.REPLY_TO_HEADER, this.replyToCri as string)\n event.setHeader(EventConstants.CORRELATION_ID_HEADER, correlationId)\n\n this.send(event)\n\n return () => {\n if (sendControlEvents && !serverSignaledCompletion) {\n // create control event to cancel long-running request\n const controlEvent: Event = new Event(event.cri)\n controlEvent.setHeader(EventConstants.CONTROL_HEADER, EventConstants.CONTROL_VALUE_CANCEL)\n controlEvent.setHeader(EventConstants.CORRELATION_ID_HEADER, correlationId)\n this.send(controlEvent)\n }\n }\n })\n }else{\n return throwError(() => this.createSendUnavailableError())\n }\n }\n\n public observe(cri: string): Observable<IEvent> {\n return this._observe(cri)\n }\n\n private cleanup(): void{\n if (this.requestRepliesSubject != null) {\n\n // This will be sent to any client waiting on an Event\n this.requestRepliesSubject.error(new Error('Connection disconnected'))\n\n if (this.requestRepliesSubscription != null) {\n this.requestRepliesSubscription.unsubscribe()\n this.requestRepliesSubscription = null\n }\n\n this.requestRepliesSubject = null;\n this.requestRepliesObservable = null\n }\n\n if (this.errorSubjectSubscription) {\n this.errorSubjectSubscription.unsubscribe()\n this.errorSubjectSubscription = null\n }\n\n this.serverInfo = null\n }\n\n /**\n * Creates the proper error to return if this.stompConnectionManager?.rxStomp is not available on a send request\n */\n private createSendUnavailableError(): Error {\n let ret: string = 'You must call connect on the event bus before sending any request'\n if(this.stompConnectionManager.maxConnectionAttemptsReached){\n ret = 'Max connection attempts reached event bus is not available'\n }\n return new Error(ret)\n }\n\n /**\n * This is internal impl of observe that creates a cold observable.\n * The public variants transform this to some type of hot observable depending on the need\n * @param cri to observe\n * @return the cold {@link Observable<IEvent>} for the given destination\n */\n private _observe(cri: string): Observable<IEvent> {\n if(this.stompConnectionManager?.rxStomp) {\n return this.stompConnectionManager\n .rxStomp\n .watch(cri)\n .pipe(map<IMessage, IEvent>((message: IMessage): IEvent => {\n\n // We translate all IMessage objects to IEvent objects\n const headers: Map<string, string> = new Map<string, string>()\n let destination: string = ''\n for (const prop of Object.keys(message.headers)) {\n if (prop === 'destination') {\n destination = message.headers[prop]\n }else{\n headers.set(prop, message.headers[prop])\n }\n }\n\n return new Event(destination, headers, message.binaryBody)\n }))\n }else{\n throw this.createSendUnavailableError()\n }\n }\n\n}\n\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\")\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CRI } from \"./CRI\"\n\n/**\n * Default implementation of the `CRI` interface.\n *\n * @author Navid Mitchell\n * @since 3/25/25\n */\nexport class DefaultCRI implements CRI {\n private readonly _scheme: string\n private readonly _scope: string | null\n private readonly _resourceName: string\n private readonly _path: string | null\n private readonly _version: string | null\n private readonly _raw: string\n\n constructor(rawCRI: string)\n constructor(scheme: string, scope: string | null, resourceName: string, path: string | null, version: string | null)\n constructor(...args: any[]) {\n if (args.length === 1) {\n const rawURC = args[0]\n if (typeof rawURC !== \"string\") {\n throw new Error(\"Raw URI must be a string\")\n }\n const parsed = DefaultCRI.parseRaw(rawURC)\n this._scheme = parsed.scheme\n this._scope = parsed.scope\n this._resourceName = parsed.resourceName\n this._path = parsed.path\n this._version = parsed.version\n this._raw = rawURC\n } else if (args.length === 5) {\n const [scheme, scope, resourceName, path, version] = args\n this._scheme = scheme\n this._scope = scope\n this._resourceName = resourceName\n this._path = path\n this._version = version\n this._raw = DefaultCRI.buildRaw(scheme, scope, resourceName, path, version)\n } else {\n throw new Error(\"Invalid constructor arguments for DefaultCRI\")\n }\n\n if (!this._scheme || !this._resourceName) {\n throw new Error(`Invalid CRI: scheme and resourceName are required. Got: ${this._raw}`)\n }\n }\n\n public scheme(): string {\n return this._scheme\n }\n\n public scope(): string | null {\n return this._scope\n }\n\n public hasScope(): boolean {\n return this._scope !== null\n }\n\n public resourceName(): string {\n return this._resourceName\n }\n\n public version(): string | null {\n return this._version\n }\n\n public hasVersion(): boolean {\n return this._version !== null\n }\n\n public path(): string | null {\n return this._path\n }\n\n public hasPath(): boolean {\n return this._path !== null\n }\n\n public baseResource(): string {\n let result = `${this._scheme}://`\n if (this.hasScope()) {\n result += `${this._scope}@`\n }\n result += this._resourceName\n return result\n }\n\n public raw(): string {\n return this._raw\n }\n\n public equals(other: any): boolean {\n if (this === other) return true\n if (!(other instanceof DefaultCRI)) return false\n return this._raw === other.raw()\n }\n\n public hashCode(): number {\n let hash = 17\n hash = hash * 37 + this._raw.split(\"\").reduce((a, c) => a + c.charCodeAt(0), 0)\n return hash\n }\n\n public toString(): string {\n return this._raw\n }\n\n // Helper to parse a raw CRI string\n private static parseRaw(raw: string): {\n scheme: string\n scope: string | null\n resourceName: string\n path: string | null\n version: string | null\n } {\n const regex = /^([^:]+):\\/\\/(?:([^@]+)@)?([^\\/#]+)(\\/[^#]*)?(?:#(.+))?$/;\n const match = raw.match(regex)\n if (!match) {\n throw new Error(`Invalid CRI format: ${raw}`)\n }\n\n const [, scheme, scope, resourceName, path, version] = match\n return {\n scheme,\n scope: scope || null,\n resourceName,\n path: path ? path.substring(1) : null,\n version: version || null,\n }\n }\n\n // Helper to build a raw CRI string\n private static buildRaw(\n scheme: string,\n scope: string | null,\n resourceName: string,\n path: string | null,\n version: string | null\n ): string {\n let result = `${scheme}://`\n if (scope) {\n result += `${scope}@`\n }\n result += resourceName\n if (path) {\n result += `/${path}`\n }\n if (version) {\n result += `#${version}`\n }\n return result\n }\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\")\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {DefaultCRI} from './DefaultCRI.js'\n\n/**\n * `CRI` is a Continuum Resource Identifier used by Continuum to route requests appropriately.\n *\n * The `CRI` is a URI where the parts are named differently for clarity as to their purpose within Continuum.\n *\n * Will be in a format as follows where anything surrounded with `[]` is optional:\n *\n * scheme://[scope@]resourceName[/path][#version]\n *\n * NOTE: If scope needs to be used to identify a sub-scope, it will follow the form `scope = scope:sub-scope`.\n *\n * This format can have varied meanings based upon the scheme used.\n *\n * @author Navid Mitchell\n * @since 3/25/25\n */\nexport interface CRI {\n /**\n * The scheme for this `CRI`.\n *\n * @returns a string containing the scheme\n */\n scheme(): string\n\n /**\n * The scope for this `CRI` or `null` if not provided.\n *\n * This is useful to narrow down the `CRI`. This could be something like a user id, device id, or a node id.\n *\n * @returns a string containing the scope if provided or `null` if not set\n */\n scope(): string | null\n\n /**\n * @returns `true` if the `scope` is set\n */\n hasScope(): boolean\n\n /**\n * The name of the resource represented by this `CRI`.\n *\n * In the case of a `srv` `CRI`, this will be the service name.\n * In the case of a `stream` `CRI`, this will be the name of the event type that the stream expects.\n *\n * For the following CRI, `resourceName` would be the portion specified by `resourceName`:\n *\n * `scheme://[scope@]resourceName/path`\n *\n * @returns the string containing the name of this resource\n */\n resourceName(): string\n\n /**\n * This is a version for the resource or `null` if not provided.\n *\n * @returns a string containing the version if provided or `null` if not set\n */\n version(): string | null\n\n /**\n * @returns `true` if the `version` is set\n */\n hasVersion(): boolean\n\n /**\n * The path for this `CRI`, without a leading `/`.\n *\n * For the following CRI, `path` would be the portion specified by `path`:\n *\n * `scheme://[scope@]resourceName/path`\n *\n * @returns the path string if provided or `null` if not set\n */\n path(): string | null\n\n /**\n * @returns `true` if the `path` is set\n */\n hasPath(): boolean\n\n /**\n * Base Resource is a portion of the fully qualified `CRI` containing the following:\n *\n * `scheme://[scope@]resourceName`\n *\n * @returns string containing the baseResource\n */\n baseResource(): string\n\n /**\n * The fully qualified value for this `CRI`.\n *\n * @returns the fully qualified `CRI` as a string\n */\n raw(): string\n}\n\n/**\n * Creates a new `CRI` from a raw string.\n *\n * @param rawUrc the raw string\n * @returns the newly created `CRI`\n */\nexport function createCRI(rawUrc: string): CRI;\n\n/**\n * Creates a new `CRI` from scheme and resourceName.\n *\n * @param scheme the scheme\n * @param resourceName the resource name\n * @returns the newly created `CRI`\n */\nexport function createCRI(scheme: string, resourceName: string): CRI;\n/**\n * Creates a new `CRI` from scheme, scope, and resourceName.\n *\n * @param scheme the scheme\n * @param scope the scope\n * @param resourceName the resource name\n * @returns the newly created `CRI`\n */\nexport function createCRI(scheme: string, scope: string | null, resourceName: string): CRI;\n/**\n * Creates a new `CRI` from all provided values.\n *\n * @param scheme the scheme\n * @param scope the scope\n * @param resourceName the resource name\n * @param path the path\n * @param version the version\n * @returns the newly created `CRI`\n */\nexport function createCRI(scheme: string, scope: string | null, resourceName: string, path: string | null, version: string | null): CRI;\n\n// Implementation of the overloaded createCRI function\nexport function createCRI(...args: any[]): CRI {\n if (args.length === 1) return new DefaultCRI(args[0]);\n if (args.length === 2) return new DefaultCRI(args[0], null, args[1], null, null);\n if (args.length === 3) return new DefaultCRI(args[0], args[1], args[2], null, null);\n if (args.length === 5) return new DefaultCRI(args[0], args[1], args[2], args[3], args[4]);\n throw new Error(\"Invalid arguments for createCRI\");\n}\n","/*\n * Copyright 2008-2021 Kinotic and the original author or authors.\n * Licensed under the Apache License, Version 2.0 (the \"License\")\n * See https://www.apache.org/licenses/LICENSE-2.0\n */\n\n\nimport {EventConstants, IEvent} from '@/core/api/IEventBus.js'\n\n/**\n * Argument resolution utilities for service invocation.\n *\n * @author Navid Mitchell 🤝Grok\n * @since 3/25/2025\n */\nexport interface ArgumentResolver {\n resolveArguments(event: IEvent): any[]\n}\n\nexport class JsonArgumentResolver implements ArgumentResolver {\n resolveArguments(event: IEvent): any[] {\n if (this.containsJsonContent(event)) {\n const data = event.getDataString()\n return data ? JSON.parse(data) : []\n }else{\n throw new Error(\"Currently only JSON content is supported\")\n }\n }\n\n protected containsJsonContent(event: IEvent): boolean {\n const contentType = event.getHeader(EventConstants.CONTENT_TYPE_HEADER)\n return contentType != null && contentType !== \"\" && contentType === \"application/json\"\n }\n}\n","/*\n * Copyright 2008-2021 Kinotic and the original author or authors.\n * Licensed under the Apache License, Version 2.0 (the \"License\")\n * See https://www.apache.org/licenses/LICENSE-2.0\n */\n\n\nimport {EventConstants, IEvent} from '@/core/api/IEventBus.js'\nimport {Event} from '@/core/api/EventBus.js'\n\n/**\n * Utility functions for working with events in the Continuum framework.\n *\n * @author Navid Mitchell 🤝Grok\n * @since 3/25/2025\n */\nexport class EventUtil {\n\n public static createReplyEvent(\n incomingHeaders: Map<string, string>,\n headers?: Map<string, string>,\n body?: Uint8Array\n ): IEvent {\n if (!incomingHeaders) {\n throw new Error(\"incomingHeaders cannot be null\")\n }\n\n const replyCRI = incomingHeaders.get(EventConstants.REPLY_TO_HEADER)\n if (!replyCRI || replyCRI.trim() === \"\") {\n throw new Error(\"No reply-to header found, cannot create outgoing message\")\n }\n\n const newHeaders = new Map<string, string>()\n for (const [key, value] of incomingHeaders) {\n if (key.startsWith(\"__\")) {\n newHeaders.set(key, value)\n }\n }\n\n if (headers) {\n for (const [key, value] of headers) {\n newHeaders.set(key, value)\n }\n }\n\n return new Event(replyCRI, newHeaders, body || undefined)\n }\n}\n","/*\n * Copyright 2008-2021 Kinotic and the original author or authors.\n * Licensed under the Apache License, Version 2.0 (the \"License\")\n * See https://www.apache.org/licenses/LICENSE-2.0\n */\n\nimport {EventConstants, IEvent} from '@/core/api/IEventBus.js'\nimport {EventUtil} from '@/internal/core/api/EventUtil.js'\n\n/**\n * Return value conversion utilities for service responses.\n *\n * @author Navid Mitchell 🤝Grok\n * @since 3/25/2025\n */\nexport interface ReturnValueConverter {\n convert(incomingMetadata: Map<string, string>, returnValue: any): IEvent\n}\n\nexport class BasicReturnValueConverter implements ReturnValueConverter {\n convert(incomingMetadata: Map<string, string>, returnValue: any): IEvent {\n return EventUtil.createReplyEvent(\n incomingMetadata,\n new Map([[EventConstants.CONTENT_TYPE_HEADER, \"application/json\"]]),\n new TextEncoder().encode(JSON.stringify(returnValue))\n )\n }\n}\n","/*\n * Copyright 2008-2021 Kinotic and the original author or authors.\n * Licensed under the Apache License, Version 2.0 (the \"License\")\n * See https://www.apache.org/licenses/LICENSE-2.0\n */\n\n/**\n * Logging utilities for the Continuum library.\n *\n * @author Navid Mitchell 🤝Grok\n * @since 3/25/2025\n */\nexport interface Logger {\n trace(message: string, ...args: any[]): void\n debug(message: string, ...args: any[]): void\n info(message: string, ...args: any[]): void\n warn(message: string, ...args: any[]): void\n error(message: string, ...args: any[]): void\n}\n\nexport class NoOpLogger implements Logger {\n trace(_message: string, ..._args: any[]): void {}\n debug(_message: string, ..._args: any[]): void {}\n info(_message: string, ..._args: any[]): void {}\n warn(_message: string, ..._args: any[]): void {}\n error(_message: string, ..._args: any[]): void {}\n}\n\nexport function createDebugLogger(namespace: string): Logger {\n let debug: any\n try {\n debug = require(\"debug\")(namespace)\n } catch (e) {\n debug = (...args: any[]) => console.debug(`[${namespace}]`, ...args)\n }\n\n return {\n trace: (...args) => debug(\"TRACE\", ...args),\n debug: (...args) => debug(\"DEBUG\", ...args),\n info: (...args) => debug(\"INFO\", ...args),\n warn: (...args) => debug(\"WARN\", ...args),\n error: (...args) => debug(\"ERROR\", ...args),\n }\n}\n","import {createCRI, CRI} from '@/core/api/CRI.js'\nimport {EventConstants} from '@/core/api/IEventBus.js'\n\nexport class ServiceIdentifier {\n\n public namespace: string\n public name: string\n public scope?: string\n public version?: string\n private _cri: CRI | null = null\n\n\n constructor(namespace: string, name: string) {\n this.namespace = namespace\n this.name = name\n }\n\n /**\n * Returns the qualified name for this {@link ServiceIdentifier}\n * This is the namespace.name\n * @return string containing the qualified name\n */\n public qualifiedName(): string{\n return this.namespace + \".\" + this.name;\n }\n\n /**\n * The {@link CRI} that represents this {@link ServiceIdentifier}\n * @return the cri for this {@link ServiceIdentifier}\n */\n public cri(): CRI {\n if(this._cri == null) {\n this._cri = createCRI(\n EventConstants.SERVICE_DESTINATION_SCHEME, // scheme\n this.scope || null, // scope\n this.qualifiedName(), // resourceName\n null, // path (null as per your example)\n this.version || null // version\n );\n }\n return this._cri;\n }\n}\n","/*\n * Copyright 2008-2021 Kinotic and the original author or authors.\n * Licensed under the Apache License, Version 2.0 (the 'License')\n * See https://www.apache.org/licenses/LICENSE-2.0\n */\n\nimport 'reflect-metadata'\nimport { Continuum } from '@/api/Continuum.js'\nimport { ServiceIdentifier } from '@/core/api/ServiceIdentifier.js'\n\n/**\n * Decorator for registering services with the Continuum ServiceRegistry.\n *\n * @author Navid Mitchell 🤝Grok\n * @since 3/25/2025\n */\nconst SCOPE_METADATA_KEY = Symbol('scope')\nconst VERSION_METADATA_KEY = Symbol('version')\nexport const CONTEXT_METADATA_KEY = Symbol('context')\n\n//@ts-ignore\nexport function Scope(target: any, propertyKey: string, descriptor?: PropertyDescriptor) {\n Reflect.defineMetadata(SCOPE_METADATA_KEY, propertyKey, target)\n}\n\nexport function Version(version: string) {\n if (!/^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9]+)?$/.test(version)) {\n throw new Error(`Invalid semantic version: ${version}. Must follow X.Y.Z[-optional] format.`)\n }\n return function (target: Function) {\n Reflect.defineMetadata(VERSION_METADATA_KEY, version, target)\n }\n}\n\nexport function Context() {\n return function (target: any, propertyKey: string, parameterIndex: number) {\n const existingContexts = Reflect.getMetadata(CONTEXT_METADATA_KEY, target, propertyKey) || [];\n existingContexts.push(parameterIndex);\n Reflect.defineMetadata(CONTEXT_METADATA_KEY, existingContexts, target, propertyKey);\n }\n}\n\nexport function Publish(namespace: string, name?: string) {\n return function (target: Function) {\n const original = target\n const serviceIdentifier = new ServiceIdentifier(namespace, name || target.name)\n\n const version = Reflect.getMetadata(VERSION_METADATA_KEY, target)\n if (version) {\n serviceIdentifier.version = version\n }\n\n const newConstructor: any = function (this: any, ...args: any[]) {\n const instance = Reflect.construct(original, args)\n\n const scopeProperty = Reflect.getMetadata(SCOPE_METADATA_KEY, target.prototype)\n if (scopeProperty) {\n const scopeValue = instance[scopeProperty]\n serviceIdentifier.scope = typeof scopeValue === 'function' ? scopeValue.call(instance) : scopeValue\n }\n\n // Register with the singleton Continuum's ServiceRegistry\n Continuum.serviceRegistry.register(serviceIdentifier, instance)\n\n return instance\n }\n\n newConstructor.prototype = original.prototype\n return newConstructor as any\n }\n}\n","/*\n * Copyright 2008-2021 Kinotic and the original author or authors.\n * Licensed under the Apache License, Version 2.0 (the \"License\")\n * See https://www.apache.org/licenses/LICENSE-2.0\n */\n\nimport { createCRI } from '@/core/api/CRI.js'\nimport { EventConstants, IEvent, IEventBus } from '@/core/api/IEventBus.js'\nimport { ServiceIdentifier } from '@/core/api/ServiceIdentifier.js'\nimport { ArgumentResolver, JsonArgumentResolver } from './ArgumentResolver.js'\nimport { EventUtil } from './EventUtil.js'\nimport { BasicReturnValueConverter, ReturnValueConverter } from './ReturnValueConverter.js'\nimport { Subscription } from \"rxjs\"\nimport { createDebugLogger, Logger } from \"./Logger.js\"\nimport { ContextInterceptor, ServiceContext } from '@/core/api/ContextInterceptor.js'\nimport { CONTEXT_METADATA_KEY } from '@/api/ContinuumDecorators.js'\n\n/**\n * Handles invoking services registered with Continuum in TypeScript.\n *\n * @author Navid Mitchell 🤝Grok\n * @since 3/25/2025\n */\nexport class ServiceInvocationSupervisor {\n private readonly log: Logger\n private active: boolean = false\n private readonly eventBusService: IEventBus\n private readonly interceptorProvider: () => ContextInterceptor<any> | null\n private readonly argumentResolver: ArgumentResolver\n private readonly returnValueConverter: ReturnValueConverter\n private readonly serviceIdentifier: ServiceIdentifier\n private readonly serviceInstance: any\n private methodSubscription: Subscription | null = null\n private readonly methodMap: Record<string, (...args: any[]) => any>\n\n constructor(\n serviceIdentifier: ServiceIdentifier,\n serviceInstance: any,\n eventBusService: IEventBus,\n interceptorProvider: () => ContextInterceptor<any> | null,\n options: {\n logger?: Logger\n argumentResolver?: ArgumentResolver\n returnValueConverter?: ReturnValueConverter\n } = {}\n ) {\n if (!serviceIdentifier) throw new Error(\"ServiceIdentifier must not be null\")\n if (!serviceInstance) throw new Error(\"Service instance must not be null\")\n if (!eventBusService) throw new Error(\"EventBusService must not be null\")\n if (!interceptorProvider) throw new Error(\"interceptorProvider must not be null\")\n\n this.serviceIdentifier = serviceIdentifier\n this.serviceInstance = serviceInstance\n this.eventBusService = eventBusService\n this.interceptorProvider = interceptorProvider\n\n this.log = options.logger || createDebugLogger(\"continuum:ServiceInvocationSupervisor\")\n this.argumentResolver = options.argumentResolver || new JsonArgumentResolver()\n this.returnValueConverter = options.returnValueConverter || new BasicReturnValueConverter()\n\n this.methodMap = this.buildMethodMap(serviceInstance)\n }\n\n public isActive(): boolean {\n return this.active\n }\n\n public start(): void {\n if (this.active) {\n throw new Error(\"Service already started\")\n }\n this.active = true\n\n const criBase = this.serviceIdentifier.cri().baseResource()\n this.methodSubscription = this.eventBusService\n .observe(criBase)\n .subscribe({\n next: async (event: IEvent) => {\n await this.processEvent(event);\n },\n error: (error: Error) => {\n this.log.error(\"Event listener error\", error)\n this.active = false\n },\n complete: () => {\n this.log.error(\"Event listener stopped unexpectedly. Setting supervisor inactive.\")\n this.active = false\n },\n })\n\n this.log.info(`ServiceInvocationSupervisor started for ${criBase}`)\n }\n\n public stop(): void {\n if (!this.active) {\n throw new Error(\"Service already stopped\")\n }\n this.active = false\n\n if (this.methodSubscription) {\n this.methodSubscription.unsubscribe()\n this.methodSubscription = null\n }\n\n this.log.info(\"ServiceInvocationSupervisor stopped\")\n }\n\n private buildMethodMap(serviceInstance: any): Record<string, (...args: any[]) => any> {\n const methodMap: Record<string, (...args: any[]) => any> = {}\n for (const key of Object.getOwnPropertyNames(Object.getPrototypeOf(serviceInstance))) {\n const method = serviceInstance[key]\n if (typeof method === \"function\" && key !== \"constructor\") {\n methodMap[key] = method.bind(serviceInstance)\n }\n }\n return methodMap\n }\n\n private async processEvent(event: IEvent): Promise<void> {\n const isControl = event.hasHeader(EventConstants.CONTROL_HEADER)\n this.log.trace(`Service ${isControl ? \"Control\" : \"Invocation\"} requested for ${event.cri}`)\n\n try {\n if (isControl) {\n this.processControlPlaneRequest(event)\n } else {\n if (this.validateReplyTo(event)) {\n await this.processInvocationRequest(event)\n } else {\n this.log.error(`ReplyTo header missing or invalid. Ignoring event: ${JSON.stringify(event)}`)\n }\n }\n } catch (e) {\n this.log.debug(`Exception processing service request: ${JSON.stringify(event)}`, e)\n this.handleException(event, e)\n }\n }\n\n private processControlPlaneRequest(event: IEvent): void {\n const correlationId = event.getHeader(EventConstants.CORRELATION_ID_HEADER)\n if (!correlationId) {\n throw new Error(\"Streaming control plane messages require a CORRELATION_ID_HEADER\")\n }\n this.log.trace(`Processing control event for correlationId: ${correlationId}`)\n }\n\n private async processInvocationRequest(event: IEvent): Promise<void> {\n const path = createCRI(event.cri).path()\n if (!path) {\n throw new Error(\"The methodId must not be blank\")\n }\n\n const handlerMethod = this.methodMap[path]\n if (!handlerMethod) {\n throw new Error(`No method resolved for methodId ${path}`)\n }\n\n const methodName = path;\n const args = this.argumentResolver.resolveArguments(event)\n const contextIndices: number[] = Reflect.getMetadata(CONTEXT_METADATA_KEY, this.serviceInstance, methodName) || [];\n\n // Create context using interceptor\n let context: ServiceContext = {};\n const interceptor = this.interceptorProvider();\n if (interceptor) {\n try {\n context = await interceptor.intercept(event, context);\n } catch (e) {\n this.log.error(`Interceptor failed to create context for event: ${JSON.stringify(event)}`, e)\n this.handleException(event, new Error(\"Internal server error\"))\n return\n }\n }\n\n // Inject context into arguments where @Context is used\n for (const index of contextIndices) {\n args[index] = context;\n }\n\n const expectedArgsCount = handlerMethod.length\n if (args.length !== expectedArgsCount) {\n throw new Error(`Argument count mismatch for method ${path}: expected ${expectedArgsCount}, got ${args.length}`)\n }\n\n let result: any\n try {\n result = handlerMethod(...args)\n if (result instanceof Promise) {\n result.then(\n (resolved) => this.processMethodInvocationResult(event, resolved),\n (error) => this.handleException(event, error)\n )\n } else {\n this.processMethodInvocationResult(event, result)\n }\n } catch (e) {\n this.handleException(event, e)\n }\n }\n\n private processMethodInvocationResult(event: IEvent, result: any): void {\n const outgoingEvent = this.returnValueConverter.convert(event.headers, result)\n this.eventBusService.send(outgoingEvent)\n }\n\n private handleException(event: IEvent, error: any): void {\n const errorEvent = EventUtil.createReplyEvent(\n event.headers,\n new Map([\n [EventConstants.ERROR_HEADER, error.message || \"Unknown error\"],\n [EventConstants.CONTENT_TYPE_HEADER, \"application/json\"]\n ]),\n new TextEncoder().encode(JSON.stringify({ message: error.message }))\n )\n this.eventBusService.send(errorEvent)\n }\n\n private validateReplyTo(event: IEvent): boolean {\n const replyTo = event.getHeader(EventConstants.REPLY_TO_HEADER)\n if (!replyTo) {\n this.log.warn(\"No reply-to header found in event\")\n return false\n }\n if (replyTo.trim() === \"\") {\n this.log.warn(\"Reply-to header must not be blank\")\n return false\n }\n if (!replyTo.startsWith(`${EventConstants.SERVICE_DESTINATION_SCHEME}:`)) {\n this.log.warn(\"Reply-to header must be a valid service destination\")\n return false\n }\n return true\n }\n}\n","/*\n * Copyright 2008-2021 Kinotic and the original author or authors.\n * Licensed under the Apache License, Version 2.0 (the \"License\")\n * See https://www.apache.org/licenses/LICENSE-2.0\n */\n\nimport { ContinuumContextStack } from '@/api/Continuum'\nimport { ServiceIdentifier } from './ServiceIdentifier.js'\nimport { ServiceInvocationSupervisor } from '@/internal/core/api/ServiceInvocationSupervisor.js'\nimport opentelemetry, { SpanKind, SpanStatusCode, Tracer } from '@opentelemetry/api'\nimport {\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n} from '@opentelemetry/semantic-conventions'\nimport { Observable } from 'rxjs'\nimport { first, map } from 'rxjs/operators'\nimport info from '../../../package.json' assert { type: 'json' }\nimport { Event } from './EventBus'\nimport { EventConstants, IEvent, IEventBus } from './IEventBus'\nimport { IEventFactory, IServiceProxy, IServiceRegistry } from './IServiceRegistry'\nimport { ContextInterceptor, ServiceContext } from './ContextInterceptor'\n\n/**\n * An implementation of a {@link IEventFactory} which uses JSON content\n */\nexport class JsonEventFactory implements IEventFactory {\n create(cri: string, args: any[] | null | undefined): IEvent {\n const event: Event = new Event(cri)\n event.setHeader(EventConstants.CONTENT_TYPE_HEADER, EventConstants.CONTENT_JSON)\n if (args != null) {\n event.setDataString(JSON.stringify(args))\n }\n return event\n }\n}\n\n/**\n * An implementation of a {@link IEventFactory} which uses text content\n */\nexport class TextEventFactory implements IEventFactory {\n create(cri: string, args: any[] | null | undefined): IEvent {\n const event: Event = new Event(cri)\n event.setHeader(EventConstants.CONTENT_TYPE_HEADER, EventConstants.CONTENT_TEXT)\n if (args != null) {\n let data: string = ''\n let i = 0\n for (const arg of args) {\n if (i > 0) {\n data = data + '\\n'\n }\n data = data + arg\n i++\n }\n if (data.length > 0) {\n event.setDataString(data)\n }\n }\n return event\n }\n}\n\n/**\n * The default implementation of {@link IServiceRegistry}\n */\nexport class ServiceRegistry implements IServiceRegistry {\n private readonly eventBus: IEventBus\n private readonly supervisors: Map<string, ServiceInvocationSupervisor> = new Map()\n private contextInterceptor: ContextInterceptor<any> | null = null\n\n constructor(eventBus: IEventBus) {\n this.eventBus = eventBus\n }\n\n public serviceProxy(serviceIdentifier: string): IServiceProxy {\n return new ServiceProxy(serviceIdentifier, this.eventBus)\n }\n\n public register(serviceIdentifier: ServiceIdentifier, service: any): void {\n const criString = serviceIdentifier.cri().raw()\n if (!this.supervisors.has(criString)) {\n const supervisor = new ServiceInvocationSupervisor(\n serviceIdentifier,\n service,\n this.eventBus,\n () => this.contextInterceptor\n )\n this.supervisors.set(criString, supervisor)\n supervisor.start()\n }\n }\n\n public unRegister(serviceIdentifier: ServiceIdentifier): void {\n const criString = serviceIdentifier.cri().raw()\n const supervisor = this.supervisors.get(criString)\n if (supervisor) {\n supervisor.stop()\n this.supervisors.delete(criString)\n }\n }\n\n public registerContextInterceptor<T extends ServiceContext>(interceptor: ContextInterceptor<T> | null): void {\n this.contextInterceptor = interceptor\n }\n}\n\n/**\n * The default implementation of {@link IEventFactory} which uses JSON content\n */\nconst defaultEventFactory: IEventFactory = new JsonEventFactory()\n\n/**\n * For internal use only should not be instantiated directly\n */\nclass ServiceProxy implements IServiceProxy {\n public readonly serviceIdentifier: string\n private readonly eventBus: IEventBus\n private tracer: Tracer\n\n constructor(serviceIdentifier: string, eventBus: IEventBus) {\n if (typeof serviceIdentifier === 'undefined' || serviceIdentifier.length === 0) {\n throw new Error('The serviceIdentifier provided must contain a value')\n }\n this.serviceIdentifier = serviceIdentifier\n this.eventBus = eventBus\n this.tracer = opentelemetry.trace.getTracer(\n 'continuum.client',\n info.version\n )\n }\n\n invoke(methodIdentifier: string,\n args?: any[] | null | undefined,\n scope?: string | null | undefined,\n eventFactory?: IEventFactory | null | undefined): Promise<any> {\n return this.tracer.startActiveSpan(\n `${this.serviceIdentifier}/${methodIdentifier}`,\n {\n kind: SpanKind.CLIENT\n },\n async (span) => {\n if (scope) {\n span.setAttribute('continuum.scope', scope)\n }\n span.setAttribute('rpc.system', 'continuum')\n span.setAttribute('rpc.service', this.serviceIdentifier)\n span.setAttribute('rpc.method', methodIdentifier)\n\n return this.__invokeStream(false, methodIdentifier, args, scope, eventFactory)\n .pipe(first())\n .toPromise()\n .then(\n async (value) => {\n span.end()\n return value\n },\n async (ex) => {\n span.recordException(ex)\n span.setStatus({ code: SpanStatusCode.ERROR })\n span.end()\n throw ex\n })\n })\n }\n\n invokeStream(methodIdentifier: string,\n args?: any[] | null | undefined,\n scope?: string | null | undefined,\n eventFactory?: IEventFactory | null | undefined): Observable<any> {\n return this.__invokeStream(true, methodIdentifier, args, scope, eventFactory)\n }\n\n private __invokeStream(sendControlEvents: boolean,\n methodIdentifier: string,\n args?: any[] | null | undefined,\n scope?: string | null | undefined,\n eventFactory?: IEventFactory | null | undefined): Observable<any> {\n const cri: string = EventConstants.SERVICE_DESTINATION_PREFIX + (scope != null ? scope + '@' : '') + this.serviceIdentifier + '/' + methodIdentifier\n let eventFactoryToUse = defaultEventFactory\n if (eventFactory) {\n eventFactoryToUse = eventFactory\n } else if (ContinuumContextStack.getEventFactory()) {\n eventFactoryToUse = ContinuumContextStack.getEventFactory()!\n }\n\n let eventBusToUse = this.eventBus\n if (ContinuumContextStack.getContinuumInstance()) {\n eventBusToUse = ContinuumContextStack.getContinuumInstance()!.eventBus\n }\n\n // store additional attribute if there is an active span\n const span = opentelemetry.trace.getActiveSpan()\n if (span) {\n span.setAttribute(ATTR_SERVER_ADDRESS, eventBusToUse.serverInfo?.host || 'unknown')\n span.setAttribute(ATTR_SERVER_PORT, eventBusToUse.serverInfo?.port || 'unknown')\n }\n\n let event: IEvent = eventFactoryToUse.create(cri, args)\n\n return eventBusToUse.requestStream(event, sendControlEvents)\n .pipe(map<IEvent, any>((value: IEvent): any => {\n const contentType: string | undefined = value.getHeader(EventConstants.CONTENT_TYPE_HEADER)\n if (contentType !== undefined) {\n if (contentType === 'application/json') {\n return JSON.parse(value.getDataString())\n } else if (contentType === 'text/plain') {\n return value.getDataString()\n } else {\n throw new Error('Content Type ' + contentType + ' is not supported')\n }\n } else {\n return null\n }\n }))\n }\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {IterablePage} from '@/core/api/crud/IterablePage'\nimport {Page} from '@/core/api/crud/Page'\nimport {CursorPageable, OffsetPageable, Pageable} from '@/core/api/crud/Pageable'\n\nexport abstract class AbstractIterablePage<T> implements IterablePage<T> {\n\n private readonly pageable: Pageable\n private currentPage: Page<T>\n private firstPage: boolean = true\n\n protected constructor(pageable: Pageable,\n page: Page<T>) {\n this.pageable = pageable\n this.currentPage = page\n }\n\n /**\n * Finds the next page of results based on the given pageable\n * @param pageable to use to find the next page\n * @return the next page of results\n */\n protected abstract findNext(pageable: Pageable): Promise<Page<T>>;\n\n async next(): Promise<IteratorResult<IterablePage<T>>> {\n let ret: IteratorResult<IterablePage<T>>\n\n if(this.firstPage) {\n this.firstPage = false\n // Check has content in case this is an empty page\n // Such as when querying entities with no results\n ret = {done: !this.hasContent(), value: this}\n } else {\n if(this.isOffsetPageable()){\n\n const offsetPageable = this.pageable as OffsetPageable\n offsetPageable.pageNumber++\n\n // ignoring undefined should be fine since OffsetPageable should always have totalElements\n const numPages = Math.ceil(this.totalElements as number / this.pageable.pageSize)\n\n // Check if we are still less than the number of pages\n if(offsetPageable.pageNumber < numPages){\n this.currentPage = await this.findNext(this.pageable)\n ret = {done: false, value: this}\n }else{\n ret = {done: true, value: this}\n }\n }else{\n\n const cursorPageable = this.pageable as CursorPageable\n cursorPageable.cursor = this.currentPage.cursor as string || null\n\n this.currentPage = await this.findNext(this.pageable)\n\n // The last page will have a null cursor, so this will work correctly\n ret = {done: this.isLastPage(), value: this}\n }\n }\n return ret\n }\n\n [Symbol.asyncIterator](): AsyncIterableIterator<IterablePage<T>> {\n return this\n }\n\n hasContent(): boolean {\n return this.currentPage.content !== null && this.currentPage.content !== undefined && this.currentPage.content.length > 0\n }\n\n isLastPage(): boolean {\n let ret: boolean\n if (this.isOffsetPageable()) {\n // ignoring undefined should be fine since OffsetPageable should always have totalElements\n const numPages = Math.ceil(this.totalElements as number / this.pageable.pageSize)\n ret = numPages === (this.pageable as OffsetPageable).pageNumber + 1\n }else{\n ret = !this.firstPage && this.currentPage.cursor === null\n }\n return ret\n }\n\n private isOffsetPageable(): boolean {\n return (this.pageable as OffsetPageable).pageNumber !== undefined\n }\n\n get totalElements(): number | null | undefined {\n return this.currentPage.totalElements\n }\n\n get cursor(): string | null | undefined {\n return this.currentPage.cursor\n }\n\n get content(): T[] | null | undefined {\n return this.currentPage.content\n }\n\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {Identifiable} from '@/api/Identifiable'\nimport {AbstractIterablePage} from '@/core/api/crud/AbstractIterablePage'\nimport {CrudServiceProxy} from '@/core/api/crud/CrudServiceProxy'\nimport {Page} from '@/core/api/crud/Page'\nimport {Pageable} from '@/core/api/crud/Pageable'\n\n/**\n * {@link IterablePage} for use when finding all\n */\nexport class FindAllIterablePage<T extends Identifiable<string>> extends AbstractIterablePage<T> {\n\n private readonly crudServiceProxy: CrudServiceProxy<T>\n\n constructor(pageable: Pageable,\n page: Page<T>,\n crudServiceProxy: CrudServiceProxy<T>) {\n super(pageable, page)\n this.crudServiceProxy = crudServiceProxy\n }\n\n protected findNext(pageable: Pageable): Promise<Page<T>> {\n return this.crudServiceProxy.findAllSinglePage(pageable)\n }\n\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {Identifiable} from '@/api/Identifiable'\nimport {AbstractIterablePage} from '@/core/api/crud/AbstractIterablePage'\nimport {CrudServiceProxy} from '@/core/api/crud/CrudServiceProxy'\nimport {Page} from '@/core/api/crud/Page'\nimport {Pageable} from '@/core/api/crud/Pageable'\n\n/**\n * {@link IterablePage} for use when searching\n */\nexport class SearchIterablePage<T extends Identifiable<string>> extends AbstractIterablePage<T> {\n\n private readonly searchText: string\n private readonly crudServiceProxy: CrudServiceProxy<T>\n\n constructor(pageable: Pageable,\n page: Page<T>,\n searchText: string,\n crudServiceProxy: CrudServiceProxy<T>) {\n super(pageable, page)\n this.searchText = searchText\n this.crudServiceProxy = crudServiceProxy\n }\n\n protected findNext(pageable: Pageable): Promise<Page<T>> {\n return this.crudServiceProxy.searchSinglePage(this.searchText, pageable)\n }\n\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {FindAllIterablePage} from '@/internal/core/api/crud/FindAllIterablePage'\nimport {SearchIterablePage} from '@/internal/core/api/crud/SearchIterablePage'\nimport { ICrudServiceProxy } from './ICrudServiceProxy'\nimport { IServiceProxy } from '../IServiceRegistry'\nimport {Identifiable, IterablePage} from '@/index'\nimport { Page } from './Page'\nimport { Pageable } from './Pageable'\n\nexport class CrudServiceProxy<T extends Identifiable<string>> implements ICrudServiceProxy<T> {\n\n protected serviceProxy: IServiceProxy\n\n constructor(serviceProxy: IServiceProxy) {\n this.serviceProxy = serviceProxy\n }\n\n public count(): Promise<number> {\n return this.serviceProxy.invoke('count')\n }\n\n public create(entity: T): Promise<T> {\n return this.serviceProxy.invoke('create', [entity])\n }\n\n public deleteById(id: string): Promise<void> {\n return this.serviceProxy.invoke('deleteById', [id])\n }\n\n public async findAll(pageable: Pageable): Promise<IterablePage<T>> {\n const page = await this.findAllSinglePage(pageable)\n return new FindAllIterablePage(pageable, page, this)\n }\n\n public findAllSinglePage(pageable: Pageable): Promise<Page<T>> {\n return this.serviceProxy.invoke('findAll', [pageable])\n }\n\n public findById(id: string): Promise<T> {\n return this.serviceProxy.invoke('findById', [id])\n }\n\n public save(entity: T): Promise<T> {\n return this.serviceProxy.invoke('save', [entity])\n }\n\n public findByIdNotIn(ids: string[], page: Pageable): Promise<Page<Identifiable<string>>> {\n return (this.serviceProxy as IServiceProxy).invoke('findByIdNotIn', [ids, page])\n }\n\n public async search(searchText: string, pageable: Pageable): Promise<IterablePage<T>> {\n const page = await this.searchSinglePage(searchText, pageable)\n return new SearchIterablePage(pageable, page, searchText, this)\n }\n\n public searchSinglePage(searchText: string, pageable: Pageable): Promise<Page<T>> {\n return this.serviceProxy.invoke('search', [searchText, pageable])\n }\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ICrudServiceProxyFactory } from './ICrudServiceProxyFactory'\nimport { ICrudServiceProxy } from './ICrudServiceProxy'\nimport { CrudServiceProxy } from './CrudServiceProxy'\nimport { Identifiable } from '@/index'\nimport { IServiceRegistry } from '@/core/api/IServiceRegistry'\n\n\n/**\n * Default implementation of {@link ICrudServiceProxyFactory}\n */\nexport class CrudServiceProxyFactory implements ICrudServiceProxyFactory {\n\n private serviceRegistry: IServiceRegistry\n\n constructor(serviceRegistry: IServiceRegistry) {\n this.serviceRegistry = serviceRegistry\n }\n\n public crudServiceProxy<T extends Identifiable<string>>(serviceIdentifier: string): ICrudServiceProxy<T> {\n if ( typeof serviceIdentifier === 'undefined' || serviceIdentifier.length === 0 ) {\n throw new Error('The serviceIdentifier provided must contain a value')\n }\n return new CrudServiceProxy<T>(this.serviceRegistry.serviceProxy(serviceIdentifier))\n }\n\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { EventBus } from '@/core/api/EventBus'\nimport {IEventBus} from '@/core/api/IEventBus'\nimport { ServiceRegistry } from '@/core/api/ServiceRegistry'\nimport {IEventFactory, IServiceProxy} from '@/core/api/IServiceRegistry'\nimport {Identifiable} from '@/api/Identifiable'\nimport {ICrudServiceProxy} from '@/core/api/crud/ICrudServiceProxy'\nimport {CrudServiceProxyFactory} from '@/core/api/crud/CrudServiceProxyFactory'\nimport {ConnectedInfo} from '@/api/security/ConnectedInfo'\nimport {ConnectionInfo} from '@/api/ConnectionInfo'\n\n\n/**\n * Provides a way to store the current {@link ContinuumSingleton} and {@link IEventFactory} instances\n * This allows the {@link IServiceProxy} instances to dynamically switch between different {@link ContinuumSingleton} and {@link IEventFactory} instances\n */\ntype ContinuumContext = {\n instance?: ContinuumSingleton\n eventFactory?: IEventFactory\n}\n\n/**\n * Interface that defines the methods needed to manage the current {@link ContinuumContext} instance\n */\ninterface IContinuumContextStack {\n /**\n * Returns the current Continuum instance to use for all {@link IServiceProxy} instances invoked with {@link ContinuumContext.execute}\n */\n getContinuumInstance(): ContinuumSingleton | undefined\n\n /**\n * Returns the current event factory to use for all {@link IServiceProxy} instances invoked with {@link ContinuumContext.execute}\n */\n getEventFactory(): IEventFactory | undefined\n}\n\n/**\n * Provides a way to store the current {@link ContinuumContext} instance\n * This is used to allow for {@link IServiceProxy} instances to dynamically switch between different {@link ContinuumSingleton} instances\n */\nclass ContinuumContextStackClass implements IContinuumContextStack {\n\n private continuumOverride: ContinuumContext[] = []\n\n getContinuumInstance(): ContinuumSingleton | undefined {\n return this.continuumOverride[this.continuumOverride.length - 1]?.instance\n }\n\n getEventFactory(): IEventFactory | undefined{\n return this.continuumOverride[this.continuumOverride.length - 1]?.eventFactory\n }\n\n /**\n * Sets the current {@link ContinuumContext} instance to use for all {@link IServiceProxy} instances invoked with {@link ContinuumContext.execute}\n * @param continuumContext\n */\n push(continuumContext: ContinuumContext): void {\n this.continuumOverride.push(continuumContext)\n }\n\n /**\n * Removes the current {@link ContinuumContext} from the stack\n */\n pop(): void {\n this.continuumOverride.pop()\n }\n}\n\n/**\n * The default {@link ContinuumContextStackClass} instance that can be used to manage the current {@link ContinuumContext} instance\n */\nexport const ContinuumContextStack: IContinuumContextStack = new ContinuumContextStackClass()\n\n/**\n * Provides a simplified way to connect to Continuum and access services.\n * All methods use a single connection to the Continuum Services\n */\nexport class ContinuumSingleton {\n /**\n * The {@link IEventBus} that is used to communicate with the Continuum server\n */\n public readonly eventBus!: IEventBus\n /**\n * The {@link ServiceRegistry} that is used to manage the services that are available\n */\n public readonly serviceRegistry!: ServiceRegistry\n /**\n * The {@link CrudServiceProxyFactory} that is used to create {@link ICrudServiceProxy} instances\n */\n public readonly crudServiceProxyFactory!: CrudServiceProxyFactory\n\n constructor() {\n this.eventBus = new EventBus()\n this.serviceRegistry = new ServiceRegistry(this.eventBus)\n this.crudServiceProxyFactory = new CrudServiceProxyFactory(this.serviceRegistry)\n }\n\n /**\n * Requests a connection to the given Stomp url\n * @param connectionInfo provides the information needed to connect to the continuum server\n * @return Promise containing the result of the initial connection attempt\n */\n public connect(connectionInfo: ConnectionInfo): Promise<ConnectedInfo> {\n return this.eventBus.connect(connectionInfo)\n }\n\n /**\n * Disconnects the client from the server\n * This will clear any subscriptions and close the connection\n */\n public disconnect(force?: boolean): Promise<void> {\n return this.eventBus.disconnect(force)\n }\n\n /**\n * Creates a new service proxy that can be used to access the desired service.\n * @param serviceIdentifier the identifier of the service to be accessed\n * @return the {@link IServiceProxy} that can be used to access the service\n */\n public serviceProxy(serviceIdentifier: string): IServiceProxy {\n return this.serviceRegistry.serviceProxy(serviceIdentifier)\n }\n\n /**\n * Returns a {@link ICrudServiceProxy} for the given service identifier\n * @param serviceIdentifier the identifier of the service to be accessed\n */\n public crudServiceProxy<T extends Identifiable<string>>(serviceIdentifier: string): ICrudServiceProxy<T> {\n return this.crudServiceProxyFactory.crudServiceProxy<T>(serviceIdentifier)\n }\n\n /**\n * Allows for the execution of a function that requires a connection to the Continuum server\n * When the function is executed any calls using an {@link IServiceProxy} will be executed using the connection defined by this {@link ContinuumSingleton}\n * @param toExecute the function to execute\n * @param eventFactory an optional {@link IEventFactory} to use for the duration of the execution\n * @return the result of the function that was executed\n * @deprecated we have decided to deprecate this method as it is not thread safe and can cause issues when used in async operations\n * NOTE: this method is experimental and does not work well across multiple threads / async operations\n */\n public async execute(toExecute: () => Promise<any>, eventFactory?: IEventFactory): Promise<any> {\n const stack = ContinuumContextStack as ContinuumContextStackClass\n stack.push({instance: this, eventFactory: eventFactory})\n\n let ret: any\n try {\n ret = await toExecute()\n } finally {\n stack.pop()\n }\n\n return ret\n }\n}\n\n/**\n * The default {@link ContinuumSingleton} instance that can be used to access Continuum services\n */\nexport const Continuum = new ContinuumSingleton()\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport enum LogLevel {\n TRACE = 'TRACE',\n DEBUG = 'DEBUG',\n INFO = 'INFO',\n WARN = 'WARN',\n ERROR = 'ERROR',\n FATAL = 'FATAL',\n OFF = 'OFF'\n}\n\nexport class LoggerLevelsDescriptor {\n public configuredLevel?: LogLevel;\n}\n\nexport class GroupLoggerLevelsDescriptor extends LoggerLevelsDescriptor {\n public members: string[] = [];\n}\n\nexport class SingleLoggerLevelsDescriptor extends LoggerLevelsDescriptor {\n public effectiveLevel?: LogLevel;\n}\n\n/**\n * Description of loggers\n */\nexport class LoggersDescriptor {\n public levels: LogLevel[] = []\n public loggerLevels: Map<string, SingleLoggerLevelsDescriptor> = new Map()\n public groups: Map<string, GroupLoggerLevelsDescriptor> = new Map()\n}\n\n/**\n * Provides the ability to manage loggers\n */\nexport interface ILogManager {\n\n /**\n * @param nodeId the continuum node to get the LoggersDescriptor from\n * @return a {@link LoggersDescriptor} containing all the loggers and their levels\n */\n loggers(nodeId: string): Promise<LoggersDescriptor>\n\n /**\n * @param nodeId the continuum node to get the LoggerLevelsDescriptor from\n * @param name the name of the logger to get\n * @return a {@link LoggerLevelsDescriptor} containing the logger and its levels\n */\n loggerLevels(nodeId: string, name: string): Promise<LoggerLevelsDescriptor>\n\n /**\n * Configures the log level for the logger with the given name\n * @param nodeId the continuum node to set the log level on\n * @param name the name of the logger to set\n * @param level the {@link LogLevel} to set for the logger with the given name\n */\n configureLogLevel(nodeId: string, name: string, level: LogLevel): Promise<void>\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ILogManager,\n LogLevel,\n LoggersDescriptor,\n LoggerLevelsDescriptor,\n SingleLoggerLevelsDescriptor,\n GroupLoggerLevelsDescriptor} from './ILogManager'\nimport { IServiceProxy } from '@/core/api/IServiceRegistry'\nimport { Continuum } from '@/api/Continuum'\n\nexport class LogManager implements ILogManager {\n private readonly serviceProxy: IServiceProxy\n\n constructor() {\n this.serviceProxy = Continuum.serviceProxy('org.kinotic.continuum.api.log.LogManager')\n }\n\n loggers(nodeId: string): Promise<LoggersDescriptor> {\n return this.serviceProxy.invoke('loggers', null, nodeId)\n }\n\n async loggerLevels(nodeId: string, name: string): Promise<LoggerLevelsDescriptor> {\n const data: any = await this.serviceProxy.invoke('loggerLevels', [name], nodeId)\n let ret: LoggerLevelsDescriptor | null = null;\n if(data.hasOwnProperty('members')) {\n ret = new GroupLoggerLevelsDescriptor()\n }else if(data.hasOwnProperty('effectiveLevel')) {\n ret = new SingleLoggerLevelsDescriptor()\n }else{\n ret = new LoggerLevelsDescriptor()\n }\n Object.assign(ret, data)\n return ret\n }\n\n configureLogLevel(nodeId: string, name: string, level: LogLevel): Promise<void> {\n return this.serviceProxy.invoke('configureLogLevel', [name, level], nodeId)\n }\n}\n\nexport const logManager = new LogManager()\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ContinuumError } from './ContinuumError'\n\nexport class AuthenticationError extends ContinuumError {\n\n constructor(message: string) {\n super(message);\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ContinuumError } from './ContinuumError'\n\nexport class AuthorizationError extends ContinuumError {\n\n constructor(message: string) {\n super(message);\n Object.setPrototypeOf(this, AuthorizationError.prototype);\n }\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {Participant} from '@/api/security/Participant'\n\n/**\n * Contains\n */\nexport class ConnectedInfo {\n\n public sessionId!: string;\n\n public replyToId!: string;\n\n public participant!: Participant;\n\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { IParticipant } from './IParticipant'\n\n/**\n * Created by Navid Mitchell on 6/2/20\n */\nexport class Participant implements IParticipant {\n\n public id: string;\n\n public tenantId?: string | null;\n\n public metadata: Map<string, string>;\n\n public roles: string[];\n\n constructor(id: string,\n tenantId?: string,\n metadata?: Map<string, string>,\n roles?: string[]) {\n this.id = id\n this.tenantId = tenantId;\n this.metadata = metadata || new Map();\n this.roles = roles || [];\n }\n\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Some common constants used for the {@link Participant} and {@link Participant#getMetadata()}\n * Created by navid on 2/3/20\n */\nexport class ParticipantConstants {\n static readonly PARTICIPANT_TYPE_METADATA_KEY: string = 'type'\n static readonly PARTICIPANT_TYPE_DEVICE: string = 'device'\n static readonly PARTICIPANT_TYPE_CLI: string = 'cli'\n static readonly PARTICIPANT_TYPE_USER: string = 'user'\n static readonly PARTICIPANT_TYPE_NODE: string = 'node'\n static readonly CLI_PARTICIPANT_ID: string = '-42-Continuum-CLI-42-'\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Identifiable } from '@/index'\n\nexport enum StreamOperation {\n EXISTING = 'EXISTING',\n UPDATE = 'UPDATE',\n REMOVE = 'REMOVE'\n}\n\n/**\n * Holder for domain objects that will be returned as a stream of changes to a data set\n *\n * Created by Navid Mitchell on 6/3/20\n */\nexport class StreamData<I, T> implements Identifiable<I> {\n\n public streamOperation: StreamOperation\n\n public id: I\n\n public value: T\n\n constructor(streamOperation: StreamOperation, id: I, value: T) {\n this.streamOperation = streamOperation\n this.id = id\n this.value = value\n }\n\n public isSet(): boolean {\n return this.value !== null && this.value !== undefined\n }\n\n}\n","import {AbstractIterablePage} from \"./AbstractIterablePage\"\nimport {Page} from \"./Page\"\nimport {Pageable} from \"./Pageable\"\n\nexport class FunctionalIterablePage<T> extends AbstractIterablePage<T> {\n\n private readonly pageFunction: (pageable: Pageable) => Promise<Page<T>>\n\n constructor(pageable: Pageable,\n page: Page<T>,\n pageFunction: (pageable: Pageable) => Promise<Page<T>>) {\n super(pageable, page)\n this.pageFunction = pageFunction\n }\n\n protected findNext(pageable: Pageable): Promise<Page<T>> {\n return this.pageFunction(pageable)\n }\n\n}\n","/*\n *\n * Copyright 2008-2021 Kinotic and the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the 'License')\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an 'AS IS' BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {Pageable} from './Pageable'\nimport {Page} from './Page'\nimport {Identifiable, IterablePage} from '@/index'\n\n/**\n * {@link IDataSource} provides an abstract way to retrieve data from various sources\n */\nexport interface IDataSource<T> {\n\n /**\n * Returns a {@link Page} of entities meeting the paging restriction provided in the {@code Pageable} object.\n *\n * @param pageable the page settings to be used\n * @return a {@link Promise} emitting the page of entities\n */\n findAll(pageable: Pageable): Promise<IterablePage<T>>\n\n /**\n * Returns a {@link Page} of entities matching the search text and paging restriction provided in the {@code Pageable} object.\n *\n * @param searchText the text to search for entities for\n * @param pageable the page settings to be used\n * @return a {@link Promise} emitting the page of entities\n */\n search(searchText: string, pageable: Pageable): Promise<IterablePage<T>>\n\n}\n\n\nexport interface IEditableDataSource<T extends Identifiable<string>> extends IDataSource<T>{\n\n /**\n * Creates a new entity if one does not already exist for the given id\n * @param entity to create if one does not already exist\n * @return a {@link Promise} containing the new entity or an error if an exception occurred\n */\n create(entity: T): Promise<T>\n\n /**\n * Saves a given entity. Use the returned instance for further operations as the save operation might have changed the\n * entity instance completely.\n *\n * @param entity must not be {@literal null}.\n * @return a {@link Promise} emitting the saved entity.\n * @throws Error in case the given {@literal entity} is {@literal null}.\n */\n save(entity: T): Promise<T>\n\n /**\n * Retrieves an entity by its id.\n *\n * @param id must not be {@literal null}.\n * @return a {@link Promise} emitting the entity with the given id or {@link Promise#empty()} if none found.\n * @throws IllegalArgumentException in case the given {@literal identity} is {@literal null}.\n */\n findById(id: string): Promise<T>\n\n /**\n * Deletes the entity with the given id.\n *\n * @param id must not be {@literal null}.\n * @return a {@link Promise} signaling when operation has completed.\n * @throws IllegalArgumentException in case the given {@literal identity} is {@literal null}.\n */\n deleteById(id: string): Promise<void>\n\n /**\n * Returns a {@link Page} of entities not in the ids list and meeting the paging restriction provided in the {@code Pageable} object.\n *\n * @param ids not to be returned in the Page\n * @param pageable the page settings to be used\n * @return a {@link Promise} emitting the page of entities\n */\n findByIdNotIn(ids: string[], pageable: Pageable): Promise<Page<Identifiable<string>>>\n}\n\n\nexport class DataSourceUtils {\n\n public static instanceOfEditableDataSource(datasource: IDataSource<any> | IEditableDataSource<any>): datasource is IEditableDataSource<any> {\n return 'create' in datasource\n }\n\n}\n","/*\n * Copyright 2008-2019 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {Sort} from './Sort'\n\n/**\n * Abstract interface for pagination information.\n *\n * Adapted from the Spring Data Commons Package\n *\n * @author Oliver Gierke\n * @author Navid Mitchell\n */\nexport abstract class Pageable {\n\n /**\n * Returns the sorting parameters (optional).\n */\n sort?: Sort | null | undefined = null\n\n /**\n * Returns the number of items to be returned.\n */\n pageSize: number = 25\n\n /**\n * Creates a {@link Pageable} that uses Offset based pagination.\n * @param pageNumber zero based page index.\n * @param pageSize the size of the page to be returned.\n * @param sort the sorting parameters (optional).\n */\n public static create(pageNumber: number, pageSize: number, sort?: Sort | null): OffsetPageable {\n return new OffsetPageable(pageNumber, pageSize, sort)\n }\n\n /**\n * Creates a {@link Pageable} that uses Cursor based pagination.\n * @param cursor the cursor to be used for subsequent retrieval of data, or null if this is the first page.\n * @param pageSize the size of the page to be returned.\n * @param sort the sorting parameters (optional).\n */\n public static createWithCursor(cursor: string | null, pageSize: number, sort?: Sort | null): CursorPageable {\n return new CursorPageable(cursor, pageSize, sort)\n }\n}\n\n/**\n * Implementation of {@link Pageable} that uses Offset based pagination.\n */\nexport class OffsetPageable extends Pageable {\n /**\n * Returns the page to be returned.\n */\n pageNumber: number = 0\n\n /**\n * Creates a {@link Pageable} that uses Offset based pagination.\n * @param pageNumber zero based page index.\n * @param pageSize the size of the page to be returned.\n * @param sort the sorting parameters (optional).\n */\n constructor(pageNumber: number, pageSize: number, sort?: Sort | null) {\n super()\n this.pageNumber = pageNumber\n this.pageSize = pageSize\n this.sort = sort\n }\n}\n\n/**\n * Implementation of {@link Pageable} that uses Cursor based pagination.\n */\nexport class CursorPageable extends Pageable {\n /**\n * The cursor to be used for subsequent retrieval of data, or null if this is the first page.\n */\n cursor: string | null\n\n /**\n * Creates a {@link Pageable} that uses Cursor based pagination.\n * @param cursor the cursor to be used for subsequent retrieval of data, or null if this is the first page.\n * @param pageSize the size of the page to be returned.\n * @param sort the sorting parameters (optional).\n */\n constructor(cursor: string | null, pageSize: number, sort?: Sort | null) {\n super()\n this.cursor = cursor\n this.pageSize = pageSize\n this.sort = sort\n }\n}\n","/*\n * Copyright 2008-2019 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Enumeration for sort directions.\n *\n * Adapted from the Spring Data Commons Package\n *\n * @author Oliver Gierke\n * @author Navid Mitchell\n */\nexport enum Direction {\n ASC = 'ASC',\n DESC = 'DESC'\n}\n\n/**\n * Enumeration for null handling hints that can be used in {@link Order} expressions.\n *\n * Adapted from the Spring Data Commons Package\n *\n * @author Thomas Darimont\n * @author Navid Mitchell\n * @since 1.8\n */\nexport enum NullHandling {\n\n /**\n * Lets the data store decide what to do with nulls.\n */\n NATIVE = 'NATIVE',\n\n /**\n * A hint to the used data store to order entries with null values before non-null entries.\n */\n NULLS_FIRST = 'NULLS_FIRST',\n\n /**\n * A hint to the used data store to order entries with null values after non-null entries.\n */\n NULLS_LAST = 'NULLS_LAST'\n}\n\nexport class Order {\n public property: string\n public direction: Direction = Direction.ASC\n public nullHandling: NullHandling = NullHandling.NATIVE\n\n constructor(property: string, direction: Direction | null) {\n this.property = property\n if (direction !== null) {\n this.direction = direction\n }\n }\n\n /**\n * Returns whether sorting for this property shall be ascending.\n */\n public isAscending(): boolean {\n return this.direction === Direction.ASC\n }\n\n /**\n * Returns whether sorting for this property shall be descending.\n */\n public isDescending(): boolean {\n return this.direction === Direction.DESC\n }\n\n}\n\n/**\n * Sort option for queries. You have to provide at least a list of properties to sort for that must not include\n * {@literal null} or empty strings. The direction defaults to {@link Sort#DEFAULT_DIRECTION}.\n *\n * Adapted from the Spring Data Commons Package\n *\n * @author Oliver Gierke\n * @author Thomas Darimont\n * @author Mark Paluch\n * @author Navid Mitchell\n */\nexport class Sort {\n\n public orders: Order[] = []\n\n}\n"],"names":["ConnectHeaders","ServerInfo","ConnectionInfo","ContinuumError","message","EventConstants","StompConnectionManager","debug","uuidv4","connectionInfo","resolve","reject","url","RxStomp","connectHeadersInternal","stompConfig","headers","key","msg","ReconnectionTimeMode","value","connectedSubscription","errorSubscription","serverHeadersSubscription","connectedInfoJson","connectedInfo","force","randomJitter","Event","cri","data","Optional","uint8Array","ret","EventBus","Subject","map","frame","error","event","carrier","propagation","context","firstValueFrom","sendControlEvents","Observable","subscriber","multicast","serverSignaledCompletion","correlationId","defaultMessagesSubscription","filter","err","controlEvent","throwError","destination","prop","DefaultCRI","args","rawURC","parsed","scheme","scope","resourceName","path","version","result","other","hash","a","c","raw","regex","match","createCRI","JsonArgumentResolver","contentType","EventUtil","incomingHeaders","body","replyCRI","newHeaders","BasicReturnValueConverter","incomingMetadata","returnValue","createDebugLogger","namespace","ServiceIdentifier","name","SCOPE_METADATA_KEY","VERSION_METADATA_KEY","CONTEXT_METADATA_KEY","Scope","target","propertyKey","descriptor","Version","Context","parameterIndex","existingContexts","Publish","original","serviceIdentifier","newConstructor","instance","scopeProperty","scopeValue","Continuum","ServiceInvocationSupervisor","serviceInstance","eventBusService","interceptorProvider","options","criBase","methodMap","method","isControl","e","handlerMethod","methodName","contextIndices","interceptor","index","expectedArgsCount","resolved","outgoingEvent","errorEvent","replyTo","JsonEventFactory","TextEventFactory","i","arg","ServiceRegistry","eventBus","ServiceProxy","service","criString","supervisor","defaultEventFactory","opentelemetry","info","methodIdentifier","eventFactory","SpanKind","span","first","ex","SpanStatusCode","eventFactoryToUse","ContinuumContextStack","eventBusToUse","ATTR_SERVER_ADDRESS","ATTR_SERVER_PORT","AbstractIterablePage","pageable","page","offsetPageable","numPages","cursorPageable","FindAllIterablePage","crudServiceProxy","SearchIterablePage","searchText","CrudServiceProxy","serviceProxy","entity","id","ids","CrudServiceProxyFactory","serviceRegistry","ContinuumContextStackClass","continuumContext","ContinuumSingleton","toExecute","stack","LogLevel","LoggerLevelsDescriptor","GroupLoggerLevelsDescriptor","SingleLoggerLevelsDescriptor","LoggersDescriptor","LogManager","nodeId","level","logManager","AuthenticationError","AuthorizationError","ConnectedInfo","Participant","tenantId","metadata","roles","ParticipantConstants","StreamOperation","StreamData","streamOperation","FunctionalIterablePage","pageFunction","DataSourceUtils","datasource","Pageable","pageNumber","pageSize","sort","OffsetPageable","cursor","CursorPageable","Direction","NullHandling","Order","property","direction","Sort"],"mappings":"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"}
|