@solana/subscribable 2.1.0 → 2.1.1-canary-20250310215239

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.
@@ -12,7 +12,7 @@ var t = globalThis.EventTarget;
12
12
  var EXPLICIT_ABORT_TOKEN;
13
13
  function createExplicitAbortToken() {
14
14
  return Symbol(
15
- process.env.NODE_ENV !== "production" ? "This symbol is thrown from a socket's iterator when the connection is explicitly aborted by the user" : undefined
15
+ process.env.NODE_ENV !== "production" ? "This symbol is thrown from a socket's iterator when the connection is explicitly aborted by the user" : void 0
16
16
  );
17
17
  }
18
18
  var UNINITIALIZED = Symbol();
@@ -186,7 +186,7 @@ function demultiplexDataPublisher(publisher, sourceChannelName, messageTransform
186
186
  innerPublisherState.numSubscribers--;
187
187
  if (innerPublisherState.numSubscribers === 0) {
188
188
  innerPublisherState.dispose();
189
- innerPublisherState = undefined;
189
+ innerPublisherState = void 0;
190
190
  }
191
191
  unsubscribe();
192
192
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../event-target-impl/src/index.browser.ts","../src/async-iterable.ts","../src/data-publisher.ts","../src/demultiplex.ts"],"names":["AbortController","EventTarget","SolanaError","SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING","SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE"],"mappings":"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","file":"index.browser.cjs","sourcesContent":["export const AbortController = globalThis.AbortController;\nexport const EventTarget = globalThis.EventTarget;\n","import {\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE,\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING,\n SolanaError,\n} from '@solana/errors';\nimport { AbortController } from '@solana/event-target-impl';\n\nimport { DataPublisher } from './data-publisher';\n\ntype Config = Readonly<{\n abortSignal: AbortSignal;\n dataChannelName: string;\n // FIXME: It would be nice to be able to constrain the type of `dataPublisher` to one that\n // definitely supports the `dataChannelName` and `errorChannelName` channels, and\n // furthermore publishes `TData` on the `dataChannelName` channel. This is more difficult\n // than it should be: https://tsplay.dev/NlZelW\n dataPublisher: DataPublisher;\n errorChannelName: string;\n}>;\n\nconst enum PublishType {\n DATA,\n ERROR,\n}\n\ntype IteratorKey = symbol;\ntype IteratorState<TData> =\n | {\n __hasPolled: false;\n publishQueue: (\n | {\n __type: PublishType.DATA;\n data: TData;\n }\n | {\n __type: PublishType.ERROR;\n err: unknown;\n }\n )[];\n }\n | {\n __hasPolled: true;\n onData: (data: TData) => void;\n onError: Parameters<ConstructorParameters<typeof Promise>[0]>[1];\n };\n\nlet EXPLICIT_ABORT_TOKEN: symbol;\nfunction createExplicitAbortToken() {\n // This function is an annoying workaround to prevent `process.env.NODE_ENV` from appearing at\n // the top level of this module and thwarting an optimizing compiler's attempt to tree-shake.\n return Symbol(\n process.env.NODE_ENV !== \"production\"\n ? \"This symbol is thrown from a socket's iterator when the connection is explicitly \" +\n 'aborted by the user'\n : undefined,\n );\n}\n\nconst UNINITIALIZED = Symbol();\n\nexport function createAsyncIterableFromDataPublisher<TData>({\n abortSignal,\n dataChannelName,\n dataPublisher,\n errorChannelName,\n}: Config): AsyncIterable<TData> {\n const iteratorState: Map<IteratorKey, IteratorState<TData>> = new Map();\n function publishErrorToAllIterators(reason: unknown) {\n for (const [iteratorKey, state] of iteratorState.entries()) {\n if (state.__hasPolled) {\n iteratorState.delete(iteratorKey);\n state.onError(reason);\n } else {\n state.publishQueue.push({\n __type: PublishType.ERROR,\n err: reason,\n });\n }\n }\n }\n const abortController = new AbortController();\n abortSignal.addEventListener('abort', () => {\n abortController.abort();\n publishErrorToAllIterators((EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken()));\n });\n const options = { signal: abortController.signal } as const;\n let firstError: unknown = UNINITIALIZED;\n dataPublisher.on(\n errorChannelName,\n err => {\n if (firstError === UNINITIALIZED) {\n firstError = err;\n abortController.abort();\n publishErrorToAllIterators(err);\n }\n },\n options,\n );\n dataPublisher.on(\n dataChannelName,\n data => {\n iteratorState.forEach((state, iteratorKey) => {\n if (state.__hasPolled) {\n const { onData } = state;\n iteratorState.set(iteratorKey, { __hasPolled: false, publishQueue: [] });\n onData(data as TData);\n } else {\n state.publishQueue.push({\n __type: PublishType.DATA,\n data: data as TData,\n });\n }\n });\n },\n options,\n );\n return {\n async *[Symbol.asyncIterator]() {\n if (abortSignal.aborted) {\n return;\n }\n if (firstError !== UNINITIALIZED) {\n throw firstError;\n }\n const iteratorKey = Symbol();\n iteratorState.set(iteratorKey, { __hasPolled: false, publishQueue: [] });\n try {\n while (true) {\n const state = iteratorState.get(iteratorKey);\n if (!state) {\n // There should always be state by now.\n throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING);\n }\n if (state.__hasPolled) {\n // You should never be able to poll twice in a row.\n throw new SolanaError(\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE,\n );\n }\n const publishQueue = state.publishQueue;\n try {\n if (publishQueue.length) {\n state.publishQueue = [];\n for (const item of publishQueue) {\n if (item.__type === PublishType.DATA) {\n yield item.data;\n } else {\n throw item.err;\n }\n }\n } else {\n yield await new Promise<TData>((resolve, reject) => {\n iteratorState.set(iteratorKey, {\n __hasPolled: true,\n onData: resolve,\n onError: reject,\n });\n });\n }\n } catch (e) {\n if (e === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {\n return;\n } else {\n throw e;\n }\n }\n }\n } finally {\n iteratorState.delete(iteratorKey);\n }\n },\n };\n}\n","import { TypedEventEmitter, TypedEventTarget } from './event-emitter';\n\ntype UnsubscribeFn = () => void;\n\nexport interface DataPublisher<TDataByChannelName extends Record<string, unknown> = Record<string, unknown>> {\n on<const TChannelName extends keyof TDataByChannelName>(\n channelName: TChannelName,\n subscriber: (data: TDataByChannelName[TChannelName]) => void,\n options?: { signal: AbortSignal },\n ): UnsubscribeFn;\n}\n\nexport function getDataPublisherFromEventEmitter<TEventMap extends Record<string, Event>>(\n eventEmitter: TypedEventEmitter<TEventMap> | TypedEventTarget<TEventMap>,\n): DataPublisher<{\n [TEventType in keyof TEventMap]: TEventMap[TEventType] extends CustomEvent ? TEventMap[TEventType]['detail'] : null;\n}> {\n return {\n on(channelName, subscriber, options) {\n function innerListener(ev: Event) {\n if (ev instanceof CustomEvent) {\n const data = (ev as CustomEvent<TEventMap[typeof channelName]>).detail;\n (subscriber as unknown as (data: TEventMap[typeof channelName]) => void)(data);\n } else {\n (subscriber as () => void)();\n }\n }\n eventEmitter.addEventListener(channelName, innerListener, options);\n return () => {\n eventEmitter.removeEventListener(channelName, innerListener);\n };\n },\n };\n}\n","import { EventTarget } from '@solana/event-target-impl';\n\nimport { DataPublisher, getDataPublisherFromEventEmitter } from './data-publisher';\n\nexport function demultiplexDataPublisher<\n TDataPublisher extends DataPublisher,\n const TChannelName extends Parameters<TDataPublisher['on']>[0],\n>(\n publisher: TDataPublisher,\n sourceChannelName: TChannelName,\n messageTransformer: (\n // FIXME: Deriving the type of the message from `TDataPublisher` and `TChannelName` would\n // help callers to constrain their transform functions.\n message: unknown,\n ) => [destinationChannelName: string, message: unknown] | void,\n): DataPublisher {\n let innerPublisherState:\n | {\n readonly dispose: () => void;\n numSubscribers: number;\n }\n | undefined;\n const eventTarget = new EventTarget();\n const demultiplexedDataPublisher = getDataPublisherFromEventEmitter(eventTarget);\n return {\n ...demultiplexedDataPublisher,\n on(channelName, subscriber, options) {\n if (!innerPublisherState) {\n const innerPublisherUnsubscribe = publisher.on(sourceChannelName, sourceMessage => {\n const transformResult = messageTransformer(sourceMessage);\n if (!transformResult) {\n return;\n }\n const [destinationChannelName, message] = transformResult;\n eventTarget.dispatchEvent(\n new CustomEvent(destinationChannelName, {\n detail: message,\n }),\n );\n });\n innerPublisherState = {\n dispose: innerPublisherUnsubscribe,\n numSubscribers: 0,\n };\n }\n innerPublisherState.numSubscribers++;\n const unsubscribe = demultiplexedDataPublisher.on(channelName, subscriber, options);\n let isActive = true;\n function handleUnsubscribe() {\n if (!isActive) {\n return;\n }\n isActive = false;\n options?.signal.removeEventListener('abort', handleUnsubscribe);\n innerPublisherState!.numSubscribers--;\n if (innerPublisherState!.numSubscribers === 0) {\n innerPublisherState!.dispose();\n innerPublisherState = undefined;\n }\n unsubscribe();\n }\n options?.signal.addEventListener('abort', handleUnsubscribe);\n return handleUnsubscribe;\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../../event-target-impl/src/index.browser.ts","../src/async-iterable.ts","../src/data-publisher.ts","../src/demultiplex.ts"],"names":["AbortController","EventTarget","SolanaError","SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING","SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE"],"mappings":"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","file":"index.browser.cjs","sourcesContent":["export const AbortController = globalThis.AbortController;\nexport const EventTarget = globalThis.EventTarget;\n","import {\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE,\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING,\n SolanaError,\n} from '@solana/errors';\nimport { AbortController } from '@solana/event-target-impl';\n\nimport { DataPublisher } from './data-publisher';\n\ntype Config = Readonly<{\n abortSignal: AbortSignal;\n dataChannelName: string;\n // FIXME: It would be nice to be able to constrain the type of `dataPublisher` to one that\n // definitely supports the `dataChannelName` and `errorChannelName` channels, and\n // furthermore publishes `TData` on the `dataChannelName` channel. This is more difficult\n // than it should be: https://tsplay.dev/NlZelW\n dataPublisher: DataPublisher;\n errorChannelName: string;\n}>;\n\nconst enum PublishType {\n DATA,\n ERROR,\n}\n\ntype IteratorKey = symbol;\ntype IteratorState<TData> =\n | {\n __hasPolled: false;\n publishQueue: (\n | {\n __type: PublishType.DATA;\n data: TData;\n }\n | {\n __type: PublishType.ERROR;\n err: unknown;\n }\n )[];\n }\n | {\n __hasPolled: true;\n onData: (data: TData) => void;\n onError: Parameters<ConstructorParameters<typeof Promise>[0]>[1];\n };\n\nlet EXPLICIT_ABORT_TOKEN: symbol;\nfunction createExplicitAbortToken() {\n // This function is an annoying workaround to prevent `process.env.NODE_ENV` from appearing at\n // the top level of this module and thwarting an optimizing compiler's attempt to tree-shake.\n return Symbol(\n process.env.NODE_ENV !== \"production\"\n ? \"This symbol is thrown from a socket's iterator when the connection is explicitly \" +\n 'aborted by the user'\n : undefined,\n );\n}\n\nconst UNINITIALIZED = Symbol();\n\nexport function createAsyncIterableFromDataPublisher<TData>({\n abortSignal,\n dataChannelName,\n dataPublisher,\n errorChannelName,\n}: Config): AsyncIterable<TData> {\n const iteratorState: Map<IteratorKey, IteratorState<TData>> = new Map();\n function publishErrorToAllIterators(reason: unknown) {\n for (const [iteratorKey, state] of iteratorState.entries()) {\n if (state.__hasPolled) {\n iteratorState.delete(iteratorKey);\n state.onError(reason);\n } else {\n state.publishQueue.push({\n __type: PublishType.ERROR,\n err: reason,\n });\n }\n }\n }\n const abortController = new AbortController();\n abortSignal.addEventListener('abort', () => {\n abortController.abort();\n publishErrorToAllIterators((EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken()));\n });\n const options = { signal: abortController.signal } as const;\n let firstError: unknown = UNINITIALIZED;\n dataPublisher.on(\n errorChannelName,\n err => {\n if (firstError === UNINITIALIZED) {\n firstError = err;\n abortController.abort();\n publishErrorToAllIterators(err);\n }\n },\n options,\n );\n dataPublisher.on(\n dataChannelName,\n data => {\n iteratorState.forEach((state, iteratorKey) => {\n if (state.__hasPolled) {\n const { onData } = state;\n iteratorState.set(iteratorKey, { __hasPolled: false, publishQueue: [] });\n onData(data as TData);\n } else {\n state.publishQueue.push({\n __type: PublishType.DATA,\n data: data as TData,\n });\n }\n });\n },\n options,\n );\n return {\n async *[Symbol.asyncIterator]() {\n if (abortSignal.aborted) {\n return;\n }\n if (firstError !== UNINITIALIZED) {\n throw firstError;\n }\n const iteratorKey = Symbol();\n iteratorState.set(iteratorKey, { __hasPolled: false, publishQueue: [] });\n try {\n while (true) {\n const state = iteratorState.get(iteratorKey);\n if (!state) {\n // There should always be state by now.\n throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING);\n }\n if (state.__hasPolled) {\n // You should never be able to poll twice in a row.\n throw new SolanaError(\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE,\n );\n }\n const publishQueue = state.publishQueue;\n try {\n if (publishQueue.length) {\n state.publishQueue = [];\n for (const item of publishQueue) {\n if (item.__type === PublishType.DATA) {\n yield item.data;\n } else {\n throw item.err;\n }\n }\n } else {\n yield await new Promise<TData>((resolve, reject) => {\n iteratorState.set(iteratorKey, {\n __hasPolled: true,\n onData: resolve,\n onError: reject,\n });\n });\n }\n } catch (e) {\n if (e === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {\n return;\n } else {\n throw e;\n }\n }\n }\n } finally {\n iteratorState.delete(iteratorKey);\n }\n },\n };\n}\n","import { TypedEventEmitter, TypedEventTarget } from './event-emitter';\n\ntype UnsubscribeFn = () => void;\n\nexport interface DataPublisher<TDataByChannelName extends Record<string, unknown> = Record<string, unknown>> {\n on<const TChannelName extends keyof TDataByChannelName>(\n channelName: TChannelName,\n subscriber: (data: TDataByChannelName[TChannelName]) => void,\n options?: { signal: AbortSignal },\n ): UnsubscribeFn;\n}\n\nexport function getDataPublisherFromEventEmitter<TEventMap extends Record<string, Event>>(\n eventEmitter: TypedEventEmitter<TEventMap> | TypedEventTarget<TEventMap>,\n): DataPublisher<{\n [TEventType in keyof TEventMap]: TEventMap[TEventType] extends CustomEvent ? TEventMap[TEventType]['detail'] : null;\n}> {\n return {\n on(channelName, subscriber, options) {\n function innerListener(ev: Event) {\n if (ev instanceof CustomEvent) {\n const data = (ev as CustomEvent<TEventMap[typeof channelName]>).detail;\n (subscriber as unknown as (data: TEventMap[typeof channelName]) => void)(data);\n } else {\n (subscriber as () => void)();\n }\n }\n eventEmitter.addEventListener(channelName, innerListener, options);\n return () => {\n eventEmitter.removeEventListener(channelName, innerListener);\n };\n },\n };\n}\n","import { EventTarget } from '@solana/event-target-impl';\n\nimport { DataPublisher, getDataPublisherFromEventEmitter } from './data-publisher';\n\nexport function demultiplexDataPublisher<\n TDataPublisher extends DataPublisher,\n const TChannelName extends Parameters<TDataPublisher['on']>[0],\n>(\n publisher: TDataPublisher,\n sourceChannelName: TChannelName,\n messageTransformer: (\n // FIXME: Deriving the type of the message from `TDataPublisher` and `TChannelName` would\n // help callers to constrain their transform functions.\n message: unknown,\n ) => [destinationChannelName: string, message: unknown] | void,\n): DataPublisher {\n let innerPublisherState:\n | {\n readonly dispose: () => void;\n numSubscribers: number;\n }\n | undefined;\n const eventTarget = new EventTarget();\n const demultiplexedDataPublisher = getDataPublisherFromEventEmitter(eventTarget);\n return {\n ...demultiplexedDataPublisher,\n on(channelName, subscriber, options) {\n if (!innerPublisherState) {\n const innerPublisherUnsubscribe = publisher.on(sourceChannelName, sourceMessage => {\n const transformResult = messageTransformer(sourceMessage);\n if (!transformResult) {\n return;\n }\n const [destinationChannelName, message] = transformResult;\n eventTarget.dispatchEvent(\n new CustomEvent(destinationChannelName, {\n detail: message,\n }),\n );\n });\n innerPublisherState = {\n dispose: innerPublisherUnsubscribe,\n numSubscribers: 0,\n };\n }\n innerPublisherState.numSubscribers++;\n const unsubscribe = demultiplexedDataPublisher.on(channelName, subscriber, options);\n let isActive = true;\n function handleUnsubscribe() {\n if (!isActive) {\n return;\n }\n isActive = false;\n options?.signal.removeEventListener('abort', handleUnsubscribe);\n innerPublisherState!.numSubscribers--;\n if (innerPublisherState!.numSubscribers === 0) {\n innerPublisherState!.dispose();\n innerPublisherState = undefined;\n }\n unsubscribe();\n }\n options?.signal.addEventListener('abort', handleUnsubscribe);\n return handleUnsubscribe;\n },\n };\n}\n"]}
@@ -10,7 +10,7 @@ var t = globalThis.EventTarget;
10
10
  var EXPLICIT_ABORT_TOKEN;
11
11
  function createExplicitAbortToken() {
12
12
  return Symbol(
13
- process.env.NODE_ENV !== "production" ? "This symbol is thrown from a socket's iterator when the connection is explicitly aborted by the user" : undefined
13
+ process.env.NODE_ENV !== "production" ? "This symbol is thrown from a socket's iterator when the connection is explicitly aborted by the user" : void 0
14
14
  );
15
15
  }
16
16
  var UNINITIALIZED = Symbol();
@@ -184,7 +184,7 @@ function demultiplexDataPublisher(publisher, sourceChannelName, messageTransform
184
184
  innerPublisherState.numSubscribers--;
185
185
  if (innerPublisherState.numSubscribers === 0) {
186
186
  innerPublisherState.dispose();
187
- innerPublisherState = undefined;
187
+ innerPublisherState = void 0;
188
188
  }
189
189
  unsubscribe();
190
190
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../event-target-impl/src/index.browser.ts","../src/async-iterable.ts","../src/data-publisher.ts","../src/demultiplex.ts"],"names":["AbortController","EventTarget"],"mappings":"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","file":"index.browser.mjs","sourcesContent":["export const AbortController = globalThis.AbortController;\nexport const EventTarget = globalThis.EventTarget;\n","import {\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE,\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING,\n SolanaError,\n} from '@solana/errors';\nimport { AbortController } from '@solana/event-target-impl';\n\nimport { DataPublisher } from './data-publisher';\n\ntype Config = Readonly<{\n abortSignal: AbortSignal;\n dataChannelName: string;\n // FIXME: It would be nice to be able to constrain the type of `dataPublisher` to one that\n // definitely supports the `dataChannelName` and `errorChannelName` channels, and\n // furthermore publishes `TData` on the `dataChannelName` channel. This is more difficult\n // than it should be: https://tsplay.dev/NlZelW\n dataPublisher: DataPublisher;\n errorChannelName: string;\n}>;\n\nconst enum PublishType {\n DATA,\n ERROR,\n}\n\ntype IteratorKey = symbol;\ntype IteratorState<TData> =\n | {\n __hasPolled: false;\n publishQueue: (\n | {\n __type: PublishType.DATA;\n data: TData;\n }\n | {\n __type: PublishType.ERROR;\n err: unknown;\n }\n )[];\n }\n | {\n __hasPolled: true;\n onData: (data: TData) => void;\n onError: Parameters<ConstructorParameters<typeof Promise>[0]>[1];\n };\n\nlet EXPLICIT_ABORT_TOKEN: symbol;\nfunction createExplicitAbortToken() {\n // This function is an annoying workaround to prevent `process.env.NODE_ENV` from appearing at\n // the top level of this module and thwarting an optimizing compiler's attempt to tree-shake.\n return Symbol(\n process.env.NODE_ENV !== \"production\"\n ? \"This symbol is thrown from a socket's iterator when the connection is explicitly \" +\n 'aborted by the user'\n : undefined,\n );\n}\n\nconst UNINITIALIZED = Symbol();\n\nexport function createAsyncIterableFromDataPublisher<TData>({\n abortSignal,\n dataChannelName,\n dataPublisher,\n errorChannelName,\n}: Config): AsyncIterable<TData> {\n const iteratorState: Map<IteratorKey, IteratorState<TData>> = new Map();\n function publishErrorToAllIterators(reason: unknown) {\n for (const [iteratorKey, state] of iteratorState.entries()) {\n if (state.__hasPolled) {\n iteratorState.delete(iteratorKey);\n state.onError(reason);\n } else {\n state.publishQueue.push({\n __type: PublishType.ERROR,\n err: reason,\n });\n }\n }\n }\n const abortController = new AbortController();\n abortSignal.addEventListener('abort', () => {\n abortController.abort();\n publishErrorToAllIterators((EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken()));\n });\n const options = { signal: abortController.signal } as const;\n let firstError: unknown = UNINITIALIZED;\n dataPublisher.on(\n errorChannelName,\n err => {\n if (firstError === UNINITIALIZED) {\n firstError = err;\n abortController.abort();\n publishErrorToAllIterators(err);\n }\n },\n options,\n );\n dataPublisher.on(\n dataChannelName,\n data => {\n iteratorState.forEach((state, iteratorKey) => {\n if (state.__hasPolled) {\n const { onData } = state;\n iteratorState.set(iteratorKey, { __hasPolled: false, publishQueue: [] });\n onData(data as TData);\n } else {\n state.publishQueue.push({\n __type: PublishType.DATA,\n data: data as TData,\n });\n }\n });\n },\n options,\n );\n return {\n async *[Symbol.asyncIterator]() {\n if (abortSignal.aborted) {\n return;\n }\n if (firstError !== UNINITIALIZED) {\n throw firstError;\n }\n const iteratorKey = Symbol();\n iteratorState.set(iteratorKey, { __hasPolled: false, publishQueue: [] });\n try {\n while (true) {\n const state = iteratorState.get(iteratorKey);\n if (!state) {\n // There should always be state by now.\n throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING);\n }\n if (state.__hasPolled) {\n // You should never be able to poll twice in a row.\n throw new SolanaError(\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE,\n );\n }\n const publishQueue = state.publishQueue;\n try {\n if (publishQueue.length) {\n state.publishQueue = [];\n for (const item of publishQueue) {\n if (item.__type === PublishType.DATA) {\n yield item.data;\n } else {\n throw item.err;\n }\n }\n } else {\n yield await new Promise<TData>((resolve, reject) => {\n iteratorState.set(iteratorKey, {\n __hasPolled: true,\n onData: resolve,\n onError: reject,\n });\n });\n }\n } catch (e) {\n if (e === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {\n return;\n } else {\n throw e;\n }\n }\n }\n } finally {\n iteratorState.delete(iteratorKey);\n }\n },\n };\n}\n","import { TypedEventEmitter, TypedEventTarget } from './event-emitter';\n\ntype UnsubscribeFn = () => void;\n\nexport interface DataPublisher<TDataByChannelName extends Record<string, unknown> = Record<string, unknown>> {\n on<const TChannelName extends keyof TDataByChannelName>(\n channelName: TChannelName,\n subscriber: (data: TDataByChannelName[TChannelName]) => void,\n options?: { signal: AbortSignal },\n ): UnsubscribeFn;\n}\n\nexport function getDataPublisherFromEventEmitter<TEventMap extends Record<string, Event>>(\n eventEmitter: TypedEventEmitter<TEventMap> | TypedEventTarget<TEventMap>,\n): DataPublisher<{\n [TEventType in keyof TEventMap]: TEventMap[TEventType] extends CustomEvent ? TEventMap[TEventType]['detail'] : null;\n}> {\n return {\n on(channelName, subscriber, options) {\n function innerListener(ev: Event) {\n if (ev instanceof CustomEvent) {\n const data = (ev as CustomEvent<TEventMap[typeof channelName]>).detail;\n (subscriber as unknown as (data: TEventMap[typeof channelName]) => void)(data);\n } else {\n (subscriber as () => void)();\n }\n }\n eventEmitter.addEventListener(channelName, innerListener, options);\n return () => {\n eventEmitter.removeEventListener(channelName, innerListener);\n };\n },\n };\n}\n","import { EventTarget } from '@solana/event-target-impl';\n\nimport { DataPublisher, getDataPublisherFromEventEmitter } from './data-publisher';\n\nexport function demultiplexDataPublisher<\n TDataPublisher extends DataPublisher,\n const TChannelName extends Parameters<TDataPublisher['on']>[0],\n>(\n publisher: TDataPublisher,\n sourceChannelName: TChannelName,\n messageTransformer: (\n // FIXME: Deriving the type of the message from `TDataPublisher` and `TChannelName` would\n // help callers to constrain their transform functions.\n message: unknown,\n ) => [destinationChannelName: string, message: unknown] | void,\n): DataPublisher {\n let innerPublisherState:\n | {\n readonly dispose: () => void;\n numSubscribers: number;\n }\n | undefined;\n const eventTarget = new EventTarget();\n const demultiplexedDataPublisher = getDataPublisherFromEventEmitter(eventTarget);\n return {\n ...demultiplexedDataPublisher,\n on(channelName, subscriber, options) {\n if (!innerPublisherState) {\n const innerPublisherUnsubscribe = publisher.on(sourceChannelName, sourceMessage => {\n const transformResult = messageTransformer(sourceMessage);\n if (!transformResult) {\n return;\n }\n const [destinationChannelName, message] = transformResult;\n eventTarget.dispatchEvent(\n new CustomEvent(destinationChannelName, {\n detail: message,\n }),\n );\n });\n innerPublisherState = {\n dispose: innerPublisherUnsubscribe,\n numSubscribers: 0,\n };\n }\n innerPublisherState.numSubscribers++;\n const unsubscribe = demultiplexedDataPublisher.on(channelName, subscriber, options);\n let isActive = true;\n function handleUnsubscribe() {\n if (!isActive) {\n return;\n }\n isActive = false;\n options?.signal.removeEventListener('abort', handleUnsubscribe);\n innerPublisherState!.numSubscribers--;\n if (innerPublisherState!.numSubscribers === 0) {\n innerPublisherState!.dispose();\n innerPublisherState = undefined;\n }\n unsubscribe();\n }\n options?.signal.addEventListener('abort', handleUnsubscribe);\n return handleUnsubscribe;\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../../event-target-impl/src/index.browser.ts","../src/async-iterable.ts","../src/data-publisher.ts","../src/demultiplex.ts"],"names":["AbortController","EventTarget"],"mappings":"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","file":"index.browser.mjs","sourcesContent":["export const AbortController = globalThis.AbortController;\nexport const EventTarget = globalThis.EventTarget;\n","import {\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE,\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING,\n SolanaError,\n} from '@solana/errors';\nimport { AbortController } from '@solana/event-target-impl';\n\nimport { DataPublisher } from './data-publisher';\n\ntype Config = Readonly<{\n abortSignal: AbortSignal;\n dataChannelName: string;\n // FIXME: It would be nice to be able to constrain the type of `dataPublisher` to one that\n // definitely supports the `dataChannelName` and `errorChannelName` channels, and\n // furthermore publishes `TData` on the `dataChannelName` channel. This is more difficult\n // than it should be: https://tsplay.dev/NlZelW\n dataPublisher: DataPublisher;\n errorChannelName: string;\n}>;\n\nconst enum PublishType {\n DATA,\n ERROR,\n}\n\ntype IteratorKey = symbol;\ntype IteratorState<TData> =\n | {\n __hasPolled: false;\n publishQueue: (\n | {\n __type: PublishType.DATA;\n data: TData;\n }\n | {\n __type: PublishType.ERROR;\n err: unknown;\n }\n )[];\n }\n | {\n __hasPolled: true;\n onData: (data: TData) => void;\n onError: Parameters<ConstructorParameters<typeof Promise>[0]>[1];\n };\n\nlet EXPLICIT_ABORT_TOKEN: symbol;\nfunction createExplicitAbortToken() {\n // This function is an annoying workaround to prevent `process.env.NODE_ENV` from appearing at\n // the top level of this module and thwarting an optimizing compiler's attempt to tree-shake.\n return Symbol(\n process.env.NODE_ENV !== \"production\"\n ? \"This symbol is thrown from a socket's iterator when the connection is explicitly \" +\n 'aborted by the user'\n : undefined,\n );\n}\n\nconst UNINITIALIZED = Symbol();\n\nexport function createAsyncIterableFromDataPublisher<TData>({\n abortSignal,\n dataChannelName,\n dataPublisher,\n errorChannelName,\n}: Config): AsyncIterable<TData> {\n const iteratorState: Map<IteratorKey, IteratorState<TData>> = new Map();\n function publishErrorToAllIterators(reason: unknown) {\n for (const [iteratorKey, state] of iteratorState.entries()) {\n if (state.__hasPolled) {\n iteratorState.delete(iteratorKey);\n state.onError(reason);\n } else {\n state.publishQueue.push({\n __type: PublishType.ERROR,\n err: reason,\n });\n }\n }\n }\n const abortController = new AbortController();\n abortSignal.addEventListener('abort', () => {\n abortController.abort();\n publishErrorToAllIterators((EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken()));\n });\n const options = { signal: abortController.signal } as const;\n let firstError: unknown = UNINITIALIZED;\n dataPublisher.on(\n errorChannelName,\n err => {\n if (firstError === UNINITIALIZED) {\n firstError = err;\n abortController.abort();\n publishErrorToAllIterators(err);\n }\n },\n options,\n );\n dataPublisher.on(\n dataChannelName,\n data => {\n iteratorState.forEach((state, iteratorKey) => {\n if (state.__hasPolled) {\n const { onData } = state;\n iteratorState.set(iteratorKey, { __hasPolled: false, publishQueue: [] });\n onData(data as TData);\n } else {\n state.publishQueue.push({\n __type: PublishType.DATA,\n data: data as TData,\n });\n }\n });\n },\n options,\n );\n return {\n async *[Symbol.asyncIterator]() {\n if (abortSignal.aborted) {\n return;\n }\n if (firstError !== UNINITIALIZED) {\n throw firstError;\n }\n const iteratorKey = Symbol();\n iteratorState.set(iteratorKey, { __hasPolled: false, publishQueue: [] });\n try {\n while (true) {\n const state = iteratorState.get(iteratorKey);\n if (!state) {\n // There should always be state by now.\n throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING);\n }\n if (state.__hasPolled) {\n // You should never be able to poll twice in a row.\n throw new SolanaError(\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE,\n );\n }\n const publishQueue = state.publishQueue;\n try {\n if (publishQueue.length) {\n state.publishQueue = [];\n for (const item of publishQueue) {\n if (item.__type === PublishType.DATA) {\n yield item.data;\n } else {\n throw item.err;\n }\n }\n } else {\n yield await new Promise<TData>((resolve, reject) => {\n iteratorState.set(iteratorKey, {\n __hasPolled: true,\n onData: resolve,\n onError: reject,\n });\n });\n }\n } catch (e) {\n if (e === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {\n return;\n } else {\n throw e;\n }\n }\n }\n } finally {\n iteratorState.delete(iteratorKey);\n }\n },\n };\n}\n","import { TypedEventEmitter, TypedEventTarget } from './event-emitter';\n\ntype UnsubscribeFn = () => void;\n\nexport interface DataPublisher<TDataByChannelName extends Record<string, unknown> = Record<string, unknown>> {\n on<const TChannelName extends keyof TDataByChannelName>(\n channelName: TChannelName,\n subscriber: (data: TDataByChannelName[TChannelName]) => void,\n options?: { signal: AbortSignal },\n ): UnsubscribeFn;\n}\n\nexport function getDataPublisherFromEventEmitter<TEventMap extends Record<string, Event>>(\n eventEmitter: TypedEventEmitter<TEventMap> | TypedEventTarget<TEventMap>,\n): DataPublisher<{\n [TEventType in keyof TEventMap]: TEventMap[TEventType] extends CustomEvent ? TEventMap[TEventType]['detail'] : null;\n}> {\n return {\n on(channelName, subscriber, options) {\n function innerListener(ev: Event) {\n if (ev instanceof CustomEvent) {\n const data = (ev as CustomEvent<TEventMap[typeof channelName]>).detail;\n (subscriber as unknown as (data: TEventMap[typeof channelName]) => void)(data);\n } else {\n (subscriber as () => void)();\n }\n }\n eventEmitter.addEventListener(channelName, innerListener, options);\n return () => {\n eventEmitter.removeEventListener(channelName, innerListener);\n };\n },\n };\n}\n","import { EventTarget } from '@solana/event-target-impl';\n\nimport { DataPublisher, getDataPublisherFromEventEmitter } from './data-publisher';\n\nexport function demultiplexDataPublisher<\n TDataPublisher extends DataPublisher,\n const TChannelName extends Parameters<TDataPublisher['on']>[0],\n>(\n publisher: TDataPublisher,\n sourceChannelName: TChannelName,\n messageTransformer: (\n // FIXME: Deriving the type of the message from `TDataPublisher` and `TChannelName` would\n // help callers to constrain their transform functions.\n message: unknown,\n ) => [destinationChannelName: string, message: unknown] | void,\n): DataPublisher {\n let innerPublisherState:\n | {\n readonly dispose: () => void;\n numSubscribers: number;\n }\n | undefined;\n const eventTarget = new EventTarget();\n const demultiplexedDataPublisher = getDataPublisherFromEventEmitter(eventTarget);\n return {\n ...demultiplexedDataPublisher,\n on(channelName, subscriber, options) {\n if (!innerPublisherState) {\n const innerPublisherUnsubscribe = publisher.on(sourceChannelName, sourceMessage => {\n const transformResult = messageTransformer(sourceMessage);\n if (!transformResult) {\n return;\n }\n const [destinationChannelName, message] = transformResult;\n eventTarget.dispatchEvent(\n new CustomEvent(destinationChannelName, {\n detail: message,\n }),\n );\n });\n innerPublisherState = {\n dispose: innerPublisherUnsubscribe,\n numSubscribers: 0,\n };\n }\n innerPublisherState.numSubscribers++;\n const unsubscribe = demultiplexedDataPublisher.on(channelName, subscriber, options);\n let isActive = true;\n function handleUnsubscribe() {\n if (!isActive) {\n return;\n }\n isActive = false;\n options?.signal.removeEventListener('abort', handleUnsubscribe);\n innerPublisherState!.numSubscribers--;\n if (innerPublisherState!.numSubscribers === 0) {\n innerPublisherState!.dispose();\n innerPublisherState = undefined;\n }\n unsubscribe();\n }\n options?.signal.addEventListener('abort', handleUnsubscribe);\n return handleUnsubscribe;\n },\n };\n}\n"]}
@@ -10,7 +10,7 @@ var t = globalThis.EventTarget;
10
10
  var EXPLICIT_ABORT_TOKEN;
11
11
  function createExplicitAbortToken() {
12
12
  return Symbol(
13
- process.env.NODE_ENV !== "production" ? "This symbol is thrown from a socket's iterator when the connection is explicitly aborted by the user" : undefined
13
+ process.env.NODE_ENV !== "production" ? "This symbol is thrown from a socket's iterator when the connection is explicitly aborted by the user" : void 0
14
14
  );
15
15
  }
16
16
  var UNINITIALIZED = Symbol();
@@ -184,7 +184,7 @@ function demultiplexDataPublisher(publisher, sourceChannelName, messageTransform
184
184
  innerPublisherState.numSubscribers--;
185
185
  if (innerPublisherState.numSubscribers === 0) {
186
186
  innerPublisherState.dispose();
187
- innerPublisherState = undefined;
187
+ innerPublisherState = void 0;
188
188
  }
189
189
  unsubscribe();
190
190
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../event-target-impl/src/index.browser.ts","../src/async-iterable.ts","../src/data-publisher.ts","../src/demultiplex.ts"],"names":["AbortController","EventTarget"],"mappings":"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","file":"index.native.mjs","sourcesContent":["export const AbortController = globalThis.AbortController;\nexport const EventTarget = globalThis.EventTarget;\n","import {\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE,\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING,\n SolanaError,\n} from '@solana/errors';\nimport { AbortController } from '@solana/event-target-impl';\n\nimport { DataPublisher } from './data-publisher';\n\ntype Config = Readonly<{\n abortSignal: AbortSignal;\n dataChannelName: string;\n // FIXME: It would be nice to be able to constrain the type of `dataPublisher` to one that\n // definitely supports the `dataChannelName` and `errorChannelName` channels, and\n // furthermore publishes `TData` on the `dataChannelName` channel. This is more difficult\n // than it should be: https://tsplay.dev/NlZelW\n dataPublisher: DataPublisher;\n errorChannelName: string;\n}>;\n\nconst enum PublishType {\n DATA,\n ERROR,\n}\n\ntype IteratorKey = symbol;\ntype IteratorState<TData> =\n | {\n __hasPolled: false;\n publishQueue: (\n | {\n __type: PublishType.DATA;\n data: TData;\n }\n | {\n __type: PublishType.ERROR;\n err: unknown;\n }\n )[];\n }\n | {\n __hasPolled: true;\n onData: (data: TData) => void;\n onError: Parameters<ConstructorParameters<typeof Promise>[0]>[1];\n };\n\nlet EXPLICIT_ABORT_TOKEN: symbol;\nfunction createExplicitAbortToken() {\n // This function is an annoying workaround to prevent `process.env.NODE_ENV` from appearing at\n // the top level of this module and thwarting an optimizing compiler's attempt to tree-shake.\n return Symbol(\n process.env.NODE_ENV !== \"production\"\n ? \"This symbol is thrown from a socket's iterator when the connection is explicitly \" +\n 'aborted by the user'\n : undefined,\n );\n}\n\nconst UNINITIALIZED = Symbol();\n\nexport function createAsyncIterableFromDataPublisher<TData>({\n abortSignal,\n dataChannelName,\n dataPublisher,\n errorChannelName,\n}: Config): AsyncIterable<TData> {\n const iteratorState: Map<IteratorKey, IteratorState<TData>> = new Map();\n function publishErrorToAllIterators(reason: unknown) {\n for (const [iteratorKey, state] of iteratorState.entries()) {\n if (state.__hasPolled) {\n iteratorState.delete(iteratorKey);\n state.onError(reason);\n } else {\n state.publishQueue.push({\n __type: PublishType.ERROR,\n err: reason,\n });\n }\n }\n }\n const abortController = new AbortController();\n abortSignal.addEventListener('abort', () => {\n abortController.abort();\n publishErrorToAllIterators((EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken()));\n });\n const options = { signal: abortController.signal } as const;\n let firstError: unknown = UNINITIALIZED;\n dataPublisher.on(\n errorChannelName,\n err => {\n if (firstError === UNINITIALIZED) {\n firstError = err;\n abortController.abort();\n publishErrorToAllIterators(err);\n }\n },\n options,\n );\n dataPublisher.on(\n dataChannelName,\n data => {\n iteratorState.forEach((state, iteratorKey) => {\n if (state.__hasPolled) {\n const { onData } = state;\n iteratorState.set(iteratorKey, { __hasPolled: false, publishQueue: [] });\n onData(data as TData);\n } else {\n state.publishQueue.push({\n __type: PublishType.DATA,\n data: data as TData,\n });\n }\n });\n },\n options,\n );\n return {\n async *[Symbol.asyncIterator]() {\n if (abortSignal.aborted) {\n return;\n }\n if (firstError !== UNINITIALIZED) {\n throw firstError;\n }\n const iteratorKey = Symbol();\n iteratorState.set(iteratorKey, { __hasPolled: false, publishQueue: [] });\n try {\n while (true) {\n const state = iteratorState.get(iteratorKey);\n if (!state) {\n // There should always be state by now.\n throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING);\n }\n if (state.__hasPolled) {\n // You should never be able to poll twice in a row.\n throw new SolanaError(\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE,\n );\n }\n const publishQueue = state.publishQueue;\n try {\n if (publishQueue.length) {\n state.publishQueue = [];\n for (const item of publishQueue) {\n if (item.__type === PublishType.DATA) {\n yield item.data;\n } else {\n throw item.err;\n }\n }\n } else {\n yield await new Promise<TData>((resolve, reject) => {\n iteratorState.set(iteratorKey, {\n __hasPolled: true,\n onData: resolve,\n onError: reject,\n });\n });\n }\n } catch (e) {\n if (e === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {\n return;\n } else {\n throw e;\n }\n }\n }\n } finally {\n iteratorState.delete(iteratorKey);\n }\n },\n };\n}\n","import { TypedEventEmitter, TypedEventTarget } from './event-emitter';\n\ntype UnsubscribeFn = () => void;\n\nexport interface DataPublisher<TDataByChannelName extends Record<string, unknown> = Record<string, unknown>> {\n on<const TChannelName extends keyof TDataByChannelName>(\n channelName: TChannelName,\n subscriber: (data: TDataByChannelName[TChannelName]) => void,\n options?: { signal: AbortSignal },\n ): UnsubscribeFn;\n}\n\nexport function getDataPublisherFromEventEmitter<TEventMap extends Record<string, Event>>(\n eventEmitter: TypedEventEmitter<TEventMap> | TypedEventTarget<TEventMap>,\n): DataPublisher<{\n [TEventType in keyof TEventMap]: TEventMap[TEventType] extends CustomEvent ? TEventMap[TEventType]['detail'] : null;\n}> {\n return {\n on(channelName, subscriber, options) {\n function innerListener(ev: Event) {\n if (ev instanceof CustomEvent) {\n const data = (ev as CustomEvent<TEventMap[typeof channelName]>).detail;\n (subscriber as unknown as (data: TEventMap[typeof channelName]) => void)(data);\n } else {\n (subscriber as () => void)();\n }\n }\n eventEmitter.addEventListener(channelName, innerListener, options);\n return () => {\n eventEmitter.removeEventListener(channelName, innerListener);\n };\n },\n };\n}\n","import { EventTarget } from '@solana/event-target-impl';\n\nimport { DataPublisher, getDataPublisherFromEventEmitter } from './data-publisher';\n\nexport function demultiplexDataPublisher<\n TDataPublisher extends DataPublisher,\n const TChannelName extends Parameters<TDataPublisher['on']>[0],\n>(\n publisher: TDataPublisher,\n sourceChannelName: TChannelName,\n messageTransformer: (\n // FIXME: Deriving the type of the message from `TDataPublisher` and `TChannelName` would\n // help callers to constrain their transform functions.\n message: unknown,\n ) => [destinationChannelName: string, message: unknown] | void,\n): DataPublisher {\n let innerPublisherState:\n | {\n readonly dispose: () => void;\n numSubscribers: number;\n }\n | undefined;\n const eventTarget = new EventTarget();\n const demultiplexedDataPublisher = getDataPublisherFromEventEmitter(eventTarget);\n return {\n ...demultiplexedDataPublisher,\n on(channelName, subscriber, options) {\n if (!innerPublisherState) {\n const innerPublisherUnsubscribe = publisher.on(sourceChannelName, sourceMessage => {\n const transformResult = messageTransformer(sourceMessage);\n if (!transformResult) {\n return;\n }\n const [destinationChannelName, message] = transformResult;\n eventTarget.dispatchEvent(\n new CustomEvent(destinationChannelName, {\n detail: message,\n }),\n );\n });\n innerPublisherState = {\n dispose: innerPublisherUnsubscribe,\n numSubscribers: 0,\n };\n }\n innerPublisherState.numSubscribers++;\n const unsubscribe = demultiplexedDataPublisher.on(channelName, subscriber, options);\n let isActive = true;\n function handleUnsubscribe() {\n if (!isActive) {\n return;\n }\n isActive = false;\n options?.signal.removeEventListener('abort', handleUnsubscribe);\n innerPublisherState!.numSubscribers--;\n if (innerPublisherState!.numSubscribers === 0) {\n innerPublisherState!.dispose();\n innerPublisherState = undefined;\n }\n unsubscribe();\n }\n options?.signal.addEventListener('abort', handleUnsubscribe);\n return handleUnsubscribe;\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../../event-target-impl/src/index.browser.ts","../src/async-iterable.ts","../src/data-publisher.ts","../src/demultiplex.ts"],"names":["AbortController","EventTarget"],"mappings":"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","file":"index.native.mjs","sourcesContent":["export const AbortController = globalThis.AbortController;\nexport const EventTarget = globalThis.EventTarget;\n","import {\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE,\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING,\n SolanaError,\n} from '@solana/errors';\nimport { AbortController } from '@solana/event-target-impl';\n\nimport { DataPublisher } from './data-publisher';\n\ntype Config = Readonly<{\n abortSignal: AbortSignal;\n dataChannelName: string;\n // FIXME: It would be nice to be able to constrain the type of `dataPublisher` to one that\n // definitely supports the `dataChannelName` and `errorChannelName` channels, and\n // furthermore publishes `TData` on the `dataChannelName` channel. This is more difficult\n // than it should be: https://tsplay.dev/NlZelW\n dataPublisher: DataPublisher;\n errorChannelName: string;\n}>;\n\nconst enum PublishType {\n DATA,\n ERROR,\n}\n\ntype IteratorKey = symbol;\ntype IteratorState<TData> =\n | {\n __hasPolled: false;\n publishQueue: (\n | {\n __type: PublishType.DATA;\n data: TData;\n }\n | {\n __type: PublishType.ERROR;\n err: unknown;\n }\n )[];\n }\n | {\n __hasPolled: true;\n onData: (data: TData) => void;\n onError: Parameters<ConstructorParameters<typeof Promise>[0]>[1];\n };\n\nlet EXPLICIT_ABORT_TOKEN: symbol;\nfunction createExplicitAbortToken() {\n // This function is an annoying workaround to prevent `process.env.NODE_ENV` from appearing at\n // the top level of this module and thwarting an optimizing compiler's attempt to tree-shake.\n return Symbol(\n process.env.NODE_ENV !== \"production\"\n ? \"This symbol is thrown from a socket's iterator when the connection is explicitly \" +\n 'aborted by the user'\n : undefined,\n );\n}\n\nconst UNINITIALIZED = Symbol();\n\nexport function createAsyncIterableFromDataPublisher<TData>({\n abortSignal,\n dataChannelName,\n dataPublisher,\n errorChannelName,\n}: Config): AsyncIterable<TData> {\n const iteratorState: Map<IteratorKey, IteratorState<TData>> = new Map();\n function publishErrorToAllIterators(reason: unknown) {\n for (const [iteratorKey, state] of iteratorState.entries()) {\n if (state.__hasPolled) {\n iteratorState.delete(iteratorKey);\n state.onError(reason);\n } else {\n state.publishQueue.push({\n __type: PublishType.ERROR,\n err: reason,\n });\n }\n }\n }\n const abortController = new AbortController();\n abortSignal.addEventListener('abort', () => {\n abortController.abort();\n publishErrorToAllIterators((EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken()));\n });\n const options = { signal: abortController.signal } as const;\n let firstError: unknown = UNINITIALIZED;\n dataPublisher.on(\n errorChannelName,\n err => {\n if (firstError === UNINITIALIZED) {\n firstError = err;\n abortController.abort();\n publishErrorToAllIterators(err);\n }\n },\n options,\n );\n dataPublisher.on(\n dataChannelName,\n data => {\n iteratorState.forEach((state, iteratorKey) => {\n if (state.__hasPolled) {\n const { onData } = state;\n iteratorState.set(iteratorKey, { __hasPolled: false, publishQueue: [] });\n onData(data as TData);\n } else {\n state.publishQueue.push({\n __type: PublishType.DATA,\n data: data as TData,\n });\n }\n });\n },\n options,\n );\n return {\n async *[Symbol.asyncIterator]() {\n if (abortSignal.aborted) {\n return;\n }\n if (firstError !== UNINITIALIZED) {\n throw firstError;\n }\n const iteratorKey = Symbol();\n iteratorState.set(iteratorKey, { __hasPolled: false, publishQueue: [] });\n try {\n while (true) {\n const state = iteratorState.get(iteratorKey);\n if (!state) {\n // There should always be state by now.\n throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING);\n }\n if (state.__hasPolled) {\n // You should never be able to poll twice in a row.\n throw new SolanaError(\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE,\n );\n }\n const publishQueue = state.publishQueue;\n try {\n if (publishQueue.length) {\n state.publishQueue = [];\n for (const item of publishQueue) {\n if (item.__type === PublishType.DATA) {\n yield item.data;\n } else {\n throw item.err;\n }\n }\n } else {\n yield await new Promise<TData>((resolve, reject) => {\n iteratorState.set(iteratorKey, {\n __hasPolled: true,\n onData: resolve,\n onError: reject,\n });\n });\n }\n } catch (e) {\n if (e === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {\n return;\n } else {\n throw e;\n }\n }\n }\n } finally {\n iteratorState.delete(iteratorKey);\n }\n },\n };\n}\n","import { TypedEventEmitter, TypedEventTarget } from './event-emitter';\n\ntype UnsubscribeFn = () => void;\n\nexport interface DataPublisher<TDataByChannelName extends Record<string, unknown> = Record<string, unknown>> {\n on<const TChannelName extends keyof TDataByChannelName>(\n channelName: TChannelName,\n subscriber: (data: TDataByChannelName[TChannelName]) => void,\n options?: { signal: AbortSignal },\n ): UnsubscribeFn;\n}\n\nexport function getDataPublisherFromEventEmitter<TEventMap extends Record<string, Event>>(\n eventEmitter: TypedEventEmitter<TEventMap> | TypedEventTarget<TEventMap>,\n): DataPublisher<{\n [TEventType in keyof TEventMap]: TEventMap[TEventType] extends CustomEvent ? TEventMap[TEventType]['detail'] : null;\n}> {\n return {\n on(channelName, subscriber, options) {\n function innerListener(ev: Event) {\n if (ev instanceof CustomEvent) {\n const data = (ev as CustomEvent<TEventMap[typeof channelName]>).detail;\n (subscriber as unknown as (data: TEventMap[typeof channelName]) => void)(data);\n } else {\n (subscriber as () => void)();\n }\n }\n eventEmitter.addEventListener(channelName, innerListener, options);\n return () => {\n eventEmitter.removeEventListener(channelName, innerListener);\n };\n },\n };\n}\n","import { EventTarget } from '@solana/event-target-impl';\n\nimport { DataPublisher, getDataPublisherFromEventEmitter } from './data-publisher';\n\nexport function demultiplexDataPublisher<\n TDataPublisher extends DataPublisher,\n const TChannelName extends Parameters<TDataPublisher['on']>[0],\n>(\n publisher: TDataPublisher,\n sourceChannelName: TChannelName,\n messageTransformer: (\n // FIXME: Deriving the type of the message from `TDataPublisher` and `TChannelName` would\n // help callers to constrain their transform functions.\n message: unknown,\n ) => [destinationChannelName: string, message: unknown] | void,\n): DataPublisher {\n let innerPublisherState:\n | {\n readonly dispose: () => void;\n numSubscribers: number;\n }\n | undefined;\n const eventTarget = new EventTarget();\n const demultiplexedDataPublisher = getDataPublisherFromEventEmitter(eventTarget);\n return {\n ...demultiplexedDataPublisher,\n on(channelName, subscriber, options) {\n if (!innerPublisherState) {\n const innerPublisherUnsubscribe = publisher.on(sourceChannelName, sourceMessage => {\n const transformResult = messageTransformer(sourceMessage);\n if (!transformResult) {\n return;\n }\n const [destinationChannelName, message] = transformResult;\n eventTarget.dispatchEvent(\n new CustomEvent(destinationChannelName, {\n detail: message,\n }),\n );\n });\n innerPublisherState = {\n dispose: innerPublisherUnsubscribe,\n numSubscribers: 0,\n };\n }\n innerPublisherState.numSubscribers++;\n const unsubscribe = demultiplexedDataPublisher.on(channelName, subscriber, options);\n let isActive = true;\n function handleUnsubscribe() {\n if (!isActive) {\n return;\n }\n isActive = false;\n options?.signal.removeEventListener('abort', handleUnsubscribe);\n innerPublisherState!.numSubscribers--;\n if (innerPublisherState!.numSubscribers === 0) {\n innerPublisherState!.dispose();\n innerPublisherState = undefined;\n }\n unsubscribe();\n }\n options?.signal.addEventListener('abort', handleUnsubscribe);\n return handleUnsubscribe;\n },\n };\n}\n"]}
@@ -19,7 +19,7 @@ var s = class extends globalThis.EventTarget {
19
19
  var EXPLICIT_ABORT_TOKEN;
20
20
  function createExplicitAbortToken() {
21
21
  return Symbol(
22
- process.env.NODE_ENV !== "production" ? "This symbol is thrown from a socket's iterator when the connection is explicitly aborted by the user" : undefined
22
+ process.env.NODE_ENV !== "production" ? "This symbol is thrown from a socket's iterator when the connection is explicitly aborted by the user" : void 0
23
23
  );
24
24
  }
25
25
  var UNINITIALIZED = Symbol();
@@ -193,7 +193,7 @@ function demultiplexDataPublisher(publisher, sourceChannelName, messageTransform
193
193
  innerPublisherState.numSubscribers--;
194
194
  if (innerPublisherState.numSubscribers === 0) {
195
195
  innerPublisherState.dispose();
196
- innerPublisherState = undefined;
196
+ innerPublisherState = void 0;
197
197
  }
198
198
  unsubscribe();
199
199
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../event-target-impl/src/index.node.ts","../src/async-iterable.ts","../src/data-publisher.ts","../src/demultiplex.ts"],"names":["AbortController","args","setMaxListeners","EventTarget","SolanaError","SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING","SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE","e"],"mappings":"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","file":"index.node.cjs","sourcesContent":["import { setMaxListeners } from 'node:events';\n\nexport const AbortController = class extends globalThis.AbortController {\n constructor(...args: ConstructorParameters<typeof globalThis.AbortController>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this.signal);\n }\n};\n\nexport const EventTarget = class extends globalThis.EventTarget {\n constructor(...args: ConstructorParameters<typeof globalThis.EventTarget>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this);\n }\n};\n","import {\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE,\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING,\n SolanaError,\n} from '@solana/errors';\nimport { AbortController } from '@solana/event-target-impl';\n\nimport { DataPublisher } from './data-publisher';\n\ntype Config = Readonly<{\n abortSignal: AbortSignal;\n dataChannelName: string;\n // FIXME: It would be nice to be able to constrain the type of `dataPublisher` to one that\n // definitely supports the `dataChannelName` and `errorChannelName` channels, and\n // furthermore publishes `TData` on the `dataChannelName` channel. This is more difficult\n // than it should be: https://tsplay.dev/NlZelW\n dataPublisher: DataPublisher;\n errorChannelName: string;\n}>;\n\nconst enum PublishType {\n DATA,\n ERROR,\n}\n\ntype IteratorKey = symbol;\ntype IteratorState<TData> =\n | {\n __hasPolled: false;\n publishQueue: (\n | {\n __type: PublishType.DATA;\n data: TData;\n }\n | {\n __type: PublishType.ERROR;\n err: unknown;\n }\n )[];\n }\n | {\n __hasPolled: true;\n onData: (data: TData) => void;\n onError: Parameters<ConstructorParameters<typeof Promise>[0]>[1];\n };\n\nlet EXPLICIT_ABORT_TOKEN: symbol;\nfunction createExplicitAbortToken() {\n // This function is an annoying workaround to prevent `process.env.NODE_ENV` from appearing at\n // the top level of this module and thwarting an optimizing compiler's attempt to tree-shake.\n return Symbol(\n process.env.NODE_ENV !== \"production\"\n ? \"This symbol is thrown from a socket's iterator when the connection is explicitly \" +\n 'aborted by the user'\n : undefined,\n );\n}\n\nconst UNINITIALIZED = Symbol();\n\nexport function createAsyncIterableFromDataPublisher<TData>({\n abortSignal,\n dataChannelName,\n dataPublisher,\n errorChannelName,\n}: Config): AsyncIterable<TData> {\n const iteratorState: Map<IteratorKey, IteratorState<TData>> = new Map();\n function publishErrorToAllIterators(reason: unknown) {\n for (const [iteratorKey, state] of iteratorState.entries()) {\n if (state.__hasPolled) {\n iteratorState.delete(iteratorKey);\n state.onError(reason);\n } else {\n state.publishQueue.push({\n __type: PublishType.ERROR,\n err: reason,\n });\n }\n }\n }\n const abortController = new AbortController();\n abortSignal.addEventListener('abort', () => {\n abortController.abort();\n publishErrorToAllIterators((EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken()));\n });\n const options = { signal: abortController.signal } as const;\n let firstError: unknown = UNINITIALIZED;\n dataPublisher.on(\n errorChannelName,\n err => {\n if (firstError === UNINITIALIZED) {\n firstError = err;\n abortController.abort();\n publishErrorToAllIterators(err);\n }\n },\n options,\n );\n dataPublisher.on(\n dataChannelName,\n data => {\n iteratorState.forEach((state, iteratorKey) => {\n if (state.__hasPolled) {\n const { onData } = state;\n iteratorState.set(iteratorKey, { __hasPolled: false, publishQueue: [] });\n onData(data as TData);\n } else {\n state.publishQueue.push({\n __type: PublishType.DATA,\n data: data as TData,\n });\n }\n });\n },\n options,\n );\n return {\n async *[Symbol.asyncIterator]() {\n if (abortSignal.aborted) {\n return;\n }\n if (firstError !== UNINITIALIZED) {\n throw firstError;\n }\n const iteratorKey = Symbol();\n iteratorState.set(iteratorKey, { __hasPolled: false, publishQueue: [] });\n try {\n while (true) {\n const state = iteratorState.get(iteratorKey);\n if (!state) {\n // There should always be state by now.\n throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING);\n }\n if (state.__hasPolled) {\n // You should never be able to poll twice in a row.\n throw new SolanaError(\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE,\n );\n }\n const publishQueue = state.publishQueue;\n try {\n if (publishQueue.length) {\n state.publishQueue = [];\n for (const item of publishQueue) {\n if (item.__type === PublishType.DATA) {\n yield item.data;\n } else {\n throw item.err;\n }\n }\n } else {\n yield await new Promise<TData>((resolve, reject) => {\n iteratorState.set(iteratorKey, {\n __hasPolled: true,\n onData: resolve,\n onError: reject,\n });\n });\n }\n } catch (e) {\n if (e === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {\n return;\n } else {\n throw e;\n }\n }\n }\n } finally {\n iteratorState.delete(iteratorKey);\n }\n },\n };\n}\n","import { TypedEventEmitter, TypedEventTarget } from './event-emitter';\n\ntype UnsubscribeFn = () => void;\n\nexport interface DataPublisher<TDataByChannelName extends Record<string, unknown> = Record<string, unknown>> {\n on<const TChannelName extends keyof TDataByChannelName>(\n channelName: TChannelName,\n subscriber: (data: TDataByChannelName[TChannelName]) => void,\n options?: { signal: AbortSignal },\n ): UnsubscribeFn;\n}\n\nexport function getDataPublisherFromEventEmitter<TEventMap extends Record<string, Event>>(\n eventEmitter: TypedEventEmitter<TEventMap> | TypedEventTarget<TEventMap>,\n): DataPublisher<{\n [TEventType in keyof TEventMap]: TEventMap[TEventType] extends CustomEvent ? TEventMap[TEventType]['detail'] : null;\n}> {\n return {\n on(channelName, subscriber, options) {\n function innerListener(ev: Event) {\n if (ev instanceof CustomEvent) {\n const data = (ev as CustomEvent<TEventMap[typeof channelName]>).detail;\n (subscriber as unknown as (data: TEventMap[typeof channelName]) => void)(data);\n } else {\n (subscriber as () => void)();\n }\n }\n eventEmitter.addEventListener(channelName, innerListener, options);\n return () => {\n eventEmitter.removeEventListener(channelName, innerListener);\n };\n },\n };\n}\n","import { EventTarget } from '@solana/event-target-impl';\n\nimport { DataPublisher, getDataPublisherFromEventEmitter } from './data-publisher';\n\nexport function demultiplexDataPublisher<\n TDataPublisher extends DataPublisher,\n const TChannelName extends Parameters<TDataPublisher['on']>[0],\n>(\n publisher: TDataPublisher,\n sourceChannelName: TChannelName,\n messageTransformer: (\n // FIXME: Deriving the type of the message from `TDataPublisher` and `TChannelName` would\n // help callers to constrain their transform functions.\n message: unknown,\n ) => [destinationChannelName: string, message: unknown] | void,\n): DataPublisher {\n let innerPublisherState:\n | {\n readonly dispose: () => void;\n numSubscribers: number;\n }\n | undefined;\n const eventTarget = new EventTarget();\n const demultiplexedDataPublisher = getDataPublisherFromEventEmitter(eventTarget);\n return {\n ...demultiplexedDataPublisher,\n on(channelName, subscriber, options) {\n if (!innerPublisherState) {\n const innerPublisherUnsubscribe = publisher.on(sourceChannelName, sourceMessage => {\n const transformResult = messageTransformer(sourceMessage);\n if (!transformResult) {\n return;\n }\n const [destinationChannelName, message] = transformResult;\n eventTarget.dispatchEvent(\n new CustomEvent(destinationChannelName, {\n detail: message,\n }),\n );\n });\n innerPublisherState = {\n dispose: innerPublisherUnsubscribe,\n numSubscribers: 0,\n };\n }\n innerPublisherState.numSubscribers++;\n const unsubscribe = demultiplexedDataPublisher.on(channelName, subscriber, options);\n let isActive = true;\n function handleUnsubscribe() {\n if (!isActive) {\n return;\n }\n isActive = false;\n options?.signal.removeEventListener('abort', handleUnsubscribe);\n innerPublisherState!.numSubscribers--;\n if (innerPublisherState!.numSubscribers === 0) {\n innerPublisherState!.dispose();\n innerPublisherState = undefined;\n }\n unsubscribe();\n }\n options?.signal.addEventListener('abort', handleUnsubscribe);\n return handleUnsubscribe;\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../../event-target-impl/src/index.node.ts","../src/async-iterable.ts","../src/data-publisher.ts","../src/demultiplex.ts"],"names":["AbortController","args","setMaxListeners","EventTarget","SolanaError","SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING","SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE","e"],"mappings":";;;;;;IAEaA,CAAkB,GAAA,cAAc,WAAW,eAAgB,CAAA;AACpE,EAAA,WAAA,CAAA,GAAeC,CAAgE,EAAA;AAC3E,IAAA,KAAA,CAAM,GAAGA,CAAI,CAAA,EACbC,uBAAgB,MAAO,CAAA,gBAAA,EAAkB,KAAK,MAAM,CAAA;AACxD;AACJ,CAAA;IAEaC,CAAc,GAAA,cAAc,WAAW,WAAY,CAAA;AAC5D,EAAA,WAAA,CAAA,GAAeF,CAA4D,EAAA;AACvE,IAAA,KAAA,CAAM,GAAGA,CAAI,CAAA,EACbC,sBAAgB,CAAA,MAAA,CAAO,kBAAkB,IAAI,CAAA;AACjD;AACJ,CAAA;;;ACgCA,IAAI,oBAAA;AACJ,SAAS,wBAA2B,GAAA;AAGhC,EAAO,OAAA,MAAA;AAAA,IACH,OAAA,CAAA,GAAA,CAAA,QAAA,KAAyB,eACnB,sGAEA,GAAA;AAAA,GACV;AACJ;AAEA,IAAM,gBAAgB,MAAO,EAAA;AAEtB,SAAS,oCAA4C,CAAA;AAAA,EACxD,WAAA;AAAA,EACA,eAAA;AAAA,EACA,aAAA;AAAA,EACA;AACJ,CAAiC,EAAA;AAC7B,EAAM,MAAA,aAAA,uBAA4D,GAAI,EAAA;AACtE,EAAA,SAAS,2BAA2B,MAAiB,EAAA;AACjD,IAAA,KAAA,MAAW,CAAC,WAAa,EAAA,KAAK,CAAK,IAAA,aAAA,CAAc,SAAW,EAAA;AACxD,MAAA,IAAI,MAAM,WAAa,EAAA;AACnB,QAAA,aAAA,CAAc,OAAO,WAAW,CAAA;AAChC,QAAA,KAAA,CAAM,QAAQ,MAAM,CAAA;AAAA,OACjB,MAAA;AACH,QAAA,KAAA,CAAM,aAAa,IAAK,CAAA;AAAA,UACpB,MAAQ,EAAA,CAAA;AAAA,UACR,GAAK,EAAA;AAAA,SACR,CAAA;AAAA;AACL;AACJ;AAEJ,EAAM,MAAA,eAAA,GAAkB,IAAI,CAAgB,EAAA;AAC5C,EAAY,WAAA,CAAA,gBAAA,CAAiB,SAAS,MAAM;AACxC,IAAA,eAAA,CAAgB,KAAM,EAAA;AACtB,IAA4B,0BAAA,CAAA,oBAAA,KAAyB,0BAA2B,CAAA;AAAA,GACnF,CAAA;AACD,EAAA,MAAM,OAAU,GAAA,EAAE,MAAQ,EAAA,eAAA,CAAgB,MAAO,EAAA;AACjD,EAAA,IAAI,UAAsB,GAAA,aAAA;AAC1B,EAAc,aAAA,CAAA,EAAA;AAAA,IACV,gBAAA;AAAA,IACA,CAAO,GAAA,KAAA;AACH,MAAA,IAAI,eAAe,aAAe,EAAA;AAC9B,QAAa,UAAA,GAAA,GAAA;AACb,QAAA,eAAA,CAAgB,KAAM,EAAA;AACtB,QAAA,0BAAA,CAA2B,GAAG,CAAA;AAAA;AAClC,KACJ;AAAA,IACA;AAAA,GACJ;AACA,EAAc,aAAA,CAAA,EAAA;AAAA,IACV,eAAA;AAAA,IACA,CAAQ,IAAA,KAAA;AACJ,MAAc,aAAA,CAAA,OAAA,CAAQ,CAAC,KAAA,EAAO,WAAgB,KAAA;AAC1C,QAAA,IAAI,MAAM,WAAa,EAAA;AACnB,UAAM,MAAA,EAAE,QAAW,GAAA,KAAA;AACnB,UAAc,aAAA,CAAA,GAAA,CAAI,aAAa,EAAE,WAAA,EAAa,OAAO,YAAc,EAAA,IAAI,CAAA;AACvE,UAAA,MAAA,CAAO,IAAa,CAAA;AAAA,SACjB,MAAA;AACH,UAAA,KAAA,CAAM,aAAa,IAAK,CAAA;AAAA,YACpB,MAAQ,EAAA,CAAA;AAAA,YACR;AAAA,WACH,CAAA;AAAA;AACL,OACH,CAAA;AAAA,KACL;AAAA,IACA;AAAA,GACJ;AACA,EAAO,OAAA;AAAA,IACH,QAAQ,MAAO,CAAA,aAAa,CAAI,GAAA;AAC5B,MAAA,IAAI,YAAY,OAAS,EAAA;AACrB,QAAA;AAAA;AAEJ,MAAA,IAAI,eAAe,aAAe,EAAA;AAC9B,QAAM,MAAA,UAAA;AAAA;AAEV,MAAA,MAAM,cAAc,MAAO,EAAA;AAC3B,MAAc,aAAA,CAAA,GAAA,CAAI,aAAa,EAAE,WAAA,EAAa,OAAO,YAAc,EAAA,IAAI,CAAA;AACvE,MAAI,IAAA;AACA,QAAA,OAAO,IAAM,EAAA;AACT,UAAM,MAAA,KAAA,GAAQ,aAAc,CAAA,GAAA,CAAI,WAAW,CAAA;AAC3C,UAAA,IAAI,CAAC,KAAO,EAAA;AAER,YAAM,MAAA,IAAIE,mBAAYC,6EAAsE,CAAA;AAAA;AAEhG,UAAA,IAAI,MAAM,WAAa,EAAA;AAEnB,YAAA,MAAM,IAAID,kBAAA;AAAA,cACNE;AAAA,aACJ;AAAA;AAEJ,UAAA,MAAM,eAAe,KAAM,CAAA,YAAA;AAC3B,UAAI,IAAA;AACA,YAAA,IAAI,aAAa,MAAQ,EAAA;AACrB,cAAA,KAAA,CAAM,eAAe,EAAC;AACtB,cAAA,KAAA,MAAW,QAAQ,YAAc,EAAA;AAC7B,gBAAI,IAAA,IAAA,CAAK,WAAW,CAAkB,aAAA;AAClC,kBAAA,MAAM,IAAK,CAAA,IAAA;AAAA,iBACR,MAAA;AACH,kBAAA,MAAM,IAAK,CAAA,GAAA;AAAA;AACf;AACJ,aACG,MAAA;AACH,cAAA,MAAM,MAAM,IAAI,OAAe,CAAA,CAAC,SAAS,MAAW,KAAA;AAChD,gBAAA,aAAA,CAAc,IAAI,WAAa,EAAA;AAAA,kBAC3B,WAAa,EAAA,IAAA;AAAA,kBACb,MAAQ,EAAA,OAAA;AAAA,kBACR,OAAS,EAAA;AAAA,iBACZ,CAAA;AAAA,eACJ,CAAA;AAAA;AACL,mBACKC,EAAG,EAAA;AACR,YAAIA,IAAAA,EAAAA,MAAO,oBAAyB,KAAA,wBAAA,EAA6B,CAAA,EAAA;AAC7D,cAAA;AAAA,aACG,MAAA;AACH,cAAMA,MAAAA,EAAAA;AAAA;AACV;AACJ;AACJ,OACF,SAAA;AACE,QAAA,aAAA,CAAc,OAAO,WAAW,CAAA;AAAA;AACpC;AACJ,GACJ;AACJ;;;AChKO,SAAS,iCACZ,YAGD,EAAA;AACC,EAAO,OAAA;AAAA,IACH,EAAA,CAAG,WAAa,EAAA,UAAA,EAAY,OAAS,EAAA;AACjC,MAAA,SAAS,cAAc,EAAW,EAAA;AAC9B,QAAA,IAAI,cAAc,WAAa,EAAA;AAC3B,UAAA,MAAM,OAAQ,EAAkD,CAAA,MAAA;AAChE,UAAC,WAAwE,IAAI,CAAA;AAAA,SAC1E,MAAA;AACH,UAAC,UAA0B,EAAA;AAAA;AAC/B;AAEJ,MAAa,YAAA,CAAA,gBAAA,CAAiB,WAAa,EAAA,aAAA,EAAe,OAAO,CAAA;AACjE,MAAA,OAAO,MAAM;AACT,QAAa,YAAA,CAAA,mBAAA,CAAoB,aAAa,aAAa,CAAA;AAAA,OAC/D;AAAA;AACJ,GACJ;AACJ;;;AC7BO,SAAS,wBAAA,CAIZ,SACA,EAAA,iBAAA,EACA,kBAKa,EAAA;AACb,EAAI,IAAA,mBAAA;AAMJ,EAAM,MAAA,WAAA,GAAc,IAAI,CAAY,EAAA;AACpC,EAAM,MAAA,0BAAA,GAA6B,iCAAiC,WAAW,CAAA;AAC/E,EAAO,OAAA;AAAA,IACH,GAAG,0BAAA;AAAA,IACH,EAAA,CAAG,WAAa,EAAA,UAAA,EAAY,OAAS,EAAA;AACjC,MAAA,IAAI,CAAC,mBAAqB,EAAA;AACtB,QAAA,MAAM,yBAA4B,GAAA,SAAA,CAAU,EAAG,CAAA,iBAAA,EAAmB,CAAiB,aAAA,KAAA;AAC/E,UAAM,MAAA,eAAA,GAAkB,mBAAmB,aAAa,CAAA;AACxD,UAAA,IAAI,CAAC,eAAiB,EAAA;AAClB,YAAA;AAAA;AAEJ,UAAM,MAAA,CAAC,sBAAwB,EAAA,OAAO,CAAI,GAAA,eAAA;AAC1C,UAAY,WAAA,CAAA,aAAA;AAAA,YACR,IAAI,YAAY,sBAAwB,EAAA;AAAA,cACpC,MAAQ,EAAA;AAAA,aACX;AAAA,WACL;AAAA,SACH,CAAA;AACD,QAAsB,mBAAA,GAAA;AAAA,UAClB,OAAS,EAAA,yBAAA;AAAA,UACT,cAAgB,EAAA;AAAA,SACpB;AAAA;AAEJ,MAAoB,mBAAA,CAAA,cAAA,EAAA;AACpB,MAAA,MAAM,WAAc,GAAA,0BAAA,CAA2B,EAAG,CAAA,WAAA,EAAa,YAAY,OAAO,CAAA;AAClF,MAAA,IAAI,QAAW,GAAA,IAAA;AACf,MAAA,SAAS,iBAAoB,GAAA;AACzB,QAAA,IAAI,CAAC,QAAU,EAAA;AACX,UAAA;AAAA;AAEJ,QAAW,QAAA,GAAA,KAAA;AACX,QAAS,OAAA,EAAA,MAAA,CAAO,mBAAoB,CAAA,OAAA,EAAS,iBAAiB,CAAA;AAC9D,QAAqB,mBAAA,CAAA,cAAA,EAAA;AACrB,QAAI,IAAA,mBAAA,CAAqB,mBAAmB,CAAG,EAAA;AAC3C,UAAA,mBAAA,CAAqB,OAAQ,EAAA;AAC7B,UAAsB,mBAAA,GAAA,MAAA;AAAA;AAE1B,QAAY,WAAA,EAAA;AAAA;AAEhB,MAAS,OAAA,EAAA,MAAA,CAAO,gBAAiB,CAAA,OAAA,EAAS,iBAAiB,CAAA;AAC3D,MAAO,OAAA,iBAAA;AAAA;AACX,GACJ;AACJ","file":"index.node.cjs","sourcesContent":["import { setMaxListeners } from 'node:events';\n\nexport const AbortController = class extends globalThis.AbortController {\n constructor(...args: ConstructorParameters<typeof globalThis.AbortController>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this.signal);\n }\n};\n\nexport const EventTarget = class extends globalThis.EventTarget {\n constructor(...args: ConstructorParameters<typeof globalThis.EventTarget>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this);\n }\n};\n","import {\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE,\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING,\n SolanaError,\n} from '@solana/errors';\nimport { AbortController } from '@solana/event-target-impl';\n\nimport { DataPublisher } from './data-publisher';\n\ntype Config = Readonly<{\n abortSignal: AbortSignal;\n dataChannelName: string;\n // FIXME: It would be nice to be able to constrain the type of `dataPublisher` to one that\n // definitely supports the `dataChannelName` and `errorChannelName` channels, and\n // furthermore publishes `TData` on the `dataChannelName` channel. This is more difficult\n // than it should be: https://tsplay.dev/NlZelW\n dataPublisher: DataPublisher;\n errorChannelName: string;\n}>;\n\nconst enum PublishType {\n DATA,\n ERROR,\n}\n\ntype IteratorKey = symbol;\ntype IteratorState<TData> =\n | {\n __hasPolled: false;\n publishQueue: (\n | {\n __type: PublishType.DATA;\n data: TData;\n }\n | {\n __type: PublishType.ERROR;\n err: unknown;\n }\n )[];\n }\n | {\n __hasPolled: true;\n onData: (data: TData) => void;\n onError: Parameters<ConstructorParameters<typeof Promise>[0]>[1];\n };\n\nlet EXPLICIT_ABORT_TOKEN: symbol;\nfunction createExplicitAbortToken() {\n // This function is an annoying workaround to prevent `process.env.NODE_ENV` from appearing at\n // the top level of this module and thwarting an optimizing compiler's attempt to tree-shake.\n return Symbol(\n process.env.NODE_ENV !== \"production\"\n ? \"This symbol is thrown from a socket's iterator when the connection is explicitly \" +\n 'aborted by the user'\n : undefined,\n );\n}\n\nconst UNINITIALIZED = Symbol();\n\nexport function createAsyncIterableFromDataPublisher<TData>({\n abortSignal,\n dataChannelName,\n dataPublisher,\n errorChannelName,\n}: Config): AsyncIterable<TData> {\n const iteratorState: Map<IteratorKey, IteratorState<TData>> = new Map();\n function publishErrorToAllIterators(reason: unknown) {\n for (const [iteratorKey, state] of iteratorState.entries()) {\n if (state.__hasPolled) {\n iteratorState.delete(iteratorKey);\n state.onError(reason);\n } else {\n state.publishQueue.push({\n __type: PublishType.ERROR,\n err: reason,\n });\n }\n }\n }\n const abortController = new AbortController();\n abortSignal.addEventListener('abort', () => {\n abortController.abort();\n publishErrorToAllIterators((EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken()));\n });\n const options = { signal: abortController.signal } as const;\n let firstError: unknown = UNINITIALIZED;\n dataPublisher.on(\n errorChannelName,\n err => {\n if (firstError === UNINITIALIZED) {\n firstError = err;\n abortController.abort();\n publishErrorToAllIterators(err);\n }\n },\n options,\n );\n dataPublisher.on(\n dataChannelName,\n data => {\n iteratorState.forEach((state, iteratorKey) => {\n if (state.__hasPolled) {\n const { onData } = state;\n iteratorState.set(iteratorKey, { __hasPolled: false, publishQueue: [] });\n onData(data as TData);\n } else {\n state.publishQueue.push({\n __type: PublishType.DATA,\n data: data as TData,\n });\n }\n });\n },\n options,\n );\n return {\n async *[Symbol.asyncIterator]() {\n if (abortSignal.aborted) {\n return;\n }\n if (firstError !== UNINITIALIZED) {\n throw firstError;\n }\n const iteratorKey = Symbol();\n iteratorState.set(iteratorKey, { __hasPolled: false, publishQueue: [] });\n try {\n while (true) {\n const state = iteratorState.get(iteratorKey);\n if (!state) {\n // There should always be state by now.\n throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING);\n }\n if (state.__hasPolled) {\n // You should never be able to poll twice in a row.\n throw new SolanaError(\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE,\n );\n }\n const publishQueue = state.publishQueue;\n try {\n if (publishQueue.length) {\n state.publishQueue = [];\n for (const item of publishQueue) {\n if (item.__type === PublishType.DATA) {\n yield item.data;\n } else {\n throw item.err;\n }\n }\n } else {\n yield await new Promise<TData>((resolve, reject) => {\n iteratorState.set(iteratorKey, {\n __hasPolled: true,\n onData: resolve,\n onError: reject,\n });\n });\n }\n } catch (e) {\n if (e === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {\n return;\n } else {\n throw e;\n }\n }\n }\n } finally {\n iteratorState.delete(iteratorKey);\n }\n },\n };\n}\n","import { TypedEventEmitter, TypedEventTarget } from './event-emitter';\n\ntype UnsubscribeFn = () => void;\n\nexport interface DataPublisher<TDataByChannelName extends Record<string, unknown> = Record<string, unknown>> {\n on<const TChannelName extends keyof TDataByChannelName>(\n channelName: TChannelName,\n subscriber: (data: TDataByChannelName[TChannelName]) => void,\n options?: { signal: AbortSignal },\n ): UnsubscribeFn;\n}\n\nexport function getDataPublisherFromEventEmitter<TEventMap extends Record<string, Event>>(\n eventEmitter: TypedEventEmitter<TEventMap> | TypedEventTarget<TEventMap>,\n): DataPublisher<{\n [TEventType in keyof TEventMap]: TEventMap[TEventType] extends CustomEvent ? TEventMap[TEventType]['detail'] : null;\n}> {\n return {\n on(channelName, subscriber, options) {\n function innerListener(ev: Event) {\n if (ev instanceof CustomEvent) {\n const data = (ev as CustomEvent<TEventMap[typeof channelName]>).detail;\n (subscriber as unknown as (data: TEventMap[typeof channelName]) => void)(data);\n } else {\n (subscriber as () => void)();\n }\n }\n eventEmitter.addEventListener(channelName, innerListener, options);\n return () => {\n eventEmitter.removeEventListener(channelName, innerListener);\n };\n },\n };\n}\n","import { EventTarget } from '@solana/event-target-impl';\n\nimport { DataPublisher, getDataPublisherFromEventEmitter } from './data-publisher';\n\nexport function demultiplexDataPublisher<\n TDataPublisher extends DataPublisher,\n const TChannelName extends Parameters<TDataPublisher['on']>[0],\n>(\n publisher: TDataPublisher,\n sourceChannelName: TChannelName,\n messageTransformer: (\n // FIXME: Deriving the type of the message from `TDataPublisher` and `TChannelName` would\n // help callers to constrain their transform functions.\n message: unknown,\n ) => [destinationChannelName: string, message: unknown] | void,\n): DataPublisher {\n let innerPublisherState:\n | {\n readonly dispose: () => void;\n numSubscribers: number;\n }\n | undefined;\n const eventTarget = new EventTarget();\n const demultiplexedDataPublisher = getDataPublisherFromEventEmitter(eventTarget);\n return {\n ...demultiplexedDataPublisher,\n on(channelName, subscriber, options) {\n if (!innerPublisherState) {\n const innerPublisherUnsubscribe = publisher.on(sourceChannelName, sourceMessage => {\n const transformResult = messageTransformer(sourceMessage);\n if (!transformResult) {\n return;\n }\n const [destinationChannelName, message] = transformResult;\n eventTarget.dispatchEvent(\n new CustomEvent(destinationChannelName, {\n detail: message,\n }),\n );\n });\n innerPublisherState = {\n dispose: innerPublisherUnsubscribe,\n numSubscribers: 0,\n };\n }\n innerPublisherState.numSubscribers++;\n const unsubscribe = demultiplexedDataPublisher.on(channelName, subscriber, options);\n let isActive = true;\n function handleUnsubscribe() {\n if (!isActive) {\n return;\n }\n isActive = false;\n options?.signal.removeEventListener('abort', handleUnsubscribe);\n innerPublisherState!.numSubscribers--;\n if (innerPublisherState!.numSubscribers === 0) {\n innerPublisherState!.dispose();\n innerPublisherState = undefined;\n }\n unsubscribe();\n }\n options?.signal.addEventListener('abort', handleUnsubscribe);\n return handleUnsubscribe;\n },\n };\n}\n"]}
@@ -17,7 +17,7 @@ var s = class extends globalThis.EventTarget {
17
17
  var EXPLICIT_ABORT_TOKEN;
18
18
  function createExplicitAbortToken() {
19
19
  return Symbol(
20
- process.env.NODE_ENV !== "production" ? "This symbol is thrown from a socket's iterator when the connection is explicitly aborted by the user" : undefined
20
+ process.env.NODE_ENV !== "production" ? "This symbol is thrown from a socket's iterator when the connection is explicitly aborted by the user" : void 0
21
21
  );
22
22
  }
23
23
  var UNINITIALIZED = Symbol();
@@ -191,7 +191,7 @@ function demultiplexDataPublisher(publisher, sourceChannelName, messageTransform
191
191
  innerPublisherState.numSubscribers--;
192
192
  if (innerPublisherState.numSubscribers === 0) {
193
193
  innerPublisherState.dispose();
194
- innerPublisherState = undefined;
194
+ innerPublisherState = void 0;
195
195
  }
196
196
  unsubscribe();
197
197
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../event-target-impl/src/index.node.ts","../src/async-iterable.ts","../src/data-publisher.ts","../src/demultiplex.ts"],"names":["AbortController","args","setMaxListeners","EventTarget","e"],"mappings":"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","file":"index.node.mjs","sourcesContent":["import { setMaxListeners } from 'node:events';\n\nexport const AbortController = class extends globalThis.AbortController {\n constructor(...args: ConstructorParameters<typeof globalThis.AbortController>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this.signal);\n }\n};\n\nexport const EventTarget = class extends globalThis.EventTarget {\n constructor(...args: ConstructorParameters<typeof globalThis.EventTarget>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this);\n }\n};\n","import {\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE,\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING,\n SolanaError,\n} from '@solana/errors';\nimport { AbortController } from '@solana/event-target-impl';\n\nimport { DataPublisher } from './data-publisher';\n\ntype Config = Readonly<{\n abortSignal: AbortSignal;\n dataChannelName: string;\n // FIXME: It would be nice to be able to constrain the type of `dataPublisher` to one that\n // definitely supports the `dataChannelName` and `errorChannelName` channels, and\n // furthermore publishes `TData` on the `dataChannelName` channel. This is more difficult\n // than it should be: https://tsplay.dev/NlZelW\n dataPublisher: DataPublisher;\n errorChannelName: string;\n}>;\n\nconst enum PublishType {\n DATA,\n ERROR,\n}\n\ntype IteratorKey = symbol;\ntype IteratorState<TData> =\n | {\n __hasPolled: false;\n publishQueue: (\n | {\n __type: PublishType.DATA;\n data: TData;\n }\n | {\n __type: PublishType.ERROR;\n err: unknown;\n }\n )[];\n }\n | {\n __hasPolled: true;\n onData: (data: TData) => void;\n onError: Parameters<ConstructorParameters<typeof Promise>[0]>[1];\n };\n\nlet EXPLICIT_ABORT_TOKEN: symbol;\nfunction createExplicitAbortToken() {\n // This function is an annoying workaround to prevent `process.env.NODE_ENV` from appearing at\n // the top level of this module and thwarting an optimizing compiler's attempt to tree-shake.\n return Symbol(\n process.env.NODE_ENV !== \"production\"\n ? \"This symbol is thrown from a socket's iterator when the connection is explicitly \" +\n 'aborted by the user'\n : undefined,\n );\n}\n\nconst UNINITIALIZED = Symbol();\n\nexport function createAsyncIterableFromDataPublisher<TData>({\n abortSignal,\n dataChannelName,\n dataPublisher,\n errorChannelName,\n}: Config): AsyncIterable<TData> {\n const iteratorState: Map<IteratorKey, IteratorState<TData>> = new Map();\n function publishErrorToAllIterators(reason: unknown) {\n for (const [iteratorKey, state] of iteratorState.entries()) {\n if (state.__hasPolled) {\n iteratorState.delete(iteratorKey);\n state.onError(reason);\n } else {\n state.publishQueue.push({\n __type: PublishType.ERROR,\n err: reason,\n });\n }\n }\n }\n const abortController = new AbortController();\n abortSignal.addEventListener('abort', () => {\n abortController.abort();\n publishErrorToAllIterators((EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken()));\n });\n const options = { signal: abortController.signal } as const;\n let firstError: unknown = UNINITIALIZED;\n dataPublisher.on(\n errorChannelName,\n err => {\n if (firstError === UNINITIALIZED) {\n firstError = err;\n abortController.abort();\n publishErrorToAllIterators(err);\n }\n },\n options,\n );\n dataPublisher.on(\n dataChannelName,\n data => {\n iteratorState.forEach((state, iteratorKey) => {\n if (state.__hasPolled) {\n const { onData } = state;\n iteratorState.set(iteratorKey, { __hasPolled: false, publishQueue: [] });\n onData(data as TData);\n } else {\n state.publishQueue.push({\n __type: PublishType.DATA,\n data: data as TData,\n });\n }\n });\n },\n options,\n );\n return {\n async *[Symbol.asyncIterator]() {\n if (abortSignal.aborted) {\n return;\n }\n if (firstError !== UNINITIALIZED) {\n throw firstError;\n }\n const iteratorKey = Symbol();\n iteratorState.set(iteratorKey, { __hasPolled: false, publishQueue: [] });\n try {\n while (true) {\n const state = iteratorState.get(iteratorKey);\n if (!state) {\n // There should always be state by now.\n throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING);\n }\n if (state.__hasPolled) {\n // You should never be able to poll twice in a row.\n throw new SolanaError(\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE,\n );\n }\n const publishQueue = state.publishQueue;\n try {\n if (publishQueue.length) {\n state.publishQueue = [];\n for (const item of publishQueue) {\n if (item.__type === PublishType.DATA) {\n yield item.data;\n } else {\n throw item.err;\n }\n }\n } else {\n yield await new Promise<TData>((resolve, reject) => {\n iteratorState.set(iteratorKey, {\n __hasPolled: true,\n onData: resolve,\n onError: reject,\n });\n });\n }\n } catch (e) {\n if (e === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {\n return;\n } else {\n throw e;\n }\n }\n }\n } finally {\n iteratorState.delete(iteratorKey);\n }\n },\n };\n}\n","import { TypedEventEmitter, TypedEventTarget } from './event-emitter';\n\ntype UnsubscribeFn = () => void;\n\nexport interface DataPublisher<TDataByChannelName extends Record<string, unknown> = Record<string, unknown>> {\n on<const TChannelName extends keyof TDataByChannelName>(\n channelName: TChannelName,\n subscriber: (data: TDataByChannelName[TChannelName]) => void,\n options?: { signal: AbortSignal },\n ): UnsubscribeFn;\n}\n\nexport function getDataPublisherFromEventEmitter<TEventMap extends Record<string, Event>>(\n eventEmitter: TypedEventEmitter<TEventMap> | TypedEventTarget<TEventMap>,\n): DataPublisher<{\n [TEventType in keyof TEventMap]: TEventMap[TEventType] extends CustomEvent ? TEventMap[TEventType]['detail'] : null;\n}> {\n return {\n on(channelName, subscriber, options) {\n function innerListener(ev: Event) {\n if (ev instanceof CustomEvent) {\n const data = (ev as CustomEvent<TEventMap[typeof channelName]>).detail;\n (subscriber as unknown as (data: TEventMap[typeof channelName]) => void)(data);\n } else {\n (subscriber as () => void)();\n }\n }\n eventEmitter.addEventListener(channelName, innerListener, options);\n return () => {\n eventEmitter.removeEventListener(channelName, innerListener);\n };\n },\n };\n}\n","import { EventTarget } from '@solana/event-target-impl';\n\nimport { DataPublisher, getDataPublisherFromEventEmitter } from './data-publisher';\n\nexport function demultiplexDataPublisher<\n TDataPublisher extends DataPublisher,\n const TChannelName extends Parameters<TDataPublisher['on']>[0],\n>(\n publisher: TDataPublisher,\n sourceChannelName: TChannelName,\n messageTransformer: (\n // FIXME: Deriving the type of the message from `TDataPublisher` and `TChannelName` would\n // help callers to constrain their transform functions.\n message: unknown,\n ) => [destinationChannelName: string, message: unknown] | void,\n): DataPublisher {\n let innerPublisherState:\n | {\n readonly dispose: () => void;\n numSubscribers: number;\n }\n | undefined;\n const eventTarget = new EventTarget();\n const demultiplexedDataPublisher = getDataPublisherFromEventEmitter(eventTarget);\n return {\n ...demultiplexedDataPublisher,\n on(channelName, subscriber, options) {\n if (!innerPublisherState) {\n const innerPublisherUnsubscribe = publisher.on(sourceChannelName, sourceMessage => {\n const transformResult = messageTransformer(sourceMessage);\n if (!transformResult) {\n return;\n }\n const [destinationChannelName, message] = transformResult;\n eventTarget.dispatchEvent(\n new CustomEvent(destinationChannelName, {\n detail: message,\n }),\n );\n });\n innerPublisherState = {\n dispose: innerPublisherUnsubscribe,\n numSubscribers: 0,\n };\n }\n innerPublisherState.numSubscribers++;\n const unsubscribe = demultiplexedDataPublisher.on(channelName, subscriber, options);\n let isActive = true;\n function handleUnsubscribe() {\n if (!isActive) {\n return;\n }\n isActive = false;\n options?.signal.removeEventListener('abort', handleUnsubscribe);\n innerPublisherState!.numSubscribers--;\n if (innerPublisherState!.numSubscribers === 0) {\n innerPublisherState!.dispose();\n innerPublisherState = undefined;\n }\n unsubscribe();\n }\n options?.signal.addEventListener('abort', handleUnsubscribe);\n return handleUnsubscribe;\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../../event-target-impl/src/index.node.ts","../src/async-iterable.ts","../src/data-publisher.ts","../src/demultiplex.ts"],"names":["AbortController","args","setMaxListeners","EventTarget","e"],"mappings":"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","file":"index.node.mjs","sourcesContent":["import { setMaxListeners } from 'node:events';\n\nexport const AbortController = class extends globalThis.AbortController {\n constructor(...args: ConstructorParameters<typeof globalThis.AbortController>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this.signal);\n }\n};\n\nexport const EventTarget = class extends globalThis.EventTarget {\n constructor(...args: ConstructorParameters<typeof globalThis.EventTarget>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this);\n }\n};\n","import {\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE,\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING,\n SolanaError,\n} from '@solana/errors';\nimport { AbortController } from '@solana/event-target-impl';\n\nimport { DataPublisher } from './data-publisher';\n\ntype Config = Readonly<{\n abortSignal: AbortSignal;\n dataChannelName: string;\n // FIXME: It would be nice to be able to constrain the type of `dataPublisher` to one that\n // definitely supports the `dataChannelName` and `errorChannelName` channels, and\n // furthermore publishes `TData` on the `dataChannelName` channel. This is more difficult\n // than it should be: https://tsplay.dev/NlZelW\n dataPublisher: DataPublisher;\n errorChannelName: string;\n}>;\n\nconst enum PublishType {\n DATA,\n ERROR,\n}\n\ntype IteratorKey = symbol;\ntype IteratorState<TData> =\n | {\n __hasPolled: false;\n publishQueue: (\n | {\n __type: PublishType.DATA;\n data: TData;\n }\n | {\n __type: PublishType.ERROR;\n err: unknown;\n }\n )[];\n }\n | {\n __hasPolled: true;\n onData: (data: TData) => void;\n onError: Parameters<ConstructorParameters<typeof Promise>[0]>[1];\n };\n\nlet EXPLICIT_ABORT_TOKEN: symbol;\nfunction createExplicitAbortToken() {\n // This function is an annoying workaround to prevent `process.env.NODE_ENV` from appearing at\n // the top level of this module and thwarting an optimizing compiler's attempt to tree-shake.\n return Symbol(\n process.env.NODE_ENV !== \"production\"\n ? \"This symbol is thrown from a socket's iterator when the connection is explicitly \" +\n 'aborted by the user'\n : undefined,\n );\n}\n\nconst UNINITIALIZED = Symbol();\n\nexport function createAsyncIterableFromDataPublisher<TData>({\n abortSignal,\n dataChannelName,\n dataPublisher,\n errorChannelName,\n}: Config): AsyncIterable<TData> {\n const iteratorState: Map<IteratorKey, IteratorState<TData>> = new Map();\n function publishErrorToAllIterators(reason: unknown) {\n for (const [iteratorKey, state] of iteratorState.entries()) {\n if (state.__hasPolled) {\n iteratorState.delete(iteratorKey);\n state.onError(reason);\n } else {\n state.publishQueue.push({\n __type: PublishType.ERROR,\n err: reason,\n });\n }\n }\n }\n const abortController = new AbortController();\n abortSignal.addEventListener('abort', () => {\n abortController.abort();\n publishErrorToAllIterators((EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken()));\n });\n const options = { signal: abortController.signal } as const;\n let firstError: unknown = UNINITIALIZED;\n dataPublisher.on(\n errorChannelName,\n err => {\n if (firstError === UNINITIALIZED) {\n firstError = err;\n abortController.abort();\n publishErrorToAllIterators(err);\n }\n },\n options,\n );\n dataPublisher.on(\n dataChannelName,\n data => {\n iteratorState.forEach((state, iteratorKey) => {\n if (state.__hasPolled) {\n const { onData } = state;\n iteratorState.set(iteratorKey, { __hasPolled: false, publishQueue: [] });\n onData(data as TData);\n } else {\n state.publishQueue.push({\n __type: PublishType.DATA,\n data: data as TData,\n });\n }\n });\n },\n options,\n );\n return {\n async *[Symbol.asyncIterator]() {\n if (abortSignal.aborted) {\n return;\n }\n if (firstError !== UNINITIALIZED) {\n throw firstError;\n }\n const iteratorKey = Symbol();\n iteratorState.set(iteratorKey, { __hasPolled: false, publishQueue: [] });\n try {\n while (true) {\n const state = iteratorState.get(iteratorKey);\n if (!state) {\n // There should always be state by now.\n throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING);\n }\n if (state.__hasPolled) {\n // You should never be able to poll twice in a row.\n throw new SolanaError(\n SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE,\n );\n }\n const publishQueue = state.publishQueue;\n try {\n if (publishQueue.length) {\n state.publishQueue = [];\n for (const item of publishQueue) {\n if (item.__type === PublishType.DATA) {\n yield item.data;\n } else {\n throw item.err;\n }\n }\n } else {\n yield await new Promise<TData>((resolve, reject) => {\n iteratorState.set(iteratorKey, {\n __hasPolled: true,\n onData: resolve,\n onError: reject,\n });\n });\n }\n } catch (e) {\n if (e === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {\n return;\n } else {\n throw e;\n }\n }\n }\n } finally {\n iteratorState.delete(iteratorKey);\n }\n },\n };\n}\n","import { TypedEventEmitter, TypedEventTarget } from './event-emitter';\n\ntype UnsubscribeFn = () => void;\n\nexport interface DataPublisher<TDataByChannelName extends Record<string, unknown> = Record<string, unknown>> {\n on<const TChannelName extends keyof TDataByChannelName>(\n channelName: TChannelName,\n subscriber: (data: TDataByChannelName[TChannelName]) => void,\n options?: { signal: AbortSignal },\n ): UnsubscribeFn;\n}\n\nexport function getDataPublisherFromEventEmitter<TEventMap extends Record<string, Event>>(\n eventEmitter: TypedEventEmitter<TEventMap> | TypedEventTarget<TEventMap>,\n): DataPublisher<{\n [TEventType in keyof TEventMap]: TEventMap[TEventType] extends CustomEvent ? TEventMap[TEventType]['detail'] : null;\n}> {\n return {\n on(channelName, subscriber, options) {\n function innerListener(ev: Event) {\n if (ev instanceof CustomEvent) {\n const data = (ev as CustomEvent<TEventMap[typeof channelName]>).detail;\n (subscriber as unknown as (data: TEventMap[typeof channelName]) => void)(data);\n } else {\n (subscriber as () => void)();\n }\n }\n eventEmitter.addEventListener(channelName, innerListener, options);\n return () => {\n eventEmitter.removeEventListener(channelName, innerListener);\n };\n },\n };\n}\n","import { EventTarget } from '@solana/event-target-impl';\n\nimport { DataPublisher, getDataPublisherFromEventEmitter } from './data-publisher';\n\nexport function demultiplexDataPublisher<\n TDataPublisher extends DataPublisher,\n const TChannelName extends Parameters<TDataPublisher['on']>[0],\n>(\n publisher: TDataPublisher,\n sourceChannelName: TChannelName,\n messageTransformer: (\n // FIXME: Deriving the type of the message from `TDataPublisher` and `TChannelName` would\n // help callers to constrain their transform functions.\n message: unknown,\n ) => [destinationChannelName: string, message: unknown] | void,\n): DataPublisher {\n let innerPublisherState:\n | {\n readonly dispose: () => void;\n numSubscribers: number;\n }\n | undefined;\n const eventTarget = new EventTarget();\n const demultiplexedDataPublisher = getDataPublisherFromEventEmitter(eventTarget);\n return {\n ...demultiplexedDataPublisher,\n on(channelName, subscriber, options) {\n if (!innerPublisherState) {\n const innerPublisherUnsubscribe = publisher.on(sourceChannelName, sourceMessage => {\n const transformResult = messageTransformer(sourceMessage);\n if (!transformResult) {\n return;\n }\n const [destinationChannelName, message] = transformResult;\n eventTarget.dispatchEvent(\n new CustomEvent(destinationChannelName, {\n detail: message,\n }),\n );\n });\n innerPublisherState = {\n dispose: innerPublisherUnsubscribe,\n numSubscribers: 0,\n };\n }\n innerPublisherState.numSubscribers++;\n const unsubscribe = demultiplexedDataPublisher.on(channelName, subscriber, options);\n let isActive = true;\n function handleUnsubscribe() {\n if (!isActive) {\n return;\n }\n isActive = false;\n options?.signal.removeEventListener('abort', handleUnsubscribe);\n innerPublisherState!.numSubscribers--;\n if (innerPublisherState!.numSubscribers === 0) {\n innerPublisherState!.dispose();\n innerPublisherState = undefined;\n }\n unsubscribe();\n }\n options?.signal.addEventListener('abort', handleUnsubscribe);\n return handleUnsubscribe;\n },\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solana/subscribable",
3
- "version": "2.1.0",
3
+ "version": "2.1.1-canary-20250310215239",
4
4
  "description": "Helpers for creating subscription-based event emitters",
5
5
  "exports": {
6
6
  "edge-light": {
@@ -54,7 +54,7 @@
54
54
  "maintained node versions"
55
55
  ],
56
56
  "dependencies": {
57
- "@solana/errors": "2.1.0"
57
+ "@solana/errors": "2.1.1-canary-20250310215239"
58
58
  },
59
59
  "peerDependencies": {
60
60
  "typescript": ">=5"