@xylabs/threads 4.6.3 → 4.7.0-rc.1

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.
Files changed (231) hide show
  1. package/dist/browser/master/implementation.browser.mjs +89 -0
  2. package/dist/browser/master/implementation.browser.mjs.map +1 -0
  3. package/dist/browser/worker/worker.browser.mjs +291 -0
  4. package/dist/browser/worker/worker.browser.mjs.map +1 -0
  5. package/dist/neutral/index.mjs +1022 -0
  6. package/dist/neutral/index.mjs.map +1 -0
  7. package/dist/neutral/master/implementation.mjs +264 -0
  8. package/dist/neutral/master/implementation.mjs.map +1 -0
  9. package/dist/neutral/master/index.mjs +988 -0
  10. package/dist/neutral/master/index.mjs.map +1 -0
  11. package/dist/neutral/master/pool.mjs +579 -0
  12. package/dist/neutral/master/pool.mjs.map +1 -0
  13. package/dist/neutral/master/register.mjs +272 -0
  14. package/dist/neutral/master/register.mjs.map +1 -0
  15. package/dist/neutral/master/spawn.mjs +412 -0
  16. package/dist/neutral/master/spawn.mjs.map +1 -0
  17. package/dist/neutral/master/thread.mjs +29 -0
  18. package/dist/neutral/master/thread.mjs.map +1 -0
  19. package/dist/neutral/observable-promise.mjs +132 -0
  20. package/dist/neutral/observable-promise.mjs.map +1 -0
  21. package/dist/neutral/observable.mjs +31 -0
  22. package/dist/neutral/observable.mjs.map +1 -0
  23. package/dist/node/master/implementation.node.mjs +154 -0
  24. package/dist/node/master/implementation.node.mjs.map +1 -0
  25. package/dist/node/worker/worker.node.mjs +304 -0
  26. package/dist/node/worker/worker.node.mjs.map +1 -0
  27. package/dist/{common.d.ts → types/common.d.ts} +5 -1
  28. package/dist/types/common.d.ts.map +1 -0
  29. package/dist/types/index.d.ts +9 -0
  30. package/dist/types/index.d.ts.map +1 -0
  31. package/dist/{master → types/master}/get-bundle-url.browser.d.ts +1 -0
  32. package/dist/types/master/get-bundle-url.browser.d.ts.map +1 -0
  33. package/dist/{master → types/master}/implementation.browser.d.ts +2 -1
  34. package/dist/types/master/implementation.browser.d.ts.map +1 -0
  35. package/dist/{master → types/master}/implementation.d.ts +4 -1
  36. package/dist/types/master/implementation.d.ts.map +1 -0
  37. package/dist/{master → types/master}/implementation.node.d.ts +2 -1
  38. package/dist/types/master/implementation.node.d.ts.map +1 -0
  39. package/dist/types/master/index.d.ts +13 -0
  40. package/dist/types/master/index.d.ts.map +1 -0
  41. package/dist/{master → types/master}/invocation-proxy.d.ts +2 -1
  42. package/dist/types/master/invocation-proxy.d.ts.map +1 -0
  43. package/dist/{master → types/master}/pool-types.d.ts +16 -1
  44. package/dist/types/master/pool-types.d.ts.map +1 -0
  45. package/dist/types/master/pool.d.ts +93 -0
  46. package/dist/types/master/pool.d.ts.map +1 -0
  47. package/dist/types/master/register.d.ts +2 -0
  48. package/dist/types/master/register.d.ts.map +1 -0
  49. package/dist/{master → types/master}/spawn.d.ts +12 -2
  50. package/dist/types/master/spawn.d.ts.map +1 -0
  51. package/dist/types/master/thread.d.ts +13 -0
  52. package/dist/types/master/thread.d.ts.map +1 -0
  53. package/dist/{observable-promise.d.ts → types/observable-promise.d.ts} +14 -0
  54. package/dist/types/observable-promise.d.ts.map +1 -0
  55. package/dist/types/observable.d.ts +21 -0
  56. package/dist/types/observable.d.ts.map +1 -0
  57. package/dist/{ponyfills.d.ts → types/ponyfills.d.ts} +1 -0
  58. package/dist/types/ponyfills.d.ts.map +1 -0
  59. package/dist/types/promise.d.ts +6 -0
  60. package/dist/types/promise.d.ts.map +1 -0
  61. package/dist/{serializers.d.ts → types/serializers.d.ts} +1 -0
  62. package/dist/types/serializers.d.ts.map +1 -0
  63. package/dist/{symbols.d.ts → types/symbols.d.ts} +1 -0
  64. package/dist/types/symbols.d.ts.map +1 -0
  65. package/{src/transferable.ts → dist/types/transferable.d.ts} +8 -33
  66. package/dist/types/transferable.d.ts.map +1 -0
  67. package/dist/types/{master.d.ts → types/master.d.ts} +17 -3
  68. package/dist/types/types/master.d.ts.map +1 -0
  69. package/dist/types/{messages.d.ts → types/messages.d.ts} +1 -0
  70. package/dist/types/types/messages.d.ts.map +1 -0
  71. package/dist/types/{worker.d.ts → types/worker.d.ts} +1 -0
  72. package/dist/types/types/worker.d.ts.map +1 -0
  73. package/dist/types/worker/WorkerGlobalScope.d.ts +6 -0
  74. package/dist/types/worker/WorkerGlobalScope.d.ts.map +1 -0
  75. package/dist/types/worker/expose.d.ts +4 -0
  76. package/dist/types/worker/expose.d.ts.map +1 -0
  77. package/dist/types/worker/worker.browser.d.ts +14 -0
  78. package/dist/types/worker/worker.browser.d.ts.map +1 -0
  79. package/dist/types/worker/worker.node.d.ts +25 -0
  80. package/dist/types/worker/worker.node.d.ts.map +1 -0
  81. package/package.json +53 -93
  82. package/dist/common.js +0 -16
  83. package/dist/esm/common.js +0 -16
  84. package/dist/esm/index.js +0 -26
  85. package/dist/esm/master/get-bundle-url.browser.js +0 -25
  86. package/dist/esm/master/implementation.browser.js +0 -65
  87. package/dist/esm/master/implementation.js +0 -43
  88. package/dist/esm/master/implementation.node.js +0 -205
  89. package/dist/esm/master/index.js +0 -14
  90. package/dist/esm/master/invocation-proxy.js +0 -121
  91. package/dist/esm/master/pool-types.js +0 -14
  92. package/dist/esm/master/pool.js +0 -262
  93. package/dist/esm/master/register.js +0 -11
  94. package/dist/esm/master/spawn.js +0 -114
  95. package/dist/esm/master/thread.js +0 -18
  96. package/dist/esm/observable-promise.js +0 -132
  97. package/dist/esm/observable.js +0 -33
  98. package/dist/esm/ponyfills.js +0 -20
  99. package/dist/esm/promise.js +0 -23
  100. package/dist/esm/serializers.js +0 -41
  101. package/dist/esm/symbols.js +0 -8
  102. package/dist/esm/transferable.js +0 -25
  103. package/dist/esm/types/master.js +0 -9
  104. package/dist/esm/types/messages.js +0 -16
  105. package/dist/esm/types/worker.js +0 -2
  106. package/dist/esm/worker/bundle-entry.js +0 -26
  107. package/dist/esm/worker/implementation.browser.js +0 -24
  108. package/dist/esm/worker/implementation.js +0 -19
  109. package/dist/esm/worker/implementation.tiny-worker.js +0 -37
  110. package/dist/esm/worker/implementation.worker_threads.js +0 -41
  111. package/dist/esm/worker/index.js +0 -174
  112. package/dist/esm/worker_threads.js +0 -13
  113. package/dist/index.d.ts +0 -7
  114. package/dist/index.js +0 -26
  115. package/dist/master/get-bundle-url.browser.js +0 -25
  116. package/dist/master/implementation.browser.js +0 -65
  117. package/dist/master/implementation.js +0 -43
  118. package/dist/master/implementation.node.js +0 -205
  119. package/dist/master/index.d.ts +0 -10
  120. package/dist/master/index.js +0 -14
  121. package/dist/master/invocation-proxy.js +0 -121
  122. package/dist/master/pool-types.js +0 -14
  123. package/dist/master/pool.d.ts +0 -50
  124. package/dist/master/pool.js +0 -262
  125. package/dist/master/register.d.ts +0 -1
  126. package/dist/master/register.js +0 -11
  127. package/dist/master/spawn.js +0 -114
  128. package/dist/master/thread.d.ts +0 -8
  129. package/dist/master/thread.js +0 -18
  130. package/dist/observable-promise.js +0 -132
  131. package/dist/observable.d.ts +0 -11
  132. package/dist/observable.js +0 -33
  133. package/dist/ponyfills.js +0 -20
  134. package/dist/promise.d.ts +0 -1
  135. package/dist/promise.js +0 -23
  136. package/dist/serializers.js +0 -41
  137. package/dist/symbols.js +0 -8
  138. package/dist/transferable.d.ts +0 -9
  139. package/dist/transferable.js +0 -25
  140. package/dist/types/master.js +0 -9
  141. package/dist/types/messages.js +0 -16
  142. package/dist/types/worker.js +0 -2
  143. package/dist/worker/bundle-entry.d.ts +0 -1
  144. package/dist/worker/bundle-entry.js +0 -26
  145. package/dist/worker/implementation.browser.d.ts +0 -6
  146. package/dist/worker/implementation.browser.js +0 -24
  147. package/dist/worker/implementation.d.ts +0 -3
  148. package/dist/worker/implementation.js +0 -19
  149. package/dist/worker/implementation.tiny-worker.d.ts +0 -6
  150. package/dist/worker/implementation.tiny-worker.js +0 -37
  151. package/dist/worker/implementation.worker_threads.d.ts +0 -8
  152. package/dist/worker/implementation.worker_threads.js +0 -41
  153. package/dist/worker/index.d.ts +0 -5
  154. package/dist/worker/index.js +0 -174
  155. package/dist/worker_threads.d.ts +0 -8
  156. package/dist/worker_threads.js +0 -13
  157. package/eslint.config.mjs +0 -35
  158. package/index.mjs +0 -10
  159. package/observable.d.ts +0 -2
  160. package/observable.js +0 -2
  161. package/observable.mjs +0 -4
  162. package/register.d.ts +0 -2
  163. package/register.js +0 -2
  164. package/register.mjs +0 -1
  165. package/rollup.config.js +0 -16
  166. package/src/common.ts +0 -19
  167. package/src/index.ts +0 -10
  168. package/src/master/get-bundle-url.browser.ts +0 -31
  169. package/src/master/implementation.browser.ts +0 -82
  170. package/src/master/implementation.node.ts +0 -285
  171. package/src/master/implementation.ts +0 -21
  172. package/src/master/index.ts +0 -19
  173. package/src/master/invocation-proxy.ts +0 -151
  174. package/src/master/pool-types.ts +0 -83
  175. package/src/master/pool.ts +0 -399
  176. package/src/master/register.ts +0 -10
  177. package/src/master/spawn.ts +0 -172
  178. package/src/master/thread.ts +0 -29
  179. package/src/observable-promise.ts +0 -183
  180. package/src/observable.ts +0 -44
  181. package/src/ponyfills.ts +0 -31
  182. package/src/promise.ts +0 -26
  183. package/src/serializers.ts +0 -68
  184. package/src/symbols.ts +0 -5
  185. package/src/types/master.ts +0 -132
  186. package/src/types/messages.ts +0 -72
  187. package/src/types/worker.ts +0 -14
  188. package/src/worker/bundle-entry.ts +0 -10
  189. package/src/worker/implementation.browser.ts +0 -40
  190. package/src/worker/implementation.tiny-worker.ts +0 -55
  191. package/src/worker/implementation.ts +0 -23
  192. package/src/worker/implementation.worker_threads.ts +0 -50
  193. package/src/worker/index.ts +0 -230
  194. package/src/worker_threads.ts +0 -27
  195. package/test/lib/index.ts +0 -1
  196. package/test/lib/serialization.ts +0 -38
  197. package/test/observable-promise.test.ts +0 -205
  198. package/test/observable.test.ts +0 -87
  199. package/test/pool.test.ts +0 -183
  200. package/test/serialization.test.ts +0 -23
  201. package/test/spawn.chromium.mocha.ts +0 -53
  202. package/test/spawn.test.ts +0 -87
  203. package/test/streaming.test.ts +0 -29
  204. package/test/transferables.test.ts +0 -71
  205. package/test/workers/arraybuffer-xor.ts +0 -10
  206. package/test/workers/count-to-five.ts +0 -12
  207. package/test/workers/counter.ts +0 -19
  208. package/test/workers/faulty-function.ts +0 -5
  209. package/test/workers/hello-world.ts +0 -5
  210. package/test/workers/increment.ts +0 -8
  211. package/test/workers/minmax.ts +0 -25
  212. package/test/workers/serialization.ts +0 -13
  213. package/test/workers/top-level-throw.ts +0 -1
  214. package/test-tooling/rollup/app.js +0 -21
  215. package/test-tooling/rollup/rollup.config.ts +0 -14
  216. package/test-tooling/rollup/worker.js +0 -7
  217. package/test-tooling/tsconfig/minimal.ts +0 -12
  218. package/test-tooling/webpack/addition-worker.ts +0 -9
  219. package/test-tooling/webpack/app-with-inlined-worker.ts +0 -28
  220. package/test-tooling/webpack/app.ts +0 -61
  221. package/test-tooling/webpack/pool-worker.ts +0 -5
  222. package/test-tooling/webpack/raw-loader.d.ts +0 -4
  223. package/test-tooling/webpack/webpack.chromium.mocha.ts +0 -21
  224. package/test-tooling/webpack/webpack.node.config.js +0 -29
  225. package/test-tooling/webpack/webpack.web.config.js +0 -28
  226. package/types/is-observable.d.ts +0 -7
  227. package/types/tiny-worker.d.ts +0 -4
  228. package/types/webworker.d.ts +0 -9
  229. package/worker.d.ts +0 -2
  230. package/worker.js +0 -2
  231. package/worker.mjs +0 -6
