SkillAgentSearch skills...

Ceibo

Ceibo is a JavaScript micro library to model trees that evaluate arbitrary code when accessing its nodes.

Install / Use

/learn @san650/Ceibo
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Latest version CI

What is Ceibo 🌱 ?

JavaScript micro library to model trees that evaluate arbitrary code when accessing its nodes.

How 💡 ?

The tree is modeled as a plain JavaScript object where each node has an arbitrary getter function. This allows to have a representation of a tree where a subtree is generated on the fly when a node is accessed.

Examples

Let's start by doing the most simple case, the identity case:

const root = Ceibo.create({
  foo: {
    bar: 'baz'
  }
});

console.log(root.foo.bar); // "baz"

You can create special node types called descriptors that allow you to respond to node access:

const root = Ceibo.create({
  foo: {
    isDescriptor: true,

    get() {
      return 'bar';
    }
  }
});

console.log(root.foo); // "bar"

As you can see, a descriptor is a JavaScript object that has a isDescriptor attribute.

You can define a get method or you can declare a value attribute, then the value attribute is going to be used as is:

const root = Ceibo.create({
  foo: {
    isDescriptor: true,

    value(answer) {
      return `The answer to life, the universe and everything is ${answer}`;
    }
  }
});

console.log(root.foo('42')); // "The answer to life, the universe and everything is 42"

descriptors can inspect and mutate the target object by defining a setup method:

const tree = Ceibo.create({
  foo: {
    isDescriptor: true,

    get() {
      return 'bar';
    },

    setup(target, keyName) {
      Ceibo.defineProperty(target, keyName.toUpperCase(), 'generated property');
    }
  }
});

console.log(tree.foo); // "bar"
console.log(tree.FOO); // "generated property"

Note that Ceibo trees are read-only, so you cannot reassign attributes:

const root = Ceibo.create({
  foo: 'bar'
});

root.foo = 'baz'; // => throws an error!

You can redefine how each value type is processed when the Ceibo tree is created:


const buildString = (node, blueprintKey, value, defaultBuilder) => {
  return defaultBuilder(node, blueprintKey, `Cuack ${value}`);
}

const root = Ceibo.create(
  {
    foo: 'first value'
  },
  {
    builder: {
      string: buildString
    }
  }
);

console.log(root.foo); // "Cuack first value"

Redefine how plain objects are processed to generate custom attributes:


const buildObject = (node, blueprintKey, blueprint /*, defaultBuilder */) => {
  const value = {
    generatedProperty: 'generated property'
  };

  // define current key and assign the new object
  Ceibo.defineProperty(node, blueprintKey, value);

  // continue to build the tree recursively
  return [value, blueprint];
}

const root = Ceibo.create(
  {
    foo: {
      bar: 'baz'
    }
  },
  {
    builder: {
      object: buildObject
    }
  }
);

console.log(root.generatedProperty); // "generated property"
console.log(root.foo.generatedProperty); // "generated property"
console.log(root.foo.bar); // "baz"

You can navigate to parent nodes

const tree = Ceibo.create({
  foo: {
    bar: {
      baz: 'a value'
    }
  }
});

console.log(Ceibo.parent(tree.foo.bar).bar.baz); // "a value"

You can assign custom parents to trees

const parentTree = Ceibo.create({ foo: 'value' });
const childTree = Ceibo.create({ bar: 'another value' }, { parent: parentTree });

console.log(Ceibo.parent(childTree).foo); // "value"

Descriptor's get function receive the key when evaluated

const descriptor = {
  isDescriptor: true,

  get: function(key) {
    return key;
  }
};

const root = Ceibo.create({
  foo: descriptor,
  bar: descriptor
});

console.log(root.foo); // "foo"
console.log(root.bar); // "bar"

Ceibo's nodes store some meta data, you can access said meta data using Ceibo.meta function.

const descriptor = {
  isDescriptor: true,

  get: function(key) {
    const keys = [key];
    let node = this;
    let meta;

    do {
      meta = Ceibo.meta(node);

      keys.unshift(meta.key);
    } while(node = Ceibo.parent(node));

    return keys;
  }
};

const tree = Ceibo.create({
  foo: {
    bar: {
      baz: {
        qux: descriptor
      }
    }
  }
});

console.log(tree.foo.bar.baz.qux); // ['root', 'foo', 'bar', 'baz', 'qux']

License

Ceibo is licensed under the MIT license.

See LICENSE for the full license text.

Related Skills

View on GitHub
GitHub Stars12
CategoryDevelopment
Updated4mo ago
Forks8

Languages

JavaScript

Security Score

87/100

Audited on Nov 10, 2025

No findings