@solana/subscribable 2.0.0-20241006045741

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/async-iterable.ts","../src/data-publisher.ts","../src/demultiplex.ts"],"names":[],"mappings":"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","file":"index.node.mjs","sourcesContent":["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';\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 | typeof UNINITIALIZED = 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 { 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"]}
@@ -0,0 +1,10 @@
1
+ import { DataPublisher } from './data-publisher';
2
+ type Config = Readonly<{
3
+ abortSignal: AbortSignal;
4
+ dataChannelName: string;
5
+ dataPublisher: DataPublisher;
6
+ errorChannelName: string;
7
+ }>;
8
+ export declare function createAsyncIterableFromDataPublisher<TData>({ abortSignal, dataChannelName, dataPublisher, errorChannelName, }: Config): AsyncIterable<TData>;
9
+ export {};
10
+ //# sourceMappingURL=async-iterable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async-iterable.d.ts","sourceRoot":"","sources":["../../src/async-iterable.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,KAAK,MAAM,GAAG,QAAQ,CAAC;IACnB,WAAW,EAAE,WAAW,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IAKxB,aAAa,EAAE,aAAa,CAAC;IAC7B,gBAAgB,EAAE,MAAM,CAAC;CAC5B,CAAC,CAAC;AA0CH,wBAAgB,oCAAoC,CAAC,KAAK,EAAE,EACxD,WAAW,EACX,eAAe,EACf,aAAa,EACb,gBAAgB,GACnB,EAAE,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,CA2G/B"}
@@ -0,0 +1,12 @@
1
+ import { TypedEventEmitter, TypedEventTarget } from './event-emitter';
2
+ type UnsubscribeFn = () => void;
3
+ export interface DataPublisher<TDataByChannelName extends Record<string, unknown> = Record<string, unknown>> {
4
+ on<const TChannelName extends keyof TDataByChannelName>(channelName: TChannelName, subscriber: (data: TDataByChannelName[TChannelName]) => void, options?: {
5
+ signal: AbortSignal;
6
+ }): UnsubscribeFn;
7
+ }
8
+ export declare function getDataPublisherFromEventEmitter<TEventMap extends Record<string, Event>>(eventEmitter: TypedEventEmitter<TEventMap> | TypedEventTarget<TEventMap>): DataPublisher<{
9
+ [TEventType in keyof TEventMap]: TEventMap[TEventType] extends CustomEvent ? TEventMap[TEventType]['detail'] : null;
10
+ }>;
11
+ export {};
12
+ //# sourceMappingURL=data-publisher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-publisher.d.ts","sourceRoot":"","sources":["../../src/data-publisher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEtE,KAAK,aAAa,GAAG,MAAM,IAAI,CAAC;AAEhC,MAAM,WAAW,aAAa,CAAC,kBAAkB,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACvG,EAAE,CAAC,KAAK,CAAC,YAAY,SAAS,MAAM,kBAAkB,EAClD,WAAW,EAAE,YAAY,EACzB,UAAU,EAAE,CAAC,IAAI,EAAE,kBAAkB,CAAC,YAAY,CAAC,KAAK,IAAI,EAC5D,OAAO,CAAC,EAAE;QAAE,MAAM,EAAE,WAAW,CAAA;KAAE,GAClC,aAAa,CAAC;CACpB;AAED,wBAAgB,gCAAgC,CAAC,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EACpF,YAAY,EAAE,iBAAiB,CAAC,SAAS,CAAC,GAAG,gBAAgB,CAAC,SAAS,CAAC,GACzE,aAAa,CAAC;KACZ,UAAU,IAAI,MAAM,SAAS,GAAG,SAAS,CAAC,UAAU,CAAC,SAAS,WAAW,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,GAAG,IAAI;CACtH,CAAC,CAiBD"}
@@ -0,0 +1,3 @@
1
+ import { DataPublisher } from './data-publisher';
2
+ export declare function demultiplexDataPublisher<TDataPublisher extends DataPublisher, const TChannelName extends Parameters<TDataPublisher['on']>[0]>(publisher: TDataPublisher, sourceChannelName: TChannelName, messageTransformer: (message: unknown) => [destinationChannelName: string, message: unknown] | void): DataPublisher;
3
+ //# sourceMappingURL=demultiplex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demultiplex.d.ts","sourceRoot":"","sources":["../../src/demultiplex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAoC,MAAM,kBAAkB,CAAC;AAEnF,wBAAgB,wBAAwB,CACpC,cAAc,SAAS,aAAa,EACpC,KAAK,CAAC,YAAY,SAAS,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAE9D,SAAS,EAAE,cAAc,EACzB,iBAAiB,EAAE,YAAY,EAC/B,kBAAkB,EAAE,CAGhB,OAAO,EAAE,OAAO,KACf,CAAC,sBAAsB,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,IAAI,GAC/D,aAAa,CAkDf"}
@@ -0,0 +1,19 @@
1
+ type EventMap = Record<string, Event>;
2
+ type Listener<TEvent extends Event> = ((evt: TEvent) => void) | {
3
+ handleEvent(object: TEvent): void;
4
+ };
5
+ export interface TypedEventEmitter<TEventMap extends EventMap> {
6
+ addEventListener<const TEventType extends keyof TEventMap>(type: TEventType, listener: Listener<TEventMap[TEventType]>, options?: AddEventListenerOptions | boolean): void;
7
+ removeEventListener<const TEventType extends keyof TEventMap>(type: TEventType, listener: Listener<TEventMap[TEventType]>, options?: EventListenerOptions | boolean): void;
8
+ }
9
+ /**
10
+ * Why not just extend the interface above, rather than to copy/paste it?
11
+ * See https://github.com/microsoft/TypeScript/issues/60008
12
+ */
13
+ export interface TypedEventTarget<TEventMap extends EventMap> {
14
+ addEventListener<const TEventType extends keyof TEventMap>(type: TEventType, listener: Listener<TEventMap[TEventType]>, options?: AddEventListenerOptions | boolean): void;
15
+ dispatchEvent<TEventType extends keyof TEventMap>(ev: TEventMap[TEventType]): void;
16
+ removeEventListener<const TEventType extends keyof TEventMap>(type: TEventType, listener: Listener<TEventMap[TEventType]>, options?: EventListenerOptions | boolean): void;
17
+ }
18
+ export {};
19
+ //# sourceMappingURL=event-emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-emitter.d.ts","sourceRoot":"","sources":["../../src/event-emitter.ts"],"names":[],"mappings":"AAAA,KAAK,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AACtC,KAAK,QAAQ,CAAC,MAAM,SAAS,KAAK,IAAI,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG;IAAE,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAEtG,MAAM,WAAW,iBAAiB,CAAC,SAAS,SAAS,QAAQ;IACzD,gBAAgB,CAAC,KAAK,CAAC,UAAU,SAAS,MAAM,SAAS,EACrD,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,EACzC,OAAO,CAAC,EAAE,uBAAuB,GAAG,OAAO,GAC5C,IAAI,CAAC;IACR,mBAAmB,CAAC,KAAK,CAAC,UAAU,SAAS,MAAM,SAAS,EACxD,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,EACzC,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,GACzC,IAAI,CAAC;CACX;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB,CAAC,SAAS,SAAS,QAAQ;IACxD,gBAAgB,CAAC,KAAK,CAAC,UAAU,SAAS,MAAM,SAAS,EACrD,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,EACzC,OAAO,CAAC,EAAE,uBAAuB,GAAG,OAAO,GAC5C,IAAI,CAAC;IACR,aAAa,CAAC,UAAU,SAAS,MAAM,SAAS,EAAE,EAAE,EAAE,SAAS,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC;IACnF,mBAAmB,CAAC,KAAK,CAAC,UAAU,SAAS,MAAM,SAAS,EACxD,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,EACzC,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,GACzC,IAAI,CAAC;CACX"}
@@ -0,0 +1,5 @@
1
+ export * from './async-iterable';
2
+ export * from './data-publisher';
3
+ export * from './demultiplex';
4
+ export * from './event-emitter';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,89 @@
1
+ {
2
+ "name": "@solana/subscribable",
3
+ "version": "2.0.0-20241006045741",
4
+ "description": "Helpers for creating subscription-based event emitters",
5
+ "exports": {
6
+ "edge-light": {
7
+ "import": "./dist/index.node.mjs",
8
+ "require": "./dist/index.node.cjs"
9
+ },
10
+ "workerd": {
11
+ "import": "./dist/index.node.mjs",
12
+ "require": "./dist/index.node.cjs"
13
+ },
14
+ "browser": {
15
+ "import": "./dist/index.browser.mjs",
16
+ "require": "./dist/index.browser.cjs"
17
+ },
18
+ "node": {
19
+ "import": "./dist/index.node.mjs",
20
+ "require": "./dist/index.node.cjs"
21
+ },
22
+ "react-native": "./dist/index.native.mjs",
23
+ "types": "./dist/types/index.d.ts"
24
+ },
25
+ "browser": {
26
+ "./dist/index.node.cjs": "./dist/index.browser.cjs",
27
+ "./dist/index.node.mjs": "./dist/index.browser.mjs"
28
+ },
29
+ "main": "./dist/index.node.cjs",
30
+ "module": "./dist/index.node.mjs",
31
+ "react-native": "./dist/index.native.mjs",
32
+ "types": "./dist/types/index.d.ts",
33
+ "type": "commonjs",
34
+ "files": [
35
+ "./dist/"
36
+ ],
37
+ "sideEffects": false,
38
+ "keywords": [
39
+ "blockchain",
40
+ "solana",
41
+ "web3"
42
+ ],
43
+ "author": "Solana Labs Maintainers <maintainers@solanalabs.com>",
44
+ "license": "MIT",
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "https://github.com/solana-labs/solana-web3.js"
48
+ },
49
+ "bugs": {
50
+ "url": "http://github.com/solana-labs/solana-web3.js/issues"
51
+ },
52
+ "browserslist": [
53
+ "supports bigint and not dead",
54
+ "maintained node versions"
55
+ ],
56
+ "engine": {
57
+ "node": ">=17.4"
58
+ },
59
+ "dependencies": {
60
+ "@solana/errors": "2.0.0-20241006045741"
61
+ },
62
+ "peerDependencies": {
63
+ "typescript": ">=5"
64
+ },
65
+ "bundlewatch": {
66
+ "defaultCompression": "gzip",
67
+ "files": [
68
+ {
69
+ "path": "./dist/index*.js"
70
+ }
71
+ ]
72
+ },
73
+ "scripts": {
74
+ "compile:js": "tsup --config build-scripts/tsup.config.package.ts",
75
+ "compile:typedefs": "tsc -p ./tsconfig.declarations.json",
76
+ "dev": "jest -c ../../node_modules/@solana/test-config/jest-dev.config.ts --rootDir . --watch",
77
+ "publish-impl": "npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks",
78
+ "publish-packages": "pnpm prepublishOnly && pnpm publish-impl",
79
+ "style:fix": "pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*",
80
+ "test:lint": "TERM_OVERRIDE=\"${TURBO_HASH:+dumb}\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.ts --rootDir . --silent",
81
+ "test:prettier": "TERM_OVERRIDE=\"${TURBO_HASH:+dumb}\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.ts --rootDir . --silent",
82
+ "test:treeshakability:browser": "agadoo dist/index.browser.mjs",
83
+ "test:treeshakability:native": "agadoo dist/index.native.mjs",
84
+ "test:treeshakability:node": "agadoo dist/index.node.mjs",
85
+ "test:typecheck": "tsc --noEmit",
86
+ "test:unit:browser": "TERM_OVERRIDE=\"${TURBO_HASH:+dumb}\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.ts --rootDir . --silent",
87
+ "test:unit:node": "TERM_OVERRIDE=\"${TURBO_HASH:+dumb}\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.ts --rootDir . --silent"
88
+ }
89
+ }