roccodb-iaaryan 1.0.1 → 1.0.2

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/index.js CHANGED
@@ -4,26 +4,26 @@ class Collection {
4
4
  constructor(dbNative, name) {
5
5
  this.dbNative = dbNative;
6
6
  this.name = name;
7
- this.listeners = []; // NEW: Stores all active real-time watchers
7
+ this.listeners = []; // Keep track of active listeners
8
8
  }
9
9
 
10
- // NEW: The Firebase-style real-time listener
10
+ // Register a listener for collection changes
11
11
  onChange(callback) {
12
12
  this.listeners.push(callback);
13
- // Returns a function to unsubscribe when the user is done listening
13
+ // Return a cleanup function for this listener
14
14
  return () => {
15
15
  this.listeners = this.listeners.filter(cb => cb !== callback);
16
16
  };
17
17
  }
18
18
 
19
- // Internal helper to fire events
19
+ // Notify every active listener
20
20
  _notify(eventType, data) {
21
21
  this.listeners.forEach(cb => cb({ type: eventType, data: data }));
22
22
  }
23
23
 
24
24
  insert(data) {
25
25
  const id = this.dbNative.insert(this.name, JSON.stringify(data));
26
- // Fire the real-time event instantly after saving to C++
26
+ // Notify listeners after the record is saved
27
27
  this._notify("INSERT", { id: id, ...data });
28
28
  return id;
29
29
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "roccodb-iaaryan",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "A high-performance folder-based NoSQL database engine written in C++",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -0,0 +1,265 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <meta name="description" content="roccoDB is an experimental local, folder-based NoSQL document database with a C++20 core and a Node.js API.">
7
+ <meta name="theme-color" content="#000000">
8
+ <meta property="og:title" content="roccoDB — The Local C++ Database for Node.js">
9
+ <meta property="og:description" content="A local, folder-based NoSQL document database built from scratch in C++20 and exposed to Node.js.">
10
+ <meta property="og:type" content="website">
11
+ <title>roccoDB — The Local C++ Database for Node.js</title>
12
+ <link rel="preconnect" href="https://fonts.googleapis.com">
13
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
14
+ <link href="https://fonts.googleapis.com/css2?family=Geist:wght@300;400;500;600&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
15
+ <link rel="stylesheet" href="style.css">
16
+ </head>
17
+ <body>
18
+ <div class="page-noise" aria-hidden="true"></div>
19
+ <div class="ambient-glow top-glow" aria-hidden="true"></div>
20
+
21
+ <header class="site-header">
22
+ <nav class="nav shell" aria-label="Main navigation">
23
+ <a class="brand" href="#top" aria-label="roccoDB home">
24
+ <span>roccoDB</span>
25
+ </a>
26
+
27
+ <button class="nav-toggle" type="button" aria-label="Open navigation" aria-expanded="false">
28
+ <span></span><span></span>
29
+ </button>
30
+
31
+ <div class="nav-links">
32
+ <a href="#features">Features</a>
33
+ <a href="#architecture">Architecture</a>
34
+ <a href="#quick-start">Quick Start</a>
35
+ <a href="#status">Status</a>
36
+ <a class="nav-pill" href="https://www.npmjs.com/package/roccodb-iaaryan" target="_blank" rel="noreferrer">npm ↗</a>
37
+ </div>
38
+ </nav>
39
+ </header>
40
+
41
+ <main id="top">
42
+ <section class="hero shell">
43
+ <h1 class="reveal">the local <span class="gradient-text">database</span><br>for node.js</h1>
44
+
45
+ <p class="hero-copy reveal">
46
+ A folder-based NoSQL document database built from scratch in C++20,
47
+ connected to Node.js through a native Node-API bridge. No separate database server required.
48
+ </p>
49
+
50
+ <div class="hero-actions reveal">
51
+ <a class="button primary" href="#quick-start">Get Started</a>
52
+ <a class="button secondary" href="https://www.npmjs.com/package/roccodb-iaaryan" target="_blank" rel="noreferrer">View on npm</a>
53
+ </div>
54
+
55
+ <div class="install-card reveal glass-panel">
56
+ <div class="window-bar">
57
+ <div class="traffic-lights" aria-hidden="true"><i></i><i></i><i></i></div>
58
+ <span class="window-title">terminal</span>
59
+ </div>
60
+ <div class="install-line">
61
+ <span class="prompt">~</span>
62
+ <code>npm install roccodb-iaaryan</code>
63
+ <button class="copy-button" type="button" data-copy="npm install roccodb-iaaryan" aria-label="Copy install command">Copy</button>
64
+ </div>
65
+ </div>
66
+
67
+ <div class="hero-meta reveal">
68
+ <span>C++20 Core</span>
69
+ <span class="separator">·</span>
70
+ <span>Node-API Bridge</span>
71
+ <span class="separator">·</span>
72
+ <span>Zero Config</span>
73
+ </div>
74
+ </section>
75
+
76
+
77
+
78
+ <section id="features" class="section shell">
79
+ <div class="section-heading reveal text-center">
80
+ <h2>Small stack. Low-level core.</h2>
81
+ <p>roccoDB keeps the developer API in clean JavaScript while the raw performance and persistence live in C++.</p>
82
+ </div>
83
+
84
+ <div class="feature-grid">
85
+ <article class="feature-card featured reveal glass-panel">
86
+ <div class="feature-icon">&lt;/&gt;</div>
87
+ <h3>C++20 Core</h3>
88
+ <p>The storage engine is built from scratch in modern C++, handling all persistence and memory management directly beneath the JavaScript API.</p>
89
+ <div class="mini-code">
90
+ <span class="muted">Engine</span><span class="value">rocco::database</span>
91
+ <span class="muted">Bridge</span><span class="value">Node-API</span>
92
+ </div>
93
+ </article>
94
+
95
+ <article class="feature-card reveal glass-panel">
96
+ <div class="feature-icon">↳</div>
97
+ <h3>Embedded & Local</h3>
98
+ <p>Run the database with your Node.js application. Your data stays locally on your machine or server.</p>
99
+ </article>
100
+
101
+ <article class="feature-card reveal glass-panel">
102
+ <div class="feature-icon">⌁</div>
103
+ <h3>O(1) Indexing</h3>
104
+ <p>An in-memory <code>unordered_map</code> maps document IDs directly to byte offsets for lightning-fast lookups.</p>
105
+ </article>
106
+
107
+ <article class="feature-card reveal glass-panel">
108
+ <div class="feature-icon">◫</div>
109
+ <h3>Media Isolation</h3>
110
+ <p>Files and images are stored efficiently outside normal document records via OS-level copies.</p>
111
+ </article>
112
+
113
+ <article class="feature-card reveal glass-panel">
114
+ <div class="feature-icon">◉</div>
115
+ <h3>Real-Time Watchers</h3>
116
+ <p>Observe collection changes inside the running application instantly with the <code>onChange()</code> API.</p>
117
+ </article>
118
+ </div>
119
+ </section>
120
+
121
+ <section id="architecture" class="section architecture-section">
122
+ <div class="ambient-glow center-glow" aria-hidden="true"></div>
123
+ <div class="shell">
124
+ <div class="section-heading text-center reveal">
125
+ <h2>JavaScript on top. <br> C++ underneath.</h2>
126
+ <p>Objects move seamlessly through a native bridge into the custom engine, persisting safely inside a local directory.</p>
127
+ </div>
128
+
129
+ <div class="architecture-flow reveal glass-panel">
130
+ <div class="arch-node">
131
+ <strong>Node.js</strong>
132
+ <small>Developer Code</small>
133
+ </div>
134
+ <div class="arch-arrow">→</div>
135
+ <div class="arch-node">
136
+ <strong>roccoDB SDK</strong>
137
+ <small>Public API</small>
138
+ </div>
139
+ <div class="arch-arrow">→</div>
140
+ <div class="arch-node active">
141
+ <strong>Node-API</strong>
142
+ <small>Native Boundary</small>
143
+ </div>
144
+ <div class="arch-arrow">→</div>
145
+ <div class="arch-node">
146
+ <strong>C++20</strong>
147
+ <small>Storage Engine</small>
148
+ </div>
149
+ <div class="arch-arrow">→</div>
150
+ <div class="arch-node">
151
+ <strong>Local Drive</strong>
152
+ <small>Binary Persistence</small>
153
+ </div>
154
+ </div>
155
+ </div>
156
+ </section>
157
+
158
+ <section id="quick-start" class="section shell">
159
+ <div class="section-heading split reveal">
160
+ <div>
161
+ <h2>From install to data<br>in seconds.</h2>
162
+ </div>
163
+ <p>The SDK focuses on developer ergonomics. Create a database, open a collection, insert a document, and retrieve it without touching a single configuration file.</p>
164
+ </div>
165
+
166
+ <div class="code-window reveal glass-panel">
167
+ <div class="window-bar">
168
+ <div class="traffic-lights" aria-hidden="true"><i></i><i></i><i></i></div>
169
+ <div class="code-tabs">
170
+ <button class="code-tab active" type="button" data-tab="basic">quick-start.js</button>
171
+ <button class="code-tab" type="button" data-tab="events">events.js</button>
172
+ <button class="code-tab" type="button" data-tab="storage">storage.js</button>
173
+ </div>
174
+ <button class="copy-button code-copy" type="button" aria-label="Copy current code">Copy</button>
175
+ </div>
176
+
177
+ <pre class="code-panel active" data-panel="basic"><code><span class="token-keyword">const</span> { RoccoDB } = <span class="token-fn">require</span>(<span class="token-string">"roccodb-iaaryan"</span>);
178
+
179
+ <span class="token-comment">// Initializes the C++ engine & creates local folders</span>
180
+ <span class="token-keyword">const</span> db = <span class="token-keyword">new</span> <span class="token-class">RoccoDB</span>(<span class="token-string">"./my_database"</span>);
181
+ <span class="token-keyword">const</span> users = db.<span class="token-fn">collection</span>(<span class="token-string">"users"</span>);
182
+
183
+ <span class="token-comment">// Insert a standard JS object</span>
184
+ <span class="token-keyword">const</span> id = users.<span class="token-fn">insert</span>({
185
+ name: <span class="token-string">"Aaryan"</span>,
186
+ role: <span class="token-string">"Systems Engineer"</span>,
187
+ active: <span class="token-bool">true</span>
188
+ });
189
+
190
+ <span class="token-comment">// Fetch it back via O(1) byte-offset lookup</span>
191
+ <span class="token-keyword">const</span> user = users.<span class="token-fn">get</span>(id);
192
+ console.<span class="token-fn">log</span>(user);</code></pre>
193
+
194
+ <pre class="code-panel" data-panel="events"><code><span class="token-keyword">const</span> messages = db.<span class="token-fn">collection</span>(<span class="token-string">"messages"</span>);
195
+
196
+ <span class="token-comment">// Set up a local event emitter</span>
197
+ messages.<span class="token-fn">onChange</span>((event) => {
198
+ console.<span class="token-fn">log</span>(<span class="token-string">"Database changed:"</span>, event.type);
199
+ console.<span class="token-fn">log</span>(<span class="token-string">"New Data payload:"</span>, event.data);
200
+ });
201
+
202
+ <span class="token-comment">// Trigger the watcher instantly</span>
203
+ messages.<span class="token-fn">insert</span>({
204
+ text: <span class="token-string">"Hello from roccoDB!"</span>,
205
+ timestamp: Date.<span class="token-fn">now</span>()
206
+ });</code></pre>
207
+
208
+ <pre class="code-panel" data-panel="storage"><code><span class="token-comment">// Fast OS-level file copy to the /storage directory</span>
209
+ <span class="token-keyword">const</span> imageRef = db.storage.<span class="token-fn">upload</span>(
210
+ <span class="token-string">"./local_files/profile.jpg"</span>
211
+ );
212
+
213
+ <span class="token-keyword">const</span> users = db.<span class="token-fn">collection</span>(<span class="token-string">"users"</span>);
214
+
215
+ <span class="token-comment">// Keep your JSON lightweight by storing the reference ID</span>
216
+ users.<span class="token-fn">insert</span>({
217
+ name: <span class="token-string">"Aaryan"</span>,
218
+ profileImage: imageRef
219
+ });</code></pre>
220
+ </div>
221
+ </section>
222
+
223
+ <section id="status" class="section shell">
224
+ <div class="status-card reveal glass-panel">
225
+ <div class="status-top">
226
+ <h2>Experimental by design.</h2>
227
+ <span class="status-badge"><i></i> v1.0.0</span>
228
+ </div>
229
+ <p>roccoDB is an educational release. It is built for learning database internals, prototyping, and local embedded tools. It is not designed for critical production workloads.</p>
230
+ <div class="limitation-grid">
231
+ <div><p>No query/filter API yet.</p></div>
232
+ <div><p>JS update/delete not exposed.</p></div>
233
+ <div><p>Events are local, not cloud sync.</p></div>
234
+ <div><p>No multi-threading locks.</p></div>
235
+ </div>
236
+ </div>
237
+ </section>
238
+
239
+ <section class="section shell">
240
+ <div class="final-cta reveal glass-panel">
241
+ <div class="ambient-glow cta-glow" aria-hidden="true"></div>
242
+ <h2>Build locally. Understand deeply.</h2>
243
+ <p>Install the experimental release and explore a database stack from Node.js down to binary storage.</p>
244
+ <div class="cta-command">
245
+ <code>npm install roccodb-iaaryan</code>
246
+ <button class="copy-button" type="button" data-copy="npm install roccodb-iaaryan">Copy</button>
247
+ </div>
248
+ </div>
249
+ </section>
250
+ </main>
251
+
252
+ <footer class="footer">
253
+ <div class="shell footer-inner">
254
+ <a class="brand" href="#top"><span>roccoDB</span></a>
255
+ <p>Engineered from scratch by Aaryan.</p>
256
+ <div class="footer-links">
257
+ <a href="https://www.npmjs.com/package/roccodb-iaaryan" target="_blank" rel="noreferrer">npm Package</a>
258
+ <a href="https://github.com/iaaryans/roccoDB" target="_blank" rel="noreferrer">GitHub</a>
259
+ </div>
260
+ </div>
261
+ </footer>
262
+
263
+ <script src="script.js"></script>
264
+ </body>
265
+ </html>
@@ -0,0 +1,83 @@
1
+ // Nav Scroll Effect
2
+ const header = document.querySelector(".site-header");
3
+ const navToggle = document.querySelector(".nav-toggle");
4
+ const navLinks = document.querySelector(".nav-links");
5
+
6
+ window.addEventListener("scroll", () => {
7
+ header.classList.toggle("scrolled", window.scrollY > 20);
8
+ }, { passive: true });
9
+
10
+ // Mobile Nav Toggle
11
+ navToggle.addEventListener("click", () => {
12
+ const open = navLinks.classList.toggle("open");
13
+ navToggle.setAttribute("aria-expanded", String(open));
14
+ });
15
+
16
+ navLinks.querySelectorAll("a").forEach((link) => {
17
+ link.addEventListener("click", () => {
18
+ navLinks.classList.remove("open");
19
+ navToggle.setAttribute("aria-expanded", "false");
20
+ });
21
+ });
22
+
23
+ // Copy to Clipboard Utility
24
+ const setCopied = (button) => {
25
+ const original = button.textContent;
26
+ button.textContent = "Copied";
27
+ button.classList.add("copied");
28
+ window.setTimeout(() => {
29
+ button.textContent = original;
30
+ button.classList.remove("copied");
31
+ }, 2000); // Extended slightly for a more relaxed feel
32
+ };
33
+
34
+ document.querySelectorAll("[data-copy]").forEach((button) => {
35
+ button.addEventListener("click", async () => {
36
+ try {
37
+ await navigator.clipboard.writeText(button.dataset.copy);
38
+ setCopied(button);
39
+ } catch {
40
+ button.textContent = "Failed";
41
+ }
42
+ });
43
+ });
44
+
45
+ // Code Window Tabs
46
+ const tabs = document.querySelectorAll(".code-tab");
47
+ const panels = document.querySelectorAll(".code-panel");
48
+ const codeCopy = document.querySelector(".code-copy");
49
+
50
+ tabs.forEach((tab) => {
51
+ tab.addEventListener("click", () => {
52
+ tabs.forEach((item) => item.classList.remove("active"));
53
+ panels.forEach((panel) => panel.classList.remove("active"));
54
+
55
+ tab.classList.add("active");
56
+ document.querySelector(`[data-panel="${tab.dataset.tab}"]`).classList.add("active");
57
+ });
58
+ });
59
+
60
+ codeCopy.addEventListener("click", async () => {
61
+ const activeCode = document.querySelector(".code-panel.active code").innerText;
62
+ try {
63
+ await navigator.clipboard.writeText(activeCode);
64
+ setCopied(codeCopy);
65
+ } catch {
66
+ codeCopy.textContent = "Failed";
67
+ }
68
+ });
69
+
70
+ // Smooth Reveal Animations
71
+ const observer = new IntersectionObserver((entries) => {
72
+ entries.forEach((entry) => {
73
+ if (entry.isIntersecting) {
74
+ entry.target.classList.add("visible");
75
+ observer.unobserve(entry.target); // Only animate once
76
+ }
77
+ });
78
+ }, {
79
+ threshold: 0.15,
80
+ rootMargin: "0px 0px -50px 0px" // Triggers slightly before element enters view
81
+ });
82
+
83
+ document.querySelectorAll(".reveal").forEach((element) => observer.observe(element));
@@ -0,0 +1,205 @@
1
+ :root {
2
+ --bg: #000000;
3
+ --panel: rgba(20, 20, 22, 0.6);
4
+ --line: rgba(255, 255, 255, 0.08);
5
+ --line-strong: rgba(255, 255, 255, 0.15);
6
+ --text: #ffffff;
7
+ --muted: #88888b;
8
+ --accent: #22d3ee; /* Cyan/Emerald vibe */
9
+ --accent-glow: rgba(34, 211, 238, 0.15);
10
+ --mono: "JetBrains Mono", monospace;
11
+ --sans: "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
12
+ --radius: 16px;
13
+ --shell: min(1080px, calc(100% - 48px));
14
+ }
15
+
16
+ * { box-sizing: border-box; scrollbar-color: #1a1a1a transparent; scrollbar-width: thin; }
17
+ html { scroll-behavior: smooth; }
18
+ body {
19
+ margin: 0; background: var(--bg); color: var(--text);
20
+ font-family: var(--sans); line-height: 1.6; overflow-x: hidden;
21
+ -webkit-font-smoothing: antialiased;
22
+ }
23
+ button, a { font: inherit; }
24
+ a { color: inherit; text-decoration: none; transition: color 0.2s; }
25
+ code, pre { font-family: var(--mono); font-size: 0.9em; }
26
+ button { color: inherit; cursor: pointer; border: none; background: transparent; }
27
+ .shell { width: var(--shell); margin-inline: auto; }
28
+
29
+ /* Premium Ambient Lighting */
30
+ .page-noise {
31
+ position: fixed; inset: 0; pointer-events: none; z-index: 99; opacity: 0.03;
32
+ background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
33
+ }
34
+ .ambient-glow {
35
+ position: absolute; border-radius: 50%; filter: blur(100px); pointer-events: none; z-index: 0;
36
+ }
37
+ .top-glow { width: 600px; height: 400px; top: -100px; left: 50%; transform: translateX(-50%); background: radial-gradient(circle, var(--accent-glow) 0%, transparent 70%); }
38
+ .center-glow { width: 800px; height: 600px; top: 50%; left: 50%; transform: translate(-50%, -50%); background: radial-gradient(circle, rgba(34, 211, 238, 0.05) 0%, transparent 60%); }
39
+
40
+ /* Glassmorphism Utilities */
41
+ .glass-panel {
42
+ background: var(--panel);
43
+ backdrop-filter: blur(24px) saturate(150%);
44
+ -webkit-backdrop-filter: blur(24px) saturate(150%);
45
+ border: 1px solid var(--line);
46
+ box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
47
+ }
48
+
49
+ /* Header */
50
+ .site-header {
51
+ position: sticky; top: 0; z-index: 50; border-bottom: 1px solid transparent;
52
+ background: rgba(0, 0, 0, 0.4); backdrop-filter: blur(20px) saturate(180%);
53
+ -webkit-backdrop-filter: blur(20px) saturate(180%); transition: border-color 0.3s;
54
+ }
55
+ .site-header.scrolled { border-color: var(--line); }
56
+ .nav { height: 64px; display: flex; align-items: center; justify-content: space-between; }
57
+ .brand { display: inline-flex; align-items: center; gap: 12px; font-weight: 500; letter-spacing: -0.02em; font-size: 15px; }
58
+ .brand-mark {
59
+ width: 26px; height: 26px; display: grid; place-items: center;
60
+ border: 1px solid var(--line-strong); border-radius: 6px;
61
+ background: linear-gradient(180deg, #1f1f1f, #000000);
62
+ color: var(--text); font-family: var(--mono); font-size: 13px;
63
+ }
64
+ .nav-links { display: flex; align-items: center; gap: 32px; font-size: 13px; color: var(--muted); font-weight: 400; }
65
+ .nav-links a:hover { color: var(--text); }
66
+ .nav-pill { padding: 6px 14px; border: 1px solid var(--line); border-radius: 99px; color: var(--text) !important; background: rgba(255,255,255,0.03); transition: background 0.2s; }
67
+ .nav-pill:hover { background: rgba(255,255,255,0.1); }
68
+ .nav-toggle { display: none; padding: 8px; }
69
+ .nav-toggle span { display: block; width: 20px; height: 1.5px; background: var(--text); margin: 5px 0; transition: 0.3s; }
70
+
71
+ /* Hero */
72
+ .hero { padding: 140px 0 100px; text-align: center; position: relative; z-index: 1; }
73
+ .eyebrow {
74
+ display: inline-flex; align-items: center; gap: 8px; padding: 6px 12px;
75
+ border: 1px solid var(--line); border-radius: 99px; background: rgba(255,255,255,0.03);
76
+ color: var(--muted); font-family: var(--mono); font-size: 11px; letter-spacing: 0.05em; text-transform: uppercase;
77
+ }
78
+ .status-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 10px var(--accent); }
79
+ .hero h1 { margin: 32px auto 24px; font-size: clamp(48px, 7vw, 96px); line-height: 1; letter-spacing: -0.04em; font-weight: 500; }
80
+ .gradient-text { background: linear-gradient(135deg, #ffffff 0%, var(--accent) 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
81
+ .hero-copy { max-width: 640px; margin: 0 auto; color: var(--muted); font-size: 18px; font-weight: 300; }
82
+ .hero-actions { display: flex; justify-content: center; gap: 16px; margin-top: 40px; }
83
+ .button { padding: 12px 24px; border-radius: 99px; font-size: 14px; font-weight: 500; transition: all 0.2s ease; border: 1px solid transparent; }
84
+ .button.primary { background: var(--text); color: #000000; }
85
+ .button.primary:hover { background: #e0e0e0; transform: scale(1.02); }
86
+ .button.secondary { background: rgba(255,255,255,0.05); color: var(--text); border-color: var(--line); }
87
+ .button.secondary:hover { background: rgba(255,255,255,0.1); }
88
+ .hero-meta { display: flex; justify-content: center; align-items: center; gap: 16px; margin-top: 40px; color: #555; font-family: var(--mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; }
89
+ .hero-meta .separator { color: #333; font-size: 16px; }
90
+
91
+ /* Windows / Terminals (macOS style) */
92
+ .window-bar { display: flex; align-items: center; height: 48px; padding: 0 16px; border-bottom: 1px solid var(--line); background: rgba(255,255,255,0.02); }
93
+ .traffic-lights { display: flex; gap: 8px; margin-right: 16px; }
94
+ .traffic-lights i { width: 12px; height: 12px; border-radius: 50%; }
95
+ .traffic-lights i:nth-child(1) { background: #ff5f56; border: 1px solid #e0443e; }
96
+ .traffic-lights i:nth-child(2) { background: #ffbd2e; border: 1px solid #dea123; }
97
+ .traffic-lights i:nth-child(3) { background: #27c93f; border: 1px solid #1aab29; }
98
+ .window-title { margin-left: auto; margin-right: auto; color: var(--muted); font-size: 12px; font-family: var(--mono); padding-right: 48px; }
99
+
100
+ /* Install Card */
101
+ .install-card { max-width: 600px; margin: 64px auto 0; border-radius: 12px; overflow: hidden; text-align: left; }
102
+ .install-line { display: flex; align-items: center; padding: 24px; gap: 16px; }
103
+ .install-line code { flex: 1; font-size: 15px; color: var(--text); }
104
+ .prompt { color: var(--accent); font-family: var(--mono); }
105
+ .copy-button { padding: 6px 12px; border: 1px solid var(--line); border-radius: 6px; background: rgba(255,255,255,0.05); font-family: var(--mono); font-size: 11px; color: var(--muted); transition: 0.2s; }
106
+ .copy-button:hover, .copy-button.copied { color: var(--text); background: rgba(255,255,255,0.1); border-color: var(--line-strong); }
107
+
108
+ /* Ticker */
109
+ .ticker { overflow: hidden; border-block: 1px solid var(--line); padding: 16px 0; background: rgba(255,255,255,0.01); color: #444; font-family: var(--mono); font-size: 12px; letter-spacing: 0.1em; }
110
+ .ticker-track { width: max-content; display: flex; gap: 40px; animation: ticker 40s linear infinite; }
111
+ .ticker b { color: #222; font-size: 10px; }
112
+ @keyframes ticker { to { transform: translateX(-50%); } }
113
+
114
+ /* Sections */
115
+ .section { padding: 140px 0; position: relative; z-index: 1; }
116
+ .section-heading { margin-bottom: 64px; }
117
+ .text-center { text-align: center; max-width: 700px; margin-inline: auto; }
118
+ .section-heading.split { display: grid; grid-template-columns: 1fr 1fr; align-items: center; gap: 40px; }
119
+ .section-heading h2 { margin: 0; font-size: clamp(32px, 4vw, 56px); line-height: 1.1; letter-spacing: -0.03em; font-weight: 500; }
120
+ .section-heading p { color: var(--muted); margin: 24px 0 0; font-size: 18px; font-weight: 300; }
121
+
122
+ /* Features */
123
+ .feature-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
124
+ .feature-card { padding: 32px; border-radius: var(--radius); display: flex; flex-direction: column; }
125
+ .feature-card.featured { grid-column: span 2; }
126
+ .feature-icon { width: 48px; height: 48px; display: grid; place-items: center; border: 1px solid var(--line); border-radius: 12px; font-family: var(--mono); font-size: 18px; color: var(--text); background: rgba(255,255,255,0.03); margin-bottom: 32px; box-shadow: inset 0 2px 10px rgba(255,255,255,0.05); }
127
+ .feature-card h3 { margin: 0 0 12px; font-size: 20px; font-weight: 500; letter-spacing: -0.01em; }
128
+ .feature-card p { color: var(--muted); margin: 0; font-size: 15px; font-weight: 300; line-height: 1.5; flex: 1; }
129
+ .mini-code { margin-top: 32px; padding: 16px; border: 1px solid var(--line); border-radius: 8px; display: grid; grid-template-columns: 80px 1fr; gap: 10px; font-family: var(--mono); font-size: 12px; background: rgba(0,0,0,0.4); }
130
+ .mini-code .value { color: var(--text); }
131
+
132
+ /* Architecture */
133
+ .architecture-section { border-block: 1px solid var(--line); }
134
+ .architecture-flow { display: grid; grid-template-columns: 1fr auto 1fr auto 1fr auto 1fr auto 1fr; align-items: center; gap: 16px; padding: 32px; border-radius: 24px; }
135
+ .arch-node { text-align: center; padding: 24px 16px; }
136
+ .arch-node.active strong { color: var(--accent); }
137
+ .arch-node strong { display: block; font-size: 15px; font-weight: 500; margin-bottom: 4px; }
138
+ .arch-node small { color: var(--muted); font-size: 12px; font-family: var(--mono); }
139
+ .arch-arrow { color: #333; font-family: var(--mono); }
140
+
141
+ /* Code Window */
142
+ .code-window { border-radius: 12px; }
143
+ .code-window .window-bar { justify-content: flex-start; }
144
+ .code-tabs { display: flex; gap: 8px; margin-left: 24px; height: 100%; }
145
+ .code-tab { border: none; border-bottom: 2px solid transparent; background: transparent; padding: 0 12px; color: #666; font-family: var(--mono); font-size: 12px; transition: 0.2s; }
146
+ .code-tab.active { color: var(--text); border-bottom-color: var(--text); }
147
+ .code-copy { margin-left: auto; }
148
+ .code-panel { display: none; margin: 0; padding: 40px; min-height: 400px; overflow: auto; font-size: 14px; line-height: 1.7; background: rgba(0,0,0,0.3); }
149
+ .code-panel.active { display: block; }
150
+ .token-keyword { color: #ff7b72; } .token-fn { color: #d2a8ff; } .token-string { color: #a5d6ff; } .token-class { color: #79c0ff; } .token-bool { color: #79c0ff; } .token-comment { color: #8b949e; font-style: italic; }
151
+
152
+ /* Status */
153
+ .status-card { padding: 64px; border-radius: 24px; }
154
+ .status-top { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 24px; }
155
+ .status-top h2 { margin: 0; font-size: 32px; font-weight: 500; }
156
+ .status-badge { display: flex; align-items: center; gap: 8px; border: 1px solid var(--line); background: rgba(255,255,255,0.05); color: var(--text); padding: 6px 14px; border-radius: 99px; font-family: var(--mono); font-size: 12px; }
157
+ .status-card > p { max-width: 600px; color: var(--muted); font-size: 16px; margin: 0 0 48px; font-weight: 300; }
158
+ .limitation-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; border-top: 1px solid var(--line); padding-top: 32px; }
159
+ .limitation-grid p { color: #999; font-size: 14px; margin: 0; }
160
+
161
+ /* CTA */
162
+ .final-cta { text-align: center; padding: 100px 32px; border-radius: 24px; position: relative; overflow: hidden; }
163
+ .cta-glow { width: 400px; height: 400px; top: 50%; left: 50%; transform: translate(-50%, -50%); background: radial-gradient(circle, var(--accent-glow) 0%, transparent 70%); }
164
+ .final-cta h2 { margin: 0; font-size: 48px; font-weight: 500; position: relative; z-index: 1; }
165
+ .final-cta p { color: var(--muted); margin: 24px auto 40px; font-size: 18px; max-width: 500px; font-weight: 300; position: relative; z-index: 1; }
166
+ .cta-command { max-width: 400px; margin: 0 auto; display: flex; align-items: center; justify-content: space-between; padding: 8px 8px 8px 24px; border: 1px solid var(--line); border-radius: 12px; background: rgba(0,0,0,0.5); position: relative; z-index: 1; }
167
+ .cta-command code { font-size: 13px; }
168
+
169
+ /* Footer */
170
+ .footer { border-top: 1px solid var(--line); background: rgba(0,0,0,0.5); padding: 48px 0; }
171
+ .footer-inner { display: flex; justify-content: space-between; align-items: center; font-size: 13px; color: var(--muted); }
172
+ .footer-inner > p { margin: 0; }
173
+ .footer-links { display: flex; gap: 24px; }
174
+ .footer-links a:hover { color: var(--text); }
175
+
176
+ /* Animations */
177
+ .reveal { opacity: 0; transform: translateY(20px); transition: opacity 0.8s cubic-bezier(0.16, 1, 0.3, 1), transform 0.8s cubic-bezier(0.16, 1, 0.3, 1); }
178
+ .reveal.visible { opacity: 1; transform: none; }
179
+
180
+ /* Responsive */
181
+ @media (max-width: 900px) {
182
+ .nav-toggle { display: block; }
183
+ .nav-links { position: absolute; top: 64px; left: 16px; right: 16px; display: none; flex-direction: column; background: rgba(20,20,22,0.95); backdrop-filter: blur(20px); border: 1px solid var(--line); border-radius: 16px; padding: 16px; text-align: center; }
184
+ .nav-links.open { display: flex; }
185
+ .section-heading.split { grid-template-columns: 1fr; text-align: center; gap: 16px; }
186
+ .section-heading.split p { margin-inline: auto; }
187
+ .feature-grid { grid-template-columns: 1fr; }
188
+ .feature-card.featured { grid-column: 1; }
189
+ .architecture-flow { grid-template-columns: 1fr; padding: 24px; }
190
+ .arch-arrow { transform: rotate(90deg); padding: 16px 0; }
191
+ .limitation-grid { grid-template-columns: 1fr 1fr; }
192
+ .footer-inner { flex-direction: column; gap: 24px; text-align: center; }
193
+ }
194
+ @media (max-width: 600px) {
195
+ .hero { padding: 100px 0 64px; }
196
+ .hero h1 { font-size: 40px; }
197
+ .hero-actions { flex-direction: column; }
198
+ .install-line { padding: 20px; flex-direction: column; text-align: center; }
199
+ .install-line code { font-size: 13px; }
200
+ .status-card { padding: 32px; }
201
+ .status-top { flex-direction: column; gap: 16px; }
202
+ .limitation-grid { grid-template-columns: 1fr; }
203
+ .code-tabs { overflow-x: auto; padding-bottom: 4px; }
204
+ .code-panel { padding: 24px; font-size: 12px; }
205
+ }
package/src/Collection.h CHANGED
@@ -4,7 +4,7 @@
4
4
  #include <fstream>
5
5
  #include <iostream>
6
6
  #include <unordered_map>
7
- #include <random> // NEW: For generating unique IDs
7
+ #include <random> // Used to generate record IDs
8
8
 
9
9
  namespace fs = std::filesystem;
10
10
 
@@ -15,7 +15,7 @@ private:
15
15
  fs::path wal_file;
16
16
  std::unordered_map<std::string, std::streampos> index;
17
17
 
18
- // NEW: Generates a random 12-character hex string (e.g., "a3f9b2c1d4e5")
18
+ // Generate a short hex ID for a new record
19
19
  std::string generate_id() {
20
20
  const char chars[] = "0123456789abcdef";
21
21
  std::string id;
@@ -90,12 +90,12 @@ public:
90
90
  build_index();
91
91
  }
92
92
 
93
- // ORIGINAL: Insert with manual ID (Used for Updates)
93
+ // Keep the same ID when writing an updated record
94
94
  void insert(const std::string& id, const std::string& data) {
95
95
  append_record(id, data, false);
96
96
  }
97
97
 
98
- // NEW API FEATURE: Insert without an ID, returns auto-generated ID
98
+ // New records get an ID automatically
99
99
  std::string insert(const std::string& data) {
100
100
  std::string new_id = generate_id();
101
101
  append_record(new_id, data, false);
package/src/binding.cpp CHANGED
@@ -10,7 +10,7 @@ public:
10
10
  Napi::Function func = DefineClass(env, "RoccoDBNative", {
11
11
  InstanceMethod("insert", &RoccoDBNative::Insert),
12
12
  InstanceMethod("get", &RoccoDBNative::Get),
13
- InstanceMethod("upload", &RoccoDBNative::Upload) // NEW: Exposing upload
13
+ InstanceMethod("upload", &RoccoDBNative::Upload) // Expose file uploads to JavaScript
14
14
  });
15
15
 
16
16
  Napi::FunctionReference* constructor = new Napi::FunctionReference();
@@ -48,7 +48,7 @@ public:
48
48
  return Napi::String::New(env, data);
49
49
  }
50
50
 
51
- // NEW: JavaScript calls this to upload a file
51
+ // Pass the file to roccoDB storage and return its generated ID
52
52
  Napi::Value Upload(const Napi::CallbackInfo& info) {
53
53
  Napi::Env env = info.Env();
54
54
  std::string source_file = info[0].As<Napi::String>().Utf8Value();
package/src/main.cpp CHANGED
@@ -8,17 +8,17 @@ int main() {
8
8
  auto users = db.collection("users");
9
9
  httplib::Server svr;
10
10
 
11
- // IMPORTANT: Serve our HTML file to the browser!
11
+ // Serve the frontend from the public directory
12
12
  svr.set_mount_point("/", "../public");
13
13
 
14
- // C: Create
14
+ // Create a user
15
15
  svr.Post("/users", [&](const httplib::Request& req, httplib::Response& res) {
16
16
  std::string id = users.insert(req.body);
17
17
  std::cout << "API Call: Created " << id << "\n";
18
18
  res.set_content("{\"id\": \"" + id + "\"}", "application/json");
19
19
  });
20
20
 
21
- // R: Read
21
+ // Fetch a user by ID
22
22
  svr.Get(R"(/users/(.+))", [&](const httplib::Request& req, httplib::Response& res) {
23
23
  std::string id = req.matches[1];
24
24
  std::string data = users.get(id);
@@ -31,7 +31,7 @@ int main() {
31
31
  }
32
32
  });
33
33
 
34
- // U: Update
34
+ // Update an existing user
35
35
  svr.Put(R"(/users/(.+))", [&](const httplib::Request& req, httplib::Response& res) {
36
36
  std::string id = req.matches[1];
37
37
  users.update(id, req.body);
@@ -39,7 +39,7 @@ int main() {
39
39
  res.set_content("{\"status\": \"Updated Successfully\"}", "application/json");
40
40
  });
41
41
 
42
- // D: Delete
42
+ // Delete a user
43
43
  svr.Delete(R"(/users/(.+))", [&](const httplib::Request& req, httplib::Response& res) {
44
44
  std::string id = req.matches[1];
45
45
  users.remove(id);
package/public/index.html DELETED
@@ -1,132 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>roccoDB | Playground</title>
7
- <script src="https://cdn.tailwindcss.com"></script>
8
- <style>
9
- /* Custom scrollbar for the terminal output */
10
- ::-webkit-scrollbar { width: 8px; height: 8px; }
11
- ::-webkit-scrollbar-track { background: #1f2937; }
12
- ::-webkit-scrollbar-thumb { background: #4b5563; border-radius: 4px; }
13
- ::-webkit-scrollbar-thumb:hover { background: #6b7280; }
14
- </style>
15
- </head>
16
- <body class="bg-gray-950 text-gray-100 font-sans antialiased min-h-screen flex flex-col">
17
-
18
- <nav class="bg-gray-900 border-b border-gray-800 px-6 py-4 flex items-center justify-between shadow-sm">
19
- <div class="flex items-center gap-3">
20
- <svg class="w-6 h-6 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4"></path></svg>
21
- <h1 class="text-xl font-bold tracking-tight text-white">rocco<span class="text-blue-500">DB</span></h1>
22
- </div>
23
- <div class="text-xs font-mono text-gray-500 bg-gray-800 px-3 py-1 rounded-full border border-gray-700">
24
- C++ Engine v1.0 • Connected
25
- </div>
26
- </nav>
27
-
28
- <main class="flex-grow p-6 grid grid-cols-1 lg:grid-cols-2 gap-6 max-w-7xl mx-auto w-full">
29
-
30
- <div class="space-y-6">
31
-
32
- <div class="bg-gray-900 border border-gray-800 rounded-xl p-5 shadow-lg">
33
- <h3 class="text-sm font-semibold text-gray-400 uppercase tracking-wider mb-4">1. Insert New Document</h3>
34
- <div class="space-y-3">
35
- <label class="block text-xs font-medium text-gray-500">JSON DATA</label>
36
- <textarea id="newData" rows="3" class="w-full bg-gray-950 border border-gray-700 rounded-lg px-4 py-3 text-sm text-green-400 font-mono focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500 transition-colors" placeholder='{"name": "Bruce", "skill": "Martial Arts"}'>{"name": "Bruce", "skill": "Martial Arts"}</textarea>
37
- <button onclick="createRecord()" class="w-full bg-blue-600 hover:bg-blue-500 text-white text-sm font-semibold py-2.5 rounded-lg transition-colors flex justify-center items-center gap-2">
38
- <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"></path></svg>
39
- Run Insert
40
- </button>
41
- </div>
42
- </div>
43
-
44
- <div class="bg-gray-900 border border-gray-800 rounded-xl p-5 shadow-lg">
45
- <h3 class="text-sm font-semibold text-gray-400 uppercase tracking-wider mb-4">2. Manage Existing Document</h3>
46
- <div class="space-y-4">
47
- <div>
48
- <label class="block text-xs font-medium text-gray-500 mb-1">TARGET RECORD ID</label>
49
- <input type="text" id="recordId" class="w-full bg-gray-950 border border-gray-700 rounded-lg px-4 py-2.5 text-sm text-gray-200 font-mono focus:outline-none focus:border-blue-500 transition-colors" placeholder="e.g., a3f9b2c1d4e5">
50
- </div>
51
- <div>
52
- <label class="block text-xs font-medium text-gray-500 mb-1">UPDATE DATA (JSON)</label>
53
- <input type="text" id="updateData" class="w-full bg-gray-950 border border-gray-700 rounded-lg px-4 py-2.5 text-sm text-green-400 font-mono focus:outline-none focus:border-blue-500 transition-colors" placeholder='{"name": "Updated Name"}'>
54
- </div>
55
-
56
- <div class="grid grid-cols-3 gap-3 pt-2">
57
- <button onclick="getRecord()" class="bg-gray-700 hover:bg-gray-600 text-white text-sm font-medium py-2 rounded-lg transition-colors">GET</button>
58
- <button onclick="updateRecord()" class="bg-emerald-600 hover:bg-emerald-500 text-white text-sm font-medium py-2 rounded-lg transition-colors">PUT (Update)</button>
59
- <button onclick="deleteRecord()" class="bg-rose-600 hover:bg-rose-500 text-white text-sm font-medium py-2 rounded-lg transition-colors">DELETE</button>
60
- </div>
61
- </div>
62
- </div>
63
- </div>
64
-
65
- <div class="bg-[#0D1117] border border-gray-800 rounded-xl flex flex-col shadow-2xl overflow-hidden h-full min-h-[400px]">
66
- <div class="bg-gray-900 border-b border-gray-800 px-4 py-2 flex items-center gap-2">
67
- <div class="flex gap-1.5">
68
- <div class="w-3 h-3 rounded-full bg-red-500"></div>
69
- <div class="w-3 h-3 rounded-full bg-yellow-500"></div>
70
- <div class="w-3 h-3 rounded-full bg-green-500"></div>
71
- </div>
72
- <span class="text-xs font-mono text-gray-500 ml-2">roccoDB API Response</span>
73
- </div>
74
- <div class="p-4 flex-grow overflow-auto relative">
75
- <pre id="output" class="text-green-400 font-mono text-sm leading-relaxed break-all whitespace-pre-wrap">> Engine standby... ready for commands.</pre>
76
- </div>
77
- </div>
78
- </main>
79
-
80
- <script>
81
- const outputEl = document.getElementById('output');
82
-
83
- // Helper to format and display JSON nicely in our terminal
84
- const print = (data, method) => {
85
- const time = new Date().toLocaleTimeString();
86
- const formattedJson = JSON.stringify(data, null, 2);
87
- outputEl.innerHTML = `<span class="text-gray-500">[${time}] ${method} 200 OK</span>\n${formattedJson}`;
88
- };
89
-
90
- async function createRecord() {
91
- outputEl.innerHTML = `<span class="text-yellow-500">Executing POST /users...</span>`;
92
- try {
93
- const res = await fetch('/users', { method: 'POST', body: document.getElementById('newData').value });
94
- const data = await res.json();
95
- document.getElementById('recordId').value = data.id; // Auto-fill
96
- print(data, 'POST');
97
- } catch (e) { outputEl.innerHTML = `<span class="text-red-500">Error: ${e.message}</span>`; }
98
- }
99
-
100
- async function getRecord() {
101
- const id = document.getElementById('recordId').value;
102
- if(!id) return outputEl.innerHTML = `<span class="text-red-500">Error: Provide an ID first!</span>`;
103
- outputEl.innerHTML = `<span class="text-yellow-500">Executing GET /users/${id}...</span>`;
104
- try {
105
- const res = await fetch('/users/' + id);
106
- print(await res.json(), 'GET');
107
- } catch (e) { outputEl.innerHTML = `<span class="text-red-500">Error: ${e.message}</span>`; }
108
- }
109
-
110
- async function updateRecord() {
111
- const id = document.getElementById('recordId').value;
112
- if(!id) return outputEl.innerHTML = `<span class="text-red-500">Error: Provide an ID first!</span>`;
113
- outputEl.innerHTML = `<span class="text-yellow-500">Executing PUT /users/${id}...</span>`;
114
- try {
115
- const res = await fetch('/users/' + id, { method: 'PUT', body: document.getElementById('updateData').value });
116
- print(await res.json(), 'PUT');
117
- } catch (e) { outputEl.innerHTML = `<span class="text-red-500">Error: ${e.message}</span>`; }
118
- }
119
-
120
- async function deleteRecord() {
121
- const id = document.getElementById('recordId').value;
122
- if(!id) return outputEl.innerHTML = `<span class="text-red-500">Error: Provide an ID first!</span>`;
123
- outputEl.innerHTML = `<span class="text-yellow-500">Executing DELETE /users/${id}...</span>`;
124
- try {
125
- const res = await fetch('/users/' + id, { method: 'DELETE' });
126
- print(await res.json(), 'DELETE');
127
- document.getElementById('recordId').value = ''; // Clear ID
128
- } catch (e) { outputEl.innerHTML = `<span class="text-red-500">Error: ${e.message}</span>`; }
129
- }
130
- </script>
131
- </body>
132
- </html>
package/roccodb-1.0.0.tgz DELETED
Binary file