Reusability in Meteor?

Hi, I have been interested in Meteor for the longest time. I do not have any real-world experience in any major js framework. So I have been searching around for a methodology to have single code base for each model where I can validate and do some business logic. if many of my react components would use a certain date format for objects coming from a subscription. it would be really annoying to do that formatting for each component and once that format is subject for change I am screwed. While browsing this wonderful forum, I have found Astronomy which sparked my attention but I am hesitant with the mixed reviews it’s getting. So I am thinking of just creating wrappers and passing in them those collection objects. Using react context afterwards to define a var for an array consisting of those wrapped objects. utility/static methods could work as well but personally hate them. idk wth i am talking about therefore your guidance and experience would be greatly appreciated.

I am really curious on how do you guys reuse functionality especially those who actively develop in meteor or any other js frameworks.

Astronomy is one option, the most common and recommended (in the Guide) though is simple-schema (with collection2). In addition to that you might want to check socialize:base-model that extends it further.

thanks for the response and yeah i feel like one of those packages is a must when using mongo for integrity and validation. More favoritism towards simpl-schema as it has less magic than astronomy while base-model seems pointless as you already would have to use simpl-schema and apart from what simpl-schema already provides, it gives little usefulness that could be replicated in a few minutes.

Anyways, what do you think of something like the below? is it too ridiculous?

super wrapper/model-ish class:

export default class BaseWrapper
{
    constructor(object)
    {
        //store original object from mongo
        this.object = object;

        //replicate props of object
        for(let prop of Object.keys(object))
        {
            this[prop] = object[prop];
        }
    }

    // just for fun
    // adding the feature from base-model
    userIdField = "userId";
    checkOwnership()
    {
        return Meteor.userId == this[this.userIdField];
    }
}

sub wrapper/model-ish class:

import moment from "moment";
import BaseWrapper from "./BaseWrapper";

export default class TaskWrapper extends BaseWrapper
{
    //optional declaration for IDE support
    createdAt;
    description;

    //some logic
    formatCreatedAt = () => ( moment(this.createdAt).format("MMMM, Do") );
    isValid = () => ( this.errors().length === 0);
    errors()
    {
        let errors = [];
        if(validator.isEmpty(this.description))
        {
            errors.push({
                key: "description",
                description: "Description cannot be empty"
            });
        }
        return errors;
    }
}

then in react:

import React from 'react';
import { withTracker } from 'meteor/react-meteor-data';
import { Tasks } from '../api/tasks.js';
import collect from 'collect.js';
import TaskWrapper from "../wrapper/TaskWrapper";


class App extends React.Component {
    render() {
        return (
            <div>App</div>
        )
    }
}

export default withTracker(() => {
    Meteor.subscribe('tasks');
    return {
        tasks: collect(Tasks.find({}).fetch()).transform((task) => (new TaskWrapper(task))),
    };
})(App);

then it seems like the app will benefit decent utility across the lifecycle. I am left scratching my head about how to get related models in a minimalistic manner. btw have u used the new withTracker, seen the blog post about it but never tried in action. what do u think of it?