|
| 1 | +// Copyright 2025 International Digital Economy Academy |
| 2 | +// |
| 3 | +// Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | +// you may not use this file except in compliance with the License. |
| 5 | +// You may obtain a copy of the License at |
| 6 | +// |
| 7 | +// http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | +// |
| 9 | +// Unless required by applicable law or agreed to in writing, software |
| 10 | +// distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | +// See the License for the specific language governing permissions and |
| 13 | +// limitations under the License. |
| 14 | + |
| 15 | +///| |
| 16 | +let _ignore_unused_import : Unit = ignore(@coroutine.spawn) |
| 17 | + |
| 18 | +///| |
| 19 | +/// A JavaScript promise that resolves to a value of type `X` |
| 20 | +#external |
| 21 | +#internal(unimplemented, "unimplemented in native backend") |
| 22 | +pub type Promise[X] |
| 23 | + |
| 24 | +///| |
| 25 | +/// A JavaScript exception wrapped in MoonBit error |
| 26 | +#internal(unimplemented, "unimplemented in native backend") |
| 27 | +suberror JsError Unit |
| 28 | + |
| 29 | +///| |
| 30 | +#internal(unimplemented, "unimplemented in native backend") |
| 31 | +pub impl Show for JsError with output(self, _logger) { |
| 32 | + let JsError(x) = self |
| 33 | + let _ = JsError(x) |
| 34 | + abort("unimplemented in native backend") |
| 35 | +} |
| 36 | + |
| 37 | +///| |
| 38 | +/// A JavaScript `AbortController` used to cancel promises |
| 39 | +#external |
| 40 | +#internal(unimplemented, "unimplemented in native backend") |
| 41 | +pub type AbortController |
| 42 | + |
| 43 | +///| |
| 44 | +/// A JavaScript `AbortSignal` used to cancel promises |
| 45 | +#external |
| 46 | +#internal(unimplemented, "unimplemented in native backend") |
| 47 | +pub type AbortSignal |
| 48 | + |
| 49 | +///| |
| 50 | +/// Create a new abort controller |
| 51 | +#internal(unimplemented, "unimplemented in native backend") |
| 52 | +pub fn AbortController::new() -> AbortController { |
| 53 | + abort("unimplemented in native backend") |
| 54 | +} |
| 55 | + |
| 56 | +///| |
| 57 | +/// Get the abort signal of an abort controller. |
| 58 | +/// The abort signal will be triggered when `.abort()` is called on the controller. |
| 59 | +#internal(unimplemented, "unimplemented in native backend") |
| 60 | +pub fn AbortController::signal(self : Self) -> AbortSignal { |
| 61 | + ignore(self) |
| 62 | + abort("unimplemented in native backend") |
| 63 | +} |
| 64 | + |
| 65 | +///| |
| 66 | +/// Abort the abort controller and activate its abort signal. |
| 67 | +/// All promises tied to the signal will be cancelled. |
| 68 | +#internal(unimplemented, "unimplemented in native backend") |
| 69 | +pub fn AbortController::abort(self : Self) -> Unit { |
| 70 | + ignore(self) |
| 71 | + abort("unimplemented in native backend") |
| 72 | +} |
| 73 | + |
| 74 | +///| |
| 75 | +/// Wait for a JavaScript promise to resolve and return the fulfilled value, |
| 76 | +/// or raise an error if the promise is rejected. |
| 77 | +/// |
| 78 | +/// If `abort_controller` is provided, |
| 79 | +/// it should be an abort controller that controls the promise, |
| 80 | +/// and `.abort()` will be called on the controller automatically when `wait` is cancelled, |
| 81 | +/// cancelling the promise automatically. |
| 82 | +/// |
| 83 | +/// If `abort_controller` is absent, `wait` is non-cancellable. |
| 84 | +#internal(unimplemented, "unimplemented in native backend") |
| 85 | +pub async fn[X] Promise::wait( |
| 86 | + promise : Promise[X], |
| 87 | + abort_controller? : AbortController, |
| 88 | +) -> X { |
| 89 | + ignore(promise) |
| 90 | + ignore(abort_controller) |
| 91 | + abort("unimplemented in native backend") |
| 92 | +} |
| 93 | + |
| 94 | +///| |
| 95 | +/// Convenient helper for calling async JavaScript code from MoonBit. |
| 96 | +/// `run_promise(f)` create a fresh abort signal, passed it to `f`, |
| 97 | +/// and wait for the promise that `f` returns. |
| 98 | +/// If `f` resolve to a value, `run_promise` return that value. |
| 99 | +/// If `f` is rejected with an error, `run_promise` raise that error. |
| 100 | +/// If `run_promise` is cancelled, the abort signal passed to `f` is activated, |
| 101 | +/// and the promise returned by `f` should be cancelled automatically. |
| 102 | +/// |
| 103 | +/// `run_promise` should only be used for cancellable JavaScript code |
| 104 | +/// (i.e. the promised returned by `f` should properly handle the passed-in abort signal). |
| 105 | +/// For non-cancellable JavaScript code, use `Promise::wait()` directly. |
| 106 | +#internal(unimplemented, "unimplemented in native backend") |
| 107 | +pub async fn[X] run_promise(f : (AbortSignal) -> Promise[X]) -> X { |
| 108 | + ignore(f) |
| 109 | + abort("unimplemented in native backend") |
| 110 | +} |
| 111 | + |
| 112 | +///| |
| 113 | +/// Convert a MoonBit async function into a JavaScript promise. |
| 114 | +/// `Promise::from_async(f)` returns a promise that: |
| 115 | +/// |
| 116 | +/// - resolve to the result of `f` when `f` return |
| 117 | +/// - reject with the error that `f` raise if `f` fail |
| 118 | +/// |
| 119 | +/// If `abort_signal` is present, |
| 120 | +/// `f` will be automatically cancelled when the signal is activated, |
| 121 | +/// and the returned promise will reject with JavaScript `AbortError`. |
| 122 | +/// |
| 123 | +/// The async function `f` will be run in a global context, |
| 124 | +/// so there is no structured concurrency support for `Promise::from_async`, |
| 125 | +/// and this function should only be used for exporting MoonBit code to JavaScript. |
| 126 | +#internal(unimplemented, "unimplemented in native backend") |
| 127 | +pub fn[X] Promise::from_async( |
| 128 | + f : async () -> X, |
| 129 | + abort_signal? : AbortSignal, |
| 130 | +) -> Promise[X] { |
| 131 | + ignore(f) |
| 132 | + ignore(abort_signal) |
| 133 | + abort("unimplemented in native backend") |
| 134 | +} |
0 commit comments