Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@uwdata/mosaic-core

Package Overview
Dependencies
Maintainers
0
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@uwdata/mosaic-core - npm Package Compare versions

Comparing version 0.11.0 to 0.12.0

dist/types/connectors/rest.d.ts

18

package.json
{
"name": "@uwdata/mosaic-core",
"version": "0.11.0",
"version": "0.12.0",
"description": "Scalable and extensible linked data views.",

@@ -19,2 +19,3 @@ "keywords": [

"unpkg": "dist/mosaic-core.min.js",
"types": "dist/types/index.d.ts",
"repository": {

@@ -26,16 +27,17 @@ "type": "git",

"prebuild": "rimraf dist && mkdir dist",
"build": "node ../../esbuild.js mosaic-core",
"build": "npm run types && node ../../esbuild.js mosaic-core",
"types": "tsc",
"lint": "eslint src test",
"test": "vitest run --dangerouslyIgnoreUnhandledErrors",
"test": "vitest run && tsc -p jsconfig.json",
"prepublishOnly": "npm run test && npm run lint && npm run build"
},
"dependencies": {
"@duckdb/duckdb-wasm": "^1.28.1-dev278.0",
"@uwdata/flechette": "^1.0.2",
"@uwdata/mosaic-sql": "^0.11.0"
"@duckdb/duckdb-wasm": "^1.29.0",
"@uwdata/flechette": "^1.1.1",
"@uwdata/mosaic-sql": "^0.12.0"
},
"devDependencies": {
"@uwdata/mosaic-duckdb": "^0.11.0"
"@uwdata/mosaic-duckdb": "^0.12.0"
},
"gitHead": "861d616f39926a1d2aee83b59dbdd70b0b3caf12"
"gitHead": "523b1afe2a0880291c92f81e4a7b91829362d285"
}
# mosaic-core
The core Mosaic components: a central coordinator, parameters (`Param`) and selections (`Selection`) for linking scalar values or query predicates (respectively) across Mosaic clients, and filter groups with optimized index management. The Mosaic coordinator can send queries either over the network to a backing server (`socket` and `rest` clients) or to a client-side [DuckDB-WASM](https://github.com/duckdb/duckdb-wasm) instance (`wasm` client).
The core Mosaic components: a central coordinator, parameters (`Param`) and selections (`Selection`) for linking scalar values or query predicates (respectively) across Mosaic clients, and filter groups with materialized views of pre-aggregated data. The Mosaic coordinator can send queries either over the network to a backing server (`socket` and `rest` clients) or to a client-side [DuckDB-WASM](https://github.com/duckdb/duckdb-wasm) instance (`wasm` client).
The `mosaic-core` facilities are included as part of the [vgplot](https://github.com/uwdata/mosaic/tree/main/packages/vgplot) API.

@@ -9,3 +9,5 @@ import { decodeIPC } from '../util/decode-ipc.js';

* @param {'exec' | 'arrow' | 'json' | 'create-bundle' | 'load-bundle'} [query.type] The query type.
* @param {string} query.sql A SQL query string.
* @param {string} [query.sql] A SQL query string.
* @param {string[]} [query.queries] The queries used to create a bundle.
* @param {string} [query.name] The name of a bundle to create or load.
* @returns the query result

@@ -12,0 +14,0 @@ */

@@ -89,3 +89,5 @@ import { decodeIPC } from '../util/decode-ipc.js';

* @param {'exec' | 'arrow' | 'json' | 'create-bundle' | 'load-bundle'} [query.type] The query type.
* @param {string} query.sql A SQL query string.
* @param {string} [query.sql] A SQL query string.
* @param {string[]} [query.queries] The queries used to create a bundle.
* @param {string} [query.name] The name of a bundle to create or load.
* @returns the query result

@@ -92,0 +94,0 @@ */

@@ -64,3 +64,3 @@ import * as duckdb from '@duckdb/duckdb-wasm';

* @param {object} query
* @param {'exec' | 'arrow' | 'json' | 'create-bundle' | 'load-bundle'} [query.type] The query type.
* @param {'exec' | 'arrow' | 'json'} [query.type] The query type.
* @param {string} query.sql A SQL query string.

@@ -67,0 +67,0 @@ * @returns the query result

import { socketConnector } from './connectors/socket.js';
import { DataCubeIndexer } from './DataCubeIndexer.js';
import { MosaicClient } from './MosaicClient.js';
import { QueryManager, Priority } from './QueryManager.js';
import { PreAggregator } from './preagg/PreAggregator.js';
import { queryFieldInfo } from './util/field-info.js';
import { QueryResult } from './util/query-result.js';
import { voidLogger } from './util/void-logger.js';
import { MosaicClient } from './MosaicClient.js';
import { QueryManager, Priority } from './QueryManager.js';

@@ -36,3 +36,3 @@ /**

* handles selection updates. The Coordinator also performs optimizations
* including query caching, consolidation, and data cube indexing.
* including query caching, consolidation, and pre-aggregation.
* @param {*} [db] Database connector. Defaults to a web socket connection.

@@ -44,4 +44,4 @@ * @param {object} [options] Coordinator options.

* @param {boolean} [options.consolidate=true] Boolean flag to enable/disable query consolidation.
* @param {import('./DataCubeIndexer.js').DataCubeIndexerOptions} [options.indexes]
* Data cube indexer options.
* @param {import('./preagg/PreAggregator.js').PreAggregateOptions} [options.preagg]
* Options for the Pre-aggregator.
*/

@@ -54,3 +54,3 @@ export class Coordinator {

consolidate = true,
indexes = {}
preagg = {}
} = {}) {

@@ -64,3 +64,3 @@ /** @type {QueryManager} */

this.clear();
this.dataCubeIndexer = new DataCubeIndexer(this, indexes);
this.preaggregator = new PreAggregator(this, preagg);
}

@@ -215,3 +215,3 @@

* the client is simply updated. Otherwise `updateClient` is called. As a
* side effect, this method clears the current data cube indexer state.
* side effect, this method clears the current preaggregator state.
* @param {MosaicClient} client The client to update.

@@ -221,3 +221,3 @@ * @param {QueryType | null} [query] The query to issue.

requestQuery(client, query) {
this.dataCubeIndexer.clear();
this.preaggregator.clear();
return query

@@ -316,6 +316,6 @@ ? this.updateClient(client, query)

function activateSelection(mc, selection, clause) {
const { dataCubeIndexer, filterGroups } = mc;
const { preaggregator, filterGroups } = mc;
const { clients } = filterGroups.get(selection);
for (const client of clients) {
dataCubeIndexer.index(client, selection, clause);
preaggregator.request(client, selection, clause);
}

@@ -332,7 +332,7 @@ }

function updateSelection(mc, selection) {
const { dataCubeIndexer, filterGroups } = mc;
const { preaggregator, filterGroups } = mc;
const { clients } = filterGroups.get(selection);
const { active } = selection;
return Promise.allSettled(Array.from(clients, client => {
const info = dataCubeIndexer.index(client, selection, active);
const info = preaggregator.request(client, selection, active);
const filter = info ? null : selection.predicate(client);

@@ -339,0 +339,0 @@

@@ -25,1 +25,14 @@ export { MosaicClient } from './MosaicClient.js';

export { toDataColumns } from './util/to-data-columns.js';
/**
* @typedef {import('./util/selection-types.js').ClauseMetadata} ClauseMetadata
* @typedef {import('./util/selection-types.js').PointMetadata} PointMetadata
* @typedef {import('./util/selection-types.js').MatchMethod} MatchMethod
* @typedef {import('./util/selection-types.js').MatchMetadata} MatchMetadata
* @typedef {import('./util/selection-types.js').ScaleType} ScaleType
* @typedef {import('./util/selection-types.js').Extent} Extent
* @typedef {import('./util/selection-types.js').Scale} Scale
* @typedef {import('./util/selection-types.js').BinMethod} BinMethod
* @typedef {import('./util/selection-types.js').IntervalMetadata} IntervalMetadata
* @typedef {import('./util/selection-types.js').SelectionClause} SelectionClause
*/

@@ -41,7 +41,8 @@ import { throttle } from './util/throttle.js';

/**
* Return a boolean indicating if the client query can be indexed. Should
* return true if changes to the filterBy selection does not change the
* groupby domain of the client query.
* Return a boolean indicating if the client query can be sped up with
* materialized views of pre-aggregated data. Should return true if changes to
* the filterBy selection does not change the groupby domain of the client
* query.
*/
get filterIndexable() {
get filterStable() {
return true;

@@ -48,0 +49,0 @@ }

@@ -1,2 +0,2 @@

import { Query, Ref, isDescribeQuery } from '@uwdata/mosaic-sql';
import { DescribeQuery, isAggregateExpression, isColumnRef, isDescribeQuery, isSelectQuery, Query } from '@uwdata/mosaic-sql';
import { QueryResult } from './util/query-result.js';

@@ -16,6 +16,5 @@

* @param {*} cache Client-side query cache (sql -> data)
* @param {*} record Query recorder function
* @returns A consolidator object
*/
export function consolidator(enqueue, cache, record) {
export function consolidator(enqueue, cache) {
let pending = [];

@@ -32,3 +31,3 @@ let id = 0;

for (const group of groups) {
consolidate(group, enqueue, record);
consolidate(group, enqueue);
processResults(group, cache);

@@ -80,3 +79,3 @@ }

* which is indicated by returning the precise query SQL as the key.
* @param {*} query The input query.
* @param {Query | DescribeQuery} query The input query.
* @param {*} cache The query cache (sql -> data).

@@ -87,8 +86,6 @@ * @returns a key string

const sql = `${query}`;
if (query instanceof Query && !cache.get(sql)) {
if (isSelectQuery(query) && !cache.get(sql)) {
if (
// @ts-ignore
query.orderby().length || query.where().length ||
// @ts-ignore
query.qualify().length || query.having().length
query._orderby.length || query._where.length ||
query._qualify.length || query._having.length
) {

@@ -101,3 +98,3 @@ // do not try to analyze if query includes clauses

// create a derived query stripped of selections
const q = query.clone().$select('*');
const q = query.clone().setSelect('*');

@@ -107,16 +104,12 @@ // check group by criteria for compatibility

// we resolve these against the true grouping expressions
const groupby = query.groupby();
// @ts-ignore
const groupby = query._groupby;
if (groupby.length) {
const map = {}; // expression map (as -> expr)
// @ts-ignore
query.select().forEach(({ as, expr }) => map[as] = expr);
// @ts-ignore
q.$groupby(groupby.map(e => (e instanceof Ref && map[e.column]) || e));
const map = {}; // expression map (alias -> expr)
query._select.forEach(({ alias, expr }) => map[alias] = expr);
q.setGroupby(groupby.map(e => (isColumnRef(e) && map[e.column]) || e));
}
// @ts-ignore
else if (query.select().some(({ expr }) => expr.aggregate)) {
else if (query._select.some(e => isAggregateExpression(e.expr))) {
// if query is an ungrouped aggregate, add an explicit groupby to
// prevent improper consolidation with non-aggregate queries
q.$groupby('ALL');
q.setGroupby('ALL');
}

@@ -136,5 +129,4 @@

* @param {*} enqueue Add entry to query queue
* @param {*} record Query recorder function
*/
function consolidate(group, enqueue, record) {
function consolidate(group, enqueue) {
if (shouldConsolidate(group)) {

@@ -146,4 +138,3 @@ // issue a single consolidated query

cache: false,
record: false,
query: (group.query = consolidatedQuery(group, record))
query: (group.query = consolidatedQuery(group))
},

@@ -181,6 +172,5 @@ result: (group.result = new QueryResult())

* @param {*} group Array of bundled query entries
* @param {*} record Query recorder function
* @returns A consolidated Query instance
*/
function consolidatedQuery(group, record) {
function consolidatedQuery(group) {
const maps = group.maps = [];

@@ -194,3 +184,3 @@ const fields = new Map;

maps.push(fieldMap);
for (const { as, expr } of query.select()) {
for (const { alias, expr } of query._select) {
const e = `${expr}`;

@@ -201,5 +191,4 @@ if (!fields.has(e)) {

const [name] = fields.get(e);
fieldMap.push([name, as]);
fieldMap.push([name, alias]);
}
record(`${query}`);
}

@@ -211,11 +200,11 @@

// update group by statement as needed
const groupby = query.groupby();
const groupby = query._groupby;
if (groupby.length) {
const map = {};
group.maps[0].forEach(([name, as]) => map[as] = name);
query.$groupby(groupby.map(e => (e instanceof Ref && map[e.column]) || e));
query.setGroupby(groupby.map(e => (isColumnRef(e) && map[e.column]) || e));
}
// update select statement and return
return query.$select(Array.from(fields.values()));
return query.setSelect(Array.from(fields.values()));
}

@@ -222,0 +211,0 @@

import { consolidator } from './QueryConsolidator.js';
import { lruCache, voidCache } from './util/cache.js';
import { PriorityQueue } from './util/priority-queue.js';
import { QueryResult } from './util/query-result.js';
import { QueryResult, QueryState } from './util/query-result.js';
import { voidLogger } from './util/void-logger.js';
export const Priority = { High: 0, Normal: 1, Low: 2 };
export const Priority = Object.freeze({ High: 0, Normal: 1, Low: 2 });
export class QueryManager {
constructor() {
constructor(
maxConcurrentRequests = 32
) {
this.queue = new PriorityQueue(3);
this.db = null;
this.clientCache = null;
this._logger = null;
this._logger = voidLogger();
this._logQueries = false;
this.recorders = [];
this.pending = null;
this._consolidate = null;
/**
* Requests pending with the query manager.
*
* @type {QueryResult[]}
*/
this.pendingResults = [];
this.maxConcurrentRequests = maxConcurrentRequests;
this.pendingExec = false;
}
next() {
if (this.pending || this.queue.isEmpty()) return;
if (this.queue.isEmpty() || this.pendingResults.length > this.maxConcurrentRequests || this.pendingExec) {
return;
}
const { request, result } = this.queue.next();
this.pending = this.submit(request, result);
this.pending.finally(() => { this.pending = null; this.next(); });
this.pendingResults.push(result);
if (request.type === 'exec') this.pendingExec = true;
this.submit(request, result).finally(() => {
// return from the queue all requests that are ready
while (this.pendingResults.length && this.pendingResults[0].state !== QueryState.pending) {
const result = this.pendingResults.shift();
if (result.state === QueryState.ready) {
result.fulfill();
} else if (result.state === QueryState.done) {
this._logger.warn('Found resolved query in pending results.');
}
}
if (request.type === 'exec') this.pendingExec = false;
this.next();
});
}
/**
* Add an entry to the query queue with a priority.
* @param {object} entry The entry to add.
* @param {*} [entry.request] The query request.
* @param {QueryResult} [entry.result] The query result.
* @param {number} priority The query priority, defaults to `Priority.Normal`.
*/
enqueue(entry, priority = Priority.Normal) {

@@ -32,18 +66,12 @@ this.queue.insert(entry, priority);

recordQuery(sql) {
if (this.recorders.length && sql) {
this.recorders.forEach(rec => rec.add(sql));
}
}
/**
* Submit the query to the connector.
* @param {*} request The request.
* @param {QueryResult} result The query result.
*/
async submit(request, result) {
try {
const { query, type, cache = false, record = true, options } = request;
const { query, type, cache = false, options } = request;
const sql = query ? `${query}` : null;
// update recorders
if (record) {
this.recordQuery(sql);
}
// check query cache

@@ -53,4 +81,5 @@ if (cache) {

if (cached) {
const data = await cached;
this._logger.debug('Cache');
result.fulfill(cached);
result.ready(data);
return;

@@ -65,6 +94,12 @@ }

}
const data = await this.db.query({ type, sql, ...options });
const promise = this.db.query({ type, sql, ...options });
if (cache) this.clientCache.set(sql, promise);
const data = await promise;
if (cache) this.clientCache.set(sql, data);
this._logger.debug(`Request: ${(performance.now() - t0).toFixed(1)}`);
result.fulfill(data);
result.ready(type === 'exec' ? null : data);
} catch (err) {

@@ -95,3 +130,3 @@ result.reject(err);

if (flag && !this._consolidate) {
this._consolidate = consolidator(this.enqueue.bind(this), this.clientCache, this.recordQuery.bind(this));
this._consolidate = consolidator(this.enqueue.bind(this), this.clientCache);
} else if (!flag && this._consolidate) {

@@ -102,2 +137,8 @@ this._consolidate = null;

/**
* Request a query result.
* @param {*} request The request.
* @param {number} priority The query priority, defaults to `Priority.Normal`.
* @returns {QueryResult} A query result promise.
*/
request(request, priority = Priority.Normal) {

@@ -124,2 +165,8 @@ const result = new QueryResult();

});
for (const result of this.pendingResults) {
if (set.has(result)) {
result.reject('Canceled');
}
}
}

@@ -133,24 +180,8 @@ }

});
}
record() {
let state = [];
const recorder = {
add(query) {
state.push(query);
},
reset() {
state = [];
},
snapshot() {
return state.slice();
},
stop() {
this.recorders = this.recorders.filter(x => x !== recorder);
return state;
}
};
this.recorders.push(recorder);
return recorder;
for (const result of this.pendingResults) {
result.reject('Cleared');
}
this.pendingResults = [];
}
}

@@ -1,3 +0,4 @@

import { or } from '@uwdata/mosaic-sql';
import { literal, or } from '@uwdata/mosaic-sql';
import { Param } from './Param.js';
import { MosaicClient } from './MosaicClient.js';

@@ -318,5 +319,7 @@ /**

* Return a selection query predicate for the given client.
* @param {*[]} clauseList An array of selection clauses.
* @param {*} active The current active selection clause.
* @param {*} client The client whose data may be filtered.
* @param {import('./util/selection-types.js').SelectionClause[]} clauseList
* An array of selection clauses.
* @param {import('./util/selection-types.js').SelectionClause} active
* The current active selection clause.
* @param {MosaicClient} client The client whose data may be filtered.
* @returns {*} The query predicate for filtering client data,

@@ -329,3 +332,3 @@ * based on the current state of this selection.

if (empty && !clauseList.length) {
return ['FALSE'];
return [literal(false)];
}

@@ -332,0 +335,0 @@

@@ -1,5 +0,2 @@

import {
SQLExpression, and, contains, isBetween, isNotDistinct, literal,
or, prefix, regexp_matches, suffix
} from '@uwdata/mosaic-sql';
import { ExprNode, and, contains, isBetween, isIn, isNotDistinct, literal, or, prefix, regexp_matches, suffix } from '@uwdata/mosaic-sql';
import { MosaicClient } from './MosaicClient.js';

@@ -13,3 +10,2 @@

* @typedef {import('./util/selection-types.js').BinMethod} BinMethod
* @typedef {SQLExpression | string} Field
*/

@@ -19,3 +15,3 @@

* Generate a selection clause for a single selected point value.
* @param {Field} field The table column or expression to select.
* @param {import('@uwdata/mosaic-sql').ExprValue} field The table column or expression to select.
* @param {*} value The selected value.

@@ -33,3 +29,3 @@ * @param {object} options Additional clause properties.

}) {
/** @type {SQLExpression | null} */
/** @type {ExprNode | null} */
const predicate = value !== undefined

@@ -49,5 +45,5 @@ ? isNotDistinct(field, literal(value))

* Generate a selection clause for multiple selected point values.
* @param {Field[]} fields The table columns or expressions to select.
* @param {any[][]} value The selected values, as an array of arrays where
* each subarray contains values corresponding to each *fields* entry.
* @param {import('@uwdata/mosaic-sql').ExprValue[]} fields The table columns or expressions to select.
* @param {any[][] | undefined} value The selected values, as an array of
* arrays. Each subarray contains values for each *fields* entry.
* @param {object} options Additional clause properties.

@@ -64,10 +60,11 @@ * @param {*} options.source The source component generating this clause.

}) {
/** @type {SQLExpression | null} */
/** @type {ExprNode | null} */
let predicate = null;
if (value) {
const clauses = value.map(vals => {
const list = vals.map((v, i) => isNotDistinct(fields[i], literal(v)));
return list.length > 1 ? and(list) : list[0];
});
predicate = clauses.length > 1 ? or(clauses) : clauses[0];
const clauses = value.length && fields.length === 1
? [isIn(fields[0], value.map(v => literal(v[0])))]
: value.map(v => and(v.map((_, i) => isNotDistinct(fields[i], literal(_)))));
predicate = value.length === 0 ? literal(false)
: clauses.length > 1 ? or(clauses)
: clauses[0];
}

@@ -85,3 +82,3 @@ return {

* Generate a selection clause for a selected 1D interval.
* @param {Field} field The table column or expression to select.
* @param {import('@uwdata/mosaic-sql').ExprValue} field The table column or expression to select.
* @param {Extent} value The selected interval as a [lo, hi] array.

@@ -105,3 +102,3 @@ * @param {object} options Additional clause properties.

}) {
/** @type {SQLExpression | null} */
/** @type {ExprNode | null} */
const predicate = value != null ? isBetween(field, value) : null;

@@ -115,3 +112,3 @@ /** @type {import('./util/selection-types.js').IntervalMetadata} */

* Generate a selection clause for multiple selected intervals.
* @param {Field[]} fields The table columns or expressions to select.
* @param {import('@uwdata/mosaic-sql').ExprValue[]} fields The table columns or expressions to select.
* @param {Extent[]} value The selected intervals, as an array of extents.

@@ -136,3 +133,3 @@ * @param {object} options Additional clause properties.

}) {
/** @type {SQLExpression | null} */
/** @type {ExprNode | null} */
const predicate = value != null

@@ -150,3 +147,3 @@ ? and(fields.map((f, i) => isBetween(f, value[i])))

* Generate a selection clause for text search matching.
* @param {Field} field The table column or expression to select.
* @param {import('@uwdata/mosaic-sql').ExprValue} field The table column or expression to select.
* @param {string} value The selected text search query string.

@@ -166,3 +163,3 @@ * @param {object} options Additional clause properties.

let fn = MATCH_METHODS[method];
/** @type {SQLExpression | null} */
/** @type {ExprNode | null} */
const predicate = value ? fn(field, literal(value)) : null;

@@ -169,0 +166,0 @@ /** @type {import('./util/selection-types.js').MatchMetadata} */

@@ -1,2 +0,2 @@

import { Query, asRelation, count, isNull, max, min, sql } from '@uwdata/mosaic-sql';
import { AggregateNode, Query, asTableRef, count, isNull, max, min, sql } from '@uwdata/mosaic-sql';
import { jsType } from './js-type.js';

@@ -11,2 +11,5 @@

/**
* @type {Record<string, (column: string) => AggregateNode>}
*/
const statMap = {

@@ -20,10 +23,17 @@ [Count]: count,

/**
*
* @param {string} table
* @param {string} column
* @param {string[]|Set<string>} stats
* @returns
*/
function summarize(table, column, stats) {
return Query
.from(table)
.select(Array.from(stats, s => [s, statMap[s](column)]));
.select(Array.from(stats, s => ({[s]: statMap[s](column)})));
}
export async function queryFieldInfo(mc, fields) {
if (fields.length === 1 && `${fields[0].column}` === '*') {
if (fields.length === 1 && fields[0].column === '*') {
return getTableInfo(mc, fields[0].table);

@@ -40,3 +50,4 @@ } else {

// use GROUP BY ALL to differentiate & consolidate aggregates
const q = Query.from({ source: table })
const q = Query
.from({ source: table })
.select({ column })

@@ -67,3 +78,3 @@ .groupby(column.aggregate ? sql`ALL` : []);

async function getTableInfo(mc, table) {
const result = await mc.query(`DESCRIBE ${asRelation(table)}`);
const result = await mc.query(`DESCRIBE ${asTableRef(table)}`);
return Array.from(result).map(desc => ({

@@ -70,0 +81,0 @@ table,

@@ -10,3 +10,3 @@ // Fowler/Noll/Vo hashing.

}
return fnv_mix(a);
return fnv_mix(a) >>> 0; // ensure non-zero value
}

@@ -13,0 +13,0 @@

@@ -0,1 +1,8 @@

export const QueryState = Object.freeze({
pending: Symbol('pending'),
ready: Symbol('ready'),
error: Symbol('error'),
done: Symbol('done')
});
/**

@@ -18,6 +25,9 @@ * A query result Promise that can allows external callers

this._reject = reject;
this._state = QueryState.pending;
this._value = undefined;
}
/**
* Resolve the result Promise with the provided value.
* Resolve the result Promise with a prepared value or the provided value.
* This method will only succeed if either a value is provided or the promise is ready.
* @param {*} value The result value.

@@ -27,3 +37,15 @@ * @returns {this}

fulfill(value) {
this._resolve(value);
if (this._value !== undefined) {
if (value !== undefined) {
throw Error('Promise is ready and fulfill has a provided value');
}
this._resolve(this._value);
} else if (value === undefined) {
throw Error('Promise is neither ready nor has provided value');
} else {
this._resolve(value);
}
this._state = QueryState.done;
return this;

@@ -33,2 +55,13 @@ }

/**
* Prepare to resolve with the provided value.
* @param {*} value The result value.
* @returns {this}
*/
ready(value) {
this._state = QueryState.ready;
this._value = value;
return this;
}
/**
* Rejects the result Promise with the provided error.

@@ -39,5 +72,14 @@ * @param {*} error The error value.

reject(error) {
this._state = QueryState.error;
this._reject(error);
return this;
}
/**
* Returns the state of this query result.
* @returns {symbol}
*/
get state() {
return this._state;
}
}

@@ -44,0 +86,0 @@

@@ -1,2 +0,2 @@

import { SQLExpression } from '@uwdata/mosaic-sql';
import { ExprNode } from '@uwdata/mosaic-sql';
import { MosaicClient } from '../MosaicClient.js';

@@ -130,9 +130,9 @@

*/
predicate: SQLExpression | null;
predicate: ExprNode | null;
/**
* Optional clause metadata that varies based on the selection type.
* The metadata can be used to optimize selection queries, for example
* by creating pre-aggregated data cubes when applicable.
* by creating materialized views of pre-aggregated data when applicable.
*/
meta?: ClauseMetadata;
}

@@ -19,11 +19,13 @@ const NIL = {};

function invoke(event) {
curr = callback(event).finally(() => {
if (next) {
const { value } = next;
next = null;
invoke(value);
} else {
curr = null;
}
});
curr = callback(event)
.catch(() => {})
.finally(() => {
if (next) {
const { value } = next;
next = null;
invoke(value);
} else {
curr = null;
}
});
}

@@ -30,0 +32,0 @@

@@ -0,9 +1,10 @@

/* eslint-disable no-unused-vars */
export function voidLogger() {
return {
debug() {},
info() {},
log() {},
warn() {},
error() {}
debug(..._) {},
info(..._) {},
log(..._) {},
warn(..._) {},
error(..._) {}
};
}

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc