@joystick.js/db-canary 0.0.0-canary.2228 → 0.0.0-canary.2230
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as l from"lmdb";import{rmSync as d,existsSync as
|
|
1
|
+
import*as l from"lmdb";import{rmSync as d,existsSync as m}from"fs";import{randomBytes as u}from"crypto";import p from"./logger.js";import{calculate_map_size as f,get_disk_size as g,should_grow_map_size as z}from"./disk_utils.js";import{initialize_index_database as b,cleanup_index_database as h}from"./index_manager.js";import{initialize_auto_index_database as w,cleanup_auto_index_database as y}from"./auto_index_manager.js";const{create_context_logger:c}=p("query_engine");let r=null,i=null,o=null;const k=(t="./data")=>{const e=c();return r||(o=t,f(o).then(s=>{i=s,r&&r.resize&&(r.resize(i),e.info("Database map_size updated",{path:o,map_size:i,map_size_gb:Math.round(i/(1024*1024*1024)*100)/100}))}).catch(s=>{e.warn("Failed to calculate map_size, using default",{database_path:o,error:s.message})}),i=1024*1024*1024*10,r=l.open({path:o,compression:!0,useVersions:!1,encoding:"msgpack",mapSize:i}),e.info("Database initialized",{path:o,map_size:i,map_size_gb:Math.round(i/(1024*1024*1024)*100)/100}),b(),w()),r},x=async()=>{if(!r||!o)return;const t=c();try{const e=r.getStats?r.getStats():{},a=e.ms_psize*e.ms_leaf_pages||0;if(a===0)return;const s=await g(o),n=z(i,a,s);n&&(t.info("Growing map_size",{current_map_size:i,new_map_size:n,used_size:a,usage_percentage:Math.round(a/i*100)}),r.resize(n),i=n,t.info("Map size grown successfully",{new_map_size:n,new_map_size_gb:Math.round(n/(1024*1024*1024)*100)/100}))}catch(e){t.error("Failed to check/grow map_size",{error:e.message})}},M=()=>{if(!r)throw new Error("Database not initialized. Call initialize_database first.");return r},S=()=>{const t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",e=u(16);let a="";for(let s=0;s<16;s++)a+=t.charAt(e[s]%t.length);return a},v=(t,e,a)=>`${t}:${e}:${a}`,D=t=>{const e=t.split(":");return{database:e[0],collection:e[1],document_id:e.slice(2).join(":")}},F=async(t=!1)=>{const e=c(),a=o;if(r){try{await new Promise(s=>setTimeout(s,100)),y(),h(),await r.close(),e.info("Database closed successfully")}catch(s){e.warn("Error closing database",{error:s.message})}r=null,i=null,o=null}if(t&&a&&_(a))try{m(a)&&(d(a,{recursive:!0,force:!0}),e.info("Test database directory removed",{path:a}))}catch(s){e.warn("Failed to remove test database directory",{path:a,error:s.message})}},_=t=>t&&(t.includes("test_data")||t.startsWith("./test_")||t.startsWith("test_"));export{v as build_collection_key,x as check_and_grow_map_size,F as cleanup_database,S as generate_document_id,M as get_database,k as initialize_database,_ as is_test_database_path,D as parse_collection_key};
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@joystick.js/db-canary",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.0-canary.
|
|
5
|
-
"canary_version": "0.0.0-canary.
|
|
4
|
+
"version": "0.0.0-canary.2230",
|
|
5
|
+
"canary_version": "0.0.0-canary.2229",
|
|
6
6
|
"description": "JoystickDB - A minimalist database server for the Joystick framework",
|
|
7
7
|
"main": "./dist/server/index.js",
|
|
8
8
|
"scripts": {
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import * as lmdb from 'lmdb';
|
|
10
10
|
import { rmSync, existsSync } from 'fs';
|
|
11
|
+
import { randomBytes } from 'crypto';
|
|
11
12
|
import create_logger from './logger.js';
|
|
12
13
|
import { calculate_map_size, get_disk_size, should_grow_map_size } from './disk_utils.js';
|
|
13
14
|
import { initialize_index_database, cleanup_index_database } from './index_manager.js';
|
|
@@ -135,11 +136,19 @@ const get_database = () => {
|
|
|
135
136
|
};
|
|
136
137
|
|
|
137
138
|
/**
|
|
138
|
-
* Generates a unique document ID
|
|
139
|
-
* @returns {string} Unique document identifier
|
|
139
|
+
* Generates a unique document ID as a 16-character alphanumeric string using cryptographically secure randomization.
|
|
140
|
+
* @returns {string} Unique document identifier (16 alphanumeric characters)
|
|
140
141
|
*/
|
|
141
142
|
const generate_document_id = () => {
|
|
142
|
-
|
|
143
|
+
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
144
|
+
const random_bytes = randomBytes(16);
|
|
145
|
+
let result = '';
|
|
146
|
+
|
|
147
|
+
for (let i = 0; i < 16; i++) {
|
|
148
|
+
result += characters.charAt(random_bytes[i] % characters.length);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return result;
|
|
143
152
|
};
|
|
144
153
|
|
|
145
154
|
/**
|
|
@@ -38,6 +38,35 @@ test('query_engine - should generate unique document ids', (t) => {
|
|
|
38
38
|
t.not(id1, id2);
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
+
test('query_engine - should generate 16-character alphanumeric document ids', (t) => {
|
|
42
|
+
const id = generate_document_id();
|
|
43
|
+
|
|
44
|
+
// Should be exactly 16 characters
|
|
45
|
+
t.is(id.length, 16);
|
|
46
|
+
|
|
47
|
+
// Should only contain alphanumeric characters (A-Z, a-z, 0-9)
|
|
48
|
+
const alphanumeric_regex = /^[A-Za-z0-9]+$/;
|
|
49
|
+
t.true(alphanumeric_regex.test(id));
|
|
50
|
+
|
|
51
|
+
// Should not contain hyphens or other punctuation
|
|
52
|
+
t.false(id.includes('-'));
|
|
53
|
+
t.false(id.includes('_'));
|
|
54
|
+
t.false(id.includes('.'));
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test('query_engine - should generate cryptographically secure document ids', (t) => {
|
|
58
|
+
// Generate multiple IDs to check for randomness
|
|
59
|
+
const ids = new Set();
|
|
60
|
+
for (let i = 0; i < 1000; i++) {
|
|
61
|
+
const id = generate_document_id();
|
|
62
|
+
t.false(ids.has(id), `Duplicate ID generated: ${id}`);
|
|
63
|
+
ids.add(id);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// All IDs should be unique
|
|
67
|
+
t.is(ids.size, 1000);
|
|
68
|
+
});
|
|
69
|
+
|
|
41
70
|
test('query_engine - should build and parse collection keys correctly', (t) => {
|
|
42
71
|
const key = build_collection_key('default', 'users', 'abc123');
|
|
43
72
|
t.is(key, 'default:users:abc123');
|