"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AsyncJ = exports.AsyncJRef = exports.AsyncJWatch = exports.AsyncJCall = exports.AsyncJGet = void 0;
const _1 = require("../../../Class/$");
const evaluate_1 = require("../../../spec/evaluate");
const Async_1 = require("./Async");
const AsyncJGet = (value) => {
    const $get = {
        $get({ name }, callback) {
            let data;
            try {
                data = value.get(name);
            }
            catch (err) {
                callback(undefined, err.message);
                return;
            }
            callback(data);
        },
        $deepGet: function ({ path }, callback) {
            let data;
            try {
                data = value.deepGet(path);
            }
            catch (err) {
                callback(undefined, err.message);
                return;
            }
            callback(data);
        },
        $hasKey: function ({ name }, callback) {
            let data;
            try {
                data = value.hasKey(name);
            }
            catch (err) {
                callback(undefined, err.message);
                return;
            }
            callback(data);
        },
        $keys: function ({}, callback) {
            let data;
            try {
                data = value.keys();
            }
            catch (err) {
                callback(undefined, err.message);
                return;
            }
            callback(data);
        },
        $deepHas: function ({ path }, callback) {
            let data;
            try {
                data = value.deepHas(path);
            }
            catch (err) {
                callback(undefined, err.message);
                return;
            }
            callback(data);
        },
    };
    return $get;
};
exports.AsyncJGet = AsyncJGet;
const AsyncJCall = (value) => {
    const $call = {
        $set({ name, data }, callback) {
            try {
                const _data = (0, evaluate_1.evaluate)(data, {}, {});
                value.set(name, _data);
            }
            catch (err) {
                callback(undefined, err.message);
                return;
            }
            callback();
        },
        $delete: function ({ name }, callback) {
            try {
                value.delete(name);
            }
            catch (err) {
                callback(undefined, err.message);
                return;
            }
            callback();
        },
        $deepSet: function ({ path, data }, callback) {
            try {
                value.deepSet(path, data);
            }
            catch (err) {
                callback(undefined, err.message);
                return;
            }
            callback();
        },
        $deepDelete: function ({ path }, callback) {
            try {
                value.deepDelete(path);
            }
            catch (err) {
                callback(undefined, err.message);
                return;
            }
            callback();
        },
    };
    return $call;
};
exports.AsyncJCall = AsyncJCall;
const AsyncJWatch = (value) => {
    const $watch = {
        $subscribe: function ({ key, path }, callback) {
            try {
                value.subscribe(path, key, (type, path, key, data) => {
                    callback({
                        type,
                        path,
                        key,
                        data,
                    });
                });
            }
            catch (err) {
                callback(undefined, err.message);
                return;
            }
        },
    };
    return $watch;
};
exports.AsyncJWatch = AsyncJWatch;
const AsyncJRef = (value) => {
    return {
        $ref({ name }) {
            let obj;
            try {
                obj = value.get(name);
            }
            catch (err) {
                return null;
            }
            if (obj === undefined) {
                return null;
            }
            if (obj instanceof _1.$) {
                const $obj = (0, Async_1.Async)(obj, obj.__, obj.__system.async);
                return $obj;
            }
            else {
                return null;
            }
        },
    };
};
exports.AsyncJRef = AsyncJRef;
const AsyncJ = (value) => {
    return {
        ...(0, exports.AsyncJGet)(value),
        ...(0, exports.AsyncJCall)(value),
        ...(0, exports.AsyncJWatch)(value),
        ...(0, exports.AsyncJRef)(value),
    };
};
exports.AsyncJ = AsyncJ;
//# sourceMappingURL=AsyncJ.js.map