'use strict';

//#region src/emnapi/async-work.js
function asyncWork (emnapiPluginCtx) {
  const { emnapiCtx, emnapiNodeBinding, emnapiAsyncWorkPoolSize } = emnapiPluginCtx;
  var mod = (function (exports, emnapi_shared, emscripten_runtime) {

    //#region src/async-work.ts
    /**
     * @__deps $emnapiCtx
     * @__deps $emnapiEnv
     * @__deps $emnapiNodeBinding
     * @__deps $emnapiAsyncWorkPoolSize
     * @__postset
     * ```
     * emnapiAWST.init();
     * ```
     */
    var emnapiAWST = {
        idGen: {},
        values: [undefined],
        queued: new Set(),
        pending: [],
        init: function () {
            const idGen = {
                nextId: 1,
                list: [],
                generate: function () {
                    let id;
                    if (idGen.list.length) {
                        id = idGen.list.shift();
                    }
                    else {
                        id = idGen.nextId;
                        idGen.nextId++;
                    }
                    return id;
                },
                reuse: function (id) {
                    idGen.list.push(id);
                }
            };
            emnapiAWST.idGen = idGen;
            emnapiAWST.values = [undefined];
            emnapiAWST.queued = new Set();
            emnapiAWST.pending = [];
        },
        create: function (env, resource, resourceName, execute, complete, data) {
            let asyncId = 0;
            let triggerAsyncId = 0;
            if (emnapiNodeBinding) {
                const asyncContext = emnapiNodeBinding.node.emitAsyncInit(resource, resourceName, -1);
                asyncId = asyncContext.asyncId;
                triggerAsyncId = asyncContext.triggerAsyncId;
            }
            const id = emnapiAWST.idGen.generate();
            emnapiAWST.values[id] = {
                env,
                id,
                resource,
                asyncId,
                triggerAsyncId,
                status: 0,
                execute,
                complete,
                data
            };
            return id;
        },
        callComplete: function (work, status) {
            const complete = work.complete;
            const env = work.env;
            const data = work.data;
            const callback = () => {
                if (!complete)
                    return;
                const envObject = emnapi_shared.emnapiEnv;
                const scope = emnapiCtx.openScope(envObject);
                try {
                    envObject.callbackIntoModule(true, () => {
                        (emnapiPluginCtx.wasmTable.get(complete))(env, status, data);
                    });
                }
                finally {
                    emnapiCtx.closeScope(envObject, scope);
                }
            };
            if (emnapiNodeBinding) {
                emnapiNodeBinding.node.makeCallback(work.resource, callback, [], {
                    asyncId: work.asyncId,
                    triggerAsyncId: work.triggerAsyncId
                });
            }
            else {
                callback();
            }
        },
        queue: function (id) {
            const work = emnapiAWST.values[id];
            if (!work)
                return;
            if (work.status === 0) {
                work.status = 1;
                if (emnapiAWST.queued.size >= (Math.abs(emnapiAsyncWorkPoolSize) || 4)) {
                    emnapiAWST.pending.push(id);
                    return;
                }
                emnapiAWST.queued.add(id);
                const env = work.env;
                const data = work.data;
                const execute = work.execute;
                work.status = 2;
                emnapiCtx.features.setImmediate(() => {
                    (emnapiPluginCtx.wasmTable.get(execute))(env, data);
                    emnapiAWST.queued.delete(id);
                    work.status = 3;
                    emnapiCtx.features.setImmediate(() => {
                        emnapiAWST.callComplete(work, 0 /* napi_status.napi_ok */);
                    });
                    if (emnapiAWST.pending.length > 0) {
                        const nextWorkId = emnapiAWST.pending.shift();
                        emnapiAWST.values[nextWorkId].status = 0;
                        emnapiAWST.queue(nextWorkId);
                    }
                });
            }
        },
        cancel: function (id) {
            const index = emnapiAWST.pending.indexOf(id);
            if (index !== -1) {
                const work = emnapiAWST.values[id];
                if (work && (work.status === 1)) {
                    work.status = 4;
                    emnapiAWST.pending.splice(index, 1);
                    emnapiCtx.features.setImmediate(() => {
                        emnapiAWST.callComplete(work, 11 /* napi_status.napi_cancelled */);
                    });
                    return 0 /* napi_status.napi_ok */;
                }
                else {
                    return 9 /* napi_status.napi_generic_failure */;
                }
            }
            return 9 /* napi_status.napi_generic_failure */;
        },
        remove: function (id) {
            const work = emnapiAWST.values[id];
            if (!work)
                return;
            if (emnapiNodeBinding) {
                emnapiNodeBinding.node.emitAsyncDestroy({
                    asyncId: work.asyncId,
                    triggerAsyncId: work.triggerAsyncId
                });
            }
            emnapiAWST.values[id] = undefined;
            emnapiAWST.idGen.reuse(id);
        }
    };

    //#endregion src/async-work.ts

    //#region src/macro.ts

    //#endregion src/macro.ts

    //#region src/core/async-work.ts
    const { 
    // onCreateWorker, napiModule, singleThreadAsyncWork, _emnapi_async_work_pool_size,
    // PThread, ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_PTHREAD, wasmInstance, _free, wasmMemory, _malloc,
    _emnapi_node_emit_async_init, _emnapi_node_emit_async_destroy, _emnapi_runtime_keepalive_pop, _emnapi_runtime_keepalive_push } = emnapiPluginCtx;
    var emnapiAWMT = {
        pool: [],
        workerReady: null,
        globalAddress: 0,
        globalOffset: {
            idle_threads: 0,
            q: 1 * 4,
            next: 1 * 4,
            prev: 2 * 4,
            mutex: 3 * 4,
            cond: 4 * 4,
            exit_message: 5 * 4,
            end: 7 * 4
        },
        offset: {
            /* napi_ref */ resource: 0,
            /* double */ async_id: 8,
            /* double */ trigger_async_id: 16,
            /* napi_env */ env: 24,
            /* int32_t */ status: 1 * 4 + 24, // 0 for pending, 1 for cancelled, 2 for completed
            queue: 2 * 4 + 24,
            queue_next: 2 * 4 + 24,
            queue_prev: 3 * 4 + 24,
            /* void* */ data: 4 * 4 + 24,
            /* napi_async_execute_callback */ execute: 5 * 4 + 24,
            /* napi_async_complete_callback */ complete: 6 * 4 + 24,
            end: 7 * 4 + 24
        },
        /**
         * When another thread grows the shared WebAssembly.Memory, this agent's
         * cached `wasmMemory.buffer` may still have the old shorter length
         * (V8 refreshes it lazily). If a pointer derived from shared memory lies
         * beyond the cached length, `wasmMemory.grow(0)` forces the agent to
         * observe the current memory size and refreshes the buffer.
         */
        ensureBufferFor(end) {
            let buffer = emscripten_runtime.wasmMemory.buffer;
            if (end > buffer.byteLength) {
                emscripten_runtime.wasmMemory.grow(0);
                buffer = emscripten_runtime.wasmMemory.buffer;
            }
            return buffer;
        },
        init() {
            emnapiAWMT.pool = [];
            emnapiAWMT.workerReady = null;
            if (typeof emscripten_runtime.PThread !== 'undefined') {
                emscripten_runtime.PThread.unusedWorkers.forEach(emnapiAWMT.addListener);
                Object.values(emscripten_runtime.PThread.pthreads).forEach(emnapiAWMT.addListener);
                const __original_getNewWorker = emscripten_runtime.PThread.getNewWorker;
                emscripten_runtime.PThread.getNewWorker = function () {
                    const r = __original_getNewWorker.apply(this, arguments);
                    emnapiAWMT.addListener(r);
                    return r;
                };
            }
        },
        addListener(worker) {
            if (!worker)
                return false;
            if (worker._emnapiAWMTListener)
                return true;
            const handler = function (e) {
                const data = emscripten_runtime.ENVIRONMENT_IS_NODE ? e : e.data;
                const __emnapi__ = data.__emnapi__;
                if (__emnapi__) {
                    const type = __emnapi__.type;
                    const payload = __emnapi__.payload;
                    if (type === 'async-work-complete') {
                        emnapiAWMT.callComplete(payload.work, 0 /* napi_status.napi_ok */);
                    }
                }
            };
            const dispose = function () {
                if (emscripten_runtime.ENVIRONMENT_IS_NODE) {
                    worker.off('message', handler);
                }
                else {
                    worker.removeEventListener('message', handler, false);
                }
                delete worker._emnapiAWMTListener;
            };
            worker._emnapiAWMTListener = { handler, dispose };
            if (emscripten_runtime.ENVIRONMENT_IS_NODE) {
                worker.on('message', handler);
            }
            else {
                worker.addEventListener('message', handler, false);
            }
            return true;
        },
        initGlobal() {
            if (!emnapiAWMT.globalAddress) {
                emnapiAWMT.globalAddress = emscripten_runtime._malloc(emnapiAWMT.globalOffset.end);
                emnapiAWMT.globalAddress >>>= 0;
                const size = emnapiAWMT.globalOffset.end;
                const addr = emnapiAWMT.globalAddress;
                new Uint8Array(emnapiAWMT.ensureBufferFor(addr + size), addr, size).fill(0);
                emnapiAWMT.queueInit(emnapiAWMT.globalAddress + emnapiAWMT.globalOffset.q);
                emnapiAWMT.queueInit(emnapiAWMT.globalAddress + emnapiAWMT.globalOffset.exit_message);
            }
        },
        terminateWorkers() {
            emnapiAWMT.pool.forEach(w => {
                w._emnapiAWMTListener?.dispose();
                w._emnapiTSFNListener?.dispose();
                w.terminate();
            });
            emnapiAWMT.pool.length = 0;
        },
        initWorkers(n) {
            if (emscripten_runtime.ENVIRONMENT_IS_PTHREAD) {
                return emnapiAWMT.workerReady || (emnapiAWMT.workerReady = Promise.resolve());
            }
            if (emnapiAWMT.workerReady)
                return emnapiAWMT.workerReady;
            if (!('emnapi_async_worker_create' in emscripten_runtime.wasmInstance.exports)) {
                throw new TypeError('`emnapi_async_worker_create` is not exported, please try to add `--export=emnapi_async_worker_create` to linker flags');
            }
            const emnapi_async_worker_create = emscripten_runtime.wasmInstance.exports.emnapi_async_worker_create;
            const args = [];
            emnapiAWMT.initGlobal();
            for (let i = 0; i < n; ++i) {
                args.push(emnapi_async_worker_create(1, emnapiAWMT.globalAddress));
            }
            const promises = args.map(index => {
                if (index === 0) {
                    return Promise.reject(new Error('Failed to create async worker'));
                }
                let worker;
                if (index < 0) {
                    worker = emnapiAWMT.pool[-index - 1];
                    if (worker)
                        return worker.whenLoaded;
                }
                index >>>= 0;
                const tidOffset = 20;
                const view = new DataView(emnapiAWMT.ensureBufferFor(index + tidOffset + 4));
                const tid = view.getInt32(index + tidOffset, true);
                worker = emscripten_runtime.PThread.pthreads[tid];
                return worker.whenLoaded;
            });
            emnapiAWMT.workerReady = Promise.all(promises);
            return emnapiAWMT.workerReady;
        },
        getResource(work) {
            emnapiAWMT.ensureBufferFor(work + emnapiAWMT.offset.resource + 4);
            var HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer), GET_HEAP_DATA_VIEW = () => HEAP_DATA_VIEW.buffer === emnapiPluginCtx.wasmMemory.buffer ? HEAP_DATA_VIEW : (HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer));
            return GET_HEAP_DATA_VIEW().getUint32(work + emnapiAWMT.offset.resource, true);
        },
        getExecute(work) {
            emnapiAWMT.ensureBufferFor(work + emnapiAWMT.offset.execute + 4);
            var HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer), GET_HEAP_DATA_VIEW = () => HEAP_DATA_VIEW.buffer === emnapiPluginCtx.wasmMemory.buffer ? HEAP_DATA_VIEW : (HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer));
            return GET_HEAP_DATA_VIEW().getUint32(work + emnapiAWMT.offset.execute, true);
        },
        getComplete(work) {
            emnapiAWMT.ensureBufferFor(work + emnapiAWMT.offset.complete + 4);
            var HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer), GET_HEAP_DATA_VIEW = () => HEAP_DATA_VIEW.buffer === emnapiPluginCtx.wasmMemory.buffer ? HEAP_DATA_VIEW : (HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer));
            return GET_HEAP_DATA_VIEW().getUint32(work + emnapiAWMT.offset.complete, true);
        },
        getEnv(work) {
            emnapiAWMT.ensureBufferFor(work + emnapiAWMT.offset.env + 4);
            var HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer), GET_HEAP_DATA_VIEW = () => HEAP_DATA_VIEW.buffer === emnapiPluginCtx.wasmMemory.buffer ? HEAP_DATA_VIEW : (HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer));
            return GET_HEAP_DATA_VIEW().getUint32(work + emnapiAWMT.offset.env, true);
        },
        getData(work) {
            emnapiAWMT.ensureBufferFor(work + emnapiAWMT.offset.data + 4);
            var HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer), GET_HEAP_DATA_VIEW = () => HEAP_DATA_VIEW.buffer === emnapiPluginCtx.wasmMemory.buffer ? HEAP_DATA_VIEW : (HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer));
            return GET_HEAP_DATA_VIEW().getUint32(work + emnapiAWMT.offset.data, true);
        },
        getMutex() {
            const index = emnapiAWMT.globalAddress + emnapiAWMT.globalOffset.mutex;
            const mutex = {
                lock() {
                    const isBrowserMain = typeof window !== 'undefined' && typeof document !== 'undefined' && !emscripten_runtime.ENVIRONMENT_IS_NODE;
                    const i32a = new Int32Array(emnapiAWMT.ensureBufferFor(index + 4), index, 1);
                    if (isBrowserMain) {
                        while (true) {
                            const oldValue = Atomics.compareExchange(i32a, 0, 0, 10);
                            if (oldValue === 0) {
                                return;
                            }
                        }
                    }
                    else {
                        while (true) {
                            const oldValue = Atomics.compareExchange(i32a, 0, 0, 10);
                            if (oldValue === 0) {
                                return;
                            }
                            Atomics.wait(i32a, 0, 10);
                        }
                    }
                },
                unlock() {
                    const i32a = new Int32Array(emnapiAWMT.ensureBufferFor(index + 4), index, 1);
                    const oldValue = Atomics.compareExchange(i32a, 0, 10, 0);
                    if (oldValue !== 10) {
                        throw new Error('Tried to unlock while not holding the mutex');
                    }
                    Atomics.notify(i32a, 0, 1);
                },
                execute(fn) {
                    mutex.lock();
                    try {
                        return fn();
                    }
                    finally {
                        mutex.unlock();
                    }
                }
            };
            return mutex;
        },
        getCond() {
            const index = emnapiAWMT.globalAddress + emnapiAWMT.globalOffset.cond;
            const mutex = emnapiAWMT.getMutex();
            const cond = {
                wait() {
                    const i32a = new Int32Array(emnapiAWMT.ensureBufferFor(index + 4), index, 1);
                    const value = Atomics.load(i32a, 0);
                    mutex.unlock();
                    Atomics.wait(i32a, 0, value);
                    mutex.lock();
                },
                signal() {
                    const i32a = new Int32Array(emnapiAWMT.ensureBufferFor(index + 4), index, 1);
                    Atomics.add(i32a, 0, 1);
                    Atomics.notify(i32a, 0, 1);
                }
            };
            return cond;
        },
        queueInit(q) {
            emnapiAWMT.ensureBufferFor(q + 4 + 4);
            var HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer), GET_HEAP_DATA_VIEW = () => HEAP_DATA_VIEW.buffer === emnapiPluginCtx.wasmMemory.buffer ? HEAP_DATA_VIEW : (HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer));
            GET_HEAP_DATA_VIEW().setUint32(q, q, true);
            GET_HEAP_DATA_VIEW().setUint32(q + 4, q, true);
        },
        queueInsertTail(h, q) {
            emnapiAWMT.ensureBufferFor(h + 4 + 4);
            emnapiAWMT.ensureBufferFor(q + 4 + 4);
            var HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer), GET_HEAP_DATA_VIEW = () => HEAP_DATA_VIEW.buffer === emnapiPluginCtx.wasmMemory.buffer ? HEAP_DATA_VIEW : (HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer));
            GET_HEAP_DATA_VIEW().setUint32(q, h, true);
            const tempValue = GET_HEAP_DATA_VIEW().getUint32(h + 4, true);
            GET_HEAP_DATA_VIEW().setUint32(q + 4, tempValue, true);
            const qprev = GET_HEAP_DATA_VIEW().getUint32(q + 4, true);
            GET_HEAP_DATA_VIEW().setUint32(qprev, q, true);
            GET_HEAP_DATA_VIEW().setUint32(h + 4, q, true);
        },
        queueRemove(q) {
            emnapiAWMT.ensureBufferFor(q + 4 + 4);
            var HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer), GET_HEAP_DATA_VIEW = () => HEAP_DATA_VIEW.buffer === emnapiPluginCtx.wasmMemory.buffer ? HEAP_DATA_VIEW : (HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer));
            const qprev = GET_HEAP_DATA_VIEW().getUint32(q + 4, true);
            const qnext = GET_HEAP_DATA_VIEW().getUint32(q, true);
            GET_HEAP_DATA_VIEW().setUint32(qprev, qnext, true);
            GET_HEAP_DATA_VIEW().setUint32(qnext + 4, qprev, true);
        },
        queueEmpty(q) {
            emnapiAWMT.ensureBufferFor(q + 4);
            var HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer), GET_HEAP_DATA_VIEW = () => HEAP_DATA_VIEW.buffer === emnapiPluginCtx.wasmMemory.buffer ? HEAP_DATA_VIEW : (HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer));
            // eslint-disable-next-line eqeqeq
            return q == GET_HEAP_DATA_VIEW().getUint32(q, true);
        },
        scheduleWork: function (work) {
            if (!emnapiAWMT.workerReady?.ready) {
                emnapiAWMT.initWorkers(emnapi_shared._emnapi_async_work_pool_size()).then(() => {
                    emnapiAWMT.workerReady.ready = true;
                }).catch((err) => {
                    emnapiAWMT.workerReady = null;
                    throw err;
                });
            }
            _emnapi_runtime_keepalive_push();
            emnapiCtx.increaseWaitingRequestCounter();
            const statusBuffer = new Int32Array(emnapiAWMT.ensureBufferFor(work + emnapiAWMT.offset.status + 4), work + emnapiAWMT.offset.status, 1);
            Atomics.store(statusBuffer, 0, 0 /* AsyncWorkStatus.Pending */);
            const mutex = emnapiAWMT.getMutex();
            const cond = emnapiAWMT.getCond();
            mutex.lock();
            try {
                emnapiAWMT.queueInsertTail(emnapiAWMT.globalAddress + emnapiAWMT.globalOffset.q, work + emnapiAWMT.offset.queue);
            }
            catch (err) {
                _emnapi_runtime_keepalive_pop();
                emnapiCtx.decreaseWaitingRequestCounter();
                mutex.unlock();
                throw err;
            }
            emnapiAWMT.ensureBufferFor(emnapiAWMT.globalAddress + emnapiAWMT.globalOffset.idle_threads + 4);
            var HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer), GET_HEAP_DATA_VIEW = () => HEAP_DATA_VIEW.buffer === emnapiPluginCtx.wasmMemory.buffer ? HEAP_DATA_VIEW : (HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer));
            if (GET_HEAP_DATA_VIEW().getUint32(emnapiAWMT.globalAddress + emnapiAWMT.globalOffset.idle_threads, true) > 0) {
                cond.signal();
            }
            mutex.unlock();
        },
        cancelWork(work) {
            let cancelled = false;
            emnapiAWMT.getMutex().execute(() => {
                emnapiAWMT.ensureBufferFor(work + emnapiAWMT.offset.status + 4);
                var HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer), GET_HEAP_DATA_VIEW = () => HEAP_DATA_VIEW.buffer === emnapiPluginCtx.wasmMemory.buffer ? HEAP_DATA_VIEW : (HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer));
                cancelled = !emnapiAWMT.queueEmpty(work + emnapiAWMT.offset.queue) && GET_HEAP_DATA_VIEW().getInt32(work + emnapiAWMT.offset.status, true) !== 2 /* AsyncWorkStatus.Completed */;
                if (cancelled) {
                    emnapiAWMT.queueRemove(work + emnapiAWMT.offset.queue);
                }
            });
            if (!cancelled) {
                return 9 /* napi_status.napi_generic_failure */;
            }
            if (Atomics.compareExchange(new Int32Array(emnapiAWMT.ensureBufferFor(work + emnapiAWMT.offset.status + 4), work + emnapiAWMT.offset.status, 1), 0, 0 /* AsyncWorkStatus.Pending */, 1 /* AsyncWorkStatus.Cancelled */) !== 0 /* AsyncWorkStatus.Pending */) {
                return 9 /* napi_status.napi_generic_failure */;
            }
            emnapiCtx.features.setImmediate(() => {
                emnapiAWMT.callComplete(work, 11 /* napi_status.napi_cancelled */);
            });
            return 0 /* napi_status.napi_ok */;
        },
        callComplete: function (work, status) {
            _emnapi_runtime_keepalive_pop();
            emnapiCtx.decreaseWaitingRequestCounter();
            const complete = emnapiAWMT.getComplete(work);
            const env = emnapiAWMT.getEnv(work);
            const data = emnapiAWMT.getData(work);
            const envObject = emnapi_shared.emnapiEnv;
            const scope = emnapiCtx.openScope(envObject);
            const callback = () => {
                if (!complete)
                    return;
                envObject.callbackIntoModule(true, () => {
                    (emnapiPluginCtx.wasmTable.get(complete))(env, status, data);
                });
            };
            try {
                if (emnapiNodeBinding) {
                    const resource = emnapiAWMT.getResource(work);
                    const resource_value = emnapiCtx.getRef(resource).get();
                    const resourceObject = emnapiCtx.jsValueFromNapiValue(resource_value);
                    const view = new DataView(emnapiAWMT.ensureBufferFor(work + emnapiAWMT.offset.trigger_async_id + 8));
                    const asyncId = view.getFloat64(work + emnapiAWMT.offset.async_id, true);
                    const triggerAsyncId = view.getFloat64(work + emnapiAWMT.offset.trigger_async_id, true);
                    emnapiNodeBinding.node.makeCallback(resourceObject, callback, [], {
                        asyncId,
                        triggerAsyncId
                    });
                }
                else {
                    callback();
                }
            }
            finally {
                emnapiCtx.closeScope(envObject, scope);
            }
        }
    };
    emnapiAWST.init();
    emnapiAWMT.init();
    /** @__sig ippppppp */
    var napi_create_async_work = emnapi_shared.singleThreadAsyncWork
        ? function (env, resource, resource_name, execute, complete, data, result) {
            if (!env)
                return 1 /* napi_status.napi_invalid_arg */;
            // @ts-expect-error
            const envObject = emnapi_shared.emnapiEnv;
            envObject.checkGCAccess();
            if (!execute)
                return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
            if (!result)
                return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
            let resourceObject;
            if (resource) {
                resourceObject = Object(emnapiCtx.jsValueFromNapiValue(resource));
            }
            else {
                resourceObject = {};
            }
            if (!resource_name)
                return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
            const resourceName = String(emnapiCtx.jsValueFromNapiValue(resource_name));
            const id = emnapiAWST.create(env, resourceObject, resourceName, execute, complete, data);
            result >>>= 0;
            var HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer), GET_HEAP_DATA_VIEW = () => HEAP_DATA_VIEW.buffer === emnapiPluginCtx.wasmMemory.buffer ? HEAP_DATA_VIEW : (HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer));
            GET_HEAP_DATA_VIEW().setUint32(result, id, true);
            return envObject.clearLastError();
        }
        : function (env, resource, resource_name, execute, complete, data, result) {
            if (!env)
                return 1 /* napi_status.napi_invalid_arg */;
            // @ts-expect-error
            const envObject = emnapi_shared.emnapiEnv;
            envObject.checkGCAccess();
            if (!execute)
                return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
            if (!result)
                return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
            let resourceObject;
            if (resource) {
                resourceObject = Object(emnapiCtx.jsValueFromNapiValue(resource));
            }
            else {
                resourceObject = {};
            }
            if (!resource_name)
                return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
            const sizeofAW = emnapiAWMT.offset.end;
            let aw = emscripten_runtime._malloc(sizeofAW);
            if (!aw)
                return envObject.setLastError(9 /* napi_status.napi_generic_failure */);
            aw >>>= 0;
            new Uint8Array(emnapiAWMT.ensureBufferFor(aw + sizeofAW)).subarray(aw, aw + sizeofAW).fill(0);
            const s = emnapiCtx.napiValueFromJsValue(resourceObject);
            const resourceRef = emnapiCtx.createReference(envObject, s, 1, 1 /* ReferenceOwnership.kUserland */);
            const resource_ = resourceRef.id;
            var HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer), GET_HEAP_DATA_VIEW = () => HEAP_DATA_VIEW.buffer === emnapiPluginCtx.wasmMemory.buffer ? HEAP_DATA_VIEW : (HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer));
            GET_HEAP_DATA_VIEW().setUint32(aw, resource_, true);
            _emnapi_node_emit_async_init(s, resource_name, -1, aw + emnapiAWMT.offset.async_id);
            GET_HEAP_DATA_VIEW().setUint32(aw + emnapiAWMT.offset.env, env, true);
            GET_HEAP_DATA_VIEW().setUint32(aw + emnapiAWMT.offset.execute, execute, true);
            GET_HEAP_DATA_VIEW().setUint32(aw + emnapiAWMT.offset.complete, complete, true);
            GET_HEAP_DATA_VIEW().setUint32(aw + emnapiAWMT.offset.data, data, true);
            emnapiAWMT.queueInit(aw + emnapiAWMT.offset.queue);
            result >>>= 0;
            GET_HEAP_DATA_VIEW().setUint32(result, aw, true);
            return envObject.clearLastError();
        };
    /** @__sig ipp */
    var napi_delete_async_work = emnapi_shared.singleThreadAsyncWork
        ? function (env, work) {
            if (!env)
                return 1 /* napi_status.napi_invalid_arg */;
            // @ts-expect-error
            const envObject = emnapi_shared.emnapiEnv;
            envObject.checkGCAccess();
            if (!work)
                return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
            work >>>= 0;
            emnapiAWST.remove(work);
            return envObject.clearLastError();
        }
        : function (env, work) {
            if (!env)
                return 1 /* napi_status.napi_invalid_arg */;
            // @ts-expect-error
            const envObject = emnapi_shared.emnapiEnv;
            envObject.checkGCAccess();
            if (!work)
                return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
            work >>>= 0;
            const resource = emnapiAWMT.getResource(work);
            emnapiCtx.getRef(resource).dispose();
            if (emnapiNodeBinding) {
                const view = new DataView(emnapiAWMT.ensureBufferFor(work + emnapiAWMT.offset.trigger_async_id + 8));
                const asyncId = view.getFloat64(work + emnapiAWMT.offset.async_id, true);
                const triggerAsyncId = view.getFloat64(work + emnapiAWMT.offset.trigger_async_id, true);
                _emnapi_node_emit_async_destroy(asyncId, triggerAsyncId);
            }
            emscripten_runtime._free(work);
            return envObject.clearLastError();
        };
    /** @__sig ipp */
    var napi_queue_async_work = emnapi_shared.singleThreadAsyncWork
        ? function (env, work) {
            if (!env)
                return 1 /* napi_status.napi_invalid_arg */;
            const envObject = emnapi_shared.emnapiEnv;
            if (!work)
                return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
            work >>>= 0;
            emnapiAWST.queue(work);
            return envObject.clearLastError();
        }
        : function (env, work) {
            if (!env)
                return 1 /* napi_status.napi_invalid_arg */;
            const envObject = emnapi_shared.emnapiEnv;
            if (!work)
                return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
            work >>>= 0;
            emnapiAWMT.scheduleWork(work);
            return envObject.clearLastError();
        };
    /** @__sig ipp */
    var napi_cancel_async_work = emnapi_shared.singleThreadAsyncWork
        ? function (env, work) {
            if (!env)
                return 1 /* napi_status.napi_invalid_arg */;
            const envObject = emnapi_shared.emnapiEnv;
            if (!work)
                return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
            work >>>= 0;
            const status = emnapiAWST.cancel(work);
            if (status === 0 /* napi_status.napi_ok */)
                return envObject.clearLastError();
            return envObject.setLastError(status);
        }
        : function (env, work) {
            if (!env)
                return 1 /* napi_status.napi_invalid_arg */;
            const envObject = emnapi_shared.emnapiEnv;
            if (!work)
                return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
            work >>>= 0;
            const status = emnapiAWMT.cancelWork(work);
            if (status === 0 /* napi_status.napi_ok */)
                return envObject.clearLastError();
            return envObject.setLastError(status);
        };
    /** @__sig pp */
    function _emnapi_async_worker(globalAddress) {
        globalAddress >>>= 0;
        emnapiAWMT.globalAddress = globalAddress;
        const mutex = emnapiAWMT.getMutex();
        const cond = emnapiAWMT.getCond();
        mutex.lock();
        const exitMessageAddr = globalAddress + emnapiAWMT.globalOffset.exit_message;
        const idleThreadsAddr = globalAddress + emnapiAWMT.globalOffset.idle_threads;
        const workerQueueAddr = globalAddress + emnapiAWMT.globalOffset.q;
        var HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer), GET_HEAP_DATA_VIEW = () => HEAP_DATA_VIEW.buffer === emnapiPluginCtx.wasmMemory.buffer ? HEAP_DATA_VIEW : (HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer));
        for (;;) {
            emnapiAWMT.ensureBufferFor(workerQueueAddr + 4);
            while (emnapiAWMT.queueEmpty(workerQueueAddr)) {
                Atomics.add(new Int32Array(emnapiAWMT.ensureBufferFor(idleThreadsAddr + 4), idleThreadsAddr, 1), 0, 1);
                cond.wait();
                Atomics.sub(new Int32Array(emnapiAWMT.ensureBufferFor(idleThreadsAddr + 4), idleThreadsAddr, 1), 0, 1);
            }
            const q = GET_HEAP_DATA_VIEW().getUint32(workerQueueAddr, true);
            if (q === exitMessageAddr) {
                cond.signal();
                mutex.unlock();
                break;
            }
            const work = q - emnapiAWMT.offset.queue;
            emnapiAWMT.queueRemove(q);
            emnapiAWMT.queueInit(q);
            mutex.unlock();
            const statusBuffer = new Int32Array(emnapiAWMT.ensureBufferFor(work + emnapiAWMT.offset.status + 4), work + emnapiAWMT.offset.status, 1);
            if (Atomics.load(statusBuffer, 0) === 1 /* AsyncWorkStatus.Cancelled */) {
                emscripten_runtime.abort('unreachable');
            }
            const execute = emnapiAWMT.getExecute(work);
            const env = emnapiAWMT.getEnv(work);
            const data = emnapiAWMT.getData(work);
            (emnapiPluginCtx.wasmTable.get(execute))(env, data);
            Atomics.store(statusBuffer, 0, 2 /* AsyncWorkStatus.Completed */);
            const postMessage = emnapi_shared.napiModule.postMessage;
            postMessage({
                __emnapi__: {
                    type: 'async-work-complete',
                    payload: { work }
                }
            });
            mutex.lock();
        }
        return 0;
    }
    /** @__sig ipp */
    function _emnapi_spawn_worker(f, globalAddress) {
        if (typeof emnapi_shared.onCreateWorker !== 'function') {
            throw new TypeError('`options.onCreateWorker` is not a function');
        }
        const promises = [];
        const args = [];
        if (!('emnapi_async_worker_create' in emscripten_runtime.wasmInstance.exports)) {
            throw new TypeError('`emnapi_async_worker_create` is not exported, please try to add `--export=emnapi_async_worker_create` to linker flags');
        }
        args.push(emscripten_runtime.wasmInstance.exports.emnapi_async_worker_create(0, 0));
        const handleError = (e) => {
            if ('message' in e && (e.message.indexOf('RuntimeError') !== -1 || e.message.indexOf('unreachable') !== -1)) {
                emnapiAWMT.terminateWorkers();
            }
        };
        let ret;
        try {
            const worker = emnapi_shared.onCreateWorker({ type: 'async-work', name: 'emnapi-async-worker' });
            const p = emscripten_runtime.PThread.loadWasmModuleToWorker(worker);
            if (emscripten_runtime.ENVIRONMENT_IS_NODE) {
                worker.on('error', handleError);
            }
            else {
                worker.addEventListener('error', handleError, false);
            }
            emnapiAWMT.addListener(worker);
            if (typeof emnapiPluginCtx.emnapiTSFN !== 'undefined') {
                emnapiPluginCtx.emnapiTSFN.addListener(worker);
            }
            promises.push(p.then(() => {
                if (typeof worker.unref === 'function') {
                    worker.unref();
                }
            }));
            ret = emnapiAWMT.pool.push(worker) - 1;
            const arg = args[0];
            worker.threadBlockBase = arg;
            worker.postMessage({
                __emnapi__: {
                    type: 'async-worker-init',
                    payload: { arg, func: [f, globalAddress] }
                }
            });
        }
        catch (err) {
            const arg = args[0];
            emscripten_runtime._free(arg);
            throw err;
        }
        return ret;
    }
    function initWorker(startArg, func) {
        if (emnapi_shared.napiModule.childThread) {
            if (typeof emscripten_runtime.wasmInstance.exports.emnapi_async_worker_init !== 'function') {
                throw new TypeError('`emnapi_async_worker_init` is not exported, please try to add `--export=emnapi_async_worker_init` to linker flags');
            }
            emscripten_runtime.wasmInstance.exports.emnapi_async_worker_init(startArg);
            (emnapiPluginCtx.wasmTable.get(func[0]))(func[1]);
        }
        else {
            throw new Error('startThread is only available in child threads');
        }
    }
    emnapi_shared.napiModule.initWorker = initWorker;

    //#endregion src/core/async-work.ts

    exports._emnapi_async_worker = _emnapi_async_worker;
    exports._emnapi_spawn_worker = _emnapi_spawn_worker;
    exports.napi_cancel_async_work = napi_cancel_async_work;
    exports.napi_create_async_work = napi_create_async_work;
    exports.napi_delete_async_work = napi_delete_async_work;
    exports.napi_queue_async_work = napi_queue_async_work;

    return exports;

})({}, emnapiPluginCtx, emnapiPluginCtx);
  return {
    importObject: (original) => {

      Object.keys(mod).forEach(key => {
        if (key.startsWith('napi_') || key.startsWith('node_api_')) {
          original.napi[key] = mod[key];
        } else {
          original.env[key] = mod[key];
        }
      });
    }
  };
}

