diff --git a/examples/baobab/generator/.gitignore b/examples/baobab/generator/.gitignore new file mode 100644 index 00000000..80ce9592 --- /dev/null +++ b/examples/baobab/generator/.gitignore @@ -0,0 +1,3 @@ +methods.v +pet_store_actor +docs \ No newline at end of file diff --git a/examples/baobab/generator/README.md b/examples/baobab/generator/README.md new file mode 100644 index 00000000..a5ea7d59 --- /dev/null +++ b/examples/baobab/generator/README.md @@ -0,0 +1,9 @@ +# Actor Generation Examples + +## `generate_methods.vsh` + +This example generates actor method prototypes from an actor specification. + +## `generate_actor_module.vsh` + +This example generates an entire actor module from an actor specification with the support for the specified interfaces. \ No newline at end of file diff --git a/examples/baobab/generator/generate_actor_module.vsh b/examples/baobab/generator/generate_actor_module.vsh new file mode 100755 index 00000000..4e3f1c4e --- /dev/null +++ b/examples/baobab/generator/generate_actor_module.vsh @@ -0,0 +1,23 @@ +#!/usr/bin/env -S v -w -n -enable-globals run + +import freeflowuniverse.herolib.baobab.generator +import freeflowuniverse.herolib.baobab.specification +import freeflowuniverse.herolib.schemas.openrpc +import os + +const example_dir = os.dir(@FILE) +const openrpc_spec_path = os.join_path(example_dir, 'openrpc.json') + +// the actor specification obtained from the OpenRPC Specification +openrpc_spec := openrpc.new(path: openrpc_spec_path)! +actor_spec := specification.from_openrpc(openrpc_spec)! + +actor_module := generator.generate_actor_module( + actor_spec, + interfaces: [.openrpc] +)! + +actor_module.write(example_dir, + format: true + overwrite: true +)! \ No newline at end of file diff --git a/examples/baobab/generator/generate_methods.vsh b/examples/baobab/generator/generate_methods.vsh new file mode 100755 index 00000000..a13451b0 --- /dev/null +++ b/examples/baobab/generator/generate_methods.vsh @@ -0,0 +1,19 @@ +#!/usr/bin/env -S v -w -n -enable-globals run + +import freeflowuniverse.herolib.baobab.generator +import freeflowuniverse.herolib.baobab.specification +import freeflowuniverse.herolib.schemas.openrpc +import os + +const example_dir = os.dir(@FILE) +const openrpc_spec_path = os.join_path(example_dir, 'openrpc.json') + +// the actor specification obtained from the OpenRPC Specification +openrpc_spec := openrpc.new(path: openrpc_spec_path)! +actor_spec := specification.from_openrpc(openrpc_spec)! + +methods_file := generator.generate_methods_file(actor_spec)! +methods_file.write(example_dir, + format: true + overwrite: true +)! \ No newline at end of file diff --git a/examples/baobab/generator/generate_openrpc_file.vsh b/examples/baobab/generator/generate_openrpc_file.vsh new file mode 100755 index 00000000..796ba871 --- /dev/null +++ b/examples/baobab/generator/generate_openrpc_file.vsh @@ -0,0 +1,19 @@ +#!/usr/bin/env -S v -w -n -enable-globals run + +import freeflowuniverse.herolib.baobab.generator +import freeflowuniverse.herolib.baobab.specification +import freeflowuniverse.herolib.schemas.openrpc +import os + +const example_dir = os.dir(@FILE) +const openrpc_spec_path = os.join_path(example_dir, 'openrpc.json') + +// the actor specification obtained from the OpenRPC Specification +openrpc_spec_ := openrpc.new(path: openrpc_spec_path)! +actor_spec := specification.from_openrpc(openrpc_spec_)! +openrpc_spec := actor_spec.to_openrpc() + +openrpc_file := generator.generate_openrpc_file(openrpc_spec)! +openrpc_file.write(os.join_path(example_dir,'docs'), + overwrite: true +)! \ No newline at end of file diff --git a/examples/baobab/generator/openrpc.json b/examples/baobab/generator/openrpc.json new file mode 100644 index 00000000..2de851bb --- /dev/null +++ b/examples/baobab/generator/openrpc.json @@ -0,0 +1,132 @@ +{ + "openrpc": "1.0.0", + "info": { + "title": "PetStore", + "version": "1.0.0" + }, + "methods": [ + { + "name": "GetPets", + "description": "finds pets in the system that the user has access to by tags and within a limit", + "params": [ + { + "name": "tags", + "description": "tags to filter by", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "limit", + "description": "maximum number of results to return", + "schema": { + "type": "integer" + } + } + ], + "result": { + "name": "pet_list", + "description": "all pets from the system, that mathes the tags", + "schema": { + "$ref": "#\/components\/schemas\/Pet" + } + } + }, + { + "name": "CreatePet", + "description": "creates a new pet in the store. Duplicates are allowed.", + "params": [ + { + "name": "new_pet", + "description": "Pet to add to the store.", + "schema": { + "$ref": "#\/components\/schemas\/NewPet" + } + } + ], + "result": { + "name": "pet", + "description": "the newly created pet", + "schema": { + "$ref": "#\/components\/schemas\/Pet" + } + } + }, + { + "name": "GetPetById", + "description": "gets a pet based on a single ID, if the user has access to the pet", + "params": [ + { + "name": "id", + "description": "ID of pet to fetch", + "schema": { + "type": "integer" + } + } + ], + "result": { + "name": "pet", + "description": "pet response", + "schema": { + "$ref": "#\/components\/schemas\/Pet" + } + } + }, + { + "name": "DeletePetById", + "description": "deletes a single pet based on the ID supplied", + "params": [ + { + "name": "id", + "description": "ID of pet to delete", + "schema": { + "type": "integer" + } + } + ], + "result": { + "name": "pet", + "description": "pet deleted", + "schema": { + "type": "null" + } + } + } + ], + "components": { + "schemas": { + "NewPet": { + "title": "NewPet", + "properties": { + "name": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "Pet": { + "title": "Pet", + "description": "a pet struct that represents a pet", + "properties": { + "name": { + "description": "name of the pet", + "type": "string" + }, + "tag": { + "description": "a tag of the pet, helps finding pet", + "type": "string" + }, + "id": { + "description": "unique indentifier", + "type": "integer" + } + } + } + } + } + } \ No newline at end of file diff --git a/lib/baobab/README.md b/lib/baobab/README.md new file mode 100644 index 00000000..a0285eda --- /dev/null +++ b/lib/baobab/README.md @@ -0,0 +1,51 @@ +# Base Object and Actor Backend + +This is Hero’s backend, designed around the concept of base objects and actors to enable modular, domain-specific operations. + +## Base Object + +Base objects are digital representations of real-world entities. Examples include projects, publications, books, stories (agile), and calendar events. These objects: + • Serve as the primary data units that actors operate on. + • Contain indexable fields for efficient retrieval. + • Share a common base class with attributes like: + • Name: The object’s identifier. + • Description: A brief summary of the object. + • Remarks: A list of additional notes or metadata. + +Base objects are stored, indexed, retrieved, and updated using OSIS (Object Storage and Indexing System). + +## Actor + +Actors are domain-specific operation handlers that work on base objects. For instance, a Project Manager Actor might manage operations on stories, sprints, or projects. + +Key Features of Actors: + • Domain-Specific Languages (DSLs): Actor methods form intuitive, logical DSLs for interacting with base objects. + • Specification-Driven: + • Actors are generated from specifications. + • Code written for actor methods can be parsed back into specifications. + • Code Generation: Specifications enable automated boilerplate code generation, reducing manual effort. + +## Modules + +### OSIS: Object Storage and Indexing System + +OSIS is a module designed for efficient storage and indexing of root objects based on specific fields. It enables seamless management of data across various backends, with built-in support for field-based filtering and searching. + +#### Key Components + +**Indexer:** +* Creates and manages SQL tables based on base object specifications. +* Enables indexing of specific fields, making them searchable and filterable. + +**Storer**: +* Handles actual data storage in different databases. +* Supports diverse encoding and encryption methods for secure data management. + +By integrating OSIS, the backend achieves both high-performance data querying and flexible, secure storage solutions. + +### Example Actor Module + +The Example Actor module is a reference and testable example of a generated actor within Baobab. It demonstrates the structure of actor modules generated from specifications and can also be parsed back into specifications. This module serves two key purposes: + +1. Acts as a reference for developers working on Baobab to understand and program against actor specifications. +2. Provides a compilable, generatable module for testing and validating Baobab’s code generation tools. \ No newline at end of file