"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.nodeApi = void 0;
const util_1 = require("../../../util");
const typed_schema_1 = require("../../typed-schema");
const proxies_1 = require("./proxies");
const types_1 = require("./types");
/**
 * The `node` object holds various functions for analyzing {@link SharedTreeNode}s.
 * @alpha
 */
exports.nodeApi = {
    schema: (node) => {
        return assertTreeNode(node).schema;
    },
    is: (value, schema) => {
        return (0, types_1.getTreeNode)(value)?.is(schema) ?? false;
    },
    parent: (node) => {
        const treeNode = assertTreeNode(node).parentField.parent.parent;
        if (treeNode !== undefined) {
            return (0, proxies_1.getProxyForNode)(treeNode);
        }
        return undefined;
    },
    key: (node) => {
        const treeNode = assertTreeNode(node);
        const parent = exports.nodeApi.parent(node);
        if (parent !== undefined) {
            const parentSchema = exports.nodeApi.schema(parent);
            if ((0, typed_schema_1.schemaIsFieldNode)(parentSchema)) {
                // The parent of `node` is a list
                return treeNode.parentField.index;
            }
        }
        // The parent of `node` is an object, a map, or undefined (and therefore `node` is a root/detached node).
        return treeNode.parentField.parent.key;
    },
    on: (node, eventName, listener) => {
        return assertTreeNode(node).on(eventName, listener);
    },
    status: (node) => {
        return assertTreeNode(node).treeStatus();
    },
};
function assertTreeNode(node) {
    return (0, types_1.getTreeNode)(node) ?? (0, util_1.fail)("Expected a SharedTreeNode");
}
//# sourceMappingURL=node.js.map