@@ -1,23 +0,0 @@
1
- /* eslint-disable import-x/no-internal-modules */
2
- // tslint:disable no-var-requires
3
- /*
4
- * This file is only a stub to make './implementation' resolve to the right module.
5
- */
6
-
7
- import type { AbstractedWorkerAPI } from '../types/worker'
8
- import WebWorkerImplementation from './implementation.browser'
9
- import TinyWorkerImplementation from './implementation.tiny-worker'
10
- import WorkerThreadsImplementation from './implementation.worker_threads'
11
-
12
- const runningInNode = typeof process !== 'undefined' && (process.arch as string) !== 'browser' && 'pid' in process
13
-
14
- function selectNodeImplementation(): AbstractedWorkerAPI {
15
- try {
16
- WorkerThreadsImplementation.testImplementation()
17
- return WorkerThreadsImplementation
18
- } catch {
19
- return TinyWorkerImplementation
20
- }
21
- }
22
-
23
- export default runningInNode ? selectNodeImplementation() : WebWorkerImplementation
@@ -1,50 +0,0 @@
1
- /* eslint-disable import-x/no-internal-modules */
2
- /* eslint-disable @typescript-eslint/no-explicit-any */
3
- // tslint:disable no-shadowed-variable
4
- import type { MessagePort } from 'node:worker_threads'
5
-
6
- import type { AbstractedWorkerAPI } from '../types/worker'
7
- import WorkerThreads from '../worker_threads'
8
-
9
- function assertMessagePort(port: MessagePort | null | undefined): MessagePort {
10
- if (!port) {
11
- throw new Error('Invariant violation: MessagePort to parent is not available.')
12
- }
13
- return port
14
- }
15
-
16
- const isWorkerRuntime: AbstractedWorkerAPI['isWorkerRuntime'] = function isWorkerRuntime() {
17
- return !WorkerThreads().isMainThread
18
- }
19
-
20
- const postMessageToMaster: AbstractedWorkerAPI['postMessageToMaster'] = function postMessageToMaster(data, transferList) {
21
- assertMessagePort(WorkerThreads().parentPort).postMessage(data, transferList as any)
22
- }
23
-
24
- const subscribeToMasterMessages: AbstractedWorkerAPI['subscribeToMasterMessages'] = function subscribeToMasterMessages(onMessage) {
25
- const parentPort = WorkerThreads().parentPort
26
-
27
- if (!parentPort) {
28
- throw new Error('Invariant violation: MessagePort to parent is not available.')
29
- }
30
- const messageHandler = (message: any) => {
31
- onMessage(message)
32
- }
33
- const unsubscribe = () => {
34
- assertMessagePort(parentPort).off('message', messageHandler)
35
- }
36
- assertMessagePort(parentPort).on('message', messageHandler)
37
- return unsubscribe
38
- }
39
-
40
- function testImplementation() {
41
- // Will throw if `worker_threads` are not available
42
- WorkerThreads()
43
- }
44
-
45
- export default {
46
- isWorkerRuntime,
47
- postMessageToMaster,
48
- subscribeToMasterMessages,
49
- testImplementation,
50
- }
@@ -1,230 +0,0 @@
1
- /* eslint-disable import-x/no-internal-modules */
2
- /* eslint-disable @typescript-eslint/no-explicit-any */
3
- /* eslint-disable @typescript-eslint/no-floating-promises */
4
- import isSomeObservable from 'is-observable-2-1-0'
5
- import type { Observable, Subscription } from 'observable-fns'
6
-
7
- import { deserialize, serialize } from '../common'
8
- import type { TransferDescriptor } from '../transferable'
9
- import { isTransferDescriptor } from '../transferable'
10
- import type {
11
- MasterJobCancelMessage,
12
- MasterJobRunMessage,
13
- SerializedError,
14
- WorkerInitMessage,
15
- WorkerJobErrorMessage,
16
- WorkerJobResultMessage,
17
- WorkerJobStartMessage,
18
- WorkerUncaughtErrorMessage,
19
- } from '../types/messages'
20
- import {
21
- MasterMessageType,
22
- WorkerMessageType,
23
- } from '../types/messages'
24
- import type { WorkerFunction, WorkerModule } from '../types/worker'
25
- import Implementation from './implementation'
26
-
27
- export { registerSerializer } from '../common'
28
- export { Transfer } from '../transferable'
29
-
30
- /** Returns `true` if this code is currently running in a worker. */
31
- export const isWorkerRuntime = Implementation.isWorkerRuntime
32
-
33
- let exposeCalled = false
34
-
35
- const activeSubscriptions = new Map<number, Subscription<any>>()
36
-
37
- const isMasterJobCancelMessage = (thing: any): thing is MasterJobCancelMessage => thing && thing.type === MasterMessageType.cancel
38
- const isMasterJobRunMessage = (thing: any): thing is MasterJobRunMessage => thing && thing.type === MasterMessageType.run
39
-
40
- /**
41
- * There are issues with `is-observable` not recognizing zen-observable's instances.
42
- * We are using `observable-fns`, but it's based on zen-observable, too.
43
- */
44
- const isObservable = (thing: any): thing is Observable<any> => isSomeObservable(thing) || isZenObservable(thing)
45
-
46
- function isZenObservable(thing: any): thing is Observable<any> {
47
- return thing && typeof thing === 'object' && typeof thing.subscribe === 'function'
48
- }
49
-
50
- function deconstructTransfer(thing: any) {
51
- return isTransferDescriptor(thing) ? { payload: thing.send, transferables: thing.transferables } : { payload: thing, transferables: undefined }
52
- }
53
-
54
- function postFunctionInitMessage() {
55
- const initMessage: WorkerInitMessage = {
56
- exposed: { type: 'function' },
57
- type: WorkerMessageType.init,
58
- }
59
- Implementation.postMessageToMaster(initMessage)
60
- }
61
-
62
- function postModuleInitMessage(methodNames: string[]) {
63
- const initMessage: WorkerInitMessage = {
64
- exposed: {
65
- methods: methodNames,
66
- type: 'module',
67
- },
68
- type: WorkerMessageType.init,
69
- }
70
- Implementation.postMessageToMaster(initMessage)
71
- }
72
-
73
- function postJobErrorMessage(uid: number, rawError: Error | TransferDescriptor<Error>) {
74
- const { payload: error, transferables } = deconstructTransfer(rawError)
75
- const errorMessage: WorkerJobErrorMessage = {
76
- error: serialize(error) as any as SerializedError,
77
- type: WorkerMessageType.error,
78
- uid,
79
- }
80
- Implementation.postMessageToMaster(errorMessage, transferables)
81
- }
82
-
83
- function postJobResultMessage(uid: number, completed: boolean, resultValue?: any) {
84
- const { payload, transferables } = deconstructTransfer(resultValue)
85
- const resultMessage: WorkerJobResultMessage = {
86
- complete: completed ? true : undefined,
87
- payload,
88
- type: WorkerMessageType.result,
89
- uid,
90
- }
91
- Implementation.postMessageToMaster(resultMessage, transferables)
92
- }
93
-
94
- function postJobStartMessage(uid: number, resultType: WorkerJobStartMessage['resultType']) {
95
- const startMessage: WorkerJobStartMessage = {
96
- resultType,
97
- type: WorkerMessageType.running,
98
- uid,
99
- }
100
- Implementation.postMessageToMaster(startMessage)
101
- }
102
-
103
- function postUncaughtErrorMessage(error: Error) {
104
- try {
105
- const errorMessage: WorkerUncaughtErrorMessage = {
106
- error: serialize(error) as any as SerializedError,
107
- type: WorkerMessageType.uncaughtError,
108
- }
109
- Implementation.postMessageToMaster(errorMessage)
110
- } catch (subError) {
111
- // tslint:disable-next-line no-console
112
- console.error(
113
- 'Not reporting uncaught error back to master thread as it ' + 'occured while reporting an uncaught error already.' + '\nLatest error:',
114
- subError,
115
- '\nOriginal error:',
116
- error,
117
- )
118
- }
119
- }
120
-
121
- async function runFunction(jobUID: number, fn: WorkerFunction, args: any[]) {
122
- let syncResult: any
123
-
124
- try {
125
- syncResult = fn(...args)
126
- } catch (error) {
127
- return postJobErrorMessage(jobUID, error)
128
- }
129
-
130
- const resultType = isObservable(syncResult) ? 'observable' : 'promise'
131
- postJobStartMessage(jobUID, resultType)
132
-
133
- if (isObservable(syncResult)) {
134
- const subscription = syncResult.subscribe(
135
- value => postJobResultMessage(jobUID, false, serialize(value)),
136
- (error) => {
137
- postJobErrorMessage(jobUID, serialize(error) as any)
138
- activeSubscriptions.delete(jobUID)
139
- },
140
- () => {
141
- postJobResultMessage(jobUID, true)
142
- activeSubscriptions.delete(jobUID)
143
- },
144
- )
145
- activeSubscriptions.set(jobUID, subscription)
146
- } else {
147
- try {
148
- const result = await syncResult
149
- postJobResultMessage(jobUID, true, serialize(result))
150
- } catch (error) {
151
- postJobErrorMessage(jobUID, serialize(error) as any)
152
- }
153
- }
154
- }
155
-
156
- /**
157
- * Expose a function or a module (an object whose values are functions)
158
- * to the main thread. Must be called exactly once in every worker thread
159
- * to signal its API to the main thread.
160
- *
161
- * @param exposed Function or object whose values are functions
162
- */
163
- export function expose(exposed: WorkerFunction | WorkerModule<any>) {
164
- if (!Implementation.isWorkerRuntime()) {
165
- throw new Error('expose() called in the master thread.')
166
- }
167
- if (exposeCalled) {
168
- throw new Error('expose() called more than once. This is not possible. Pass an object to expose() if you want to expose multiple functions.')
169
- }
170
- exposeCalled = true
171
-
172
- if (typeof exposed === 'function') {
173
- Implementation.subscribeToMasterMessages((messageData) => {
174
- if (isMasterJobRunMessage(messageData) && !messageData.method) {
175
- runFunction(messageData.uid, exposed, messageData.args.map(deserialize))
176
- }
177
- })
178
- postFunctionInitMessage()
179
- } else if (typeof exposed === 'object' && exposed) {
180
- Implementation.subscribeToMasterMessages((messageData) => {
181
- if (isMasterJobRunMessage(messageData) && messageData.method) {
182
- runFunction(messageData.uid, exposed[messageData.method], messageData.args.map(deserialize))
183
- }
184
- })
185
-
186
- const methodNames = Object.keys(exposed).filter(key => typeof exposed[key] === 'function')
187
- postModuleInitMessage(methodNames)
188
- } else {
189
- throw new Error(`Invalid argument passed to expose(). Expected a function or an object, got: ${exposed}`)
190
- }
191
-
192
- Implementation.subscribeToMasterMessages((messageData) => {
193
- if (isMasterJobCancelMessage(messageData)) {
194
- const jobUID = messageData.uid
195
- const subscription = activeSubscriptions.get(jobUID)
196
-
197
- if (subscription) {
198
- subscription.unsubscribe()
199
- activeSubscriptions.delete(jobUID)
200
- }
201
- }
202
- })
203
- }
204
-
205
- if (typeof globalThis !== 'undefined' && typeof self.addEventListener === 'function' && Implementation.isWorkerRuntime()) {
206
- self.addEventListener('error', (event) => {
207
- // Post with some delay, so the master had some time to subscribe to messages
208
- setTimeout(() => postUncaughtErrorMessage(event.error || event), 250)
209
- })
210
- self.addEventListener('unhandledrejection', (event) => {
211
- const error = (event as any).reason
212
- if (error && typeof (error as any).message === 'string') {
213
- // Post with some delay, so the master had some time to subscribe to messages
214
- setTimeout(() => postUncaughtErrorMessage(error), 250)
215
- }
216
- })
217
- }
218
-
219
- if (typeof process !== 'undefined' && typeof process.on === 'function' && Implementation.isWorkerRuntime()) {
220
- process.on('uncaughtException', (error) => {
221
- // Post with some delay, so the master had some time to subscribe to messages
222
- setTimeout(() => postUncaughtErrorMessage(error), 250)
223
- })
224
- process.on('unhandledRejection', (error) => {
225
- if (error && typeof (error as any).message === 'string') {
226
- // Post with some delay, so the master had some time to subscribe to messages
227
- setTimeout(() => postUncaughtErrorMessage(error as any), 250)
228
- }
229
- })
230
- }
@@ -1,27 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- // Webpack hack
3
- // tslint:disable no-eval
4
-
5
- declare function __non_webpack_require__(module: string): any
6
-
7
- // FIXME
8
- type MessagePort = any
9
-
10
- interface WorkerThreadsModule {
11
- MessagePort: typeof MessagePort
12
- isMainThread: boolean
13
- parentPort: MessagePort
14
- }
15
-
16
- let implementation: WorkerThreadsModule | undefined
17
-
18
- function selectImplementation(): WorkerThreadsModule {
19
- return typeof __non_webpack_require__ === 'function' ? __non_webpack_require__('worker_threads') : eval('require')('worker_threads')
20
- }
21
-
22
- export default function getImplementation(): WorkerThreadsModule {
23
- if (!implementation) {
24
- implementation = selectImplementation()
25
- }
26
- return implementation
27
- }
package/test/lib/index.ts DELETED
@@ -1 +0,0 @@
1
- export * from './serialization.js'
@@ -1,38 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
-
3
- import type { JsonSerializable, SerializerImplementation } from '../../src/index'
4
-
5
- export class Foo<T> {
6
- private readonly value: T
7
-
8
- constructor(value: T) {
9
- this.value = value
10
- }
11
-
12
- getValue() {
13
- return this.value
14
- }
15
- }
16
-
17
- interface SerializedFoo<T extends JsonSerializable> {
18
- __type: '$$foo'
19
- val: T
20
- }
21
-
22
- const isSerializedFoo = (thing: any): thing is SerializedFoo<JsonSerializable> =>
23
- thing && typeof thing === 'object' && '__type' in thing && thing.__type === '$$foo'
24
-
25
- export const fooSerializer: SerializerImplementation = {
26
- deserialize(serialized, fallback) {
27
- return isSerializedFoo(serialized) ? new Foo(serialized.val) : fallback(serialized)
28
- },
29
-
30
- serialize(data, fallback) {
31
- return data instanceof Foo
32
- ? {
33
- __type: '$$foo',
34
- val: data.getValue(),
35
- }
36
- : fallback(data)
37
- },
38
- }
@@ -1,205 +0,0 @@
1
- /* eslint-disable import-x/no-internal-modules */
2
- /* eslint-disable @typescript-eslint/no-explicit-any */
3
-
4
- import { Observable } from 'observable-fns'
5
- import { expect, test } from 'vitest'
6
-
7
- import { ObservablePromise } from '../src/observable-promise'
8
-
9
- const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms))
10
-
11
- test('can create an observable promise', async () => {
12
- expect.assertions(1)
13
-
14
- await new ObservablePromise((observer) => {
15
- expect(true).toBe(true)
16
- observer.complete()
17
- })
18
- })
19
-
20
- test('init function is only called once', async () => {
21
- let initCallCount = 0
22
-
23
- const async = new ObservablePromise((observer) => {
24
- initCallCount++
25
- setTimeout(() => observer.complete(), 10)
26
- })
27
-
28
- await Promise.all([
29
- async.then(() => expect(true).toBe(true)),
30
- async.then(() => expect(true).toBe(true)),
31
- async.then(() => expect(true).toBe(true)),
32
- ])
33
-
34
- expect(initCallCount).toBe(1)
35
- })
36
-
37
- test('can proxy a promise fulfillment', async () => {
38
- expect.assertions(2) // Ensure two assertions are made
39
-
40
- const async = new ObservablePromise((observer) => {
41
- setTimeout(() => {
42
- observer.next(123)
43
-
44
- // Ignore all values after the first one
45
- observer.next(456)
46
- observer.complete()
47
- }, 1)
48
- })
49
-
50
- const promise1 = async.then(
51
- value => expect(value).toBe(123),
52
- () => expect.fail('Promise was rejected unexpectedly'),
53
- )
54
-
55
- await delay(10)
56
-
57
- const promise2 = async.then(
58
- value => expect(value).toBe(123),
59
- () => expect.fail('Promise was rejected unexpectedly'),
60
- )
61
-
62
- await Promise.all([promise1, promise2])
63
- })
64
-
65
- test('can proxy a promise rejection', async () => {
66
- let handlerCallCount = 0
67
-
68
- const async = new ObservablePromise((observer) => {
69
- setTimeout(() => observer.error(new Error('I am supposed to be rejected.')), 1)
70
- })
71
-
72
- const promise1 = async.then(
73
- () => expect.fail('Promise should not become fulfilled'),
74
- () => handlerCallCount++,
75
- )
76
-
77
- await delay(10)
78
-
79
- const promise2 = async.then(
80
- () => expect.fail('Promise should not become fulfilled'),
81
- () => handlerCallCount++,
82
- )
83
-
84
- await Promise.all([promise1.catch(() => true), promise2.catch(() => true)])
85
- expect(handlerCallCount).toBe(2)
86
- })
87
-
88
- test('can proxy a promise rejection caused by a sync throw', async () => {
89
- let handlerCallCount = 0
90
-
91
- const async = new ObservablePromise(() => {
92
- throw new Error('I am supposed to be rejected.')
93
- })
94
-
95
- const promise1 = async.then(
96
- () => expect.fail('Promise should not become fulfilled'),
97
- () => handlerCallCount++,
98
- )
99
-
100
- await delay(10)
101
-
102
- const promise2 = async.then(
103
- () => expect.fail('Promise should not become fulfilled'),
104
- () => handlerCallCount++,
105
- )
106
-
107
- await Promise.all([promise1.catch(() => true), promise2.catch(() => true)])
108
- expect(handlerCallCount).toBe(2)
109
- })
110
-
111
- test('can subscribe to values and completion', async () => {
112
- const capturedValues: any[] = []
113
- let capturedCompletions = 0
114
-
115
- const async = new ObservablePromise((observer) => {
116
- setTimeout(() => observer.next(1), 10)
117
- setTimeout(() => observer.next(2), 20)
118
- setTimeout(() => observer.complete(), 30)
119
- })
120
-
121
- for (let index = 0; index < 2; index++) {
122
- async.subscribe(
123
- value => capturedValues.push(value),
124
- () => {},
125
- () => capturedCompletions++,
126
- )
127
- }
128
-
129
- await async.finally()
130
- await delay(1)
131
-
132
- expect(capturedValues).toEqual([1, 1, 2, 2])
133
- expect(capturedCompletions).toBe(2)
134
- })
135
-
136
- test('can subscribe to errors', async () => {
137
- const capturedErrorMessages: string[] = []
138
- const capturedValues: any[] = []
139
- let capturedCompletions = 0
140
-
141
- const async = new ObservablePromise((observer) => {
142
- setTimeout(() => observer.next(1), 10)
143
- setTimeout(() => observer.error(new Error('Fails as expected.')), 20)
144
- setTimeout(() => observer.next(2), 30) // This won't be called due to error
145
- setTimeout(() => observer.complete(), 40) // This also won't be called
146
- })
147
-
148
- for (let index = 0; index < 2; index++) {
149
- async.subscribe(
150
- value => capturedValues.push(value),
151
- error => capturedErrorMessages.push(error.message),
152
- () => capturedCompletions++,
153
- )
154
- }
155
-
156
- await async.finally()
157
- await delay(35) // Wait to ensure the error and all async events are captured
158
-
159
- expect(capturedValues).toEqual([1, 1])
160
- expect(capturedErrorMessages).toEqual(['Fails as expected.', 'Fails as expected.'])
161
- expect(capturedCompletions).toBe(0)
162
- })
163
-
164
- test('from(Observable) works', async () => {
165
- const capturedErrorMessages: string[] = []
166
- const capturedValues: any[] = []
167
- let capturedCompletions = 0
168
-
169
- const async = ObservablePromise.from(
170
- new Observable((observer) => {
171
- setTimeout(() => observer.next(1), 10)
172
- setTimeout(() => observer.error(new Error('Fails as expected.')), 20)
173
- setTimeout(() => observer.next(2), 30) // This won't be called due to error
174
- setTimeout(() => observer.complete(), 40) // This also won't be called
175
- }),
176
- )
177
-
178
- for (let index = 0; index < 2; index++) {
179
- async.subscribe(
180
- value => capturedValues.push(value),
181
- error => capturedErrorMessages.push(error.message),
182
- () => capturedCompletions++,
183
- )
184
- }
185
-
186
- await async.finally()
187
- await delay(35) // Allow time for error and async processing
188
-
189
- expect(capturedValues).toEqual([1, 1])
190
- expect(capturedErrorMessages).toEqual(['Fails as expected.', 'Fails as expected.'])
191
- expect(capturedCompletions).toBe(0)
192
- })
193
-
194
- test('from(Promise) works', async () => {
195
- const resolved = ObservablePromise.from(
196
- new Promise((resolve) => {
197
- setTimeout(() => resolve('Works'), 10)
198
- }),
199
- )
200
-
201
- await expect(resolved).resolves.toBe('Works')
202
-
203
- const rejected = ObservablePromise.from(Promise.reject(new Error('Fails')))
204
- await expect(rejected).rejects.toThrow('Fails')
205
- })
@@ -1,87 +0,0 @@
1
- /* eslint-disable import-x/no-internal-modules */
2
- /* eslint-disable require-await */
3
-
4
- import { expect, test } from 'vitest'
5
-
6
- import { Observable, Subject } from '../src/observable'
7
-
8
- test('Observable subject emits values and completion event', async () => {
9
- let completed1 = false
10
- const values1: number[] = []
11
- let completed2 = false
12
- const values2: number[] = []
13
- let completed3 = false
14
- const values3: number[] = []
15
-
16
- const subject = new Subject<number>()
17
- const observable = Observable.from(subject)
18
-
19
- const subscription1 = subject.subscribe(
20
- value => values1.push(value),
21
- undefined,
22
- () => (completed1 = false),
23
- )
24
- subject.subscribe(
25
- value => values2.push(value),
26
- undefined,
27
- () => (completed2 = true),
28
- )
29
- observable.subscribe(
30
- value => values3.push(value),
31
- undefined,
32
- () => (completed3 = true),
33
- )
34
-
35
- subject.next(1)
36
- subscription1.unsubscribe()
37
-
38
- subject.next(2)
39
- subject.complete()
40
-
41
- expect(values1).toEqual([1])
42
- expect(values2).toEqual([1, 2])
43
- expect(values3).toEqual([1, 2])
44
- expect(completed1).toBe(false)
45
- expect(completed2).toBe(true)
46
- expect(completed3).toBe(true)
47
- })
48
-
49
- test('Observable subject propagates errors', async () => {
50
- let completed1 = false
51
- let error1: Error | undefined
52
- let completed2 = false
53
- let error2: Error | undefined
54
- let completed3 = false
55
- let error3: Error | undefined
56
-
57
- const subject = new Subject<number>()
58
- const observable = Observable.from(subject)
59
-
60
- const subscription1 = subject.subscribe(
61
- () => {},
62
- error => (error1 = error),
63
- () => (completed1 = true),
64
- )
65
- subject.subscribe(
66
- () => {},
67
- error => (error2 = error),
68
- () => (completed2 = true),
69
- )
70
- observable.subscribe(
71
- () => {},
72
- error => (error3 = error),
73
- () => (completed3 = true),
74
- )
75
-
76
- const testingError = new Error('Test, test!')
77
-
78
- subscription1.unsubscribe()
79
- subject.error(testingError)
80
-
81
- expect(completed1).toBe(false)
82
- expect(error1).toBeUndefined()
83
- expect(completed2).toBe(false)
84
- expect(error2).toBe(testingError)
85
- expect(completed3).toBe(false)
86
- expect(error3).toBe(testingError)
87
- })