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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@simtlix/simfinity-js

v3.7.0

Published

MongoDB/Mongoose adapter and compatibility facade for Simfinity GraphQL APIs

Readme

@simtlix/simfinity-js

MongoDB/Mongoose adapter and compatibility facade for Simfinity. This package generates GraphQL queries, mutations, relationships and models from GraphQLObjectType definitions using the shared Simfinity runtime.

npm install @simtlix/simfinity-js graphql@^16.11.0 mongoose@^8.24.2

graphql and mongoose are peer dependencies: the facade uses your application's copies, and npm reports an out-of-range version as a peer conflict instead of installing a second copy. The MCP transports (createMCPServer, startStdioMCPServer, createHTTPMCPHandler) need the optional peer @modelcontextprotocol/sdk@^1.31.0; install it only when you use them. generateMCPTools works without it. The package does not install graphql-middleware.

import mongoose from 'mongoose';
import * as simfinity from '@simtlix/simfinity-js';

await mongoose.connect(process.env.MONGODB_URI);
// Register your GraphQLObjectType definitions before creating the schema.
simfinity.connect(null, SerieType, 'serie', 'series');
const schema = simfinity.createSchema();

Use a MongoDB replica set or sharded cluster for transactional mutations. The library requires Node.js >=18.18.0 and GraphQL 16.

Generated single-reference reads can be batched within a request. Models with any find or findOne pre/post query hook retain individual findOne reads, including hooks shared by both operations, to preserve access restrictions and other middleware behavior. For the same reason, they keep the read that generated mutations otherwise skip before a delete without onDelete and before an update that merges no embedded value. So do models with findOneAndUpdate or findOneAndDelete hooks (including the one Mongoose's timestamps option adds) or with their own findById, findOne, findByIdAndUpdate, findOneAndUpdate, findByIdAndDelete or findOneAndDelete statics, which run before Mongoose casts the ID: the read rejects a malformed ID first. Models with application _id setters also keep the read, because setters can branch on the query operation before casting; Mongoose's built-in automatic ObjectId setter remains eligible for the optimization. See the relationship contract.

Generated models store enum internal values with their own type (numbers, booleans or strings; other combinations as given) and support embedded fields named type. Embedded types that contain each other are rejected with INVALID_MODEL (Embedded cycle at …) when a generated model reaches them, and always in transactional mode; in the default mode, a cycle that only supplied models reach is not checked. Range filters, sorts and aggregates on numeric and boolean enums follow that type; PostgreSQL uses their text form. Earlier versions stored numeric and boolean enum values as strings; convert existing documents once as described in the schema guide.

The facade registers generated models on your application's default Mongoose instance and does not change global Mongoose options such as strictQuery. Supplied models may use another connection, such as one from mongoose.createConnection(): generated mutations and saveObject() use the model's connection, and, in the default referentialIntegrity: 'off' mode, custom mutations use the default connection unless it is unused, never opened and without compiled models, also on its useDb() descendants, and the registered models share one MongoDB client; with transactional reference integrity they use the first protected model's connection. createMongoAdapter().castId accepts only an ObjectId or its 24-character hexadecimal string and throws NOT_VALID_ID (400) otherwise; create new identifiers with new mongoose.Types.ObjectId(). Owned transactions retry transient failures after a short random delay, and a write conflict that outlasts the retries fails with TRANSACTION_RETRY_EXCEEDED (409).

Mongoose 8.24.2 or later within version 8 is required to exclude the update-casting prototype-pollution vulnerability. Existing applications should update Mongoose and their dependency lockfile, then run npm audit; upgrading Simfinity does not refresh every transitive dependency already locked by the application.

Optional batched collection reads

Generated collection fields read one parent at a time by default. With batchedCollections: true, the adapter reads the collection fields of many parents that share their arguments with aggregate commands of up to collectionBatchSize parents each (an integer from 1 to 100, default 5), sent concurrently:

import { createMongoAdapter, createRuntime } from '@simtlix/simfinity-js';

const adapter = createMongoAdapter({ batchedCollections: true }); // collectionBatchSize: 5
const simfinity = createRuntime(adapter);

Each parent's own pipeline (filters, sort and page) runs as one sub-pipeline: the first is the command's pipeline and the others are $unionWith stages. Like referentialIntegrity, the option needs your own adapter and runtime; the package-root runtime (simfinity.connect() and the rest) keeps one read per parent. Children of models with aggregate middleware, their own aggregate static, a discriminator child model or a wrapped Model.collection.aggregate, reads inside a transactionAsyncLocalStorage transaction, and adapter copies or overrides of findChildren keep one read per parent. A command runs its sub-pipelines one after another, so fewer commands can come with a slower single request, and command monitoring, query settings and $queryStats see the new command shape: read the upgrade notes before enabling it. Invalid values throw INVALID_MONGO_ADAPTER_OPTIONS (400).

Optional transactional reference integrity

Choose the mode once when creating an adapter; the default remains 'off':

import { createMongoAdapter, createRuntime } from '@simtlix/simfinity-js';

const adapter = createMongoAdapter({ referentialIntegrity: 'transactional' });
const simfinity = createRuntime(adapter);
await mongoose.connect(process.env.MONGODB_URI);
// Register every application type on this runtime.
simfinity.connect(null, SerieType, 'serie', 'series');
const schema = simfinity.createSchema();
await adapter.initialize();

Initialization checks transaction support and audits existing references. Protected mutations reject nonexistent references, including embedded paths, inferred/private inverse keys and explicit link entities. Deleting a referenced target is restricted. Target-document writes coordinate concurrent creation/deletion; a violation rolls back the whole mutation with REFERENCE_CONSTRAINT_VIOLATION (409).

Owned transactions use snapshot reads and majority commits. Supplied sessions need the same options; a reference violation or guarded-write error aborts even a supplied transaction. The reserved _simfinityReferenceLock storage field is excluded from GraphQL. All writers must use the same complete registry and mode. Direct Mongoose/driver writes bypass this protection; this is not a native MongoDB FK. Read the full setup, concurrency and migration contract.

The source now lives in packages/mongodb in the monorepo. Its public npm name remains @simtlix/simfinity-js; existing imports, including paths under @simtlix/simfinity-js/src/, retain their layout. Shared helpers, error identities and MCP compatibility exports are preserved. Internal Simfinity dependencies use the same exact release version.

Its legacy src/ modules that re-export public API (src/index.js, src/auth/index.js, src/auth/errors.js, src/auth/expressions.js, src/auth/rules.js, src/plugins.js, src/scalars.js, src/validators.js, src/mcp.js, src/const/*.js, src/errors/*.js, and their extensionless aliases) ship TypeScript declarations with the types of the package root and the matching @simtlix/simfinity-core subpaths; src/mongo/* is internal and undeclared. New code should still import auth, plugins, scalars and validators from the package root. Importing the typed @simtlix/simfinity-core subpaths, such as @simtlix/simfinity-core/auth, instead needs @simtlix/simfinity-core as a direct dependency pinned to this package's exact version.

For tooling that locates the package, use require.resolve('@simtlix/simfinity-js/package.json') or the package root without a trailing slash. Directory specifiers ending in / were not valid ESM imports and are not supported by the export map, including in require.resolve; use explicit filenames such as src/auth/index.js.