A high-performance, multi-tenant database orchestration and synchronization routing layer. It dynamically manages distributed data architectures, allowing applications to read from and write to multiple databases simultaneously in parallel using a single unified payload object. It handles tenant-isolated workspace caching, orchestrates cross-database data synchronization, and bridges real-time WebSocket communication matrices with structural persistence.
- Features
- Supported Database Engines
- Installation
- Usage A high-performance, multi-tenant database orchestration and synchronization routing layer.
This README focuses on the unified payload contract and practical examples so integrators immediately understand how to use the server-side CRUD router. The @cocreate/crud-server runtime accepts a single standardized payload object and routes it to the appropriate storage adapters (one or many) and transports (local drivers, remote sockets).
Summary
- Single, unified payload contract drives all operations (
methoddetermines behavior). - Operates in multi-tenant mode using
organization_idto scope execution. - Supports parallel write/read across multiple storage adapters via
storagearray.
Table of contents
- Features
- Installation
- Quick start (server initialization)
- Payload examples (common tasks)
- WebSocket & transport patterns
- Configuration & tips
- Contributing
- License
Features
- Unified object payload API for all CRUD operations.
- Multi-tenant isolation by
organization_id. - Parallel multi-storage execution when
storageis an array. - Pluggable drivers via dynamic
import(). - WebSocket integration for real-time actions and synchronization.
Installation
npm install @cocreate/crud-serverQuick start — initialize during server bootstrap
import crudServer from '@cocreate/crud-server';
import CoCreateServer from '@cocreate/cluster';
const server = await CoCreateServer.start();
await crudServer.init(server);
// After init, you can call the router directly
await crudServer.send({
organization_id: 'org1',
method: 'object.create',
array: 'users',
storage: 'mongodb',
object: [{ name: 'Alice', email: 'alice@example.com' }]
});Bootstrap storage configuration
CoCreate.config.js stores a single flat bootstrap connection:
export default {
storage: {
name: 'platform-mongodb',
provider: 'mongodb',
connectionString: 'mongodb://host/platform'
}
};Startup uses Config.prompt() to request a single valid JSON storage object
when storage is not configured. Include non-empty name and provider strings
and the credential fields required by the driver. For example:
{"name":"primary","provider":"mongodb","connectionString":"mongodb://host/platform"}.
Credential field names and nested credential objects are preserved as supplied;
the driver validates its connection requirements. Valid prompt input is parsed
before it is saved as the global storage object. Existing local, global, or
environment configuration is used without prompting. Storage is selected as one
complete object; local and global credential fields are not merged. Omit local
storage to inherit the global object. The environment carries the object as
JSON for child processes.
Bootstrap storage and named apis storage records are passed unchanged to the
driver as storageConfig. Bootstrap arrays and maps keyed by connection name are
not supported. Omit a CRUD request's storage to use the bootstrap connection,
or specify its exact name. Other names resolve enabled storage records from
apis using the bootstrap connection.
Core payload contract
method(String) — dot-notated action identifier, e.g.object.create,object.read,object.update,array.list.organization_id(String) — tenant identifier (required for multi-tenant deployments).array(String) — logical collection/table name.storage(String | Array) — named storage adapter(s) to target. When an array is supplied, the same payload runs in parallel against each matching driver.object(Array) — document(s) for create/update/delete operations.filter(Object) — optional query, paging, sort and projection controls.- The client-side
@cocreate/crud-clientsends the same unified payload viacrud.send()which will route the request locally (IndexedDB) and remotely viacrud.socket.send(). - On the server, socket messages map directly into the same
crudServer.send(payload)contract. This keeps the client and server API identical and stateless. - Ensure
organization_idis supplied for multi-tenant routing. - When targeting multiple storages use the
storagearray; the router runs each adapter in parallel and returns consolidated responses. - Bootstrap values are loaded through
Config.prompt. Local configuration undercrudis then merged over the bootstrap values, followed by scoped platformservers_configrecords withtype: "crud". Database configuration has the highest precedence. organizationStorageFallbackcontrols routing when an organization has no storage. Its optionalstoragenames a platform storage; when omitted, the platform default is used.database: "$organization_id"keeps a database per tenant, while another string selects a literal shared database. Set the option tofalseto disable fallback. File requests retain host-owned routing and always use the platform default storage with the requesting organization database when storage fallback is needed.- For long-running operations or streaming transports (AI sessions), implement plugin-level session tracking and persist conversation history via
server.crudon the server side.
Examples — common operations
Create
await crudServer.send({
method: 'object.create',
organization_id: 'org1',
array: 'posts',
storage: 'mongodb',
object: [{ title: 'Hello', body: 'World' }]
});Read (with filter)
const res = await crudServer.send({
method: 'object.read',
organization_id: 'org1',
array: 'users',
filter: { query: { email: 'alice@example.com' }, limit: 1 }
});Update (parallel to two storages)
await crudServer.send({
method: 'object.update',
organization_id: 'org1',
array: 'users',
storage: ['mongodb','pgsql-backup'],
object: [{ _id: 'abc123', active: true }]
});Delete
await crudServer.send({
method: 'object.delete',
organization_id: 'org1',
array: 'sessions',
object: [{ _id: 'session_xyz' }]
});WebSocket / transport patterns
Example: sending an AI prompt to a Copilot plugin (convention)
// client: send via crud.socket.send
await crud.socket.send({
method: 'copilot.chat',
copilot: {
prompt: 'Generate a hero section',
organization_id: 'org1',
user_id: 'u1'
}
});
// server plugin receives payload and routes to AI engine
// plugin will read payload.copilot and persist history using server.crudConfiguration & tips
Contributing Contributions are welcome. See CONTRIBUTING.md in the repo for guidance and tests.
License This software is dual-licensed under AGPLv3 and a commercial license. See the repository LICENSE file for details.