
Security News
PodRocket Podcast: Inside the Recent npm Supply Chain Attacks
Socket CEO Feross Aboukhadijeh discusses the recent npm supply chain attacks on PodRocket, covering novel attack vectors and how developers can protect themselves.
A lightweight, in-memory document database for smaller projects. You can think of this as MongoDB's little brother.
A lightweight, in-memory document database for smaller projects. You can think of this as MongoDB's little brother.
npm i @prsm/db
For a more thorough API reference, please look at the tests in this repository.
A collection is just a .json
file.
import { Collection } from "@prism/db";
type Planet = {
planet: string;
diameter: number;
population?: number;
temp: {
avg: number;
};
};
// from `./.data` load or create `planets.json`
const collection = new Collection<Planet>(".data", "planets");
collection.insert({ planet: "Mercury", diameter: 4880, temp: { avg: 475 } });
collection.insert([
{ planet: "Venus", diameter: 12_104, temp: { avg: 737_000 } },
{ planet: "Earth", diameter: 12_742, temp: { avg: 288 } },
]);
// finds Earth document
collection.find({ avg: 288 });
collection.find({ planet: "Earth" });
// finds Venus and Earth documents
collection.find({ diameter: { $gt: 12_000 } });
// finds Mercury and Earth documents
collection.find({ temp: { avg: { $lt: 1_000 } } });
// finds Mercury and Earth documents
collection.find({ $and: [{ avg: { $gt: 100 } }, { avg: { $lt: 10_000 } }] });
Any queries that work with .find
work with .update
.
// increase population, creating the property if it doesn't exist.
collection.update({ planet: "Earth" }, { $inc: { population: 1 } });
Any queries that work with .find
work with .remove
.
// remove every planet except Earth
collection.remove({ $not: { planet: "Earth" } });
find
, update
and remove
accept a QueryOptions
object.
{
/** When true, attempts to deeply match the query against documents. */
deep: boolean;
/** Provide fallback values for null or undefined properties */
ifNull: Record<string, any>;
/** Provide fallback values for 'empty' properties ([], {}, "") */
ifEmpty: Record<string, any>;
/** Provide fallback values for null, undefined, or 'empty' properties. */
ifNullOrEmpty: Record<string, any>;
/**
* -1 || 0: descending
* 1: ascending
*/
sort: { [property: string]: -1 | 0 | 1 };
/**
* Particularly useful when sorting, `skip` defines the number of documents
* to ignore from the beginning of the result set.
*/
skip: number;
/** Determines the number of documents returned. */
take: number;
/**
* 1: property included in result document
* 0: property excluded from result document
*/
project: {
[property: string]: 0 | 1;
};
aggregate: {
[property: string]:
Record<"$floor", string> |
Record<"$ceil", string> |
Record<"$sub", (string|number)[]> |
Record<"$mult", (string|number)[]> |
Record<"$div", (string|number)[]> |
Record<"$add", (string|number)[]>;
};
join: Array<{
/** The collection to join on. */
collection: Collection<any>;
/** The property containing the foreign key(s). */
from: string;
/** The property on the joining collection that the foreign key should point to. */
on: string;
/** The name of the property to be created while will contain the joined documents. */
as: string;
/** QueryOptions that will be applied to the joined collection. */
options?: QueryOptions;
}>;
}
// [
// { a: 1, b: 2, c: 3 },
// ];
collection.find({ a: 1 }, { ifNull: { d: 4 } });
// [
// { a: 1, b: 2, c: 3, d: 4 },
// ];
// [
// { a: 1, b: 2, c: 3, d: " " },
// { a: 1, b: 2, c: 3, d: [] },
// { a: 1, b: 2, c: 3, d: {} },
// ];
collection.find({ a: 1 }, { ifEmpty: { d: 4 } });
// [
// { a: 1, b: 2, c: 3, d: 4 },
// { a: 1, b: 2, c: 3, d: 4 },
// { a: 1, b: 2, c: 3, d: 4 },
// ];
// [
// { name: "Deanna Troi", age: 28 },
// { name: "Worf", age: 24 },
// { name: "Xorf", age: 24 },
// { name: "Zorf", age: 24 },
// { name: "Jean-Luc Picard", age: 59 },
// { name: "William Riker", age: 29 },
// ];
collection.find({ age: { $gt: 1 } }, { sort: { age: 1, name: -1 } });
// └─ asc └─ desc
// [
// { name: "Zorf", age: 24 },
// { name: "Xorf", age: 24 },
// { name: "Worf", age: 24 },
// { name: "Deanna Troi", age: 28 },
// { name: "William Riker", age: 29 },
// { name: "Jean-Luc Picard", age: 59 },
// ];
Mostly useful when paired with sort
.
// [
// { a: 1, b: 1, c: 1 },
// { a: 2, b: 2, c: 2 },
// { a: 3, b: 3, c: 3 },
// ];
collection.find({ a: { $gt: 0 } }, { skip: 1, take: 1 });
// [
// { a: 2, b: 2, c: 2 },
// ];
The ID property of a document is always included unless explicitly excluded.
When all projected properties have a value of 1
, this
is "implicit exclusion" mode.
In this mode, all document properties that are not defined in the projection are excluded from the result document.
// [
// { a: 1, b: 1, c: 1 },
// ];
collection.find({ a: 1 }, { project: { b: 1 } });
// [
// { _id: .., b: 1 },
// ];
When all projected properties have a value of 0
, this
is "implicit inclusion" mode.
In this mode, all document properties that are not defined in the projection are included from the result document.
// [
// { a: 1, b: 1, c: 1 },
// ];
collection.find({ a: 1 }, { project: { b: 0 } });
// [
// { _id: .., a: 1, c: 1 },
// ];
In the only remaining case, all document properties
are included unless explicitly removed with a 0
.
This is effectively the same behavior as implicit inclusion.
// [
// { a: 1, b: 1, c: 1 },
// ];
collection.find({ a: 1 }, { project: { b: 1, c: 0 } });
// [
// { _id: .., a: 1, b: 1 },
// ];
// [
// { math: 72, english: 82, science: 92 },
// { math: 60, english: 70, science: 80 },
// { math: 90, english: 72, science: 84 }
// ]
collection.find(
{},
{
aggregate: {
total: { $add: ["math", "english", "science"] },
average: { $div: ["total", 3] },
},
project: {
_id: 0,
total: 0,
},
}
);
// [
// { math: 72, english: 82, science: 92, average: 82 },
// { math: 60, english: 70, science: 80, average: 70 },
// { math: 90, english: 72, science: 84, average: 82 },
// ]
// "users" collection
// [
// { name: "Alice", purchasedTicketIds: [1, 2] },
// ];
// "tickets" collection
// [
// { _id: 0, seat: "A1" },
// { _id: 1, seat: "B1" },
// { _id: 2, seat: "C1" },
// { _id: 3, seat: "D1" },
// ];
users.find(
{ name: "Alice" },
{
join: [
{
collection: tickets,
from: "purchasedTicketIds",
on: "_id",
as: "tickets",
options: {
project: { _id: 0 },
},
},
],
}
);
// [
// {
// name: "Alice",
// purchasedTicketIds: [1, 2],
// tickets: [
// { seat: "B1" },
// { seat: "C1" },
// ],
// },
// ];
join
allows for QueryOptions
which in turn alows for join
.
This means that joins can be chained for more complex relationships
between collections.
users.find(
{ .. },
{
join: [{
collection: tickets,
options: {
join: [{
collection: seats,
options: {
join: [{
collection: auditoriums,
}]
}
}]
}
}]
}
);
The default property names for document ID (default _id
), "created at"
(default _created_at
) and "updated at" (default _updated_at
) timestamps can all be changed.
import { ID_KEY, CREATED_AT_KEY, UPDATED_AT_KEY } from "@prism/db";
ID_KEY = "id";
CREATED_AT_KEY = "createdAt";
UPDATED_AT_KEY = "updatedAt";
If you do this, make sure to do it at the beginning of collection creation.
The returned value from find
, update
and remove
is always an array, even when there
are no results.
FAQs
A lightweight, in-memory document database for smaller projects. You can think of this as MongoDB's little brother.
We found that @prsm/db demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Socket CEO Feross Aboukhadijeh discusses the recent npm supply chain attacks on PodRocket, covering novel attack vectors and how developers can protect themselves.
Security News
Maintainers back GitHub’s npm security overhaul but raise concerns about CI/CD workflows, enterprise support, and token management.
Product
Socket Firewall is a free tool that blocks malicious packages at install time, giving developers proactive protection against rising supply chain attacks.