@joystick.js/db-canary 0.0.0-canary.2248 → 0.0.0-canary.2250

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{get_database as D,build_collection_key as A}from"../query_engine.js";import{can_use_index as J,find_documents_by_index as v}from"../index_manager.js";import{record_query as N,record_index_usage as F}from"../auto_index_manager.js";import S from"../logger.js";const{create_context_logger:R}=S("find"),C=(n,t)=>{const o=t.split(".");let r=n;for(const e of o){if(r==null)return;r=r[e]}return r},P=(n,t)=>{const o=t.split(".");let r=n;for(let e=0;e<o.length;e++){if(r==null||typeof r!="object")return!1;if(e===o.length-1)return r.hasOwnProperty(o[e]);r=r[o[e]]}return!1},O=(n,t)=>{if(!t||Object.keys(t).length===0)return!0;for(const[o,r]of Object.entries(t)){const e=C(n,o);if(typeof r=="object"&&r!==null&&!Array.isArray(r))for(const[i,s]of Object.entries(r))switch(i){case"$eq":if(e!==s)return!1;break;case"$ne":if(e===s)return!1;break;case"$gt":if(e<=s)return!1;break;case"$gte":if(e<s)return!1;break;case"$lt":if(e>=s)return!1;break;case"$lte":if(e>s)return!1;break;case"$in":if(!Array.isArray(s)||!s.includes(e))return!1;break;case"$nin":if(!Array.isArray(s)||s.includes(e))return!1;break;case"$exists":const c=P(n,o);if(s&&!c||!s&&c)return!1;break;case"$regex":const u=r.$options||"";if(!new RegExp(s,u).test(e))return!1;break;default:throw new Error(`Unsupported query operator: ${i}`)}else if(e!==r)return!1}return!0},U=(n,t)=>{if(!t||Object.keys(t).length===0)return n;const o=Object.values(t).some(e=>e===1||e===!0),r={};if(o){r._id=n._id;for(const[e,i]of Object.entries(t))e==="_id"&&(i===0||i===!1)?delete r._id:(i===1||i===!0)&&(r[e]=n[e])}else{Object.assign(r,n);for(const[e,i]of Object.entries(t))(i===0||i===!1)&&delete r[e]}return r},z=(n,t)=>!t||Object.keys(t).length===0?n:n.sort((o,r)=>{for(const[e,i]of Object.entries(t)){const s=o[e],c=r[e];if(s===c)continue;if(s===void 0)return 1;if(c===void 0)return-1;const u=s<c?-1:s>c?1:0;return i===-1?-u:u}return 0}),B=async(n,t,o={},r={})=>{const e=R();if(!n)throw new Error("Database name is required");if(!t)throw new Error("Collection name is required");const i=D(),{projection:s,sort:c,limit:u,skip:h=0}=r,E=Date.now();try{let d=[],_=!1,k=null;const $=J(n,t,o);if($){const{field:f,operators:x}=$,a=o[f];if(k=f,typeof a=="object"&&a!==null&&!Array.isArray(a)){for(const l of x)if(a[l]!==void 0){const p=v(n,t,f,l,a[l]);if(p){_=!0,F(n,t,f);for(const m of p){const b=A(n,t,m),y=i.get(b);if(y){const q=JSON.parse(y);O(q,o)&&d.push(q)}}break}}}else if(x.includes("eq")){const l=v(n,t,f,"eq",a);if(l){_=!0,F(n,t,f);for(const p of l){const m=A(n,t,p),b=i.get(m);if(b){const y=JSON.parse(b);O(y,o)&&d.push(y)}}}}}if(!_){const f=`${n}:${t}:`,x=i.getRange({start:f,end:f+"\xFF"});for(const{key:a,value:l}of x){const p=JSON.parse(l);O(p,o)&&d.push(p)}}let g=z(d,c);h>0&&(g=g.slice(h)),u&&u>0&&(g=g.slice(0,u));const j=g.map(f=>U(f,s)),w=Date.now()-E;try{N(t,o,w,_,k)}catch(f){e.warn("Failed to record query for auto-indexing",{error:f.message})}return e.info("Find operation completed",{database:n,collection:t,documents_found:j.length,total_matching:d.length,used_index:_,indexed_field:k,execution_time_ms:w}),j}catch(d){throw e.error("Failed to find documents",{database:n,collection:t,error:d.message}),d}};var L=B;export{L as default};
1
+ import{get_database as D,build_collection_key as q}from"../query_engine.js";import{can_use_index as J,find_documents_by_index as v}from"../index_manager.js";import{record_query as N,record_index_usage as F}from"../auto_index_manager.js";import S from"../logger.js";const{create_context_logger:R}=S("find"),C=(n,r)=>{const o=r.split(".");let t=n;for(const e of o){if(t==null)return;t=t[e]}return t},P=(n,r)=>{const o=r.split(".");let t=n;for(let e=0;e<o.length;e++){if(t==null||typeof t!="object")return!1;if(e===o.length-1)return t.hasOwnProperty(o[e]);t=t[o[e]]}return!1},b=(n,r)=>{if(!r||Object.keys(r).length===0)return!0;if(r.$or&&Array.isArray(r.$or)){if(!r.$or.some(e=>b(n,e)))return!1;const t={...r};return delete t.$or,Object.keys(t).length>0?b(n,t):!0}for(const[o,t]of Object.entries(r)){const e=C(n,o);if(typeof t=="object"&&t!==null&&!Array.isArray(t))for(const[i,s]of Object.entries(t))switch(i){case"$eq":if(e!==s)return!1;break;case"$ne":if(e===s)return!1;break;case"$gt":if(e<=s)return!1;break;case"$gte":if(e<s)return!1;break;case"$lt":if(e>=s)return!1;break;case"$lte":if(e>s)return!1;break;case"$in":if(!Array.isArray(s)||!s.includes(e))return!1;break;case"$nin":if(!Array.isArray(s)||s.includes(e))return!1;break;case"$exists":const c=P(n,o);if(s&&!c||!s&&c)return!1;break;case"$regex":const u=t.$options||"";if(!new RegExp(s,u).test(e))return!1;break;case"$options":break;default:throw new Error(`Unsupported query operator: ${i}`)}else if(e!==t)return!1}return!0},U=(n,r)=>{if(!r||Object.keys(r).length===0)return n;const o=Object.values(r).some(e=>e===1||e===!0),t={};if(o){t._id=n._id;for(const[e,i]of Object.entries(r))e==="_id"&&(i===0||i===!1)?delete t._id:(i===1||i===!0)&&(t[e]=n[e])}else{Object.assign(t,n);for(const[e,i]of Object.entries(r))(i===0||i===!1)&&delete t[e]}return t},z=(n,r)=>!r||Object.keys(r).length===0?n:n.sort((o,t)=>{for(const[e,i]of Object.entries(r)){const s=o[e],c=t[e];if(s===c)continue;if(s===void 0)return 1;if(c===void 0)return-1;const u=s<c?-1:s>c?1:0;return i===-1?-u:u}return 0}),B=async(n,r,o={},t={})=>{const e=R();if(!n)throw new Error("Database name is required");if(!r)throw new Error("Collection name is required");const i=D(),{projection:s,sort:c,limit:u,skip:k=0}=t,E=Date.now();try{let d=[],_=!1,$=null;const O=J(n,r,o);if(O){const{field:f,operators:h}=O,a=o[f];if($=f,typeof a=="object"&&a!==null&&!Array.isArray(a)){for(const l of h)if(a[l]!==void 0){const p=v(n,r,f,l,a[l]);if(p){_=!0,F(n,r,f);for(const m of p){const x=q(n,r,m),y=i.get(x);if(y){const A=JSON.parse(y);b(A,o)&&d.push(A)}}break}}}else if(h.includes("eq")){const l=v(n,r,f,"eq",a);if(l){_=!0,F(n,r,f);for(const p of l){const m=q(n,r,p),x=i.get(m);if(x){const y=JSON.parse(x);b(y,o)&&d.push(y)}}}}}if(!_){const f=`${n}:${r}:`,h=i.getRange({start:f,end:f+"\xFF"});for(const{key:a,value:l}of h){const p=JSON.parse(l);b(p,o)&&d.push(p)}}let g=z(d,c);k>0&&(g=g.slice(k)),u&&u>0&&(g=g.slice(0,u));const j=g.map(f=>U(f,s)),w=Date.now()-E;try{N(r,o,w,_,$)}catch(f){e.warn("Failed to record query for auto-indexing",{error:f.message})}return e.info("Find operation completed",{database:n,collection:r,documents_found:j.length,total_matching:d.length,used_index:_,indexed_field:$,execution_time_ms:w}),j}catch(d){throw e.error("Failed to find documents",{database:n,collection:r,error:d.message}),d}};var L=B;export{L as default};
@@ -1 +1 @@
1
- import{get_database as A,build_collection_key as j}from"../query_engine.js";import{can_use_index as v,find_documents_by_index as m}from"../index_manager.js";import{record_query as D,record_index_usage as q}from"../auto_index_manager.js";import E from"../logger.js";const{create_context_logger:F}=E("find_one"),N=(o,t)=>{const n=t.split(".");let r=o;for(const e of n){if(r==null)return;r=r[e]}return r},J=(o,t)=>{const n=t.split(".");let r=o;for(let e=0;e<n.length;e++){if(r==null||typeof r!="object")return!1;if(e===n.length-1)return r.hasOwnProperty(n[e]);r=r[n[e]]}return!1},w=(o,t)=>{if(!t||Object.keys(t).length===0)return!0;for(const[n,r]of Object.entries(t)){const e=N(o,n);if(typeof r=="object"&&r!==null&&!Array.isArray(r))for(const[i,s]of Object.entries(r))switch(i){case"$eq":if(e!==s)return!1;break;case"$ne":if(e===s)return!1;break;case"$gt":if(e<=s)return!1;break;case"$gte":if(e<s)return!1;break;case"$lt":if(e>=s)return!1;break;case"$lte":if(e>s)return!1;break;case"$in":if(!Array.isArray(s)||!s.includes(e))return!1;break;case"$nin":if(!Array.isArray(s)||s.includes(e))return!1;break;case"$exists":const x=J(o,n);if(s&&!x||!s&&x)return!1;break;case"$regex":const b=r.$options||"";if(!new RegExp(s,b).test(e))return!1;break;default:throw new Error(`Unsupported query operator: ${i}`)}else if(e!==r)return!1}return!0},S=(o,t)=>{if(!t||Object.keys(t).length===0)return o;const n=Object.values(t).some(e=>e===1||e===!0),r={};if(n){r._id=o._id;for(const[e,i]of Object.entries(t))e==="_id"&&(i===0||i===!1)?delete r._id:(i===1||i===!0)&&(r[e]=o[e])}else{Object.assign(r,o);for(const[e,i]of Object.entries(t))(i===0||i===!1)&&delete r[e]}return r},R=async(o,t,n={},r={})=>{const e=F();if(!o)throw new Error("Database name is required");if(!t)throw new Error("Collection name is required");const i=A(),{projection:s,sort:x}=r,b=Date.now();try{let c=null,a=!1,_=null;const O=v(o,t,n);if(O){const{field:f,operators:g}=O,d=n[f];if(_=f,typeof d=="object"&&d!==null&&!Array.isArray(d)){for(const u of g)if(d[u]!==void 0){const l=m(o,t,f,u,d[u]);if(l&&l.length>0){a=!0,q(o,t,f);for(const h of l){const y=j(o,t,h),p=i.get(y);if(p)try{const $=JSON.parse(p);if(w($,n)){c=$;break}}catch{continue}}break}}}else if(g.includes("eq")){const u=m(o,t,f,"eq",d);if(u&&u.length>0){a=!0,q(o,t,f);for(const l of u){const h=j(o,t,l),y=i.get(h);if(y)try{const p=JSON.parse(y);if(w(p,n)){c=p;break}}catch{continue}}}}}if(!a){const f=`${o}:${t}:`,g=i.getRange({start:f,end:f+"\xFF"});for(const{key:d,value:u}of g)try{const l=JSON.parse(u);if(w(l,n)){c=l;break}}catch{continue}}const k=Date.now()-b;try{D(t,n,k,a,_)}catch(f){e.warn("Failed to record query for auto-indexing",{error:f.message})}if(c){const f=S(c,s);return e.info("Document found",{database:o,collection:t,document_id:c._id,used_index:a,indexed_field:_,execution_time_ms:k}),f}return e.info("No document found",{database:o,collection:t,used_index:a,indexed_field:_,execution_time_ms:k}),null}catch(c){throw e.error("Failed to find document",{database:o,collection:t,error:c.message}),c}};var B=R;export{B as default};
1
+ import{get_database as q,build_collection_key as j}from"../query_engine.js";import{can_use_index as v,find_documents_by_index as m}from"../index_manager.js";import{record_query as D,record_index_usage as A}from"../auto_index_manager.js";import E from"../logger.js";const{create_context_logger:F}=E("find_one"),N=(o,t)=>{const n=t.split(".");let r=o;for(const e of n){if(r==null)return;r=r[e]}return r},J=(o,t)=>{const n=t.split(".");let r=o;for(let e=0;e<n.length;e++){if(r==null||typeof r!="object")return!1;if(e===n.length-1)return r.hasOwnProperty(n[e]);r=r[n[e]]}return!1},p=(o,t)=>{if(!t||Object.keys(t).length===0)return!0;if(t.$or&&Array.isArray(t.$or)){if(!t.$or.some(e=>p(o,e)))return!1;const r={...t};return delete r.$or,Object.keys(r).length>0?p(o,r):!0}for(const[n,r]of Object.entries(t)){const e=N(o,n);if(typeof r=="object"&&r!==null&&!Array.isArray(r))for(const[i,s]of Object.entries(r))switch(i){case"$eq":if(e!==s)return!1;break;case"$ne":if(e===s)return!1;break;case"$gt":if(e<=s)return!1;break;case"$gte":if(e<s)return!1;break;case"$lt":if(e>=s)return!1;break;case"$lte":if(e>s)return!1;break;case"$in":if(!Array.isArray(s)||!s.includes(e))return!1;break;case"$nin":if(!Array.isArray(s)||s.includes(e))return!1;break;case"$exists":const x=J(o,n);if(s&&!x||!s&&x)return!1;break;case"$regex":const k=r.$options||"";if(!new RegExp(s,k).test(e))return!1;break;case"$options":break;default:throw new Error(`Unsupported query operator: ${i}`)}else if(e!==r)return!1}return!0},S=(o,t)=>{if(!t||Object.keys(t).length===0)return o;const n=Object.values(t).some(e=>e===1||e===!0),r={};if(n){r._id=o._id;for(const[e,i]of Object.entries(t))e==="_id"&&(i===0||i===!1)?delete r._id:(i===1||i===!0)&&(r[e]=o[e])}else{Object.assign(r,o);for(const[e,i]of Object.entries(t))(i===0||i===!1)&&delete r[e]}return r},R=async(o,t,n={},r={})=>{const e=F();if(!o)throw new Error("Database name is required");if(!t)throw new Error("Collection name is required");const i=q(),{projection:s,sort:x}=r,k=Date.now();try{let f=null,a=!1,g=null;const O=v(o,t,n);if(O){const{field:c,operators:y}=O,d=n[c];if(g=c,typeof d=="object"&&d!==null&&!Array.isArray(d)){for(const u of y)if(d[u]!==void 0){const l=m(o,t,c,u,d[u]);if(l&&l.length>0){a=!0,A(o,t,c);for(const $ of l){const b=j(o,t,$),_=i.get(b);if(_)try{const w=JSON.parse(_);if(p(w,n)){f=w;break}}catch{continue}}break}}}else if(y.includes("eq")){const u=m(o,t,c,"eq",d);if(u&&u.length>0){a=!0,A(o,t,c);for(const l of u){const $=j(o,t,l),b=i.get($);if(b)try{const _=JSON.parse(b);if(p(_,n)){f=_;break}}catch{continue}}}}}if(!a){const c=`${o}:${t}:`,y=i.getRange({start:c,end:c+"\xFF"});for(const{key:d,value:u}of y)try{const l=JSON.parse(u);if(p(l,n)){f=l;break}}catch{continue}}const h=Date.now()-k;try{D(t,n,h,a,g)}catch(c){e.warn("Failed to record query for auto-indexing",{error:c.message})}if(f){const c=S(f,s);return e.info("Document found",{database:o,collection:t,document_id:f._id,used_index:a,indexed_field:g,execution_time_ms:h}),c}return e.info("No document found",{database:o,collection:t,used_index:a,indexed_field:g,execution_time_ms:h}),null}catch(f){throw e.error("Failed to find document",{database:o,collection:t,error:f.message}),f}};var B=R;export{B as default};
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.2248",
5
- "canary_version": "0.0.0-canary.2247",
4
+ "version": "0.0.0-canary.2250",
5
+ "canary_version": "0.0.0-canary.2249",
6
6
  "description": "JoystickDB - A minimalist database server for the Joystick framework",
