npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@haventech/persistor

v13.0.1

Published

A subclass of supertype that serializes to and reconstitutes from MongoDB or SQL databases

Downloads

475

Readme

Persistor

Description

Persistor is a subclass of SuperType that serializes to and reconstitutes from mongoDB or PostgreSQL.

Installation

It is automatically installed with Amorphic

Example

First create some object templates (many-to-many example):

var ObjectTemplate = require('@haventech/supertype').default;
var PersistObjectTemplate = require('persistor')(ObjectTemplate, null, ObjectTemplate);

var Customer = PersistObjectTemplate.create("customer:Customer", {
    email:		{type: String},
    firstName:  {type: String},
    middleName: {type: String},
    lastName:	{type: String}
});

var Account = PersistObjectTemplate.create("account:Account", {
    init:       function (number, title, customer) {
        this.number = number;
        this.title = title;
        if (customer)
            this.addCustomer(customer);
    },
    addCustomer: function(customer, relationship) {
        var role = new Role(customer, this, relationship);
        this.roles.push(role);
        customer.roles.push(role);
    },
    number:     {type: Number},
    title:      {type: Array, of: String, max: 4}
});

var Role = PersistObjectTemplate.create("role:Role", {
    init:       function (customer, account, relationship) {
        this.customer = customer;
        this.account = account;
        if (relationship)
            this.relationship = relationship;
    },
    relationship: {type: String, value: "primary"},
    customer:     {type: Customer}
});

Customer.mixin({
    roles:      {type: Array, of: Role, value: [], fetch: true}
});

Account.mixin({
    roles:      {type: Array, of: Role, value: [], fetch: true}
});

Next you need a schema but this schema only defines the foreign key relationships

var collections = {
    customer: {
        children: {
            roles: {template: Role, id:"customer_id"}
        }
    },
    account: {
        children: {
            roles: {id:"account_id"}
        }
    },
    role: {
        parents: {
            customer: {id: 'customer_id'},
            account: {id: 'account_id'}
        }
    },
};

In the schema, the high level properties, customer, account and role are the names of the documents and must match the names of the documents in the template definition which is always :

var Role = PersistObjectTemplate.create("role:Role", {

Then open your database and set the schema

return Q.ninvoke(MongoClient, "connect", "mongodb://localhost:27017/testpersist").then(function (db) {
    PersistObjectTemplate.setDB(db);
    PersistObjectTemplate.setSchema(collections);
    return Q(db);
}).then ....;

Create some objects

var sam = new Customer("Sam", "M", "Elsamman");
var karen = new Customer("Karen", "", "Burke");
var account = new Account(123, ['Sam Elsamman', 'Karen Burke'], sam);
account.addCustomer(karen, "joint");

Persist the top level and any connected dirty objects will automatically persist as well, managing all foreign keys needed to maintain the relationships.

sam.persistSave().then(function() {
    // id inserted after saving
    return Q(sam._id);
}).then ....

And retrieve stuff back by id, cascading down to fetch the roles as well.

Customer.getFromPersistWithId(customer_id, {roles: true}).then (function (customer) {
    // Customer object complete with collection of role objects fetched and instantiated
});
    

Or fetch with a query

Customer.getFromPersistWithQuery({lastName: "Elsamman"}, {roles: true}).then (function (customer) {
    // Customer object complete with collection of role objects fetched and instantiated
});

The account object connected to the fetched role is also automatically when a role is fetched because the template specified {fetch: true}. Had it not been specified you would manually fetch the related account object like this

Customer.getFromPersistWithId(customer_id, {roles: true}).then (function (customer) {
    customer.role[0].fetch({account: true}).then(function() {
        // Now you can reference customer.role[0].account
    });
});

Debugging the container

1. Remove local node_modules folder and delete package-lock file and run the following commnd to launch the container in debug mode.
    npm run test:docker:debug

    If you are using Visual Studio Code, you can use the following setting to attach to the debugging container.
        {
            "type": "node",
            "request": "attach",
            "name": "persistor_debug",
            "port": 5858,
            "localRoot": "${workspaceFolder}",
            "remoteRoot": "/app"
        }

Debugging in the local environment.

    2. Make sure to install the mongodb and postgres locally and set the environment variables from the test.local.env file.
        If you are using Visual Studio Code, you can use the following setting to debug.
             {
                "type": "node",
                "request": "launch",
                "name": "Mocha Tests",
                "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
                "args": [
                    "-u",
                    "tdd",
                    "--timeout",
                    "999999",
                    "--colors",
                    "${workspaceFolder}/test"
                ],
                "envFile": "${workspaceFolder}/test.local.env",
                "internalConsoleOptions": "openOnSessionStart"
            }
    

Important features:

Version 10.0.0

With this version we are introducing a config enableIsRemoteObjectFeature as a required flag, to enable isRemoteObject property to take effect. This is to allow modules to set their isRemoteObject flag to true and client apps can safely upgrade to these modules without the requirement to also start using remote storage. When clients are ready to take advantage of isRemoteObject property, they can simply set the enableIsRemoteObjectFeature config to true in their respective config file(s). CAUTION: This is an all or nothing flag. Once enableIsRemoteObjectFeature is set to true:

  1. The isRemoteObject behavior defined on individual record properties will be enabled across your app (including the ones on your modules).
  2. All properties where isRemoteObject is set to true, would need to be migrated to a remote storage, as going forward their retreival and storage would happen from remote storage.
  3. If a client is already using isRemoteObject to send docs to remote storage, they must set enableIsRemoteObjectFeature this flag to true in their config.

Behavior: Only the first scenario will result in storage to s3.

  1. if isRemoteObject is true and enableIsRemoteObjectFeature is true -> persistor will store in remote s3 bucket.
  2. if isRemoteObject is false and enableIsRemoteObjectFeature is false -> persistor will store in db.
  3. if isRemoteObject is false and enableIsRemoteObjectFeature is true -> persistor will store in db.
  4. if isRemoteObject is true and enableIsRemoteObjectFeature is false -> persistor will store in db.
  5. if isRemoteObject is undefined or not set on record property and enableIsRemoteObjectFeature is true -> persistor will store in db.
  6. if isRemoteObject is undefined or not set on record property and enableIsRemoteObjectFeature is false -> persistor will store in db.
  7. if isRemoteObject is false and enableIsRemoteObjectFeature is undefined or not set on client -> persistor will store in db.
  8. if isRemoteObject is true and enableIsRemoteObjectFeature is undefined or not set on client -> persistor will store in db.
  9. if isRemoteObject is undefined or not set on record property and enableIsRemoteObjectFeature is undefined or not set on client -> persistor will store in db.

License

Persistor is licensed under the MIT license