@xylabs/threads 4.7.0 → 4.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +17 -47
- package/eslint.config.mjs +0 -35
- package/index.mjs +0 -10
- package/src/common.ts +0 -23
- package/src/index.ts +0 -11
- package/src/master/get-bundle-url.browser.ts +0 -32
- package/src/master/implementation.browser.ts +0 -82
- package/src/master/implementation.node.ts +0 -208
- package/src/master/implementation.ts +0 -21
- package/src/master/index.ts +0 -19
- package/src/master/invocation-proxy.ts +0 -151
- package/src/master/pool-types.ts +0 -83
- package/src/master/pool.ts +0 -400
- package/src/master/register.ts +0 -11
- package/src/master/spawn.ts +0 -172
- package/src/master/thread.ts +0 -29
- package/src/observable-promise.ts +0 -184
- package/src/observable.ts +0 -44
- package/src/ponyfills.ts +0 -31
- package/src/promise.ts +0 -26
- package/src/serializers.ts +0 -68
- package/src/symbols.ts +0 -5
- package/src/transferable.ts +0 -69
- package/src/types/master.ts +0 -132
- package/src/types/messages.ts +0 -72
- package/src/types/worker.ts +0 -14
- package/src/worker/WorkerGlobalScope.ts +0 -5
- package/src/worker/expose.ts +0 -234
- package/src/worker/is-observable.d.ts +0 -7
- package/src/worker/worker.browser.ts +0 -56
- package/src/worker/worker.node.ts +0 -68
- package/types/is-observable.d.ts +0 -7
- package/types/tiny-worker.d.ts +0 -4
- package/xy.config.ts +0 -24
package/src/types/master.ts
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
/// <reference lib="dom" />
|
|
3
|
-
// tslint:disable max-classes-per-file
|
|
4
|
-
|
|
5
|
-
// Cannot use `compilerOptions.esModuleInterop` and default import syntax
|
|
6
|
-
// See <https://github.com/microsoft/TypeScript/issues/28009>
|
|
7
|
-
import type { Observable } from 'observable-fns'
|
|
8
|
-
|
|
9
|
-
import type { ObservablePromise } from '../observable-promise.ts'
|
|
10
|
-
import type {
|
|
11
|
-
$errors, $events, $terminate, $worker,
|
|
12
|
-
} from '../symbols.ts'
|
|
13
|
-
import type { TransferDescriptor } from '../transferable.ts'
|
|
14
|
-
|
|
15
|
-
interface ObservableLikeSubscription {
|
|
16
|
-
unsubscribe(): any
|
|
17
|
-
}
|
|
18
|
-
interface ObservableLike<T> {
|
|
19
|
-
subscribe(onNext: (value: T) => any, onError?: (error: any) => any, onComplete?: () => any): ObservableLikeSubscription
|
|
20
|
-
subscribe(listeners: { complete?(): any; error?(error: any): any; next?(value: T): any }): ObservableLikeSubscription
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export type StripAsync<Type> =
|
|
24
|
-
Type extends Promise<infer PromiseBaseType> ? PromiseBaseType
|
|
25
|
-
: Type extends ObservableLike<infer ObservableBaseType> ? ObservableBaseType
|
|
26
|
-
: Type
|
|
27
|
-
|
|
28
|
-
type StripTransfer<Type> = Type extends TransferDescriptor<infer BaseType> ? BaseType : Type
|
|
29
|
-
|
|
30
|
-
export type ModuleMethods = { [methodName: string]: (...args: any) => any }
|
|
31
|
-
|
|
32
|
-
type ProxyableArgs<Args extends any[]> =
|
|
33
|
-
Args extends [arg0: infer Arg0, ...rest: infer RestArgs] ? [Arg0 extends Transferable ? Arg0 | TransferDescriptor<Arg0> : Arg0, ...RestArgs] : Args
|
|
34
|
-
|
|
35
|
-
export type ProxyableFunction<Args extends any[], ReturnType> =
|
|
36
|
-
Args extends [] ? () => ObservablePromise<StripTransfer<StripAsync<ReturnType>>>
|
|
37
|
-
: (...args: ProxyableArgs<Args>) => ObservablePromise<StripTransfer<StripAsync<ReturnType>>>
|
|
38
|
-
|
|
39
|
-
export type ModuleProxy<Methods extends ModuleMethods> = {
|
|
40
|
-
[method in keyof Methods]: ProxyableFunction<Parameters<Methods[method]>, ReturnType<Methods[method]>>
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface PrivateThreadProps {
|
|
44
|
-
[$errors]: Observable<Error>
|
|
45
|
-
[$events]: Observable<WorkerEvent>
|
|
46
|
-
[$terminate]: () => Promise<void>
|
|
47
|
-
[$worker]: Worker
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export type FunctionThread<Args extends any[] = any[], ReturnType = any> = ProxyableFunction<Args, ReturnType> & PrivateThreadProps
|
|
51
|
-
export type ModuleThread<Methods extends ModuleMethods = any> = ModuleProxy<Methods> & PrivateThreadProps
|
|
52
|
-
|
|
53
|
-
// We have those extra interfaces to keep the general non-specific `Thread` type
|
|
54
|
-
// as an interface, so it's displayed concisely in any TypeScript compiler output.
|
|
55
|
-
interface AnyFunctionThread extends PrivateThreadProps {
|
|
56
|
-
(...args: any[]): ObservablePromise<any>
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// tslint:disable-next-line no-empty-interface
|
|
60
|
-
interface AnyModuleThread extends PrivateThreadProps {
|
|
61
|
-
// Not specifying an index signature here as that would make `ModuleThread` incompatible
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/** Worker thread. Either a `FunctionThread` or a `ModuleThread`. */
|
|
65
|
-
export type Thread = AnyFunctionThread | AnyModuleThread
|
|
66
|
-
|
|
67
|
-
export type TransferList = Transferable[]
|
|
68
|
-
|
|
69
|
-
/** Worker instance. Either a web worker or a node.js Worker provided by `worker_threads` or `tiny-worker`. */
|
|
70
|
-
export interface Worker extends EventTarget {
|
|
71
|
-
postMessage(value: any, transferList?: TransferList): void
|
|
72
|
-
/** In nodejs 10+ return type is Promise while with tiny-worker and in browser return type is void */
|
|
73
|
-
terminate(callback?: (error?: Error, exitCode?: number) => void): void | Promise<number>
|
|
74
|
-
}
|
|
75
|
-
export interface ThreadsWorkerOptions extends WorkerOptions {
|
|
76
|
-
/** Whether to apply CORS protection workaround. Defaults to true. */
|
|
77
|
-
CORSWorkaround?: boolean
|
|
78
|
-
/** Prefix for the path passed to the Worker constructor. Web worker only. */
|
|
79
|
-
_baseURL?: string
|
|
80
|
-
/** Resource limits passed on to Node worker_threads */
|
|
81
|
-
resourceLimits?: {
|
|
82
|
-
/** The size of a pre-allocated memory range used for generated code. */
|
|
83
|
-
codeRangeSizeMb?: number
|
|
84
|
-
/** The maximum size of the main heap in MB. */
|
|
85
|
-
maxOldGenerationSizeMb?: number
|
|
86
|
-
/** The maximum size of a heap space for recently created objects. */
|
|
87
|
-
maxYoungGenerationSizeMb?: number
|
|
88
|
-
}
|
|
89
|
-
/** Data passed on to node.js worker_threads. */
|
|
90
|
-
workerData?: any
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/** Worker implementation. Either web worker or a node.js Worker class. */
|
|
94
|
-
export declare class WorkerImplementation extends EventTarget implements Worker {
|
|
95
|
-
constructor(path: string, options?: ThreadsWorkerOptions)
|
|
96
|
-
postMessage(value: any, transferList?: TransferList): void
|
|
97
|
-
terminate(): void | Promise<number>
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/** Class to spawn workers from a blob or source string. */
|
|
101
|
-
export declare class BlobWorker extends WorkerImplementation {
|
|
102
|
-
constructor(blob: Blob, options?: ThreadsWorkerOptions)
|
|
103
|
-
static fromText(source: string, options?: ThreadsWorkerOptions): WorkerImplementation
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export interface ImplementationExport {
|
|
107
|
-
blob: typeof BlobWorker
|
|
108
|
-
default: typeof WorkerImplementation
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/** Event as emitted by worker thread. Subscribe to using `Thread.events(thread)`. */
|
|
112
|
-
export enum WorkerEventType {
|
|
113
|
-
internalError = 'internalError',
|
|
114
|
-
message = 'message',
|
|
115
|
-
termination = 'termination',
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export interface WorkerInternalErrorEvent {
|
|
119
|
-
error: Error
|
|
120
|
-
type: WorkerEventType.internalError
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export interface WorkerMessageEvent<Data> {
|
|
124
|
-
data: Data
|
|
125
|
-
type: WorkerEventType.message
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export interface WorkerTerminationEvent {
|
|
129
|
-
type: WorkerEventType.termination
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
export type WorkerEvent = WorkerInternalErrorEvent | WorkerMessageEvent<any> | WorkerTerminationEvent
|
package/src/types/messages.ts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
/* eslint-disable @typescript-eslint/member-ordering */
|
|
3
|
-
export interface SerializedError {
|
|
4
|
-
__error_marker: '$$error'
|
|
5
|
-
message: string
|
|
6
|
-
name: string
|
|
7
|
-
stack?: string
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/////////////////////////////
|
|
11
|
-
// Messages sent by master:
|
|
12
|
-
|
|
13
|
-
export enum MasterMessageType {
|
|
14
|
-
cancel = 'cancel',
|
|
15
|
-
run = 'run',
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export type MasterJobCancelMessage = {
|
|
19
|
-
type: MasterMessageType.cancel
|
|
20
|
-
uid: number
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export type MasterJobRunMessage = {
|
|
24
|
-
type: MasterMessageType.run
|
|
25
|
-
uid: number
|
|
26
|
-
method?: string
|
|
27
|
-
args: any[]
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
////////////////////////////
|
|
31
|
-
// Messages sent by worker:
|
|
32
|
-
|
|
33
|
-
export enum WorkerMessageType {
|
|
34
|
-
error = 'error',
|
|
35
|
-
init = 'init',
|
|
36
|
-
result = 'result',
|
|
37
|
-
running = 'running',
|
|
38
|
-
uncaughtError = 'uncaughtError',
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export type WorkerUncaughtErrorMessage = {
|
|
42
|
-
type: WorkerMessageType.uncaughtError
|
|
43
|
-
error: {
|
|
44
|
-
message: string
|
|
45
|
-
name: string
|
|
46
|
-
stack?: string
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export type WorkerInitMessage = {
|
|
51
|
-
type: WorkerMessageType.init
|
|
52
|
-
exposed: { type: 'function' } | { type: 'module'; methods: string[] }
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export type WorkerJobErrorMessage = {
|
|
56
|
-
type: WorkerMessageType.error
|
|
57
|
-
uid: number
|
|
58
|
-
error: SerializedError
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export type WorkerJobResultMessage = {
|
|
62
|
-
type: WorkerMessageType.result
|
|
63
|
-
uid: number
|
|
64
|
-
complete?: true
|
|
65
|
-
payload?: any
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export type WorkerJobStartMessage = {
|
|
69
|
-
type: WorkerMessageType.running
|
|
70
|
-
uid: number
|
|
71
|
-
resultType: 'observable' | 'promise'
|
|
72
|
-
}
|
package/src/types/worker.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
type UnsubscribeFn = () => void
|
|
3
|
-
|
|
4
|
-
export interface AbstractedWorkerAPI {
|
|
5
|
-
isWorkerRuntime(): boolean
|
|
6
|
-
postMessageToMaster(message: any, transferList?: Transferable[]): void
|
|
7
|
-
subscribeToMasterMessages(onMessage: (data: any) => void): UnsubscribeFn
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export type WorkerFunction = ((...args: any[]) => any) | (() => any)
|
|
11
|
-
|
|
12
|
-
export type WorkerModule<Keys extends string> = {
|
|
13
|
-
[key in Keys]: WorkerFunction
|
|
14
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
export interface WorkerGlobalScope {
|
|
2
|
-
addEventListener(eventName: string, listener: (event: Event) => void): void
|
|
3
|
-
postMessage(message: unknown, transferList?: Readonly<Transferable[]>): void
|
|
4
|
-
removeEventListener(eventName: string, listener: (event: Event) => void): void
|
|
5
|
-
}
|
package/src/worker/expose.ts
DELETED
|
@@ -1,234 +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
|
-
|
|
5
|
-
import isSomeObservable from 'is-observable-2-1-0'
|
|
6
|
-
import type { Observable, Subscription } from 'observable-fns'
|
|
7
|
-
|
|
8
|
-
import { deserialize, serialize } from '../common.ts'
|
|
9
|
-
import type { TransferDescriptor } from '../transferable.ts'
|
|
10
|
-
import { isTransferDescriptor } from '../transferable.ts'
|
|
11
|
-
import type {
|
|
12
|
-
MasterJobCancelMessage,
|
|
13
|
-
MasterJobRunMessage,
|
|
14
|
-
SerializedError,
|
|
15
|
-
WorkerInitMessage,
|
|
16
|
-
WorkerJobErrorMessage,
|
|
17
|
-
WorkerJobResultMessage,
|
|
18
|
-
WorkerJobStartMessage,
|
|
19
|
-
WorkerUncaughtErrorMessage,
|
|
20
|
-
} from '../types/messages.ts'
|
|
21
|
-
import {
|
|
22
|
-
MasterMessageType,
|
|
23
|
-
WorkerMessageType,
|
|
24
|
-
} from '../types/messages.ts'
|
|
25
|
-
import type {
|
|
26
|
-
AbstractedWorkerAPI, WorkerFunction, WorkerModule,
|
|
27
|
-
} from '../types/worker.ts'
|
|
28
|
-
import type { WorkerGlobalScope } from './WorkerGlobalScope.ts'
|
|
29
|
-
|
|
30
|
-
const isErrorEvent = (value: Event): value is ErrorEvent => value && (value as ErrorEvent).error
|
|
31
|
-
|
|
32
|
-
export function createExpose(implementation: AbstractedWorkerAPI, self: WorkerGlobalScope) {
|
|
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 (ex) {
|
|
127
|
-
const error = ex as Error
|
|
128
|
-
return postJobErrorMessage(jobUID, error)
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const resultType = isObservable(syncResult) ? 'observable' : 'promise'
|
|
132
|
-
postJobStartMessage(jobUID, resultType)
|
|
133
|
-
|
|
134
|
-
if (isObservable(syncResult)) {
|
|
135
|
-
const subscription = syncResult.subscribe(
|
|
136
|
-
value => postJobResultMessage(jobUID, false, serialize(value)),
|
|
137
|
-
(error) => {
|
|
138
|
-
postJobErrorMessage(jobUID, serialize(error) as any)
|
|
139
|
-
activeSubscriptions.delete(jobUID)
|
|
140
|
-
},
|
|
141
|
-
() => {
|
|
142
|
-
postJobResultMessage(jobUID, true)
|
|
143
|
-
activeSubscriptions.delete(jobUID)
|
|
144
|
-
},
|
|
145
|
-
)
|
|
146
|
-
activeSubscriptions.set(jobUID, subscription)
|
|
147
|
-
} else {
|
|
148
|
-
try {
|
|
149
|
-
const result = await syncResult
|
|
150
|
-
postJobResultMessage(jobUID, true, serialize(result))
|
|
151
|
-
} catch (error) {
|
|
152
|
-
postJobErrorMessage(jobUID, serialize(error) as any)
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Expose a function or a module (an object whose values are functions)
|
|
159
|
-
* to the main thread. Must be called exactly once in every worker thread
|
|
160
|
-
* to signal its API to the main thread.
|
|
161
|
-
*
|
|
162
|
-
* @param exposed Function or object whose values are functions
|
|
163
|
-
*/
|
|
164
|
-
const expose = (exposed: WorkerFunction | WorkerModule<any>) => {
|
|
165
|
-
if (!implementation.isWorkerRuntime()) {
|
|
166
|
-
throw new Error('expose() called in the master thread.')
|
|
167
|
-
}
|
|
168
|
-
if (exposeCalled) {
|
|
169
|
-
throw new Error('expose() called more than once. This is not possible. Pass an object to expose() if you want to expose multiple functions.')
|
|
170
|
-
}
|
|
171
|
-
exposeCalled = true
|
|
172
|
-
|
|
173
|
-
if (typeof exposed === 'function') {
|
|
174
|
-
implementation.subscribeToMasterMessages((messageData: unknown) => {
|
|
175
|
-
if (isMasterJobRunMessage(messageData) && !messageData.method) {
|
|
176
|
-
runFunction(messageData.uid, exposed, messageData.args.map(deserialize))
|
|
177
|
-
}
|
|
178
|
-
})
|
|
179
|
-
postFunctionInitMessage()
|
|
180
|
-
} else if (typeof exposed === 'object' && exposed) {
|
|
181
|
-
implementation.subscribeToMasterMessages((messageData: unknown) => {
|
|
182
|
-
if (isMasterJobRunMessage(messageData) && messageData.method) {
|
|
183
|
-
runFunction(messageData.uid, exposed[messageData.method], messageData.args.map(deserialize))
|
|
184
|
-
}
|
|
185
|
-
})
|
|
186
|
-
|
|
187
|
-
const methodNames = Object.keys(exposed).filter(key => typeof exposed[key] === 'function')
|
|
188
|
-
postModuleInitMessage(methodNames)
|
|
189
|
-
} else {
|
|
190
|
-
throw new Error(`Invalid argument passed to expose(). Expected a function or an object, got: ${exposed}`)
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
implementation.subscribeToMasterMessages((messageData: unknown) => {
|
|
194
|
-
if (isMasterJobCancelMessage(messageData)) {
|
|
195
|
-
const jobUID = messageData.uid
|
|
196
|
-
const subscription = activeSubscriptions.get(jobUID)
|
|
197
|
-
|
|
198
|
-
if (subscription) {
|
|
199
|
-
subscription.unsubscribe()
|
|
200
|
-
activeSubscriptions.delete(jobUID)
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
})
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
if (typeof globalThis !== 'undefined' && typeof self.addEventListener === 'function' && implementation.isWorkerRuntime()) {
|
|
207
|
-
self.addEventListener('error', (event) => {
|
|
208
|
-
// Post with some delay, so the master had some time to subscribe to messages
|
|
209
|
-
setTimeout(() => postUncaughtErrorMessage(isErrorEvent(event) ? event.error : event), 250)
|
|
210
|
-
})
|
|
211
|
-
self.addEventListener('unhandledrejection', (event) => {
|
|
212
|
-
const error = (event as any).reason
|
|
213
|
-
if (error && typeof (error as any).message === 'string') {
|
|
214
|
-
// Post with some delay, so the master had some time to subscribe to messages
|
|
215
|
-
setTimeout(() => postUncaughtErrorMessage(error), 250)
|
|
216
|
-
}
|
|
217
|
-
})
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
if (typeof process !== 'undefined' && typeof process.on === 'function' && implementation.isWorkerRuntime()) {
|
|
221
|
-
process.on('uncaughtException', (error) => {
|
|
222
|
-
// Post with some delay, so the master had some time to subscribe to messages
|
|
223
|
-
setTimeout(() => postUncaughtErrorMessage(error), 250)
|
|
224
|
-
})
|
|
225
|
-
process.on('unhandledRejection', (error) => {
|
|
226
|
-
if (error && typeof (error as any).message === 'string') {
|
|
227
|
-
// Post with some delay, so the master had some time to subscribe to messages
|
|
228
|
-
setTimeout(() => postUncaughtErrorMessage(error as any), 250)
|
|
229
|
-
}
|
|
230
|
-
})
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
return expose
|
|
234
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/* eslint-disable import-x/no-internal-modules */
|
|
2
|
-
|
|
3
|
-
/// <reference lib="webworker" />
|
|
4
|
-
// tslint:disable no-shadowed-variable
|
|
5
|
-
|
|
6
|
-
import type { AbstractedWorkerAPI } from '../types/worker.ts'
|
|
7
|
-
import { createExpose } from './expose.ts'
|
|
8
|
-
import type { WorkerGlobalScope } from './WorkerGlobalScope.ts'
|
|
9
|
-
|
|
10
|
-
declare const self: WorkerGlobalScope
|
|
11
|
-
|
|
12
|
-
const isWorkerRuntime: AbstractedWorkerAPI['isWorkerRuntime'] = function isWorkerRuntime() {
|
|
13
|
-
const isWindowContext = self !== undefined && typeof Window !== 'undefined' && self instanceof Window
|
|
14
|
-
return self !== undefined && self['postMessage'] && !isWindowContext ? true : false
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const postMessageToMaster: AbstractedWorkerAPI['postMessageToMaster'] = function postMessageToMaster(data, transferList?) {
|
|
18
|
-
self.postMessage(data, transferList)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const subscribeToMasterMessages: AbstractedWorkerAPI['subscribeToMasterMessages'] = function subscribeToMasterMessages(onMessage) {
|
|
22
|
-
const messageHandler = (messageEvent: MessageEvent) => {
|
|
23
|
-
onMessage(messageEvent.data)
|
|
24
|
-
}
|
|
25
|
-
const unsubscribe = () => {
|
|
26
|
-
self.removeEventListener('message', messageHandler as EventListener)
|
|
27
|
-
}
|
|
28
|
-
self.addEventListener('message', messageHandler as EventListener)
|
|
29
|
-
return unsubscribe
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const addEventListener = self.addEventListener
|
|
33
|
-
const postMessage = self.postMessage
|
|
34
|
-
const removeEventListener = self.removeEventListener
|
|
35
|
-
|
|
36
|
-
export {
|
|
37
|
-
addEventListener,
|
|
38
|
-
postMessage,
|
|
39
|
-
removeEventListener,
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const expose = createExpose({
|
|
43
|
-
isWorkerRuntime, postMessageToMaster, subscribeToMasterMessages,
|
|
44
|
-
}, {
|
|
45
|
-
addEventListener, postMessage, removeEventListener,
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
export {
|
|
49
|
-
isWorkerRuntime,
|
|
50
|
-
postMessageToMaster,
|
|
51
|
-
subscribeToMasterMessages,
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export { registerSerializer } from '../common.ts'
|
|
55
|
-
export { Transfer } from '../transferable.ts'
|
|
56
|
-
export { expose }
|
|
@@ -1,68 +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
|
-
|
|
5
|
-
import type { MessagePort, TransferListItem } from 'node:worker_threads'
|
|
6
|
-
import { parentPort as optionalParentPort } from 'node:worker_threads'
|
|
7
|
-
|
|
8
|
-
import { assertEx } from '@xylabs/assert'
|
|
9
|
-
|
|
10
|
-
import type { AbstractedWorkerAPI } from '../types/worker.ts'
|
|
11
|
-
import { createExpose } from './expose.ts'
|
|
12
|
-
|
|
13
|
-
const parentPort = assertEx(optionalParentPort, () => 'Invariant violation: MessagePort to parent is not available.')
|
|
14
|
-
|
|
15
|
-
function assertMessagePort(port: MessagePort | null | undefined): MessagePort {
|
|
16
|
-
if (!port) {
|
|
17
|
-
throw new Error('Invariant violation: MessagePort to parent is not available.')
|
|
18
|
-
}
|
|
19
|
-
return port
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const isWorkerRuntime: AbstractedWorkerAPI['isWorkerRuntime'] = function isWorkerRuntime() {
|
|
23
|
-
return true // isMainThread
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const postMessageToMaster: AbstractedWorkerAPI['postMessageToMaster'] = function postMessageToMaster(data, transferList) {
|
|
27
|
-
assertMessagePort(parentPort).postMessage(data, transferList as TransferListItem[])
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const subscribeToMasterMessages: AbstractedWorkerAPI['subscribeToMasterMessages'] = function subscribeToMasterMessages(onMessage) {
|
|
31
|
-
if (!parentPort) {
|
|
32
|
-
throw new Error('Invariant violation: MessagePort to parent is not available.')
|
|
33
|
-
}
|
|
34
|
-
const messageHandler = (message: any) => {
|
|
35
|
-
onMessage(message)
|
|
36
|
-
}
|
|
37
|
-
const unsubscribe = () => {
|
|
38
|
-
assertMessagePort(parentPort).off('message', messageHandler)
|
|
39
|
-
}
|
|
40
|
-
assertMessagePort(parentPort).on('message', messageHandler)
|
|
41
|
-
return unsubscribe
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const addEventListener = parentPort?.on.bind(parentPort)
|
|
45
|
-
const postMessage = parentPort?.postMessage.bind(parentPort)
|
|
46
|
-
const removeEventListener = parentPort?.off.bind(parentPort)
|
|
47
|
-
|
|
48
|
-
export {
|
|
49
|
-
addEventListener,
|
|
50
|
-
postMessage,
|
|
51
|
-
removeEventListener,
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const expose = createExpose({
|
|
55
|
-
isWorkerRuntime, postMessageToMaster, subscribeToMasterMessages,
|
|
56
|
-
}, {
|
|
57
|
-
addEventListener, postMessage, removeEventListener,
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
export {
|
|
61
|
-
isWorkerRuntime,
|
|
62
|
-
postMessageToMaster,
|
|
63
|
-
subscribeToMasterMessages,
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export { registerSerializer } from '../common.ts'
|
|
67
|
-
export { Transfer } from '../transferable.ts'
|
|
68
|
-
export { expose }
|
package/types/is-observable.d.ts
DELETED
package/types/tiny-worker.d.ts
DELETED
package/xy.config.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { XyTsupConfig } from '@xylabs/ts-scripts-yarn3'
|
|
2
|
-
const config: XyTsupConfig = {
|
|
3
|
-
compile: {
|
|
4
|
-
browser: { src: { entry: ['./src/master/implementation.browser.ts', './src/worker/worker.browser.ts'] } },
|
|
5
|
-
neutral: {
|
|
6
|
-
src: {
|
|
7
|
-
entry: [
|
|
8
|
-
'./src/index.ts',
|
|
9
|
-
'./src/master/index.ts',
|
|
10
|
-
'./src/master/pool.ts',
|
|
11
|
-
'./src/observable.ts',
|
|
12
|
-
'./src/observable-promise.ts',
|
|
13
|
-
'./src/master/implementation.ts',
|
|
14
|
-
'./src/master/register.ts',
|
|
15
|
-
'./src/master/spawn.ts',
|
|
16
|
-
'./src/master/thread.ts',
|
|
17
|
-
],
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
node: { src: { entry: ['./src/master/implementation.node.ts', './src/worker/worker.node.ts'] } },
|
|
21
|
-
},
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export default config
|