7
7
  "main": "./dist/server/index.js",
8
8
  "scripts": {
@@ -69,6 +69,20 @@ const matches_filter = (document, filter) => {
69
69
  return true;
70
70
  }
71
71
 
72
+ // Handle $or operator at the top level
73
+ if (filter.$or && Array.isArray(filter.$or)) {
74
+ const or_match = filter.$or.some(or_condition => matches_filter(document, or_condition));
75
+ if (!or_match) return false;
76
+
77
+ // Continue checking other conditions (if any) outside of $or
78
+ const remaining_filter = { ...filter };
79
+ delete remaining_filter.$or;
80
+ if (Object.keys(remaining_filter).length > 0) {
81
+ return matches_filter(document, remaining_filter);
82
+ }
83
+ return true;
84
+ }
85
+
72
86
  for (const [field, value] of Object.entries(filter)) {
73
87
  const field_value = get_field_value(document, field);
74
88
 
@@ -110,6 +124,9 @@ const matches_filter = (document, filter) => {
110
124
  const regex = new RegExp(operand, regex_options);
111
125
  if (!regex.test(field_value)) return false;
112
126
  break;
127
+ case '$options':
128
+ // $options is handled as part of $regex, skip it here
129
+ break;
113
130
  default:
114
131
  throw new Error(`Unsupported query operator: ${operator}`);
115
132
  }
@@ -70,6 +70,20 @@ const matches_filter = (document, filter) => {
70
70
  return true;
71
71
  }
72
72
 
73
+ // Handle $or operator at the top level
74
+ if (filter.$or && Array.isArray(filter.$or)) {
75
+ const or_match = filter.$or.some(or_condition => matches_filter(document, or_condition));
76
+ if (!or_match) return false;
77
+
78
+ // Continue checking other conditions (if any) outside of $or
79
+ const remaining_filter = { ...filter };
80
+ delete remaining_filter.$or;
81
+ if (Object.keys(remaining_filter).length > 0) {
82
+ return matches_filter(document, remaining_filter);
83
+ }
84
+ return true;
85
+ }
86
+
73
87
  for (const [field, value] of Object.entries(filter)) {
74
88
  const field_value = get_field_value(document, field);
75
89
 
@@ -111,6 +125,9 @@ const matches_filter = (document, filter) => {
111
125
  const regex = new RegExp(operand, regex_options);
112
126
  if (!regex.test(field_value)) return false;
113
127
  break;
128
+ case '$options':
129
+ // $options is handled as part of $regex, skip it here
130
+ break;
114
131
  default:
115
132
  throw new Error(`Unsupported query operator: ${operator}`);
116
133
  }