squirreling 0.2.0 → 0.2.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/README.md CHANGED
@@ -7,6 +7,7 @@
7
7
  [![minzipped](https://img.shields.io/bundlephobia/minzip/squirreling)](https://www.npmjs.com/package/squirreling)
8
8
  [![workflow status](https://github.com/hyparam/squirreling/actions/workflows/ci.yml/badge.svg)](https://github.com/hyparam/squirreling/actions)
9
9
  [![mit license](https://img.shields.io/badge/License-MIT-orange.svg)](https://opensource.org/licenses/MIT)
10
+ ![coverage](https://img.shields.io/badge/Coverage-89-darkred)
10
11
  [![dependencies](https://img.shields.io/badge/Dependencies-0-blueviolet)](https://www.npmjs.com/package/squirreling?activeTab=dependencies)
11
12
 
12
13
  Squirreling is a lightweight SQL engine for JavaScript applications, designed to provide efficient and easy-to-use database functionalities in the browser.
@@ -29,7 +30,7 @@ const source = [
29
30
  { id: 2, name: 'Bob' },
30
31
  ]
31
32
 
32
- const result = executeSql({ source, sql: 'SELECT UPPER(name) AS name_upper FROM users' })
33
+ const result = executeSql({ source, query: 'SELECT UPPER(name) AS name_upper FROM users' })
33
34
  console.log(result)
34
35
  // Output: [ { name_upper: 'ALICE' }, { name_upper: 'BOB' } ]
35
36
  ```
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "squirreling",
3
- "version": "0.2.0",
4
- "description": "",
3
+ "version": "0.2.2",
4
+ "description": "Squirreling SQL Engine",
5
5
  "author": "Hyperparam",
6
6
  "homepage": "https://hyperparam.app",
7
7
  "keywords": [
@@ -40,7 +40,7 @@
40
40
  "@types/node": "24.10.1",
41
41
  "@vitest/coverage-v8": "4.0.13",
42
42
  "eslint": "9.39.1",
43
- "eslint-plugin-jsdoc": "61.4.0",
43
+ "eslint-plugin-jsdoc": "61.4.1",
44
44
  "typescript": "5.9.3",
45
45
  "vitest": "4.0.13"
46
46
  }
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { defaultAggregateAlias, evaluateAggregate } from './aggregates.js'
6
6
  import { evaluateExpr } from './expression.js'
7
- import { createHavingContext, evaluateHavingExpr } from './having.js'
7
+ import { evaluateHavingExpr } from './having.js'
8
8
  import { parseSql } from '../parse/parse.js'
9
9
  import { createMemorySource, createRowAccessor } from '../backend/memory.js'
10
10
 
@@ -14,8 +14,8 @@ import { createMemorySource, createRowAccessor } from '../backend/memory.js'
14
14
  * @param {ExecuteSqlOptions} options - the execution options
15
15
  * @returns {Record<string, any>[]} the result rows matching the query
16
16
  */
17
- export function executeSql({ source, sql }) {
18
- const select = parseSql(sql)
17
+ export function executeSql({ source, query }) {
18
+ const select = parseSql(query)
19
19
  const dataSource = Array.isArray(source) ? createMemorySource(source) : source
20
20
  return evaluateSelectAst(select, dataSource)
21
21
  }
@@ -142,6 +142,8 @@ function evaluateSelectAst(select, dataSource) {
142
142
  throw new Error('JOIN is not supported')
143
143
  }
144
144
 
145
+ // SQL priority: from, where, group by, having, select, order by, offset, limit
146
+
145
147
  // WHERE clause filtering
146
148
  /** @type {RowSource[]} */
147
149
  const working = []
@@ -244,8 +246,7 @@ function evaluateSelectAst(select, dataSource) {
244
246
  if (select.having) {
245
247
  // For HAVING, we need to evaluate aggregates in the context of the group
246
248
  // Create a special row context that includes both the group data and aggregate values
247
- const havingContext = createHavingContext(resultRow, group)
248
- if (!evaluateHavingExpr(select.having, havingContext, group)) {
249
+ if (!evaluateHavingExpr(select.having, resultRow, group)) {
249
250
  continue
250
251
  }
251
252
  }
@@ -12,7 +12,7 @@ import { evaluateExpr } from './expression.js'
12
12
  * @param {RowSource[]} group - the group of rows
13
13
  * @returns {RowSource} a context row for HAVING evaluation
14
14
  */
15
- export function createHavingContext(resultRow, group) {
15
+ function createHavingContext(resultRow, group) {
16
16
  // Include the first row of the group (for GROUP BY columns)
17
17
  const firstRow = group[0]
18
18
  /** @type {Record<string, any>} */
@@ -41,11 +41,13 @@ export function createHavingContext(resultRow, group) {
41
41
  * Evaluates a HAVING expression with support for aggregate functions
42
42
  *
43
43
  * @param {ExprNode} expr - the HAVING expression
44
- * @param {RowSource} context - the context row with aggregated values
44
+ * @param {Record<string, any>} row - the aggregated result row
45
45
  * @param {RowSource[]} group - the group of rows for re-evaluating aggregates
46
46
  * @returns {boolean} whether the HAVING condition is satisfied
47
47
  */
48
- export function evaluateHavingExpr(expr, context, group) {
48
+ export function evaluateHavingExpr(expr, row, group) {
49
+ const context = createHavingContext(row, group)
50
+
49
51
  // For HAVING, we need special handling of aggregate functions
50
52
  // They need to be re-evaluated against the group
51
53
  if (expr.type === 'function') {
package/src/index.d.ts CHANGED
@@ -1,13 +1,14 @@
1
- import type { RowSource, SelectStatement } from './types.js'
1
+ import type { ExecuteSqlOptions, SelectStatement } from './types.js'
2
2
 
3
3
  /**
4
4
  * Executes a SQL SELECT query against an array of data rows
5
5
  *
6
- * @param rows - data rows to query as a list of objects
7
- * @param sql - SQL query string
6
+ * @param options
7
+ * @param options.source - source data as a list of objects or a DataSource
8
+ * @param options.sql - SQL query string
8
9
  * @returns rows matching the query
9
10
  */
10
- export function executeSql(rows: RowSource[], sql: string): RowSource[]
11
+ export function executeSql(options: ExecuteSqlOptions): Record<string, any>[]
11
12
 
12
13
  /**
13
14
  * Parses a SQL query string into an abstract syntax tree
@@ -15,4 +16,4 @@ export function executeSql(rows: RowSource[], sql: string): RowSource[]
15
16
  * @param sql - SQL query string to parse
16
17
  * @returns parsed SQL select statement
17
18
  */
18
- export function parseSql(sql: string): SelectStatement
19
+ export function parseSql(query: string): SelectStatement
package/src/types.d.ts CHANGED
@@ -10,7 +10,7 @@ export interface DataSource {
10
10
 
11
11
  export interface ExecuteSqlOptions {
12
12
  source: Record<string, any>[] | DataSource
13
- sql: string
13
+ query: string
14
14
  }
15
15
 
16
16
  export type SqlPrimitive = string | number | bigint | boolean | null