@effectionx/worker 0.3.1 → 0.4.0
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/dist/message-channel.d.ts.map +1 -0
- package/dist/mod.d.ts +4 -0
- package/dist/mod.d.ts.map +1 -0
- package/{esm → dist}/mod.js +1 -0
- package/dist/test-simple-worker.d.ts +2 -0
- package/dist/test-simple-worker.d.ts.map +1 -0
- package/dist/test-simple-worker.js +11 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types.d.ts.map +1 -0
- package/{esm → dist}/worker-main.d.ts +1 -1
- package/dist/worker-main.d.ts.map +1 -0
- package/{esm → dist}/worker-main.js +34 -16
- package/dist/worker.d.ts.map +1 -0
- package/{esm → dist}/worker.js +3 -4
- package/message-channel.ts +13 -0
- package/mod.ts +3 -0
- package/package.json +22 -16
- package/test-assets/boom-result-worker.ts +5 -0
- package/test-assets/boom-worker.ts +7 -0
- package/test-assets/counter-worker.ts +15 -0
- package/test-assets/crash-worker.ts +1 -0
- package/test-assets/echo-worker.ts +7 -0
- package/test-assets/result-worker.ts +5 -0
- package/test-assets/shutdown-worker.ts +24 -0
- package/test-assets/suspend-worker.ts +4 -0
- package/test-simple-worker.ts +12 -0
- package/tsconfig.json +20 -0
- package/types.ts +38 -0
- package/worker-main.ts +248 -0
- package/worker.test.ts +179 -0
- package/worker.ts +159 -0
- package/esm/_dnt.shims.d.ts +0 -2
- package/esm/_dnt.shims.d.ts.map +0 -1
- package/esm/_dnt.shims.js +0 -57
- package/esm/deps/jsr.io/@std/assert/1.0.16/almost_equals.d.ts +0 -29
- package/esm/deps/jsr.io/@std/assert/1.0.16/almost_equals.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/almost_equals.js +0 -46
- package/esm/deps/jsr.io/@std/assert/1.0.16/array_includes.d.ts +0 -24
- package/esm/deps/jsr.io/@std/assert/1.0.16/array_includes.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/array_includes.js +0 -46
- package/esm/deps/jsr.io/@std/assert/1.0.16/assert.d.ts +0 -16
- package/esm/deps/jsr.io/@std/assert/1.0.16/assert.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/assert.js +0 -22
- package/esm/deps/jsr.io/@std/assert/1.0.16/assertion_error.d.ts +0 -26
- package/esm/deps/jsr.io/@std/assert/1.0.16/assertion_error.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/assertion_error.js +0 -30
- package/esm/deps/jsr.io/@std/assert/1.0.16/equal.d.ts +0 -17
- package/esm/deps/jsr.io/@std/assert/1.0.16/equal.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/equal.js +0 -186
- package/esm/deps/jsr.io/@std/assert/1.0.16/equals.d.ts +0 -35
- package/esm/deps/jsr.io/@std/assert/1.0.16/equals.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/equals.js +0 -59
- package/esm/deps/jsr.io/@std/assert/1.0.16/exists.d.ts +0 -18
- package/esm/deps/jsr.io/@std/assert/1.0.16/exists.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/exists.js +0 -27
- package/esm/deps/jsr.io/@std/assert/1.0.16/fail.d.ts +0 -15
- package/esm/deps/jsr.io/@std/assert/1.0.16/fail.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/fail.js +0 -20
- package/esm/deps/jsr.io/@std/assert/1.0.16/false.d.ts +0 -18
- package/esm/deps/jsr.io/@std/assert/1.0.16/false.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/false.js +0 -22
- package/esm/deps/jsr.io/@std/assert/1.0.16/greater.d.ts +0 -20
- package/esm/deps/jsr.io/@std/assert/1.0.16/greater.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/greater.js +0 -29
- package/esm/deps/jsr.io/@std/assert/1.0.16/greater_or_equal.d.ts +0 -20
- package/esm/deps/jsr.io/@std/assert/1.0.16/greater_or_equal.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/greater_or_equal.js +0 -29
- package/esm/deps/jsr.io/@std/assert/1.0.16/instance_of.d.ts +0 -23
- package/esm/deps/jsr.io/@std/assert/1.0.16/instance_of.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/instance_of.js +0 -52
- package/esm/deps/jsr.io/@std/assert/1.0.16/is_error.d.ts +0 -25
- package/esm/deps/jsr.io/@std/assert/1.0.16/is_error.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/is_error.js +0 -53
- package/esm/deps/jsr.io/@std/assert/1.0.16/less.d.ts +0 -19
- package/esm/deps/jsr.io/@std/assert/1.0.16/less.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/less.js +0 -28
- package/esm/deps/jsr.io/@std/assert/1.0.16/less_or_equal.d.ts +0 -20
- package/esm/deps/jsr.io/@std/assert/1.0.16/less_or_equal.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/less_or_equal.js +0 -29
- package/esm/deps/jsr.io/@std/assert/1.0.16/match.d.ts +0 -18
- package/esm/deps/jsr.io/@std/assert/1.0.16/match.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/match.js +0 -26
- package/esm/deps/jsr.io/@std/assert/1.0.16/mod.d.ts +0 -44
- package/esm/deps/jsr.io/@std/assert/1.0.16/mod.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/mod.js +0 -45
- package/esm/deps/jsr.io/@std/assert/1.0.16/not_equals.d.ts +0 -21
- package/esm/deps/jsr.io/@std/assert/1.0.16/not_equals.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/not_equals.js +0 -33
- package/esm/deps/jsr.io/@std/assert/1.0.16/not_instance_of.d.ts +0 -20
- package/esm/deps/jsr.io/@std/assert/1.0.16/not_instance_of.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/not_instance_of.js +0 -29
- package/esm/deps/jsr.io/@std/assert/1.0.16/not_match.d.ts +0 -18
- package/esm/deps/jsr.io/@std/assert/1.0.16/not_match.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/not_match.js +0 -26
- package/esm/deps/jsr.io/@std/assert/1.0.16/not_strict_equals.d.ts +0 -23
- package/esm/deps/jsr.io/@std/assert/1.0.16/not_strict_equals.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/not_strict_equals.js +0 -32
- package/esm/deps/jsr.io/@std/assert/1.0.16/object_match.d.ts +0 -29
- package/esm/deps/jsr.io/@std/assert/1.0.16/object_match.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/object_match.js +0 -167
- package/esm/deps/jsr.io/@std/assert/1.0.16/rejects.d.ts +0 -42
- package/esm/deps/jsr.io/@std/assert/1.0.16/rejects.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/rejects.js +0 -53
- package/esm/deps/jsr.io/@std/assert/1.0.16/strict_equals.d.ts +0 -24
- package/esm/deps/jsr.io/@std/assert/1.0.16/strict_equals.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/strict_equals.js +0 -58
- package/esm/deps/jsr.io/@std/assert/1.0.16/string_includes.d.ts +0 -18
- package/esm/deps/jsr.io/@std/assert/1.0.16/string_includes.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/string_includes.js +0 -26
- package/esm/deps/jsr.io/@std/assert/1.0.16/throws.d.ts +0 -45
- package/esm/deps/jsr.io/@std/assert/1.0.16/throws.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/throws.js +0 -44
- package/esm/deps/jsr.io/@std/assert/1.0.16/unimplemented.d.ts +0 -15
- package/esm/deps/jsr.io/@std/assert/1.0.16/unimplemented.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/unimplemented.js +0 -20
- package/esm/deps/jsr.io/@std/assert/1.0.16/unreachable.d.ts +0 -15
- package/esm/deps/jsr.io/@std/assert/1.0.16/unreachable.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/assert/1.0.16/unreachable.js +0 -20
- package/esm/deps/jsr.io/@std/internal/1.0.12/build_message.d.ts +0 -80
- package/esm/deps/jsr.io/@std/internal/1.0.12/build_message.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/internal/1.0.12/build_message.js +0 -116
- package/esm/deps/jsr.io/@std/internal/1.0.12/diff.d.ts +0 -140
- package/esm/deps/jsr.io/@std/internal/1.0.12/diff.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/internal/1.0.12/diff.js +0 -276
- package/esm/deps/jsr.io/@std/internal/1.0.12/diff_str.d.ts +0 -99
- package/esm/deps/jsr.io/@std/internal/1.0.12/diff_str.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/internal/1.0.12/diff_str.js +0 -182
- package/esm/deps/jsr.io/@std/internal/1.0.12/format.d.ts +0 -29
- package/esm/deps/jsr.io/@std/internal/1.0.12/format.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/internal/1.0.12/format.js +0 -70
- package/esm/deps/jsr.io/@std/internal/1.0.12/styles.d.ts +0 -159
- package/esm/deps/jsr.io/@std/internal/1.0.12/styles.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/internal/1.0.12/styles.js +0 -207
- package/esm/deps/jsr.io/@std/internal/1.0.12/types.d.ts +0 -25
- package/esm/deps/jsr.io/@std/internal/1.0.12/types.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/internal/1.0.12/types.js +0 -3
- package/esm/message-channel.d.ts.map +0 -1
- package/esm/mod.d.ts +0 -3
- package/esm/mod.d.ts.map +0 -1
- package/esm/package.json +0 -3
- package/esm/types.d.ts.map +0 -1
- package/esm/worker-main.d.ts.map +0 -1
- package/esm/worker.d.ts.map +0 -1
- package/script/_dnt.shims.d.ts +0 -2
- package/script/_dnt.shims.d.ts.map +0 -1
- package/script/_dnt.shims.js +0 -60
- package/script/deps/jsr.io/@std/assert/1.0.16/almost_equals.d.ts +0 -29
- package/script/deps/jsr.io/@std/assert/1.0.16/almost_equals.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/almost_equals.js +0 -49
- package/script/deps/jsr.io/@std/assert/1.0.16/array_includes.d.ts +0 -24
- package/script/deps/jsr.io/@std/assert/1.0.16/array_includes.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/array_includes.js +0 -49
- package/script/deps/jsr.io/@std/assert/1.0.16/assert.d.ts +0 -16
- package/script/deps/jsr.io/@std/assert/1.0.16/assert.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/assert.js +0 -25
- package/script/deps/jsr.io/@std/assert/1.0.16/assertion_error.d.ts +0 -26
- package/script/deps/jsr.io/@std/assert/1.0.16/assertion_error.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/assertion_error.js +0 -34
- package/script/deps/jsr.io/@std/assert/1.0.16/equal.d.ts +0 -17
- package/script/deps/jsr.io/@std/assert/1.0.16/equal.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/equal.js +0 -222
- package/script/deps/jsr.io/@std/assert/1.0.16/equals.d.ts +0 -35
- package/script/deps/jsr.io/@std/assert/1.0.16/equals.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/equals.js +0 -62
- package/script/deps/jsr.io/@std/assert/1.0.16/exists.d.ts +0 -18
- package/script/deps/jsr.io/@std/assert/1.0.16/exists.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/exists.js +0 -30
- package/script/deps/jsr.io/@std/assert/1.0.16/fail.d.ts +0 -15
- package/script/deps/jsr.io/@std/assert/1.0.16/fail.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/fail.js +0 -23
- package/script/deps/jsr.io/@std/assert/1.0.16/false.d.ts +0 -18
- package/script/deps/jsr.io/@std/assert/1.0.16/false.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/false.js +0 -25
- package/script/deps/jsr.io/@std/assert/1.0.16/greater.d.ts +0 -20
- package/script/deps/jsr.io/@std/assert/1.0.16/greater.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/greater.js +0 -32
- package/script/deps/jsr.io/@std/assert/1.0.16/greater_or_equal.d.ts +0 -20
- package/script/deps/jsr.io/@std/assert/1.0.16/greater_or_equal.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/greater_or_equal.js +0 -32
- package/script/deps/jsr.io/@std/assert/1.0.16/instance_of.d.ts +0 -23
- package/script/deps/jsr.io/@std/assert/1.0.16/instance_of.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/instance_of.js +0 -55
- package/script/deps/jsr.io/@std/assert/1.0.16/is_error.d.ts +0 -25
- package/script/deps/jsr.io/@std/assert/1.0.16/is_error.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/is_error.js +0 -56
- package/script/deps/jsr.io/@std/assert/1.0.16/less.d.ts +0 -19
- package/script/deps/jsr.io/@std/assert/1.0.16/less.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/less.js +0 -31
- package/script/deps/jsr.io/@std/assert/1.0.16/less_or_equal.d.ts +0 -20
- package/script/deps/jsr.io/@std/assert/1.0.16/less_or_equal.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/less_or_equal.js +0 -32
- package/script/deps/jsr.io/@std/assert/1.0.16/match.d.ts +0 -18
- package/script/deps/jsr.io/@std/assert/1.0.16/match.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/match.js +0 -29
- package/script/deps/jsr.io/@std/assert/1.0.16/mod.d.ts +0 -44
- package/script/deps/jsr.io/@std/assert/1.0.16/mod.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/mod.js +0 -61
- package/script/deps/jsr.io/@std/assert/1.0.16/not_equals.d.ts +0 -21
- package/script/deps/jsr.io/@std/assert/1.0.16/not_equals.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/not_equals.js +0 -36
- package/script/deps/jsr.io/@std/assert/1.0.16/not_instance_of.d.ts +0 -20
- package/script/deps/jsr.io/@std/assert/1.0.16/not_instance_of.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/not_instance_of.js +0 -32
- package/script/deps/jsr.io/@std/assert/1.0.16/not_match.d.ts +0 -18
- package/script/deps/jsr.io/@std/assert/1.0.16/not_match.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/not_match.js +0 -29
- package/script/deps/jsr.io/@std/assert/1.0.16/not_strict_equals.d.ts +0 -23
- package/script/deps/jsr.io/@std/assert/1.0.16/not_strict_equals.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/not_strict_equals.js +0 -35
- package/script/deps/jsr.io/@std/assert/1.0.16/object_match.d.ts +0 -29
- package/script/deps/jsr.io/@std/assert/1.0.16/object_match.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/object_match.js +0 -170
- package/script/deps/jsr.io/@std/assert/1.0.16/rejects.d.ts +0 -42
- package/script/deps/jsr.io/@std/assert/1.0.16/rejects.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/rejects.js +0 -56
- package/script/deps/jsr.io/@std/assert/1.0.16/strict_equals.d.ts +0 -24
- package/script/deps/jsr.io/@std/assert/1.0.16/strict_equals.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/strict_equals.js +0 -61
- package/script/deps/jsr.io/@std/assert/1.0.16/string_includes.d.ts +0 -18
- package/script/deps/jsr.io/@std/assert/1.0.16/string_includes.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/string_includes.js +0 -29
- package/script/deps/jsr.io/@std/assert/1.0.16/throws.d.ts +0 -45
- package/script/deps/jsr.io/@std/assert/1.0.16/throws.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/throws.js +0 -47
- package/script/deps/jsr.io/@std/assert/1.0.16/unimplemented.d.ts +0 -15
- package/script/deps/jsr.io/@std/assert/1.0.16/unimplemented.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/unimplemented.js +0 -23
- package/script/deps/jsr.io/@std/assert/1.0.16/unreachable.d.ts +0 -15
- package/script/deps/jsr.io/@std/assert/1.0.16/unreachable.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/assert/1.0.16/unreachable.js +0 -23
- package/script/deps/jsr.io/@std/internal/1.0.12/build_message.d.ts +0 -80
- package/script/deps/jsr.io/@std/internal/1.0.12/build_message.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/internal/1.0.12/build_message.js +0 -121
- package/script/deps/jsr.io/@std/internal/1.0.12/diff.d.ts +0 -140
- package/script/deps/jsr.io/@std/internal/1.0.12/diff.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/internal/1.0.12/diff.js +0 -283
- package/script/deps/jsr.io/@std/internal/1.0.12/diff_str.d.ts +0 -99
- package/script/deps/jsr.io/@std/internal/1.0.12/diff_str.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/internal/1.0.12/diff_str.js +0 -188
- package/script/deps/jsr.io/@std/internal/1.0.12/format.d.ts +0 -29
- package/script/deps/jsr.io/@std/internal/1.0.12/format.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/internal/1.0.12/format.js +0 -106
- package/script/deps/jsr.io/@std/internal/1.0.12/styles.d.ts +0 -159
- package/script/deps/jsr.io/@std/internal/1.0.12/styles.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/internal/1.0.12/styles.js +0 -252
- package/script/deps/jsr.io/@std/internal/1.0.12/types.d.ts +0 -25
- package/script/deps/jsr.io/@std/internal/1.0.12/types.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/internal/1.0.12/types.js +0 -4
- package/script/message-channel.d.ts +0 -3
- package/script/message-channel.d.ts.map +0 -1
- package/script/message-channel.js +0 -16
- package/script/mod.d.ts +0 -3
- package/script/mod.d.ts.map +0 -1
- package/script/mod.js +0 -18
- package/script/package.json +0 -3
- package/script/types.d.ts +0 -33
- package/script/types.d.ts.map +0 -1
- package/script/types.js +0 -2
- package/script/worker-main.d.ts +0 -84
- package/script/worker-main.d.ts.map +0 -1
- package/script/worker-main.js +0 -190
- package/script/worker.d.ts +0 -63
- package/script/worker.d.ts.map +0 -1
- package/script/worker.js +0 -124
- /package/{esm → dist}/message-channel.d.ts +0 -0
- /package/{esm → dist}/message-channel.js +0 -0
- /package/{esm → dist}/types.d.ts +0 -0
- /package/{esm → dist}/types.js +0 -0
- /package/{esm → dist}/worker.d.ts +0 -0
package/worker-main.ts
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import assert from "node:assert";
|
|
2
|
+
import { MessagePort, parentPort } from "node:worker_threads";
|
|
3
|
+
import type { ValueSignal } from "@effectionx/signals";
|
|
4
|
+
import {
|
|
5
|
+
Err,
|
|
6
|
+
Ok,
|
|
7
|
+
type Operation,
|
|
8
|
+
type Task,
|
|
9
|
+
createSignal,
|
|
10
|
+
each,
|
|
11
|
+
main,
|
|
12
|
+
on,
|
|
13
|
+
resource,
|
|
14
|
+
spawn,
|
|
15
|
+
} from "effection";
|
|
16
|
+
|
|
17
|
+
import type { WorkerControl, WorkerMainOptions } from "./types.ts";
|
|
18
|
+
|
|
19
|
+
// Get the appropriate worker port for the current environment as a resource
|
|
20
|
+
function useWorkerPort(): Operation<MessagePort> {
|
|
21
|
+
return resource(function* (provide) {
|
|
22
|
+
const port = parentPort
|
|
23
|
+
? parentPort // Node.js worker_threads
|
|
24
|
+
: (self as unknown as MessagePort); // Browser/Deno Web Worker
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
yield* provide(port);
|
|
28
|
+
} finally {
|
|
29
|
+
port.close();
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Entrypoint used in the worker that estaliblishes communication
|
|
36
|
+
* with the main thread. It can be used to return a value,
|
|
37
|
+
* respond to messages or both.
|
|
38
|
+
*
|
|
39
|
+
* @example Returning a value
|
|
40
|
+
* ```ts
|
|
41
|
+
* import { workerMain } from "../worker.ts";
|
|
42
|
+
*
|
|
43
|
+
* await workerMain(function* ({ data }) {
|
|
44
|
+
* return data;
|
|
45
|
+
* });
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @example Responding to messages
|
|
49
|
+
* ```ts
|
|
50
|
+
* import { workerMain } from "../worker.ts";
|
|
51
|
+
*
|
|
52
|
+
* await workerMain(function* ({ messages }) {
|
|
53
|
+
* yield* messages.forEach(function* (message) {
|
|
54
|
+
* return message;
|
|
55
|
+
* });
|
|
56
|
+
* });
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* @example Responding to messages and return a value
|
|
60
|
+
* ```ts
|
|
61
|
+
* import { workerMain } from "../worker.ts";
|
|
62
|
+
*
|
|
63
|
+
* await workerMain<number, number, number, number>(
|
|
64
|
+
* function* ({ messages, data: initial }) {
|
|
65
|
+
* let counter = initial;
|
|
66
|
+
*
|
|
67
|
+
* yield* messages.forEach(function* (message) {
|
|
68
|
+
* counter += message;
|
|
69
|
+
* return counter; // returns a value after each message
|
|
70
|
+
* });
|
|
71
|
+
*
|
|
72
|
+
* return counter; // returns the final value
|
|
73
|
+
* },
|
|
74
|
+
* );
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* @template TSend - value main thread will send to the worker
|
|
78
|
+
* @template TRecv - value main thread will receive from the worker
|
|
79
|
+
* @template TReturn - worker operation return value
|
|
80
|
+
* @template TData - data passed from the main thread to the worker during initialization
|
|
81
|
+
* @param {(options: WorkerMainOptions<TSend, TRecv, TData>) => Operation<TReturn>} body
|
|
82
|
+
* @returns {Promise<void>}
|
|
83
|
+
*/
|
|
84
|
+
export async function workerMain<TSend, TRecv, TReturn, TData>(
|
|
85
|
+
body: (options: WorkerMainOptions<TSend, TRecv, TData>) => Operation<TReturn>,
|
|
86
|
+
): Promise<void> {
|
|
87
|
+
await main(function* () {
|
|
88
|
+
const port = yield* useWorkerPort();
|
|
89
|
+
let sent = createSignal<{ value: TSend; response: MessagePort }>();
|
|
90
|
+
let worker = yield* createWorkerStatesSignal();
|
|
91
|
+
|
|
92
|
+
yield* spawn(function* () {
|
|
93
|
+
for (const message of yield* each(on(port, "message"))) {
|
|
94
|
+
const control: WorkerControl<TSend, TData> = (message as MessageEvent)
|
|
95
|
+
.data;
|
|
96
|
+
switch (control.type) {
|
|
97
|
+
case "init": {
|
|
98
|
+
worker.start(
|
|
99
|
+
yield* spawn(function* () {
|
|
100
|
+
try {
|
|
101
|
+
let value = yield* body({
|
|
102
|
+
data: control.data,
|
|
103
|
+
messages: {
|
|
104
|
+
*forEach(fn: (value: TSend) => Operation<TRecv>) {
|
|
105
|
+
for (let { value, response } of yield* each(sent)) {
|
|
106
|
+
yield* spawn(function* () {
|
|
107
|
+
try {
|
|
108
|
+
let result = yield* fn(value);
|
|
109
|
+
response.postMessage(Ok(result));
|
|
110
|
+
} catch (error) {
|
|
111
|
+
response.postMessage(Err(error as Error));
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
yield* each.next();
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
worker.complete(value);
|
|
121
|
+
} catch (error) {
|
|
122
|
+
worker.crash(error as Error);
|
|
123
|
+
}
|
|
124
|
+
}),
|
|
125
|
+
);
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
case "send": {
|
|
129
|
+
let { value, response } = control;
|
|
130
|
+
// Ensure that response is a proper MessagePort (DOM)
|
|
131
|
+
assert(
|
|
132
|
+
response instanceof MessagePort,
|
|
133
|
+
"Expect response to be an instance of MessagePort",
|
|
134
|
+
);
|
|
135
|
+
sent.send({ value, response });
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
case "close": {
|
|
139
|
+
const current = worker.valueOf();
|
|
140
|
+
if (current.type === "running") {
|
|
141
|
+
yield* current.task.halt();
|
|
142
|
+
worker.interrupt();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
yield* each.next();
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
for (const state of yield* each(worker)) {
|
|
152
|
+
if (state.type === "new") {
|
|
153
|
+
port.postMessage({ type: "open" });
|
|
154
|
+
} else if (state.type === "interrupted" || state.type === "error") {
|
|
155
|
+
port.postMessage({ type: "close", result: Err(state.error) });
|
|
156
|
+
break;
|
|
157
|
+
} else if (state.type === "complete") {
|
|
158
|
+
port.postMessage({ type: "close", result: Ok(state.value) });
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
yield* each.next();
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
type New = { type: "new" };
|
|
167
|
+
type Running = { type: "running"; task: Task<void> };
|
|
168
|
+
type Complete = { type: "complete"; value: unknown };
|
|
169
|
+
type Errored = { type: "error"; error: Error };
|
|
170
|
+
type Interrupted = { type: "interrupted"; error: Error };
|
|
171
|
+
|
|
172
|
+
type WorkerState = New | Running | Complete | Errored | Interrupted;
|
|
173
|
+
|
|
174
|
+
interface WorkerStateSignal extends ValueSignal<WorkerState> {
|
|
175
|
+
state: WorkerState["type"];
|
|
176
|
+
start(task: Task<void>): Running | Complete;
|
|
177
|
+
complete(value: unknown): Complete;
|
|
178
|
+
crash(error: Error): Errored;
|
|
179
|
+
interrupt(): Interrupted;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export function createWorkerStatesSignal(): Operation<WorkerStateSignal> {
|
|
183
|
+
return resource(function* (provide) {
|
|
184
|
+
let ref: { current: WorkerState } = {
|
|
185
|
+
current: { type: "new" },
|
|
186
|
+
};
|
|
187
|
+
const signal = createSignal<WorkerState>();
|
|
188
|
+
|
|
189
|
+
const set: WorkerStateSignal["set"] = (value) => {
|
|
190
|
+
ref.current = value;
|
|
191
|
+
signal.send(value);
|
|
192
|
+
return value;
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
const update: WorkerStateSignal["update"] = (updater) =>
|
|
196
|
+
set(updater(ref.current));
|
|
197
|
+
|
|
198
|
+
const interrupt: WorkerStateSignal["interrupt"] = () => {
|
|
199
|
+
let next: Interrupted = {
|
|
200
|
+
type: "interrupted",
|
|
201
|
+
error: new Error("worker terminated"),
|
|
202
|
+
};
|
|
203
|
+
set(next);
|
|
204
|
+
return next;
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
try {
|
|
208
|
+
yield* provide({
|
|
209
|
+
*[Symbol.iterator]() {
|
|
210
|
+
let subscription = yield* signal;
|
|
211
|
+
signal.send(ref.current);
|
|
212
|
+
return subscription;
|
|
213
|
+
},
|
|
214
|
+
get state() {
|
|
215
|
+
return ref.current.type;
|
|
216
|
+
},
|
|
217
|
+
set,
|
|
218
|
+
update,
|
|
219
|
+
valueOf() {
|
|
220
|
+
return ref.current;
|
|
221
|
+
},
|
|
222
|
+
start(task) {
|
|
223
|
+
if (ref.current.type === "complete") {
|
|
224
|
+
return ref.current;
|
|
225
|
+
}
|
|
226
|
+
const next: Running = { type: "running", task };
|
|
227
|
+
set(next);
|
|
228
|
+
return next;
|
|
229
|
+
},
|
|
230
|
+
complete(value) {
|
|
231
|
+
let next: Complete = { type: "complete", value };
|
|
232
|
+
set(next);
|
|
233
|
+
return next;
|
|
234
|
+
},
|
|
235
|
+
crash(error) {
|
|
236
|
+
let next: Errored = { type: "error", error };
|
|
237
|
+
set(next);
|
|
238
|
+
return next;
|
|
239
|
+
},
|
|
240
|
+
interrupt: interrupt,
|
|
241
|
+
});
|
|
242
|
+
} finally {
|
|
243
|
+
if (ref.current.type === "running") {
|
|
244
|
+
interrupt();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
}
|
package/worker.test.ts
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { access, mkdir, readFile, rm } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { beforeEach, describe, it } from "@effectionx/bdd";
|
|
5
|
+
import { when } from "@effectionx/converge";
|
|
6
|
+
import { scoped, spawn, suspend, until } from "effection";
|
|
7
|
+
import { expect } from "expect";
|
|
8
|
+
|
|
9
|
+
import type { ShutdownWorkerParams } from "./test-assets/shutdown-worker.ts";
|
|
10
|
+
import { useWorker } from "./worker.ts";
|
|
11
|
+
|
|
12
|
+
describe("worker", () => {
|
|
13
|
+
it("sends and receive messages in synchrony", function* () {
|
|
14
|
+
expect.assertions(1);
|
|
15
|
+
let worker = yield* useWorker(
|
|
16
|
+
import.meta.resolve("./test-assets/echo-worker.ts"),
|
|
17
|
+
{ type: "module" },
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
let result = yield* worker.send("hello world");
|
|
21
|
+
expect(result).toEqual("hello world");
|
|
22
|
+
});
|
|
23
|
+
it("will raise an exception if an exception happens on the remote side", function* () {
|
|
24
|
+
expect.assertions(2);
|
|
25
|
+
let worker = yield* useWorker<void, unknown, unknown, unknown>(
|
|
26
|
+
import.meta.resolve("./test-assets/boom-worker.ts"),
|
|
27
|
+
{ type: "module" },
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
yield* worker.send();
|
|
32
|
+
} catch (e) {
|
|
33
|
+
expect(e).toBeInstanceOf(Error);
|
|
34
|
+
expect(e).toMatchObject({ message: "boom!" });
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
it("produces its return value", function* () {
|
|
38
|
+
expect.assertions(2);
|
|
39
|
+
let worker = yield* useWorker(
|
|
40
|
+
import.meta.resolve("./test-assets/result-worker.ts"),
|
|
41
|
+
{ type: "module", data: "this is the worker result" },
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
expect(yield* worker).toEqual("this is the worker result");
|
|
45
|
+
expect(yield* worker).toEqual("this is the worker result");
|
|
46
|
+
});
|
|
47
|
+
it("raises an exception if the worker raises one", function* () {
|
|
48
|
+
expect.assertions(2);
|
|
49
|
+
let worker = yield* useWorker(
|
|
50
|
+
import.meta.resolve("./test-assets/boom-result-worker.ts"),
|
|
51
|
+
{ type: "module", data: "boom!" },
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
yield* worker;
|
|
56
|
+
} catch (e) {
|
|
57
|
+
expect(e).toBeInstanceOf(Error);
|
|
58
|
+
expect(e).toMatchObject({ message: "boom!" });
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
describe("shutdown", () => {
|
|
62
|
+
let startFile: string;
|
|
63
|
+
let endFile: string;
|
|
64
|
+
let url: string;
|
|
65
|
+
|
|
66
|
+
beforeEach(function* () {
|
|
67
|
+
let dir = fileURLToPath(import.meta.resolve("./test-tmp"));
|
|
68
|
+
yield* until(
|
|
69
|
+
rm(dir, { recursive: true, force: true }).then(() =>
|
|
70
|
+
mkdir(dir, { recursive: true }),
|
|
71
|
+
),
|
|
72
|
+
);
|
|
73
|
+
startFile = join(dir, "started.txt");
|
|
74
|
+
endFile = join(dir, "ended.txt");
|
|
75
|
+
url = import.meta.resolve("./test-assets/shutdown-worker.ts");
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("shuts down gracefully", function* () {
|
|
79
|
+
let task = yield* spawn(function* () {
|
|
80
|
+
yield* useWorker(url, {
|
|
81
|
+
type: "module",
|
|
82
|
+
data: {
|
|
83
|
+
startFile,
|
|
84
|
+
endFile,
|
|
85
|
+
endText: "goodbye cruel world!",
|
|
86
|
+
} satisfies ShutdownWorkerParams,
|
|
87
|
+
});
|
|
88
|
+
yield* suspend();
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// Wait for worker to start
|
|
92
|
+
yield* when(
|
|
93
|
+
function* () {
|
|
94
|
+
let exists = yield* until(
|
|
95
|
+
access(startFile).then(
|
|
96
|
+
() => true,
|
|
97
|
+
() => false,
|
|
98
|
+
),
|
|
99
|
+
);
|
|
100
|
+
if (!exists) throw new Error("start file not found");
|
|
101
|
+
return true;
|
|
102
|
+
},
|
|
103
|
+
{ timeout: 10_000 },
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
yield* task.halt();
|
|
107
|
+
|
|
108
|
+
// Wait for the end file to be written with expected content
|
|
109
|
+
let { value: content } = yield* when(
|
|
110
|
+
function* () {
|
|
111
|
+
let text = yield* until(readFile(endFile, "utf-8").catch(() => ""));
|
|
112
|
+
if (text !== "goodbye cruel world!") {
|
|
113
|
+
throw new Error(`expected "goodbye cruel world!", got "${text}"`);
|
|
114
|
+
}
|
|
115
|
+
return text;
|
|
116
|
+
},
|
|
117
|
+
{ timeout: 500 },
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
expect(content).toEqual("goodbye cruel world!");
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it("becomes halted if you try and await its value out of scope", function* () {
|
|
125
|
+
let url = import.meta.resolve("./test-assets/suspend-worker.ts");
|
|
126
|
+
let worker = yield* scoped(function* () {
|
|
127
|
+
return yield* useWorker(url, { type: "module" });
|
|
128
|
+
});
|
|
129
|
+
try {
|
|
130
|
+
yield* worker;
|
|
131
|
+
} catch (e) {
|
|
132
|
+
expect(e).toBeInstanceOf(Error);
|
|
133
|
+
expect(e).toMatchObject({ message: "worker terminated" });
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it("supports stateful operations", function* () {
|
|
138
|
+
expect.assertions(3);
|
|
139
|
+
|
|
140
|
+
let url = import.meta.resolve("./test-assets/counter-worker.ts");
|
|
141
|
+
|
|
142
|
+
let worker = yield* useWorker(url, { type: "module", data: 2 });
|
|
143
|
+
|
|
144
|
+
expect(yield* worker.send(10)).toEqual(12);
|
|
145
|
+
|
|
146
|
+
expect(yield* worker.send(-5)).toEqual(7);
|
|
147
|
+
|
|
148
|
+
expect(yield* worker.send(35)).toEqual(42);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it.skip("crashes if there is an uncaught error in the worker", function* () {
|
|
152
|
+
let crash = import.meta.resolve("./test-assets/crash-worker.ts");
|
|
153
|
+
let worker = yield* useWorker(crash, { name: "crash", type: "module" });
|
|
154
|
+
try {
|
|
155
|
+
yield* worker;
|
|
156
|
+
} catch (e) {
|
|
157
|
+
expect(e).toBeInstanceOf(Error);
|
|
158
|
+
expect(e).toMatchObject({ message: "boom!" });
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it.skip("crashes if the worker module cannot be found", function* () {
|
|
163
|
+
let crash = import.meta.resolve("./test-assets/non-existent-worker.ts");
|
|
164
|
+
let worker = yield* useWorker(crash, { name: "crash", type: "module" });
|
|
165
|
+
try {
|
|
166
|
+
yield* worker;
|
|
167
|
+
} catch (e) {
|
|
168
|
+
expect(e).toBeInstanceOf(Error);
|
|
169
|
+
expect(e).toMatchObject({ message: "boom!" });
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
it.skip("crashes if there is a message error from the main thread", function* () {
|
|
173
|
+
// don't know how to reproduce this
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it.skip("crashes if there is a message error from the worker thread", function* () {
|
|
177
|
+
// don't know how to trigger
|
|
178
|
+
});
|
|
179
|
+
});
|
package/worker.ts
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import assert from "node:assert";
|
|
2
|
+
import {
|
|
3
|
+
Err,
|
|
4
|
+
Ok,
|
|
5
|
+
on,
|
|
6
|
+
once,
|
|
7
|
+
type Operation,
|
|
8
|
+
resource,
|
|
9
|
+
type Result,
|
|
10
|
+
spawn,
|
|
11
|
+
withResolvers,
|
|
12
|
+
} from "effection";
|
|
13
|
+
import Worker from "web-worker";
|
|
14
|
+
|
|
15
|
+
import { useMessageChannel } from "./message-channel.ts";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Argument received by workerMain function
|
|
19
|
+
*
|
|
20
|
+
* @template TSend - value main thread will send to the worker
|
|
21
|
+
* @template TRecv - value main thread will receive from the worker
|
|
22
|
+
* @template TData - data passed from the main thread to the worker during initialization
|
|
23
|
+
*/
|
|
24
|
+
export interface WorkerResource<TSend, TRecv, TReturn>
|
|
25
|
+
extends Operation<TReturn> {
|
|
26
|
+
send(data: TSend): Operation<TRecv>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Use on the main thread to create and exeecute a well behaved web worker.
|
|
31
|
+
*
|
|
32
|
+
* @example Compute a single value
|
|
33
|
+
* ```ts
|
|
34
|
+
* import { run } from "effection";
|
|
35
|
+
* import { useWorker } from "@effectionx/worker"
|
|
36
|
+
*
|
|
37
|
+
* await run(function*() {
|
|
38
|
+
* const worker = yield* useWorker("script.ts", { type: "module" });
|
|
39
|
+
*
|
|
40
|
+
* try {
|
|
41
|
+
* const result = yield* worker;
|
|
42
|
+
* } catch (e) {
|
|
43
|
+
* console.error(e);
|
|
44
|
+
* }
|
|
45
|
+
* });
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @example Compute multipe values
|
|
49
|
+
* ```ts
|
|
50
|
+
* import { run } from "effection";
|
|
51
|
+
* import { useWorker } from "@effectionx/worker"
|
|
52
|
+
*
|
|
53
|
+
* await run(function*() {
|
|
54
|
+
* const worker = yield* useWorker("script.ts", { type: "module" });
|
|
55
|
+
*
|
|
56
|
+
* try {
|
|
57
|
+
* const result1 = yield* worker.send("Tom");
|
|
58
|
+
* const result2 = yield* worker.send("Dick");
|
|
59
|
+
* const result2 = yield* worker.send("Harry");
|
|
60
|
+
*
|
|
61
|
+
* // get the last result
|
|
62
|
+
* const finalResult = yield* worker;
|
|
63
|
+
* } catch (e) {
|
|
64
|
+
* console.error(e);
|
|
65
|
+
* }
|
|
66
|
+
* });
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* @param url URL or string of script
|
|
70
|
+
* @param options WorkerOptions
|
|
71
|
+
* @template TSend - value main thread will send to the worker
|
|
72
|
+
* @template TRecv - value main thread will receive from the worker
|
|
73
|
+
* @template TReturn - worker operation return value
|
|
74
|
+
* @template TData - data passed from the main thread to the worker during initialization
|
|
75
|
+
* @returns {Operation<WorkerResource<TSend, TRecv>>}
|
|
76
|
+
*/
|
|
77
|
+
export function useWorker<TSend, TRecv, TReturn, TData>(
|
|
78
|
+
url: string | URL,
|
|
79
|
+
options?: WorkerOptions & { data?: TData },
|
|
80
|
+
): Operation<WorkerResource<TSend, TRecv, TReturn>> {
|
|
81
|
+
return resource(function* (provide) {
|
|
82
|
+
let outcome = withResolvers<TReturn>();
|
|
83
|
+
|
|
84
|
+
let worker = new Worker(url, options);
|
|
85
|
+
let subscription = yield* on(worker, "message");
|
|
86
|
+
|
|
87
|
+
let onclose = (event: MessageEvent) => {
|
|
88
|
+
if (event.data.type === "close") {
|
|
89
|
+
let { result } = event.data as { result: Result<TReturn> };
|
|
90
|
+
if (result.ok) {
|
|
91
|
+
outcome.resolve(result.value);
|
|
92
|
+
} else {
|
|
93
|
+
outcome.reject(result.error);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
worker.addEventListener("message", onclose);
|
|
99
|
+
|
|
100
|
+
let first = yield* subscription.next();
|
|
101
|
+
|
|
102
|
+
assert(
|
|
103
|
+
first.value.data.type === "open",
|
|
104
|
+
`expected first message to arrive from worker to be of type "open", but was: ${first.value.data.type}`,
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
yield* spawn(function* () {
|
|
108
|
+
let event = yield* once(worker, "error");
|
|
109
|
+
event.preventDefault();
|
|
110
|
+
throw event.error;
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
worker.postMessage({
|
|
115
|
+
type: "init",
|
|
116
|
+
data: options?.data,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
yield* provide({
|
|
120
|
+
*send(value) {
|
|
121
|
+
let channel = yield* useMessageChannel();
|
|
122
|
+
worker.postMessage(
|
|
123
|
+
{
|
|
124
|
+
type: "send",
|
|
125
|
+
value,
|
|
126
|
+
response: channel.port2,
|
|
127
|
+
},
|
|
128
|
+
[channel.port2],
|
|
129
|
+
);
|
|
130
|
+
channel.port1.start();
|
|
131
|
+
let event = yield* once(channel.port1, "message");
|
|
132
|
+
let result = (event as MessageEvent).data;
|
|
133
|
+
if (result.ok) {
|
|
134
|
+
return result.value;
|
|
135
|
+
}
|
|
136
|
+
throw result.error;
|
|
137
|
+
},
|
|
138
|
+
[Symbol.iterator]: outcome.operation[Symbol.iterator],
|
|
139
|
+
});
|
|
140
|
+
} finally {
|
|
141
|
+
worker.postMessage({ type: "close" });
|
|
142
|
+
yield* settled(outcome.operation);
|
|
143
|
+
worker.removeEventListener("message", onclose);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function settled<T>(operation: Operation<T>): Operation<Result<void>> {
|
|
149
|
+
return {
|
|
150
|
+
*[Symbol.iterator]() {
|
|
151
|
+
try {
|
|
152
|
+
yield* operation;
|
|
153
|
+
return Ok(void 0);
|
|
154
|
+
} catch (error) {
|
|
155
|
+
return Err(error as Error);
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
}
|
package/esm/_dnt.shims.d.ts
DELETED
package/esm/_dnt.shims.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_dnt.shims.d.ts","sourceRoot":"","sources":["../src/_dnt.shims.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa,gCAA2C,CAAC"}
|
package/esm/_dnt.shims.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
const dntGlobals = {};
|
|
2
|
-
export const dntGlobalThis = createMergeProxy(globalThis, dntGlobals);
|
|
3
|
-
function createMergeProxy(baseObj, extObj) {
|
|
4
|
-
return new Proxy(baseObj, {
|
|
5
|
-
get(_target, prop, _receiver) {
|
|
6
|
-
if (prop in extObj) {
|
|
7
|
-
return extObj[prop];
|
|
8
|
-
}
|
|
9
|
-
else {
|
|
10
|
-
return baseObj[prop];
|
|
11
|
-
}
|
|
12
|
-
},
|
|
13
|
-
set(_target, prop, value) {
|
|
14
|
-
if (prop in extObj) {
|
|
15
|
-
delete extObj[prop];
|
|
16
|
-
}
|
|
17
|
-
baseObj[prop] = value;
|
|
18
|
-
return true;
|
|
19
|
-
},
|
|
20
|
-
deleteProperty(_target, prop) {
|
|
21
|
-
let success = false;
|
|
22
|
-
if (prop in extObj) {
|
|
23
|
-
delete extObj[prop];
|
|
24
|
-
success = true;
|
|
25
|
-
}
|
|
26
|
-
if (prop in baseObj) {
|
|
27
|
-
delete baseObj[prop];
|
|
28
|
-
success = true;
|
|
29
|
-
}
|
|
30
|
-
return success;
|
|
31
|
-
},
|
|
32
|
-
ownKeys(_target) {
|
|
33
|
-
const baseKeys = Reflect.ownKeys(baseObj);
|
|
34
|
-
const extKeys = Reflect.ownKeys(extObj);
|
|
35
|
-
const extKeysSet = new Set(extKeys);
|
|
36
|
-
return [...baseKeys.filter((k) => !extKeysSet.has(k)), ...extKeys];
|
|
37
|
-
},
|
|
38
|
-
defineProperty(_target, prop, desc) {
|
|
39
|
-
if (prop in extObj) {
|
|
40
|
-
delete extObj[prop];
|
|
41
|
-
}
|
|
42
|
-
Reflect.defineProperty(baseObj, prop, desc);
|
|
43
|
-
return true;
|
|
44
|
-
},
|
|
45
|
-
getOwnPropertyDescriptor(_target, prop) {
|
|
46
|
-
if (prop in extObj) {
|
|
47
|
-
return Reflect.getOwnPropertyDescriptor(extObj, prop);
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
return Reflect.getOwnPropertyDescriptor(baseObj, prop);
|
|
51
|
-
}
|
|
52
|
-
},
|
|
53
|
-
has(_target, prop) {
|
|
54
|
-
return prop in extObj || prop in baseObj;
|
|
55
|
-
},
|
|
56
|
-
});
|
|
57
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Make an assertion that `actual` and `expected` are almost equal numbers
|
|
3
|
-
* through a given tolerance. It can be used to take into account IEEE-754
|
|
4
|
-
* double-precision floating-point representation limitations. If the values
|
|
5
|
-
* are not almost equal then throw.
|
|
6
|
-
*
|
|
7
|
-
* The default tolerance is one hundred thousandth of a percent of the
|
|
8
|
-
* expected value.
|
|
9
|
-
*
|
|
10
|
-
* @example Usage
|
|
11
|
-
* ```ts ignore
|
|
12
|
-
* import { assertAlmostEquals } from "@std/assert";
|
|
13
|
-
*
|
|
14
|
-
* assertAlmostEquals(0.01, 0.02); // Throws
|
|
15
|
-
* assertAlmostEquals(1e-8, 1e-9); // Throws
|
|
16
|
-
* assertAlmostEquals(1.000000001e-8, 1.000000002e-8); // Doesn't throw
|
|
17
|
-
* assertAlmostEquals(0.01, 0.02, 0.1); // Doesn't throw
|
|
18
|
-
* assertAlmostEquals(0.1 + 0.2, 0.3, 1e-16); // Doesn't throw
|
|
19
|
-
* assertAlmostEquals(0.1 + 0.2, 0.3, 1e-17); // Throws
|
|
20
|
-
* ```
|
|
21
|
-
*
|
|
22
|
-
* @param actual The actual value to compare.
|
|
23
|
-
* @param expected The expected value to compare.
|
|
24
|
-
* @param tolerance The tolerance to consider the values almost equal. The
|
|
25
|
-
* default is one hundred thousandth of a percent of the expected value.
|
|
26
|
-
* @param msg The optional message to include in the error.
|
|
27
|
-
*/
|
|
28
|
-
export declare function assertAlmostEquals(actual: number, expected: number, tolerance?: number, msg?: string): void;
|
|
29
|
-
//# sourceMappingURL=almost_equals.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"almost_equals.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/assert/1.0.16/almost_equals.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,EAClB,GAAG,CAAC,EAAE,MAAM,QAmBb"}
|