@cocreate/crud-server 1.37.2 → 1.37.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -37
- package/package.json +23 -11
- package/src/index.js +20 -17
package/README.md
CHANGED
|
@@ -1,65 +1,145 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @cocreate/crud-server
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
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.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-

|
|
7
|
-

|
|
8
|
-

|
|
5
|
+
---
|
|
9
6
|
|
|
10
|
-
|
|
7
|
+
## Table of Contents
|
|
11
8
|
|
|
12
|
-
[
|
|
9
|
+
* [Features](#features)
|
|
10
|
+
* [Supported Database Engines](#supported-database-engines)
|
|
11
|
+
* [Installation](#installation)
|
|
12
|
+
* [Usage](#usage)
|
|
13
|
+
* [How it Works](#how-it-works)
|
|
14
|
+
* [Architecture and Payload Specs](#architecture-and-payload-specs)
|
|
15
|
+
* [Configuration Guidelines](#configuration-guidelines)
|
|
16
|
+
* [How to Contribute](#how-to-contribute)
|
|
17
|
+
* [License](#license)
|
|
13
18
|
|
|
14
|
-
|
|
19
|
+
---
|
|
15
20
|
|
|
16
|
-
|
|
21
|
+
## Features
|
|
17
22
|
|
|
18
|
-
|
|
23
|
+
* **Parallel Multi-Database Execution:** Connects seamlessly to multiple storage endpoints simultaneously. Data mutation queries execute in parallel across all defined database engines for immediate multi-source consistency.
|
|
24
|
+
* **Unified Object Architecture:** Send data once. A single, standardized data object schema abstractly targets and updates multiple heterogeneous databases in parallel, eliminating the need for database-specific query translation at the application layer.
|
|
25
|
+
* **Multi-Tenant Isolation:** Dynamically maps connection strategies by checking unique incoming system `host` configurations or structural `organization_id` tracking elements.
|
|
26
|
+
* **Dynamic Driver Pluggability:** Follows a convention-over-configuration strategy to load target database driver utilities lazily via asynchronous dynamic imports.
|
|
27
|
+
* **V8 Coalescing Caching Engine:** Features an efficient, state-retaining in-memory pool for fast organization tracking, eliminating redundant disk I/O bottlenecks.
|
|
28
|
+
* **Dual-Layer Communication Matrix:** Listens directly for transactional mutations across core function calls (`send()`) or updates data trees over real-time WebSockets using dedicated event hooks.
|
|
29
|
+
* **Cross-Organization Synchronization:** Automatically intercepts administration-level document mutations to sync system properties instantly across tenant environments.
|
|
19
30
|
|
|
20
|
-
|
|
21
|
-
- [Announcements](#announcements)
|
|
22
|
-
- [Roadmap](#roadmap)
|
|
23
|
-
- [How to Contribute](#how-to-contribute)
|
|
24
|
-
- [About](#about)
|
|
25
|
-
- [License](#license)
|
|
31
|
+
---
|
|
26
32
|
|
|
27
|
-
|
|
33
|
+
## Supported Database Engines
|
|
28
34
|
|
|
29
|
-
|
|
35
|
+
The server engine natively resolves external adapters across a wide variety of relational, NoSQL, vector, and distributed architectures using a single unified payload contract:
|
|
30
36
|
|
|
31
|
-
|
|
37
|
+
| Relational & SQL | Cloud NoSQL & Document | Distributed & Edge | Specialized & OLAP |
|
|
38
|
+
| :--- | :--- | :--- | :--- |
|
|
39
|
+
| • MySQL<br>• PostgreSQL<br>• MariaDB<br>• OracleDB<br>• SQLite | • MongoDB<br>• Firestore<br>• DocumentDB<br>• FerretDB | • CockroachDB<br>• TiDB<br>• PlanetScale<br>• Turso<br>• YugabyteDB | • Amazon Redshift<br>• DynamoDB<br>• CosmosDB<br>• Qdrant *(Vector)*<br>• TimescaleDB *(Time-series)*<br>• Rqlite / Dqlite *(Distributed SQL)* |
|
|
32
40
|
|
|
33
|
-
|
|
41
|
+
---
|
|
34
42
|
|
|
35
|
-
|
|
43
|
+
## Installation
|
|
36
44
|
|
|
37
|
-
|
|
45
|
+
```bash
|
|
46
|
+
npm install @cocreate/crud-server
|
|
47
|
+
```
|
|
38
48
|
|
|
39
|
-
|
|
49
|
+
---
|
|
40
50
|
|
|
41
|
-
|
|
51
|
+
## Usage
|
|
42
52
|
|
|
43
|
-
|
|
53
|
+
### Server Initialization
|
|
44
54
|
|
|
45
|
-
|
|
55
|
+
Bind the CRUD controller during the initialization workflow of your core `CoCreateServer` context:
|
|
46
56
|
|
|
47
|
-
|
|
57
|
+
```javascript
|
|
58
|
+
import crudServer from '@cocreate/crud-server';
|
|
59
|
+
import { CoCreateServer } from '@cocreate/server';
|
|
48
60
|
|
|
49
|
-
|
|
61
|
+
// Boot the primary application server instance
|
|
62
|
+
const serverContext = await CoCreateServer.start();
|
|
50
63
|
|
|
51
|
-
|
|
64
|
+
// Initialize the stateless routing layer
|
|
65
|
+
await crudServer.init(serverContext);
|
|
66
|
+
```
|
|
52
67
|
|
|
53
|
-
|
|
68
|
+
### Direct Programmatic CRUD Operations
|
|
54
69
|
|
|
55
|
-
|
|
70
|
+
Execute transactional database updates across configured engines via asynchronous queries using a single unified object:
|
|
56
71
|
|
|
57
|
-
|
|
72
|
+
```javascript
|
|
73
|
+
import crudServer from '@cocreate/crud-server';
|
|
58
74
|
|
|
59
|
-
This
|
|
75
|
+
// This single unified payload object targets and writes to all matching drivers in parallel
|
|
76
|
+
const payload = {
|
|
77
|
+
organization_id: "64b9a32e18f21bc56789abcd",
|
|
78
|
+
method: "object.update",
|
|
79
|
+
array: "users",
|
|
80
|
+
storage: ["primary-mongodb", "backup-postgresql"], // Invokes parallel driver execution
|
|
81
|
+
object: [{ _id: "75c2e12a45f91bd45123efab", status: "active" }]
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const result = await crudServer.send(payload);
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## How it Works
|
|
90
|
+
|
|
91
|
+
1. **Bootstrap & Driver Injection:** On start, the platform invokes `@cocreate/config` to prompt for missing environment variables, extracts storage configuration blocks, and dynamically pulls matching database driver modules sequentially via `import()`.
|
|
92
|
+
2. **WebSocket Handshake Mapping:** If a real-time framework context is present, the server maps system scopes (`storage`, `database`, `array`, `index`, `object`) against mutations (`create`, `read`, `update`, `delete`), registering action event listeners over active socket networks.
|
|
93
|
+
3. **Tenant Evaluation Pass:** For every action, `getOrganization()` evaluates incoming tracking tags against memory caches (`hosts` and `organizations`) to load tenant-specific connection rules.
|
|
94
|
+
4. **Symmetrical Multi-Database Processing:** Loops through arrays provided inside the `data.storage` key. If an item matches several configured providers, the router breaks down the single unified object payload and routes it concurrently to each designated engine database in an asynchronous parallel loop (`await providers[storage.provider].send(data)`).
|
|
95
|
+
5. **Data Formatting & Post-Processing:** Applies server-side filters, manages sorting array indices via utility methods, syncs sensitive profile updates between platform entities, and emits a global `crud-event` event before returning a response.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Architecture and Payload Specs
|
|
100
|
+
|
|
101
|
+
### Unified Payload Object Schema
|
|
102
|
+
|
|
103
|
+
The data engine relies heavily on structural, flat parameter objects passed down into the execution chain:
|
|
104
|
+
|
|
105
|
+
| Field Element | Type | Role |
|
|
106
|
+
| --- | --- | --- |
|
|
107
|
+
| `organization_id` | `String` | **Required.** Targets the root tenant profile partition mapping to execution databases. |
|
|
108
|
+
| `method` | `String` | Operational identifier following dot notations (e.g., `"object.read"`, `"array.update"`). |
|
|
109
|
+
| `array` | `String` | Target database collection or sheet name context. |
|
|
110
|
+
| `storage` | `String \| Array` | Specific storage adapter name(s). Pass an array of strings to invoke parallel execution across multiple targets. |
|
|
111
|
+
| `object` | `Array<Object>` | Raw workspace target objects or tracking query arguments containing targeted IDs (`_id`). |
|
|
112
|
+
| `$filter` | `Object` | Extra functional configuration object containing query criteria, array boundaries, limits, and sort constraints. |
|
|
113
|
+
|
|
114
|
+
---
|
|
60
115
|
|
|
61
|
-
|
|
116
|
+
## Configuration Guidelines
|
|
62
117
|
|
|
63
|
-
|
|
118
|
+
Upon launching the engine for the first time, your terminal context will request essential operational parameters via standard inputs if a local profile isn't active:
|
|
119
|
+
|
|
120
|
+
```text
|
|
121
|
+
Enter your organization_id: 64b9a32e18f21bc56789abcd
|
|
122
|
+
Enter a friendly name for the new storage (e.g., primary): primary
|
|
123
|
+
Enter the storage provider (e.g., mongodb): mongodb
|
|
124
|
+
Enter the storage connection url: mongodb://localhost:27017/cocreate
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
> [!WARNING]
|
|
128
|
+
> If a valid configuration URL (`url`) or an `organization_id` cannot be discovered on boot, the system outputs failure diagnostic metrics to the terminal and forcefully triggers a hard process kill state (`process.exit(1)`).
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## How to Contribute
|
|
133
|
+
|
|
134
|
+
We encourage contribution to our libraries (you might even score some nifty swag), please see our [CONTRIBUTING.md](https://github.com/CoCreate-app/CoCreate-crud-server/blob/master/CONTRIBUTING.md) guide for details. If you encounter any bugs or wish to make feature requests, please submit an issue on our [GitHub Issues](https://github.com/CoCreate-app/CoCreate-crud-server/issues) tracker. We want this library to be community-driven, and CoCreate led. We need your help to realize this goal.
|
|
135
|
+
|
|
136
|
+
For broader system configurations and API guides, please visit our [CoCreate CRUD Server Documentation](https://cocreatejs.com/docs/crud-server).
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## License
|
|
141
|
+
|
|
142
|
+
This software is dual-licensed under the GNU Affero General Public License version 3 (AGPLv3) and a commercial license.
|
|
64
143
|
|
|
65
|
-
|
|
144
|
+
* **Open Source Use:** For open-source projects and non-commercial use, this software is available under the AGPLv3. For the full license text, see the LICENSE file.
|
|
145
|
+
* **Commercial Use:** For-profit companies and individuals intending to use this software for commercial purposes must obtain a commercial license. The commercial license is available when you sign up for an API key on our website.
|
package/package.json
CHANGED
|
@@ -1,16 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cocreate/crud-server",
|
|
3
|
-
"version": "1.37.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.37.4",
|
|
4
|
+
"description": "High-performance, multi-tenant server-side CRUD orchestration engine supporting parallel multi-database writing, real-time sync, and tenant-isolated data routing across 20+ database engines.",
|
|
5
5
|
"keywords": [
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
6
|
+
"multi-database",
|
|
7
|
+
"parallel-writing",
|
|
8
|
+
"distributed-database",
|
|
9
|
+
"database-router",
|
|
10
|
+
"multi-tenant-crud",
|
|
11
|
+
"realtime-sync",
|
|
12
|
+
"mongodb",
|
|
13
|
+
"postgresql",
|
|
14
|
+
"mysql",
|
|
15
|
+
"dynamodb",
|
|
16
|
+
"firestore",
|
|
17
|
+
"sqlite",
|
|
18
|
+
"cockroachdb",
|
|
19
|
+
"mariadb",
|
|
20
|
+
"oracle-db",
|
|
21
|
+
"timescaledb",
|
|
22
|
+
"planetscale",
|
|
23
|
+
"turso",
|
|
24
|
+
"ferretdb",
|
|
25
|
+
"redshift"
|
|
14
26
|
],
|
|
15
27
|
"publishConfig": {
|
|
16
28
|
"access": "public"
|
|
@@ -33,7 +45,7 @@
|
|
|
33
45
|
"homepage": "https://cocreate.app/docs/CoCreate-crud-server",
|
|
34
46
|
"dependencies": {
|
|
35
47
|
"@cocreate/config": "^1.14.0",
|
|
36
|
-
"@cocreate/
|
|
48
|
+
"@cocreate/mongodb": "^1.25.2",
|
|
37
49
|
"@cocreate/utils": "^1.44.0"
|
|
38
50
|
}
|
|
39
51
|
}
|
package/src/index.js
CHANGED
|
@@ -23,9 +23,12 @@
|
|
|
23
23
|
|
|
24
24
|
import { ObjectId, sortData } from "@cocreate/utils";
|
|
25
25
|
import Config from '@cocreate/config';
|
|
26
|
+
import mongodb from '@cocreate/mongodb';
|
|
26
27
|
|
|
27
28
|
// In-process memory caches and storage registers (strictly module-internal)
|
|
28
|
-
const providers = {
|
|
29
|
+
const providers = {
|
|
30
|
+
mongodb
|
|
31
|
+
};
|
|
29
32
|
const organizations = {};
|
|
30
33
|
const hosts = {};
|
|
31
34
|
let config = null;
|
|
@@ -53,7 +56,7 @@ export async function init(Server) {
|
|
|
53
56
|
wsManager = Server.wsManager;
|
|
54
57
|
}
|
|
55
58
|
|
|
56
|
-
config = await Config({
|
|
59
|
+
config = await Config.request({
|
|
57
60
|
'organization_id': { prompt: 'Enter your organization_id: ' },
|
|
58
61
|
'storage': {
|
|
59
62
|
prompt: 'Enter a friendly name for the new storage (e.g., primary): ',
|
|
@@ -96,23 +99,23 @@ export async function init(Server) {
|
|
|
96
99
|
}
|
|
97
100
|
|
|
98
101
|
// Dynamically import and register drivers configured on the server
|
|
99
|
-
if (config.storage && providers) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
+
// if (config.storage && providers) {
|
|
103
|
+
// for (const [friendlyName, storageConfig] of Object.entries(config.storage)) {
|
|
104
|
+
// const { provider } = storageConfig;
|
|
102
105
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
+
// if (provider) {
|
|
107
|
+
// // Convention over Configuration: fallback to @cocreate/provider if explicit import is omitted
|
|
108
|
+
// const importPath = storageConfig.import || `@cocreate/${provider}`;
|
|
106
109
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}
|
|
110
|
+
// try {
|
|
111
|
+
// const driverModule = await import(importPath);
|
|
112
|
+
// providers[provider] = driverModule.default || driverModule;
|
|
113
|
+
// } catch (err) {
|
|
114
|
+
// console.error(`[@cocreate/crud-server] Failed to dynamically load database driver "${importPath}" for provider "${provider}":`, err);
|
|
115
|
+
// }
|
|
116
|
+
// }
|
|
117
|
+
// }
|
|
118
|
+
// }
|
|
116
119
|
|
|
117
120
|
// Deferred WebSocket Listener Auto-Registration
|
|
118
121
|
const bindSocketListeners = () => {
|