@hybrid-compute/core 0.0.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/.release-it.json +64 -0
- package/README.md +78 -0
- package/eslint.config.mjs +3 -0
- package/package.json +51 -0
- package/src/__tests__/core.spec.ts +139 -0
- package/src/index.ts +103 -0
- package/src/types.ts +88 -0
- package/tsconfig.json +12 -0
package/.release-it.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"git": false,
|
|
3
|
+
"github": {
|
|
4
|
+
"release": true,
|
|
5
|
+
"tokenRef": "GH_TOKEN"
|
|
6
|
+
},
|
|
7
|
+
"npm": {
|
|
8
|
+
"publish": true,
|
|
9
|
+
"skipChecks": true
|
|
10
|
+
},
|
|
11
|
+
"hooks": {
|
|
12
|
+
"after:release": "echo Successfully released ${name} v${version} to ${repo.repository}."
|
|
13
|
+
},
|
|
14
|
+
"plugins": {
|
|
15
|
+
"@release-it/conventional-changelog": {
|
|
16
|
+
"header": "# Changelog",
|
|
17
|
+
"preset": {
|
|
18
|
+
"name": "conventionalcommits",
|
|
19
|
+
"types": [
|
|
20
|
+
{
|
|
21
|
+
"type": "chore",
|
|
22
|
+
"section": "Tasks"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"type": "docs",
|
|
26
|
+
"section": "Documentation"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"type": "feat",
|
|
30
|
+
"section": "Feature"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"type": "fix",
|
|
34
|
+
"section": "Bug"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"type": "perf",
|
|
38
|
+
"section": "Performance change"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"type": "refactor",
|
|
42
|
+
"section": "Refactoring"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"type": "release",
|
|
46
|
+
"section": "Create a release commit",
|
|
47
|
+
"hidden": true
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"type": "style",
|
|
51
|
+
"section": "Markup, white-space, formatting, missing semi-colons...",
|
|
52
|
+
"hidden": true
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"type": "test",
|
|
56
|
+
"section": "Adding missing tests",
|
|
57
|
+
"hidden": true
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
"infile": "CHANGELOG.md"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
package/README.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# @hybrid-compute/core
|
|
2
|
+
|
|
3
|
+
[](http://commitizen.github.io/cz-cli/)
|
|
4
|
+
[](http://makeapullrequest.com)
|
|
5
|
+
[](http://semver.org/spec/v2.0.0.html)
|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+

|
|
11
|
+

|
|
12
|
+
[](https://codecov.io/gh/phun-ky/hybrid-compute)
|
|
13
|
+
[](https://github.com/phun-ky/hybrid-compute/actions/workflows/check.yml)
|
|
14
|
+
|
|
15
|
+
Part of the [`@hybrid-compute`](https://github.com/phun-ky/hybrid-compute)
|
|
16
|
+
monorepo.
|
|
17
|
+
|
|
18
|
+
> See the [main README](https://github.com/phun-ky/hybrid-compute#readme) for
|
|
19
|
+
> full project overview, usage examples, architecture, and contribution
|
|
20
|
+
> guidelines.
|
|
21
|
+
|
|
22
|
+
## API Docs
|
|
23
|
+
|
|
24
|
+
[HybridCompute Core API Documentation](https://github.com/phun-ky/hybrid-compute/blob/main/docs/api/core/src/classes/HybridCompute.md)
|
|
25
|
+
|
|
26
|
+
## 📦 Package Info
|
|
27
|
+
|
|
28
|
+
This package provides:
|
|
29
|
+
|
|
30
|
+
- The core orchestrator `HybridCompute` class
|
|
31
|
+
- Strategy-based task routing (`local`, `worker`, `remote`, or `auto`)
|
|
32
|
+
- Unified API for compute execution
|
|
33
|
+
|
|
34
|
+
## Usage
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm install @hybrid-compute/core
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import { HybridCompute } from '@hybrid-compute/core';
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Contributing
|
|
47
|
+
|
|
48
|
+
Want to contribute? Please read the
|
|
49
|
+
[CONTRIBUTING.md](https://github.com/phun-ky/hybrid-compute/blob/main/CONTRIBUTING.md)
|
|
50
|
+
and
|
|
51
|
+
[CODE_OF_CONDUCT.md](https://github.com/phun-ky/hybrid-compute/blob/main/CODE_OF_CONDUCT.md)
|
|
52
|
+
|
|
53
|
+
## License
|
|
54
|
+
|
|
55
|
+
This project is licensed under the MIT License - see the
|
|
56
|
+
[LICENSE](https://github.com/phun-ky/hybrid-compute/blob/main/LICENSE) file for
|
|
57
|
+
details.
|
|
58
|
+
|
|
59
|
+
## Sponsor me
|
|
60
|
+
|
|
61
|
+
I'm an Open Source evangelist, creating stuff that does not exist yet to help
|
|
62
|
+
get rid of secondary activities and to enhance systems already in place, be it
|
|
63
|
+
documentation, tools or web sites.
|
|
64
|
+
|
|
65
|
+
The sponsorship is an unique opportunity to alleviate more hours for me to
|
|
66
|
+
maintain my projects, create new ones and contribute to the large community
|
|
67
|
+
we're all part of :)
|
|
68
|
+
|
|
69
|
+
[Support me on GitHub Sponsors](https://github.com/sponsors/phun-ky).
|
|
70
|
+
|
|
71
|
+
p.s. **Ukraine is still under brutal Russian invasion. A lot of Ukrainian people
|
|
72
|
+
are hurt, without shelter and need help**. You can help in various ways, for
|
|
73
|
+
instance, directly helping refugees, spreading awareness, putting pressure on
|
|
74
|
+
your local government or companies. You can also support Ukraine by donating
|
|
75
|
+
e.g. to [Red Cross](https://www.icrc.org/en/donate/ukraine),
|
|
76
|
+
[Ukraine humanitarian organisation](https://savelife.in.ua/en/donate-en/#donate-army-card-weekly)
|
|
77
|
+
or
|
|
78
|
+
[donate Ambulances for Ukraine](https://www.gofundme.com/f/help-to-save-the-lives-of-civilians-in-a-war-zone).
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hybrid-compute/core",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "Core orchestrator for dispatching compute tasks to local, threaded, or remote backends.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"compute",
|
|
7
|
+
"task-dispatch",
|
|
8
|
+
"core",
|
|
9
|
+
"strategy",
|
|
10
|
+
"hybrid",
|
|
11
|
+
"orchestrator",
|
|
12
|
+
"execution",
|
|
13
|
+
"modular",
|
|
14
|
+
"framework"
|
|
15
|
+
],
|
|
16
|
+
"homepage": "https://phun-ky.net/projects/hybrid-compute",
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/phun-ky/hybrid-compute/issues"
|
|
19
|
+
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/phun-ky/hybrid-compute.git"
|
|
23
|
+
},
|
|
24
|
+
"funding": "https://github.com/phun-ky/hybrid-compute?sponsor=1",
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"author": "Alexander Vassbotn Røyne-Helgesen <alexander@phun-ky.net>",
|
|
27
|
+
"type": "module",
|
|
28
|
+
"exports": "./dist/index.js",
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"scripts": {
|
|
31
|
+
"clean": "rm -rf dist tsconfig.tsbuildinfo",
|
|
32
|
+
"release": "release-it",
|
|
33
|
+
"test": "tsx --test **/__tests__/**/*.spec.ts",
|
|
34
|
+
"pretest:ci": "rm -rf coverage && mkdir -p coverage",
|
|
35
|
+
"test:ci": "glob -c \"node --import tsx --test --no-warnings --experimental-test-coverage --test-reporter=cobertura --test-reporter-destination=coverage/cobertura-coverage.xml --test-reporter=spec --test-reporter-destination=stdout\" \"**/__tests__/**/*.spec.ts\""
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "^22.15.24",
|
|
39
|
+
"eslint": "^9.27.0",
|
|
40
|
+
"eslint-config-phun-ky": "^1.0.3",
|
|
41
|
+
"prettier": "^3.5.3",
|
|
42
|
+
"typescript": "^5.8.3"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=22.0.0",
|
|
46
|
+
"npm": ">=10.8.2"
|
|
47
|
+
},
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import test, { describe } from 'node:test';
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
import {
|
|
4
|
+
ComputeBackendInterface,
|
|
5
|
+
createHybridCompute,
|
|
6
|
+
HybridCompute
|
|
7
|
+
} from '..';
|
|
8
|
+
|
|
9
|
+
// Mocks
|
|
10
|
+
const mockTaskName = 'double';
|
|
11
|
+
const mockInput = 21;
|
|
12
|
+
const mockOutput = 42;
|
|
13
|
+
|
|
14
|
+
function createMockBackend(): ComputeBackendInterface {
|
|
15
|
+
return {
|
|
16
|
+
canRun: (taskName) => taskName === 'double',
|
|
17
|
+
runTask: async <Input, Output>(
|
|
18
|
+
taskName: string,
|
|
19
|
+
input: Input
|
|
20
|
+
): Promise<Output> => {
|
|
21
|
+
// mock response — force-cast for test purposes
|
|
22
|
+
return 42 as unknown as Output;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function createNonRunnableMockBackend(): ComputeBackendInterface {
|
|
28
|
+
return {
|
|
29
|
+
canRun: () => false,
|
|
30
|
+
runTask: async <Input, Output>() => {
|
|
31
|
+
throw new Error('Should not be called');
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
describe('HybridCompute', () => {
|
|
37
|
+
test('runs task using local strategy', async () => {
|
|
38
|
+
const compute = new HybridCompute({ local: createMockBackend() });
|
|
39
|
+
|
|
40
|
+
const result = await compute.runTask(mockTaskName, mockInput, 'local');
|
|
41
|
+
assert.strictEqual(result, mockOutput);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('runs task using worker strategy', async () => {
|
|
45
|
+
const compute = new HybridCompute({ worker: createMockBackend() });
|
|
46
|
+
|
|
47
|
+
const result = await compute.runTask(mockTaskName, mockInput, 'worker');
|
|
48
|
+
assert.strictEqual(result, mockOutput);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test('runs task using remote strategy', async () => {
|
|
52
|
+
const compute = new HybridCompute({ remote: createMockBackend() });
|
|
53
|
+
|
|
54
|
+
const result = await compute.runTask(mockTaskName, mockInput, 'remote');
|
|
55
|
+
assert.strictEqual(result, mockOutput);
|
|
56
|
+
});
|
|
57
|
+
test('uses auto strategy with priority: worker > local > remote', async () => {
|
|
58
|
+
const callOrder: string[] = [];
|
|
59
|
+
|
|
60
|
+
const worker: ComputeBackendInterface = {
|
|
61
|
+
canRun: () => (callOrder.push('worker'), true),
|
|
62
|
+
runTask: async <Input, Output>(
|
|
63
|
+
taskName: string,
|
|
64
|
+
input: Input
|
|
65
|
+
): Promise<Output> => {
|
|
66
|
+
callOrder.push('runWorker');
|
|
67
|
+
return mockOutput as unknown as Output;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const local: ComputeBackendInterface = {
|
|
72
|
+
canRun: () => (callOrder.push('local'), true),
|
|
73
|
+
runTask: async <Input, Output>(
|
|
74
|
+
taskName: string,
|
|
75
|
+
input: Input
|
|
76
|
+
): Promise<Output> => {
|
|
77
|
+
callOrder.push('runLocal');
|
|
78
|
+
return mockOutput as unknown as Output;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const remote: ComputeBackendInterface = {
|
|
83
|
+
canRun: () => (callOrder.push('remote'), true),
|
|
84
|
+
runTask: async <Input, Output>(
|
|
85
|
+
taskName: string,
|
|
86
|
+
input: Input
|
|
87
|
+
): Promise<Output> => {
|
|
88
|
+
callOrder.push('runRemote');
|
|
89
|
+
return mockOutput as unknown as Output;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const compute = new HybridCompute({ worker, local, remote });
|
|
94
|
+
const result = await compute.runTask(mockTaskName, mockInput, 'auto');
|
|
95
|
+
|
|
96
|
+
assert.strictEqual(result, mockOutput);
|
|
97
|
+
assert.deepStrictEqual(callOrder, ['worker', 'runWorker']);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test('falls back in auto strategy if earlier backends cannot run', async () => {
|
|
101
|
+
const compute = new HybridCompute({
|
|
102
|
+
worker: createMockBackend(),
|
|
103
|
+
local: createMockBackend(),
|
|
104
|
+
remote: createMockBackend()
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const result = await compute.runTask(mockTaskName, mockInput, 'auto');
|
|
108
|
+
assert.strictEqual(result, mockOutput);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test('throws if no backend matches the strategy', async () => {
|
|
112
|
+
const compute = new HybridCompute({});
|
|
113
|
+
|
|
114
|
+
await assert.rejects(
|
|
115
|
+
() => compute.runTask(mockTaskName, mockInput, 'local'),
|
|
116
|
+
/No backend available/
|
|
117
|
+
);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test('throws if no backend can run in auto strategy', async () => {
|
|
121
|
+
const compute = new HybridCompute({
|
|
122
|
+
worker: createNonRunnableMockBackend(),
|
|
123
|
+
local: createNonRunnableMockBackend(),
|
|
124
|
+
remote: createNonRunnableMockBackend()
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
await assert.rejects(
|
|
128
|
+
() => compute.runTask(mockTaskName, mockInput, 'auto'),
|
|
129
|
+
/No backend available/
|
|
130
|
+
);
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
describe('createHybridCompute', () => {
|
|
135
|
+
test('returns HybridCompute instance', () => {
|
|
136
|
+
const instance = createHybridCompute({ local: createMockBackend() });
|
|
137
|
+
assert.ok(instance instanceof HybridCompute);
|
|
138
|
+
});
|
|
139
|
+
});
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
ExecutionStrategyType,
|
|
5
|
+
HybridComputeOptionsInterface
|
|
6
|
+
} from './types.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The HybridCompute class acts as an orchestrator to delegate compute tasks
|
|
10
|
+
* across different backends (local, worker, or remote) using a flexible strategy.
|
|
11
|
+
*
|
|
12
|
+
* It supports four strategies:
|
|
13
|
+
* - `'local'`: Forces execution on the local (main thread) backend.
|
|
14
|
+
* - `'worker'`: Forces execution on a threaded/WebWorker backend.
|
|
15
|
+
* - `'remote'`: Forces execution on a remote/server backend.
|
|
16
|
+
* - `'auto'`: Automatically selects the first available backend that supports the task.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* const compute = new HybridCompute({
|
|
21
|
+
* local: createLocalCompute(),
|
|
22
|
+
* worker: createThreadedCompute(workerPath, ['double']),
|
|
23
|
+
* remote: createRemoteCompute({ transport: 'fetch', endpoint: '/api/compute' })
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* const result = await compute.runTask<number, number>('double', 21, 'auto');
|
|
27
|
+
* console.log(result); // 42
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export class HybridCompute {
|
|
31
|
+
private backends: HybridComputeOptionsInterface;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Creates a new HybridCompute orchestrator.
|
|
35
|
+
*
|
|
36
|
+
* @param backends - An object containing optional local, worker, and remote backends.
|
|
37
|
+
*/
|
|
38
|
+
constructor(backends: HybridComputeOptionsInterface) {
|
|
39
|
+
this.backends = backends;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Runs a task using the specified execution strategy.
|
|
44
|
+
*
|
|
45
|
+
* If `strategy` is `'auto'`, it will try the worker, then local, then remote backend in order of priority.
|
|
46
|
+
*
|
|
47
|
+
* @typeParam Input - The type of the input expected by the task.
|
|
48
|
+
* @typeParam Output - The expected output type returned by the task.
|
|
49
|
+
*
|
|
50
|
+
* @param taskName - The name of the task to execute.
|
|
51
|
+
* @param input - The input payload for the task.
|
|
52
|
+
* @param strategy - The execution strategy to use. Defaults to `'auto'`.
|
|
53
|
+
*
|
|
54
|
+
* @returns A Promise resolving to the task's output.
|
|
55
|
+
*
|
|
56
|
+
* @throws If no backend is available or able to run the task.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* const output = await compute.runTask('greetUser', { name: 'Alice' }, 'worker');
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
async runTask<Input, Output>(
|
|
64
|
+
taskName: string,
|
|
65
|
+
input: Input,
|
|
66
|
+
strategy: ExecutionStrategyType = 'auto'
|
|
67
|
+
): Promise<Output> {
|
|
68
|
+
if (strategy === 'local' && this.backends.local) {
|
|
69
|
+
return this.backends.local.runTask(taskName, input);
|
|
70
|
+
} else if (strategy === 'worker' && this.backends.worker) {
|
|
71
|
+
return this.backends.worker.runTask(taskName, input);
|
|
72
|
+
} else if (strategy === 'remote' && this.backends.remote) {
|
|
73
|
+
return this.backends.remote.runTask(taskName, input);
|
|
74
|
+
} else if (strategy === 'auto') {
|
|
75
|
+
if (this.backends.worker?.canRun(taskName)) {
|
|
76
|
+
return this.backends.worker.runTask(taskName, input);
|
|
77
|
+
} else if (this.backends.local?.canRun(taskName)) {
|
|
78
|
+
return this.backends.local.runTask(taskName, input);
|
|
79
|
+
} else if (this.backends.remote?.canRun(taskName)) {
|
|
80
|
+
return this.backends.remote.runTask(taskName, input);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
throw new Error(
|
|
85
|
+
`No backend available for task '${taskName}' using strategy '${strategy}'`
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Factory function for creating a HybridCompute instance.
|
|
92
|
+
*
|
|
93
|
+
* @param backends - Configuration options specifying available backends.
|
|
94
|
+
* @returns A new HybridCompute orchestrator.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* const hybrid = createHybridCompute({ local: createLocalCompute() });
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
export function createHybridCompute(backends: HybridComputeOptionsInterface) {
|
|
102
|
+
return new HybridCompute(backends);
|
|
103
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The strategy used to determine which compute backend to use.
|
|
3
|
+
*
|
|
4
|
+
* - `auto`: Automatically select the best backend available.
|
|
5
|
+
* - `local`: Run tasks directly on the main thread.
|
|
6
|
+
* - `worker`: Offload tasks to WebWorker or thread-based compute.
|
|
7
|
+
* - `remote`: Offload tasks to a remote server or service.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* const strategy: ExecutionStrategyType = 'worker';
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export type ExecutionStrategyType = 'auto' | 'local' | 'worker' | 'remote';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Describes a unit of work that can be executed by a compute backend.
|
|
18
|
+
*
|
|
19
|
+
* @template Input The input type expected by the task.
|
|
20
|
+
* @template Output The output type returned by the task.
|
|
21
|
+
*
|
|
22
|
+
* @property name - A unique name used to identify the task.
|
|
23
|
+
* @property run - A function that takes input and returns a Promise of the output.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* const task: ComputeTaskInterface<number, number> = {
|
|
28
|
+
* name: 'double',
|
|
29
|
+
* run: async (x) => x * 2
|
|
30
|
+
* };
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export interface ComputeTaskInterface<Input = unknown, Output = unknown> {
|
|
34
|
+
name: string;
|
|
35
|
+
run(input: Input): Promise<Output>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Represents a backend capable of executing registered compute tasks.
|
|
40
|
+
*
|
|
41
|
+
* Each backend must be able to:
|
|
42
|
+
* - Determine if it can run a given task (`canRun`)
|
|
43
|
+
* - Execute a named task with input and return a Promise of output (`runTask`)
|
|
44
|
+
*
|
|
45
|
+
* @template Input The input type for task execution.
|
|
46
|
+
* @template Output The output type for task execution.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* const backend: ComputeBackendInterface = {
|
|
51
|
+
* canRun: (taskName) => taskName === 'double',
|
|
52
|
+
* runTask: async (taskName, input) => {
|
|
53
|
+
* if (taskName === 'double') return (input as number) * 2;
|
|
54
|
+
* throw new Error('Unknown task');
|
|
55
|
+
* }
|
|
56
|
+
* };
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export interface ComputeBackendInterface {
|
|
60
|
+
canRun(taskName: string): boolean;
|
|
61
|
+
runTask<Input, Output>(taskName: string, input: Input): Promise<Output>;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Configuration options for initializing the HybridCompute orchestrator.
|
|
66
|
+
*
|
|
67
|
+
* Backends are optional, and can be combined or omitted based on the environment or needs.
|
|
68
|
+
*
|
|
69
|
+
* @property local - A local synchronous compute backend (main thread).
|
|
70
|
+
* @property worker - A background-thread compute backend (e.g. WebWorker).
|
|
71
|
+
* @property remote - A server-side or cloud compute backend.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* const options: HybridComputeOptionsInterface = {
|
|
76
|
+
* local: createLocalCompute(),
|
|
77
|
+
* remote: createRemoteCompute({ ... })
|
|
78
|
+
* };
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API
|
|
82
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
|
|
83
|
+
*/
|
|
84
|
+
export interface HybridComputeOptionsInterface {
|
|
85
|
+
local?: ComputeBackendInterface;
|
|
86
|
+
worker?: ComputeBackendInterface;
|
|
87
|
+
remote?: ComputeBackendInterface;
|
|
88
|
+
}
|