//#region src/emnapi/threadsafe-function.js
function threadsafeFunction (emnapiPluginCtx) {
  const { emnapiCtx, emnapiNodeBinding, _emnapi_node_emit_async_destroy: __emnapi_node_emit_async_destroy, _emnapi_node_emit_async_init: __emnapi_node_emit_async_init, _emnapi_runtime_keepalive_pop: __emnapi_runtime_keepalive_pop, _emnapi_runtime_keepalive_push: __emnapi_runtime_keepalive_push } = emnapiPluginCtx;
  var mod = (function (exports, emnapi_shared, emscripten_runtime) {

    //#region src/macro.ts

    //#endregion src/macro.ts

    //#region src/threadsafe-function.ts
    /* eslint-disable @stylistic/indent */
    /**
     * @__deps malloc
     * @__deps free
     * @__deps $emnapiCtx
     * @__deps $emnapiEnv
     * @__deps $emnapiNodeBinding
     * @__deps _emnapi_node_emit_async_destroy
     * @__deps _emnapi_runtime_keepalive_pop
     * @__postset
     * ```
     * emnapiTSFN.init();
     * ```
     */
    const emnapiTSFN = {
        _liveSet: {},
        offset: {
            __size__: 0,
            /* napi_ref */ resource: 0,
            /* double */ async_id: 0,
            /* double */ trigger_async_id: 0,
            /* size_t */ queue_size: 0,
            /* bool */ is_some: 0,
            /* void* */ queue: 0,
            // Reuse uv_async_t storage as JS-side wakeup state: pending event + scheduled drain.
            async_pending: 0,
            async_u_fd: 0,
            /* size_t */ thread_count: 0,
            /* int32_t */ state: 0,
            /* atomic_uchar */ dispatch_state: 0,
            /* void* */ context: 0,
            /* size_t */ max_queue_size: 0,
            /* napi_ref */ ref: 0,
            /* napi_env */ env: 0,
            /* void* */ finalize_data: 0,
            /* napi_finalize */ finalize_cb: 0,
            /* napi_threadsafe_function_call_js */ call_js_cb: 0,
            /* bool */ handles_closing: 0,
            /* bool */ async_ref: 0,
            /* int32_t */ mutex: 0,
            /* int32_t */ cond: 0,
        },
        init() {
            emnapiTSFN._liveSet = new Set();
            emnapiTSFN.offset.__size__ = 184 /* NapiTSFNOffset32.__size__ */;
            emnapiTSFN.offset.resource = 0 /* NapiTSFNOffset32.async_resource_resource */;
            emnapiTSFN.offset.async_id = 8 /* NapiTSFNOffset32.async_resource_async_context_async_id */;
            emnapiTSFN.offset.trigger_async_id = 16 /* NapiTSFNOffset32.async_resource_async_context_trigger_async_id */;
            emnapiTSFN.offset.queue_size = 60 /* NapiTSFNOffset32.queue_size */;
            emnapiTSFN.offset.is_some = 24 /* NapiTSFNOffset32.async_resource_is_some */;
            emnapiTSFN.offset.queue = 64 /* NapiTSFNOffset32.queue */;
            emnapiTSFN.offset.async_pending = 132 /* NapiTSFNOffset32.async_pending */;
            emnapiTSFN.offset.async_u_fd = 96 /* NapiTSFNOffset32.async_u_fd */;
            emnapiTSFN.offset.thread_count = 136 /* NapiTSFNOffset32.thread_count */;
            emnapiTSFN.offset.state = 140 /* NapiTSFNOffset32.state */;
            emnapiTSFN.offset.dispatch_state = 144 /* NapiTSFNOffset32.dispatch_state */;
            emnapiTSFN.offset.context = 148 /* NapiTSFNOffset32.context */;
            emnapiTSFN.offset.max_queue_size = 152 /* NapiTSFNOffset32.max_queue_size */;
            emnapiTSFN.offset.ref = 156 /* NapiTSFNOffset32.ref */;
            emnapiTSFN.offset.env = 160 /* NapiTSFNOffset32.env */;
            emnapiTSFN.offset.finalize_data = 164 /* NapiTSFNOffset32.finalize_data */;
            emnapiTSFN.offset.finalize_cb = 168 /* NapiTSFNOffset32.finalize_cb */;
            emnapiTSFN.offset.call_js_cb = 172 /* NapiTSFNOffset32.call_js_cb */;
            emnapiTSFN.offset.handles_closing = 176 /* NapiTSFNOffset32.handles_closing */;
            emnapiTSFN.offset.async_ref = 180 /* NapiTSFNOffset32.async_ref */;
            emnapiTSFN.offset.mutex = 32 /* NapiTSFNOffset32.mutex */;
            emnapiTSFN.offset.cond = 56 /* NapiTSFNOffset32.cond */;
            emnapiTSFN.offset.mutex = emnapiTSFN.offset.mutex + 4;
            if (typeof emscripten_runtime.PThread !== 'undefined') {
                emscripten_runtime.PThread.unusedWorkers.forEach(emnapiTSFN.addListener);
                Object.values(emscripten_runtime.PThread.pthreads).forEach(emnapiTSFN.addListener);
                const __original_getNewWorker = emscripten_runtime.PThread.getNewWorker;
                emscripten_runtime.PThread.getNewWorker = function () {
                    const r = __original_getNewWorker.apply(this, arguments);
                    emnapiTSFN.addListener(r);
                    return r;
                };
            }
        },
        addListener(worker) {
            if (!worker)
                return false;
            if (worker._emnapiTSFNListener)
                return true;
            const handler = function (e) {
                const data = emscripten_runtime.ENVIRONMENT_IS_NODE ? e : e.data;
                const __emnapi__ = data.__emnapi__;
                if (__emnapi__) {
                    const type = __emnapi__.type;
                    const payload = __emnapi__.payload;
                    if (type === 'tsfn-send') {
                        const pendng = payload.tsfn + emnapiTSFN.offset.async_pending;
                        if (Atomics.load(new Int32Array(emnapiTSFN.ensureBufferFor(pendng + 4)), pendng >>> 2) !== 0) {
                            emnapiTSFN.enqueue(payload.tsfn);
                        }
                    }
                }
            };
            const dispose = function () {
                if (emscripten_runtime.ENVIRONMENT_IS_NODE) {
                    worker.off('message', handler);
                }
                else {
                    worker.removeEventListener('message', handler, false);
                }
                delete worker._emnapiTSFNListener;
            };
            worker._emnapiTSFNListener = { handler, dispose };
            if (emscripten_runtime.ENVIRONMENT_IS_NODE) {
                worker.on('message', handler);
            }
            else {
                worker.addEventListener('message', handler, false);
            }
            return true;
        },
        /**
         * When another thread grows the shared WebAssembly.Memory, this agent's
         * cached `wasmMemory.buffer` may still have the old shorter length
         * (V8 refreshes it lazily). If a pointer derived from shared memory lies
         * beyond the cached length, `wasmMemory.grow(0)` forces the agent to
         * observe the current memory size and refreshes the buffer.
         */
        ensureBufferFor(end) {
            let buffer = emscripten_runtime.wasmMemory.buffer;
            if (end > buffer.byteLength) {
                emscripten_runtime.wasmMemory.grow(0);
                buffer = emscripten_runtime.wasmMemory.buffer;
            }
            return buffer;
        },
        initQueue(func) {
            const size = 2 * 4;
            let queue = emscripten_runtime._malloc(size);
            if (!queue)
                return false;
            queue >>>= 0;
            new Uint8Array(emnapiTSFN.ensureBufferFor(queue + size), queue, size).fill(0);
            emnapiTSFN.storeSizeTypeValue(func + emnapiTSFN.offset.queue, queue, false);
            return true;
        },
        destroyQueue(func) {
            const queue = emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.queue, false);
            if (queue) {
                let node = emnapiTSFN.loadSizeTypeValue(queue, false);
                while (node !== 0) {
                    const next = emnapiTSFN.loadSizeTypeValue(node + 4, false);
                    emscripten_runtime._free(node);
                    node = next;
                }
                emscripten_runtime._free(queue);
            }
        },
        pushQueue(func, data) {
            const queue = emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.queue, false);
            const head = emnapiTSFN.loadSizeTypeValue(queue, false);
            const tail = emnapiTSFN.loadSizeTypeValue(queue + 4, false);
            const size = 2 * 4;
            let node = emscripten_runtime._malloc(size);
            if (!node)
                throw new Error('OOM');
            node >>>= 0;
            emnapiTSFN.storeSizeTypeValue(node, data, false);
            emnapiTSFN.storeSizeTypeValue(node + 4, 0, false);
            if (head === 0 && tail === 0) {
                emnapiTSFN.storeSizeTypeValue(queue, node, false);
                emnapiTSFN.storeSizeTypeValue(queue + 4, node, false);
            }
            else {
                emnapiTSFN.storeSizeTypeValue(tail + 4, node, false);
                emnapiTSFN.storeSizeTypeValue(queue + 4, node, false);
            }
            emnapiTSFN.addQueueSize(func);
        },
        shiftQueue(func) {
            const queue = emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.queue, false);
            const head = emnapiTSFN.loadSizeTypeValue(queue, false);
            if (head === 0)
                return 0;
            const node = head;
            const next = emnapiTSFN.loadSizeTypeValue(head + 4, false);
            emnapiTSFN.storeSizeTypeValue(queue, next, false);
            if (next === 0) {
                emnapiTSFN.storeSizeTypeValue(queue + 4, 0, false);
            }
            emnapiTSFN.storeSizeTypeValue(node + 4, 0, false);
            const value = emnapiTSFN.loadSizeTypeValue(node, false);
            emscripten_runtime._free(node);
            emnapiTSFN.subQueueSize(func);
            return value;
        },
        push(func, data, mode) {
            const mutex = emnapiTSFN.getMutex(func);
            const cond = emnapiTSFN.getCond(func);
            const waitCondition = () => {
                const queueSize = emnapiTSFN.getQueueSize(func);
                const maxSize = emnapiTSFN.getMaxQueueSize(func);
                return queueSize >= maxSize && maxSize > 0 && emnapiTSFN.getState(func) === 0 /* State.kOpen */;
            };
            const isBrowserMain = typeof window !== 'undefined' && typeof document !== 'undefined' && !emscripten_runtime.ENVIRONMENT_IS_NODE;
            let shouldDelete = false;
            const ret = mutex.execute(() => {
                while (waitCondition()) {
                    if (mode === 0 /* napi_threadsafe_function_call_mode.napi_tsfn_nonblocking */) {
                        return 15 /* napi_status.napi_queue_full */;
                    }
                    /**
                     * Browser JS main thread can not use `Atomics.wait`
                     *
                     * Related:
                     * https://github.com/nodejs/node/pull/32689
                     * https://github.com/nodejs/node/pull/33453
                     */
                    if (isBrowserMain) {
                        return 21 /* napi_status.napi_would_deadlock */;
                    }
                    cond.wait();
                }
                if (emnapiTSFN.getState(func) === 0 /* State.kOpen */) {
                    emnapiTSFN.pushQueue(func, data);
                    emnapiTSFN.send(func);
                    return 0 /* napi_status.napi_ok */;
                }
                if (emnapiTSFN.getThreadCount(func) === 0) {
                    return 1 /* napi_status.napi_invalid_arg */;
                }
                emnapiTSFN.subThreadCount(func);
                if (!(emnapiTSFN.getState(func) === 2 /* State.kClosed */ && emnapiTSFN.getThreadCount(func) === 0)) {
                    return 16 /* napi_status.napi_closing */;
                }
                shouldDelete = true;
                return 16 /* napi_status.napi_closing */;
            });
            if (shouldDelete) {
                emnapiTSFN.destroy(func);
            }
            return ret;
        },
        getMutex(func) {
            const index = func + emnapiTSFN.offset.mutex;
            const mutex = {
                lock() {
                    const isBrowserMain = typeof window !== 'undefined' && typeof document !== 'undefined' && !emscripten_runtime.ENVIRONMENT_IS_NODE;
                    const i32a = new Int32Array(emnapiTSFN.ensureBufferFor(index + 4), index, 1);
                    if (isBrowserMain) {
                        while (true) {
                            const oldValue = Atomics.compareExchange(i32a, 0, 0, 10);
                            if (oldValue === 0) {
                                return;
                            }
                        }
                    }
                    else {
                        while (true) {
                            const oldValue = Atomics.compareExchange(i32a, 0, 0, 10);
                            if (oldValue === 0) {
                                return;
                            }
                            Atomics.wait(i32a, 0, 10);
                        }
                    }
                },
                /* lockAsync () {
                  return new Promise<void>(resolve => {
                    const again = (): void => { fn() }
                    const fn = (): void => {
                      const i32a = new Int32Array(emnapiTSFN.ensureBufferFor(index + 4), index, 1)
                      const oldValue = Atomics.compareExchange(i32a, 0, 0, 10)
                      if (oldValue === 0) {
                        resolve()
                        return
                      }
                      (Atomics as any).waitAsync(i32a, 0, 10).value.then(again)
                    }
                    fn()
                  })
                }, */
                unlock() {
                    const i32a = new Int32Array(emnapiTSFN.ensureBufferFor(index + 4), index, 1);
                    const oldValue = Atomics.compareExchange(i32a, 0, 10, 0);
                    if (oldValue !== 10) {
                        throw new Error('Tried to unlock while not holding the mutex');
                    }
                    Atomics.notify(i32a, 0, 1);
                },
                execute(fn) {
                    mutex.lock();
                    try {
                        return fn();
                    }
                    finally {
                        mutex.unlock();
                    }
                } /* ,
                executeAsync<T> (fn: () => Promise<T>): Promise<T> {
                  return mutex.lockAsync().then(() => {
                    const r = fn()
                    mutex.unlock()
                    return r
                  }, (err) => {
                    mutex.unlock()
                    throw err
                  })
                } */
            };
            return mutex;
        },
        getCond(func) {
            const index = func + emnapiTSFN.offset.cond;
            const mutex = emnapiTSFN.getMutex(func);
            const cond = {
                wait() {
                    const i32a = new Int32Array(emnapiTSFN.ensureBufferFor(index + 4), index, 1);
                    const value = Atomics.load(i32a, 0);
                    mutex.unlock();
                    Atomics.wait(i32a, 0, value);
                    mutex.lock();
                },
                /* waitAsync () {
                  const i32a = new Int32Array(emnapiTSFN.ensureBufferFor(index + 4), index, 1)
                  const value = Atomics.load(i32a, 0)
                  mutex.unlock()
                  const lock = (): Promise<void> => mutex.lockAsync()
                  try {
                    return (Atomics as any).waitAsync(i32a, 0, value).value.then(lock, lock)
                  } catch (err) {
                    return lock()
                  }
                }, */
                signal() {
                    const i32a = new Int32Array(emnapiTSFN.ensureBufferFor(index + 4), index, 1);
                    Atomics.add(i32a, 0, 1);
                    Atomics.notify(i32a, 0, 1);
                }
            };
            return cond;
        },
        getQueueSize(func) {
            return emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.queue_size, true);
        },
        addQueueSize(func) {
            const offset = emnapiTSFN.offset.queue_size;
            let arr, index;
            arr = new Uint32Array(emnapiTSFN.ensureBufferFor(func + offset + 4));
            index = (func + offset) >>> 2;
            Atomics.add(arr, index, 1);
        },
        subQueueSize(func) {
            const offset = emnapiTSFN.offset.queue_size;
            let arr, index;
            arr = new Uint32Array(emnapiTSFN.ensureBufferFor(func + offset + 4));
            index = (func + offset) >>> 2;
            Atomics.sub(arr, index, 1);
        },
        getThreadCount(func) {
            return emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.thread_count, true);
        },
        addThreadCount(func) {
            const offset = emnapiTSFN.offset.thread_count;
            let arr, index;
            arr = new Uint32Array(emnapiTSFN.ensureBufferFor(func + offset + 4));
            index = (func + offset) >>> 2;
            Atomics.add(arr, index, 1);
        },
        subThreadCount(func) {
            const offset = emnapiTSFN.offset.thread_count;
            let arr, index;
            arr = new Uint32Array(emnapiTSFN.ensureBufferFor(func + offset + 4));
            index = (func + offset) >>> 2;
            Atomics.sub(arr, index, 1);
        },
        getState(func) {
            return Atomics.load(new Int32Array(emnapiTSFN.ensureBufferFor(func + emnapiTSFN.offset.state + 4)), (func + emnapiTSFN.offset.state) >>> 2);
        },
        setState(func, value) {
            Atomics.store(new Int32Array(emnapiTSFN.ensureBufferFor(func + emnapiTSFN.offset.state + 4)), (func + emnapiTSFN.offset.state) >>> 2, value);
        },
        getHandlesClosing(func) {
            return Atomics.load(new Int8Array(emnapiTSFN.ensureBufferFor(func + emnapiTSFN.offset.handles_closing + 1)), (func + emnapiTSFN.offset.handles_closing));
        },
        setHandlesClosing(func, value) {
            Atomics.store(new Int8Array(emnapiTSFN.ensureBufferFor(func + emnapiTSFN.offset.handles_closing + 1)), (func + emnapiTSFN.offset.handles_closing), value);
        },
        getDispatchState(func) {
            return Atomics.load(new Uint32Array(emnapiTSFN.ensureBufferFor(func + emnapiTSFN.offset.dispatch_state + 4)), (func + emnapiTSFN.offset.dispatch_state) >>> 2);
        },
        getContext(func) {
            return emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.context, false);
        },
        getMaxQueueSize(func) {
            return emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.max_queue_size, true);
        },
        getEnv(func) {
            return emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.env, false);
        },
        getCallJSCb(func) {
            return emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.call_js_cb, false);
        },
        getRef(func) {
            return emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.ref, false);
        },
        getResource(func) {
            return emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.resource, false);
        },
        getFinalizeCb(func) {
            return emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.finalize_cb, false);
        },
        getFinalizeData(func) {
            return emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.finalize_data, false);
        },
        loadSizeTypeValue(offset, unsigned) {
            let ret;
            let arr;
            if (unsigned) {
                arr = new Uint32Array(emnapiTSFN.ensureBufferFor(offset + 4));
                ret = Atomics.load(arr, offset >>> 2);
                return ret;
            }
            else {
                arr = new Int32Array(emnapiTSFN.ensureBufferFor(offset + 4));
                ret = Atomics.load(arr, offset >>> 2);
                return ret;
            }
        },
        storeSizeTypeValue(offset, value, unsigned) {
            let arr;
            if (unsigned) {
                arr = new Uint32Array(emnapiTSFN.ensureBufferFor(offset + 4));
                Atomics.store(arr, offset >>> 2, value);
                return undefined;
            }
            else {
                arr = new Int32Array(emnapiTSFN.ensureBufferFor(offset + 4));
                Atomics.store(arr, offset >>> 2, value >>> 0);
                return undefined;
            }
        },
        releaseResources(func) {
            if (emnapiTSFN.getState(func) !== 2 /* State.kClosed */) {
                emnapiTSFN.setState(func, 2 /* State.kClosed */);
                emnapiTSFN.getEnv(func);
                const envObject = emnapi_shared.emnapiEnv;
                const ref = emnapiTSFN.getRef(func);
                if (ref) {
                    emnapiCtx.getRef(ref).dispose();
                }
                const resource = emnapiTSFN.getResource(func);
                emnapiCtx.getRef(resource).dispose();
                emnapiTSFN.ensureBufferFor(func + emnapiTSFN.offset.is_some + 1);
                var HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer), GET_HEAP_DATA_VIEW = () => HEAP_DATA_VIEW.buffer === emnapiPluginCtx.wasmMemory.buffer ? HEAP_DATA_VIEW : (HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer));
                GET_HEAP_DATA_VIEW().setInt8(func + emnapiTSFN.offset.is_some, 0, true);
                emnapiCtx.removeCleanupHook(envObject, emnapiTSFN.cleanup, func);
                envObject.unref();
                const asyncRefAddress = func + emnapiTSFN.offset.async_ref;
                const asyncRefOffset = asyncRefAddress >>> 2;
                const arr = new Uint32Array(emnapiTSFN.ensureBufferFor(asyncRefAddress + 4));
                if (Atomics.load(arr, asyncRefOffset) > 0) {
                    Atomics.store(arr, asyncRefOffset, 0);
                    __emnapi_runtime_keepalive_pop();
                    emnapiCtx.decreaseWaitingRequestCounter();
                }
                if (emnapiNodeBinding) {
                    const view = new DataView(emnapiTSFN.ensureBufferFor(func + emnapiTSFN.offset.trigger_async_id + 8));
                    const asyncId = view.getFloat64(func + emnapiTSFN.offset.async_id, true);
                    const triggerAsyncId = view.getFloat64(func + emnapiTSFN.offset.trigger_async_id, true);
                    __emnapi_node_emit_async_destroy(asyncId, triggerAsyncId);
                }
            }
        },
        destroy(func) {
            emnapiTSFN._liveSet.delete(func);
            emnapiTSFN.destroyQueue(func);
            emnapiTSFN.releaseResources(func);
            emscripten_runtime._free(func);
        },
        emptyQueue(func) {
            const drainQueue = [];
            emnapiTSFN.getMutex(func).execute(() => {
                while (emnapiTSFN.getQueueSize(func) > 0) {
                    drainQueue.push(emnapiTSFN.shiftQueue(func));
                }
            });
            const callJsCb = emnapiTSFN.getCallJSCb(func);
            const context = emnapiTSFN.getContext(func);
            let data;
            for (let i = 0; i < drainQueue.length; i++) {
                data = drainQueue[i];
                if (callJsCb) {
                    (emnapiPluginCtx.wasmTable.get(callJsCb))(0, 0, context, data);
                }
            }
        },
        maybeDelete(func) {
            let shouldDelete = false;
            emnapiTSFN.getMutex(func).execute(() => {
                if (emnapiTSFN.getThreadCount(func) > 0) {
                    emnapiTSFN.releaseResources(func);
                }
                else {
                    shouldDelete = true;
                }
            });
            if (shouldDelete) {
                emnapiTSFN.destroy(func);
            }
        },
        finalize(func) {
            emnapiTSFN.getEnv(func);
            const envObject = emnapi_shared.emnapiEnv;
            emnapiCtx.openScope(envObject);
            const finalize = emnapiTSFN.getFinalizeCb(func);
            const data = emnapiTSFN.getFinalizeData(func);
            const context = emnapiTSFN.getContext(func);
            const f = () => {
                envObject.callFinalizerInternal(0, finalize, data, context);
            };
            try {
                emnapiTSFN.emptyQueue(func);
                if (finalize) {
                    if (emnapiNodeBinding) {
                        const resource = emnapiTSFN.getResource(func);
                        const resource_value = emnapiCtx.getRef(resource).get();
                        const resourceObject = emnapiCtx.jsValueFromNapiValue(resource_value);
                        const view = new DataView(emnapiTSFN.ensureBufferFor(func + emnapiTSFN.offset.trigger_async_id + 8));
                        const asyncId = view.getFloat64(func + emnapiTSFN.offset.async_id, true);
                        const triggerAsyncId = view.getFloat64(func + emnapiTSFN.offset.trigger_async_id, true);
                        emnapiNodeBinding.node.makeCallback(resourceObject, f, [], {
                            asyncId,
                            triggerAsyncId
                        });
                    }
                    else {
                        f();
                    }
                }
                emnapiTSFN.maybeDelete(func);
            }
            finally {
                emnapiCtx.closeScope(envObject);
            }
        },
        cleanup(func) {
            emnapiTSFN.closeHandlesAndMaybeDelete(func, 1);
        },
        closeHandlesAndMaybeDelete(func, set_closing) {
            emnapiTSFN.getEnv(func);
            const envObject = emnapi_shared.emnapiEnv;
            emnapiCtx.openScope(envObject);
            try {
                if (set_closing) {
                    emnapiTSFN.getMutex(func).execute(() => {
                        emnapiTSFN.setState(func, 1 /* State.kClosing */);
                        if (emnapiTSFN.getMaxQueueSize(func) > 0) {
                            emnapiTSFN.getCond(func).signal();
                        }
                    });
                }
                if (emnapiTSFN.getHandlesClosing(func)) {
                    return;
                }
                emnapiTSFN.setHandlesClosing(func, 1);
                Atomics.store(new Int32Array(emnapiTSFN.ensureBufferFor(func + emnapiTSFN.offset.async_pending + 4)), (func + emnapiTSFN.offset.async_pending) >>> 2, 1);
                emnapiCtx.features.setImmediate(() => {
                    emnapiTSFN.finalize(func);
                });
            }
            finally {
                emnapiCtx.closeScope(envObject);
            }
        },
        dispatchOne(func) {
            let data = 0;
            let popped_value = false;
            let has_more = false;
            const mutex = emnapiTSFN.getMutex(func);
            const cond = emnapiTSFN.getCond(func);
            mutex.execute(() => {
                if (emnapiTSFN.getState(func) === 0 /* State.kOpen */) {
                    let size = emnapiTSFN.getQueueSize(func);
                    if (size > 0) {
                        data = emnapiTSFN.shiftQueue(func);
                        popped_value = true;
                        const maxQueueSize = emnapiTSFN.getMaxQueueSize(func);
                        if (size === maxQueueSize && maxQueueSize > 0) {
                            cond.signal();
                        }
                        size--;
                    }
                    if (size === 0) {
                        if (emnapiTSFN.getThreadCount(func) === 0) {
                            emnapiTSFN.setState(func, 1 /* State.kClosing */);
                            if (emnapiTSFN.getMaxQueueSize(func) > 0) {
                                cond.signal();
                            }
                            emnapiTSFN.closeHandlesAndMaybeDelete(func, 0);
                        }
                    }
                    else {
                        has_more = true;
                    }
                }
                else {
                    emnapiTSFN.closeHandlesAndMaybeDelete(func, 0);
                }
            });
            if (popped_value) {
                const env = emnapiTSFN.getEnv(func);
                const envObject = emnapi_shared.emnapiEnv;
                emnapiCtx.openScope(envObject);
                const f = () => {
                    envObject.callbackIntoModule(false, () => {
                        const callJsCb = emnapiTSFN.getCallJSCb(func);
                        const ref = emnapiTSFN.getRef(func);
                        const js_callback = ref ? emnapiCtx.getRef(ref).get() : 0;
                        if (callJsCb) {
                            const context = emnapiTSFN.getContext(func);
                            (emnapiPluginCtx.wasmTable.get(callJsCb))(env, js_callback, context, data);
                        }
                        else {
                            const jsCallback = js_callback ? emnapiCtx.jsValueFromNapiValue(js_callback) : null;
                            if (typeof jsCallback === 'function') {
                                jsCallback();
                            }
                        }
                    });
                };
                try {
                    if (emnapiNodeBinding) {
                        const resource = emnapiTSFN.getResource(func);
                        const resource_value = emnapiCtx.getRef(resource).get();
                        const resourceObject = emnapiCtx.jsValueFromNapiValue(resource_value);
                        const view = new DataView(emnapiTSFN.ensureBufferFor(func + emnapiTSFN.offset.trigger_async_id + 8));
                        emnapiNodeBinding.node.makeCallback(resourceObject, f, [], {
                            asyncId: view.getFloat64(func + emnapiTSFN.offset.async_id, true),
                            triggerAsyncId: view.getFloat64(func + emnapiTSFN.offset.trigger_async_id, true)
                        });
                    }
                    else {
                        f();
                    }
                }
                finally {
                    emnapiCtx.closeScope(envObject);
                }
            }
            return has_more;
        },
        dispatch(func) {
            let has_more = true;
            let iterations_left = 1000;
            const dispatchStateAddress = func + emnapiTSFN.offset.dispatch_state;
            const index = dispatchStateAddress >>> 2;
            while (has_more && --iterations_left !== 0) {
                Atomics.store(new Uint32Array(emnapiTSFN.ensureBufferFor(dispatchStateAddress + 4)), index, 1);
                try {
                    has_more = emnapiTSFN.dispatchOne(func);
                }
                catch (err) {
                    // A throwing callback must not leave dispatch_state marked as
                    // dispatching, or every later send() would be swallowed. Re-arm
                    // the state and schedule another drain before rethrowing.
                    if (emnapiTSFN._liveSet.has(func)) {
                        Atomics.exchange(new Uint32Array(emnapiTSFN.ensureBufferFor(dispatchStateAddress + 4)), index, 0);
                        emnapiTSFN.send(func);
                    }
                    throw err;
                }
                if (Atomics.exchange(new Uint32Array(emnapiTSFN.ensureBufferFor(dispatchStateAddress + 4)), index, 0) !== 1) {
                    has_more = true;
                }
            }
            if (has_more) {
                emnapiTSFN.send(func);
            }
        },
        enqueue(func) {
            // `pending` means a worker thread has requested a wakeup that has not
            // been drained on the main thread yet.
            const pending = func + emnapiTSFN.offset.async_pending;
            // `scheduled` prevents queueing the same main-thread drain chain more than
            // once while a previous wakeup is still in flight.
            const scheduled = func + emnapiTSFN.offset.async_u_fd;
            const end = Math.max(pending, scheduled) + 4;
            const state = () => new Int32Array(emnapiTSFN.ensureBufferFor(end));
            if (Atomics.exchange(state(), scheduled >>> 2, 1) !== 0) {
                return;
            }
            // Match uv_async_send-style coalescing in JS: the first turn represents
            // the wakeup reaching the main thread, and the second turn performs the
            // actual TSFN drain after nearby Send/Signal calls have had a chance to
            // collapse into the shared AsyncProgressWorker state.
            emnapiCtx.features.setImmediate(() => {
                if (!emnapiTSFN._liveSet.has(func)) {
                    return;
                }
                if (Atomics.load(state(), pending >>> 2) === 0) {
                    Atomics.store(state(), scheduled >>> 2, 0);
                    return;
                }
                emnapiCtx.features.setImmediate(() => {
                    // After destroy(), the func address is freed.  Skip the atomics
                    // on that address entirely to avoid use-after-free (JS-side
                    // lifecycle check must run before touching the state words).
                    if (!emnapiTSFN._liveSet.has(func)) {
                        return;
                    }
                    try {
                        // Consume the coalesced wakeup once, then let dispatch() observe any
                        // queue mutations through dispatch_state like the C implementation.
                        if (Atomics.exchange(state(), pending >>> 2, 0) === 0) {
                            return;
                        }
                        emnapiTSFN.dispatch(func);
                    }
                    finally {
                        // Allow a later wakeup to schedule a new drain chain. If another
                        // worker-thread send raced with this drain, enqueue one more turn.
                        if (emnapiTSFN._liveSet.has(func)) {
                            Atomics.store(state(), scheduled >>> 2, 0);
                            if (Atomics.load(state(), pending >>> 2) !== 0) {
                                emnapiTSFN.enqueue(func);
                            }
                        }
                    }
                });
            });
        },
        send(func) {
            const dispatchStateAddress = func + emnapiTSFN.offset.dispatch_state;
            const current_state = Atomics.or(new Uint32Array(emnapiTSFN.ensureBufferFor(dispatchStateAddress + 4)), dispatchStateAddress >>> 2, 1 << 1);
            if ((current_state & 1) === 1) {
                return;
            }
            const pendng = func + emnapiTSFN.offset.async_pending;
            // A wakeup is already pending, so this send only needs to leave the queued
            // work in the TSFN queue and let the existing drain pick it up.
            if (Atomics.load(new Int32Array(emnapiTSFN.ensureBufferFor(pendng + 4)), pendng >>> 2) !== 0) {
                return;
            }
            if (Atomics.exchange(new Int32Array(emnapiTSFN.ensureBufferFor(pendng + 4)), pendng >>> 2, 1) === 0) {
                if ((typeof emscripten_runtime.ENVIRONMENT_IS_PTHREAD !== 'undefined') && emscripten_runtime.ENVIRONMENT_IS_PTHREAD) {
                    // Worker threads only post a wakeup token. Main-thread draining is
                    // serialized by enqueue() once the message is received.
                    postMessage({
                        __emnapi__: {
                            type: 'tsfn-send',
                            payload: {
                                tsfn: func
                            }
                        }
                    });
                }
                else {
                    // On the main thread we can skip the cross-thread hop and schedule the
                    // coalesced drain chain directly.
                    emnapiTSFN.enqueue(func);
                }
            }
        }
    };
    emnapiTSFN.init();
    emnapiPluginCtx.emnapiTSFN = emnapiTSFN;
    /**
     * @__deps _emnapi_node_emit_async_init
     * @__deps _emnapi_runtime_keepalive_push
     * @__sig ippppppppppp
     */
    function napi_create_threadsafe_function(env, func, async_resource, async_resource_name, max_queue_size, initial_thread_count, thread_finalize_data, thread_finalize_cb, context, call_js_cb, result) {
        if (!env)
            return 1 /* napi_status.napi_invalid_arg */;
        // @ts-expect-error
        const envObject = emnapi_shared.emnapiEnv;
        envObject.checkGCAccess();
        if (!async_resource_name)
            return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
        max_queue_size >>>= 0;
        initial_thread_count >>>= 0;
        env >>>= 0;
        thread_finalize_data >>>= 0;
        thread_finalize_cb >>>= 0;
        context >>>= 0;
        call_js_cb >>>= 0;
        max_queue_size = max_queue_size >>> 0;
        initial_thread_count = initial_thread_count >>> 0;
        if (initial_thread_count === 0) {
            return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
        }
        if (!result)
            return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
        let ref = 0;
        func >>>= 0;
        if (!func) {
            if (!call_js_cb)
                return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
        }
        else {
            const funcValue = emnapiCtx.jsValueFromNapiValue(func);
            if (typeof funcValue !== 'function') {
                return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
            }
            ref = emnapiCtx.createReference(envObject, func, 1, 1 /* ReferenceOwnership.kUserland */).id;
        }
        let asyncResourceObject;
        if (async_resource) {
            asyncResourceObject = emnapiCtx.jsValueFromNapiValue(async_resource);
            if (asyncResourceObject == null) {
                return envObject.setLastError(2 /* napi_status.napi_object_expected */);
            }
            asyncResourceObject = Object(asyncResourceObject);
        }
        else {
            asyncResourceObject = {};
        }
        const resource = emnapiCtx.napiValueFromJsValue(asyncResourceObject);
        let asyncResourceName = emnapiCtx.jsValueFromNapiValue(async_resource_name);
        if (typeof asyncResourceName === 'symbol') {
            return envObject.setLastError(3 /* napi_status.napi_string_expected */);
        }
        asyncResourceName = String(asyncResourceName);
        const resource_name = emnapiCtx.napiValueFromJsValue(asyncResourceName);
        // tsfn create
        const sizeofTSFN = emnapiTSFN.offset.__size__;
        let tsfn = emscripten_runtime._malloc(sizeofTSFN);
        if (!tsfn)
            return envObject.setLastError(9 /* napi_status.napi_generic_failure */);
        tsfn >>>= 0;
        new Uint8Array(emnapiTSFN.ensureBufferFor(tsfn + sizeofTSFN)).subarray(tsfn, tsfn + sizeofTSFN).fill(0);
        const resourceRef = emnapiCtx.createReference(envObject, resource, 1, 1 /* ReferenceOwnership.kUserland */);
        const resource_ = resourceRef.id;
        var HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer), GET_HEAP_DATA_VIEW = () => HEAP_DATA_VIEW.buffer === emnapiPluginCtx.wasmMemory.buffer ? HEAP_DATA_VIEW : (HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer));
        GET_HEAP_DATA_VIEW().setUint32(tsfn + emnapiTSFN.offset.resource, resource_, true);
        if (!emnapiTSFN.initQueue(tsfn)) {
            emscripten_runtime._free(tsfn);
            resourceRef.dispose();
            return envObject.setLastError(9 /* napi_status.napi_generic_failure */);
        }
        __emnapi_node_emit_async_init(resource, resource_name, -1, tsfn + emnapiTSFN.offset.async_id);
        GET_HEAP_DATA_VIEW().setInt8(tsfn + emnapiTSFN.offset.is_some, 1, true);
        GET_HEAP_DATA_VIEW().setUint32(tsfn + emnapiTSFN.offset.thread_count, initial_thread_count, true);
        GET_HEAP_DATA_VIEW().setUint32(tsfn + emnapiTSFN.offset.context, context, true);
        GET_HEAP_DATA_VIEW().setUint32(tsfn + emnapiTSFN.offset.max_queue_size, max_queue_size, true);
        GET_HEAP_DATA_VIEW().setUint32(tsfn + emnapiTSFN.offset.ref, ref, true);
        GET_HEAP_DATA_VIEW().setUint32(tsfn + emnapiTSFN.offset.env, env, true);
        GET_HEAP_DATA_VIEW().setUint32(tsfn + emnapiTSFN.offset.finalize_data, thread_finalize_data, true);
        GET_HEAP_DATA_VIEW().setUint32(tsfn + emnapiTSFN.offset.finalize_cb, thread_finalize_cb, true);
        GET_HEAP_DATA_VIEW().setUint32(tsfn + emnapiTSFN.offset.call_js_cb, call_js_cb, true);
        emnapiCtx.addCleanupHook(envObject, emnapiTSFN.cleanup, tsfn);
        emnapiTSFN._liveSet.add(tsfn);
        envObject.ref();
        __emnapi_runtime_keepalive_push();
        emnapiCtx.increaseWaitingRequestCounter();
        GET_HEAP_DATA_VIEW().setUint32(tsfn + emnapiTSFN.offset.async_ref, 1, true);
        result >>>= 0;
        GET_HEAP_DATA_VIEW().setUint32(result, tsfn, true);
        return envObject.clearLastError();
    }
    /** @__sig ipp */
    function napi_get_threadsafe_function_context(func, result) {
        if (!func || !result) {
            emscripten_runtime.abort();
            return 1 /* napi_status.napi_invalid_arg */;
        }
        func >>>= 0;
        result >>>= 0;
        const context = emnapiTSFN.getContext(func);
        var HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer), GET_HEAP_DATA_VIEW = () => HEAP_DATA_VIEW.buffer === emnapiPluginCtx.wasmMemory.buffer ? HEAP_DATA_VIEW : (HEAP_DATA_VIEW = new DataView(emnapiPluginCtx.wasmMemory.buffer));
        GET_HEAP_DATA_VIEW().setUint32(result, context, true);
        return 0 /* napi_status.napi_ok */;
    }
    /** @__sig ippi */
    function napi_call_threadsafe_function(func, data, mode) {
        if (!func) {
            emscripten_runtime.abort();
            return 1 /* napi_status.napi_invalid_arg */;
        }
        func >>>= 0;
        data >>>= 0;
        return emnapiTSFN.push(func, data, mode);
    }
    /** @__sig ip */
    function napi_acquire_threadsafe_function(func) {
        if (!func) {
            emscripten_runtime.abort();
            return 1 /* napi_status.napi_invalid_arg */;
        }
        func >>>= 0;
        const mutex = emnapiTSFN.getMutex(func);
        return mutex.execute(() => {
            if (emnapiTSFN.getState(func) === 0 /* State.kOpen */) {
                emnapiTSFN.addThreadCount(func);
                return 0 /* napi_status.napi_ok */;
            }
            return 16 /* napi_status.napi_closing */;
        });
    }
    /** @__sig ipi */
    function napi_release_threadsafe_function(func, mode) {
        if (!func) {
            emscripten_runtime.abort();
            return 1 /* napi_status.napi_invalid_arg */;
        }
        func >>>= 0;
        const mutex = emnapiTSFN.getMutex(func);
        const cond = emnapiTSFN.getCond(func);
        let shouldDelete = false;
        const ret = mutex.execute(() => {
            if (emnapiTSFN.getThreadCount(func) === 0) {
                return 1 /* napi_status.napi_invalid_arg */;
            }
            emnapiTSFN.subThreadCount(func);
            if (emnapiTSFN.getThreadCount(func) === 0 || mode === 1 /* napi_threadsafe_function_release_mode.napi_tsfn_abort */) {
                if (emnapiTSFN.getState(func) === 0 /* State.kOpen */) {
                    if (mode === 1 /* napi_threadsafe_function_release_mode.napi_tsfn_abort */) {
                        emnapiTSFN.setState(func, 1 /* State.kClosing */);
                    }
                    if (emnapiTSFN.getState(func) === 1 /* State.kClosing */ && emnapiTSFN.getMaxQueueSize(func) > 0) {
                        cond.signal();
                    }
                    emnapiTSFN.send(func);
                }
            }
            if (!(emnapiTSFN.getState(func) === 2 /* State.kClosed */ && emnapiTSFN.getThreadCount(func) === 0)) {
                return 0 /* napi_status.napi_ok */;
            }
            shouldDelete = true;
            return 0 /* napi_status.napi_ok */;
        });
        if (shouldDelete) {
            emnapiTSFN.destroy(func);
        }
        return ret;
    }
    /**
     * @__deps _emnapi_runtime_keepalive_pop
     * @__sig ipp
     */
    function napi_unref_threadsafe_function(env, func) {
        if (!func) {
            emscripten_runtime.abort();
            return 1 /* napi_status.napi_invalid_arg */;
        }
        func >>>= 0;
        const asyncRefAddress = func + emnapiTSFN.offset.async_ref;
        const asyncRefOffset = asyncRefAddress >>> 2;
        const arr = new Uint32Array(emnapiTSFN.ensureBufferFor(asyncRefAddress + 4));
        const currentValue = Atomics.load(arr, asyncRefOffset);
        if (currentValue > 0) {
            Atomics.store(arr, asyncRefOffset, currentValue - 1);
            if (currentValue === 1) {
                __emnapi_runtime_keepalive_pop();
                emnapiCtx.decreaseWaitingRequestCounter();
            }
        }
        return 0 /* napi_status.napi_ok */;
    }
    /**
     * @__deps _emnapi_runtime_keepalive_push
     * @__sig ipp
     */
    function napi_ref_threadsafe_function(env, func) {
        if (!func) {
            emscripten_runtime.abort();
            return 1 /* napi_status.napi_invalid_arg */;
        }
        func >>>= 0;
        const asyncRefAddress = func + emnapiTSFN.offset.async_ref;
        const asyncRefOffset = asyncRefAddress >>> 2;
        const arr = new Uint32Array(emnapiTSFN.ensureBufferFor(asyncRefAddress + 4));
        const currentValue = Atomics.load(arr, asyncRefOffset);
        if (!currentValue) {
            __emnapi_runtime_keepalive_push();
            emnapiCtx.increaseWaitingRequestCounter();
        }
        Atomics.store(arr, asyncRefOffset, currentValue + 1);
        return 0 /* napi_status.napi_ok */;
    }

    //#endregion src/threadsafe-function.ts

    exports.napi_acquire_threadsafe_function = napi_acquire_threadsafe_function;
    exports.napi_call_threadsafe_function = napi_call_threadsafe_function;
    exports.napi_create_threadsafe_function = napi_create_threadsafe_function;
    exports.napi_get_threadsafe_function_context = napi_get_threadsafe_function_context;
    exports.napi_ref_threadsafe_function = napi_ref_threadsafe_function;
    exports.napi_release_threadsafe_function = napi_release_threadsafe_function;
    exports.napi_unref_threadsafe_function = napi_unref_threadsafe_function;

    return exports;

})({}, emnapiPluginCtx, emnapiPluginCtx);
  return {
    importObject: (original) => {
      Object.assign(original.napi, mod);
    }
  };
}

exports.emnapiAsyncWorkPlugin = asyncWork;
exports.emnapiTSFNPlugin = threadsafeFunction;
