This repository contains:
- client/: The Sengo MongoDB-like client library (TypeScript, Node.js) (client/README.md)
- shell/: An interactive shell for using the Sengo client (shell/README.md)
Sengo is designed for small, cost-sensitive applications that use AWS S3 for document storage. It is ideal for apps with infrequent use (e.g., volunteer orgs, occasional data entry) and aims for near-zero storage costs when idle. Sengo supports efficient search and retrieval via a flexible, document-based indexing system. See client/INDEX-DESIGN.md for details on the indexing feature design and future plans.
-
Install dependencies for all packages:
npm install
-
Build all packages:
npm run build
-
Clean all build outputs:
npm run clean
-
Start the interactive shell:
npm start
This will launch the shell in the
shellpackage.
After installing dependencies, you can launch the interactive Sengo shell directly using:
npx sengoOr, if installed globally:
sengoThis will start the shell and allow you to connect to a memory or S3-backed repository, run commands, and interact with your data.
For more details, see shell/README.md.
-
To use the shell interactively:
cd shell npm start -
To use the client library, see
client/README.mdfor details.
Sengo gives you a MongoDB-like programming model for common application workflows, with data stored in S3.
What you can do today:
- Insert a single document with
insertOne - Query documents with
findandfindOne - Update a single document with
updateOneusing$set - Delete a single document with
deleteOne - Create, list, and drop indexes with
createIndex,listIndexes, anddropIndex - Sort and limit query results using query options
Supported query operators:
- Logical:
$or - Comparison/membership:
$eq,$ne,$gt,$gte,$lt,$lte,$in,$nin,$exists - Direct field equality: for example
{ status: 'active' }
Important behavior notes:
limitis supported as a query option, not as a query operator.findOnealways returns at most one document.updateOnecurrently supports$setstyle updates.
import { SengoClient } from 'sengo';
type Order = {
customerId: string;
status: 'new' | 'processing' | 'shipped';
total: number;
createdAt: string;
};
const client = new SengoClient();
const orders = client.db('s3').collection<Order>('orders');
// Insert
await orders.insertOne({
customerId: 'cust-123',
status: 'new',
total: 149.99,
createdAt: new Date().toISOString(),
});
// Find with operators + sort + limit
const recentHighValue = await orders.find(
{
status: { $in: ['new', 'processing'] },
total: { $gte: 100 },
},
{
sort: { createdAt: -1 },
limit: 20,
}
).toArray();
// Find one
const oneOrder = await orders.findOne({ customerId: 'cust-123' }, { sort: { createdAt: -1 } });
// Update one with $set
await orders.updateOne(
{ customerId: 'cust-123', status: 'new' },
{ $set: { status: 'processing' } }
);
// Delete one
await orders.deleteOne({ customerId: 'cust-123', status: 'shipped' });
await client.close();In S3-backed systems, the expensive part of a query is usually loading full document files. Indexes help reduce those reads.
- Single-field index, for frequent filters on one field:
createIndex({ status: 1 })
- Compound index, for filter + sort patterns:
createIndex({ customerId: 1, createdAt: -1 })
- Put equality/filter fields first.
- Put the main sort or range field last.
This lets Sengo use index ordering more effectively, especially for top-N queries (sort + limit).
import { SengoClient } from 'sengo';
type Event = {
accountId: string;
severity: 'info' | 'warn' | 'error';
timestamp: number;
message: string;
};
const client = new SengoClient();
const events = client.db('s3').collection<Event>('events');
// Index for account-scoped timelines
await events.createIndex({ accountId: 1, timestamp: -1 });
// Query pattern aligned with that index
const latest = await events.find(
{ accountId: 'acct-42', severity: { $in: ['warn', 'error'] } },
{ sort: { timestamp: -1 }, limit: 50 }
).toArray();
await client.close();For deeper technical details and test-backed support matrices, see:
The sengo skill is intended for projects that consume Sengo, not just this monorepo.
From this repository, run:
npm run install-client-skill -- <path-to-consumer-project>This copies the skill to:
<consumer-project>/.github/skills/sengo/
If you run the command without a path, it installs to the current working directory.
SKILL.mdreferences/SUPPORTED-COMMANDS-OPERATORS.mdreferences/SUPPORTED-INDEX-FEATURES.mdVERSION.md
- Re-run the install command against the consumer project.
- Review
VERSION.mdin the target project to confirm the installed version. - Re-test a few prompts in the consumer project:
- insert
- find/findOne with sort/limit
- updateOne with
$set - index recommendations
For more information, see the individual client/README.md and shell/README.md files in each package.