@perspective-dev/client 4.2.0 → 4.3.0
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/dist/cdn/perspective.js +1 -1
- package/dist/cdn/perspective.js.map +3 -3
- package/dist/esm/perspective.inline.js +2 -2
- package/dist/esm/perspective.inline.js.map +3 -3
- package/dist/esm/perspective.js +1 -1
- package/dist/esm/perspective.js.map +3 -3
- package/dist/esm/perspective.node.js +9 -9
- package/dist/esm/perspective.node.js.map +2 -2
- package/dist/esm/ts-rs/GroupRollupMode.d.ts +1 -0
- package/dist/esm/ts-rs/ViewConfig.d.ts +2 -0
- package/dist/esm/ts-rs/ViewConfigUpdate.d.ts +2 -0
- package/dist/esm/ts-rs/ViewWindow.d.ts +0 -1
- package/dist/esm/virtual_servers/clickhouse.js +1 -1
- package/dist/esm/virtual_servers/clickhouse.js.map +3 -3
- package/dist/esm/virtual_servers/duckdb.d.ts +1 -0
- package/dist/esm/virtual_servers/duckdb.js +1 -1
- package/dist/esm/virtual_servers/duckdb.js.map +3 -3
- package/dist/wasm/perspective-js.d.ts +5 -5
- package/dist/wasm/perspective-js.js +11 -11
- package/dist/wasm/perspective-js.wasm +0 -0
- package/dist/wasm/perspective-js.wasm.d.ts +5 -5
- package/package.json +1 -1
- package/src/rust/utils/futures.rs +1 -6
- package/src/ts/ts-rs/GroupRollupMode.ts +3 -0
- package/src/ts/ts-rs/ViewConfig.ts +2 -1
- package/src/ts/ts-rs/ViewConfigUpdate.ts +2 -1
- package/src/ts/ts-rs/ViewWindow.ts +1 -1
- package/src/ts/virtual_servers/clickhouse.ts +1 -0
- package/src/ts/virtual_servers/duckdb.ts +40 -24
- package/tsconfig.json +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type GroupRollupMode = "rollup" | "flat" | "total";
|
|
@@ -2,12 +2,14 @@ import type { Aggregate } from "./Aggregate.js";
|
|
|
2
2
|
import type { Expressions } from "./Expressions.js";
|
|
3
3
|
import type { Filter } from "./Filter.js";
|
|
4
4
|
import type { FilterReducer } from "./FilterReducer.js";
|
|
5
|
+
import type { GroupRollupMode } from "./GroupRollupMode.js";
|
|
5
6
|
import type { Sort } from "./Sort.js";
|
|
6
7
|
export type ViewConfig = {
|
|
7
8
|
group_by: Array<string>;
|
|
8
9
|
split_by: Array<string>;
|
|
9
10
|
sort: Array<Sort>;
|
|
10
11
|
filter: Array<Filter>;
|
|
12
|
+
group_rollup_mode: GroupRollupMode;
|
|
11
13
|
filter_op?: FilterReducer;
|
|
12
14
|
expressions: Expressions;
|
|
13
15
|
columns: Array<string | null>;
|
|
@@ -2,6 +2,7 @@ import type { Aggregate } from "./Aggregate.js";
|
|
|
2
2
|
import type { Expressions } from "./Expressions.js";
|
|
3
3
|
import type { Filter } from "./Filter.js";
|
|
4
4
|
import type { FilterReducer } from "./FilterReducer.js";
|
|
5
|
+
import type { GroupRollupMode } from "./GroupRollupMode.js";
|
|
5
6
|
import type { Sort } from "./Sort.js";
|
|
6
7
|
export type ViewConfigUpdate = {
|
|
7
8
|
/**
|
|
@@ -87,4 +88,5 @@ export type ViewConfigUpdate = {
|
|
|
87
88
|
};
|
|
88
89
|
group_by_depth?: number;
|
|
89
90
|
filter_op?: FilterReducer;
|
|
91
|
+
group_rollup_mode?: GroupRollupMode;
|
|
90
92
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var C=["sum","count","any_value","arbitrary","array_agg","avg","bit_and","bit_or","bit_xor","bitstring_agg","bool_and","bool_or","countif","favg","fsum","geomean","kahan_sum","last","max","min","product","string_agg","sumkahan"],y=["count","any_value","arbitrary","first","countif","last","string_agg"],p=["==","!=","LIKE","IS DISTINCT FROM","IS NOT DISTINCT FROM",">=","<=",">","<"];function h(
|
|
1
|
+
var C=["sum","count","any_value","arbitrary","array_agg","avg","bit_and","bit_or","bit_xor","bitstring_agg","bool_and","bool_or","countif","favg","fsum","geomean","kahan_sum","last","max","min","product","string_agg","sumkahan"],y=["count","any_value","arbitrary","first","countif","last","string_agg"],p=["==","!=","LIKE","IS DISTINCT FROM","IS NOT DISTINCT FROM",">=","<=",">","<"];function h(i){if(i.startsWith("Nullable")&&(i=i.match(/Nullable\((.+?)\)/)[1]),i.startsWith("Array"))return"string";if(i==="Int64"||i==="UInt64"||i==="Float64")return"float";if(i==="String")return"string";if(i==="DateTime")return"datetime";if(i==="Date")return"date";throw new Error(`Unknown type '${i}'`)}function q(i,t){if(!(i instanceof Uint32Array||i instanceof Int32Array))return i;let e=BigInt(0);for(let r=0;r<i.length;r++)e|=BigInt(i[r])<<BigInt(r*32);let s=t.match(/Decimal\[\d+e(\d+)\]/);if(s){let r=parseInt(s[1]);return Number(e)/Math.pow(10,r)}else return Number(e)}var w=class{lockPromise;constructor(){this.lockPromise=Promise.resolve()}acquire(){let t,e=new Promise(r=>{t=r}),s=this.lockPromise.then(()=>t);return this.lockPromise=e,s}},N=new w;async function u(i,t,e={}){t=t.replace(/\s+/g," ").trim();let s=await N.acquire();try{let r=await i.query({query:t});if(!e.execute){let{data:o,meta:l}=await r.json();return e.columns?{rows:o,columns:l.map(a=>a.name),dtypes:l.map(a=>a.type)}:o}}catch(r){throw console.error("Query error:",r),console.error("Query:",t),r}finally{s()}}var T=class{db;sqlBuilder;constructor(t,e){if(!e&&customElements){let s=customElements.get("perspective-viewer");if(s)e=s.__wasm_module__;else throw new Error("Missing perspective-client.wasm")}this.db=t,this.sqlBuilder=new e.GenericSQLVirtualServerModel({create_entity:"VIEW",grouping_fn:"GROUPING"})}getFeatures(){return{group_by:!0,split_by:!1,sort:!0,expressions:!0,group_rollup_mode:["rollup","flat","total"],filter_ops:{integer:p,float:p,string:p,boolean:p,date:p,datetime:p},aggregates:{integer:C,float:C,string:y,boolean:y,date:y,datetime:y}}}async getHostedTables(){return(await u(this.db,"SHOW TABLES")).map(s=>`${s.name}`)}async tableSchema(t,e){let s=this.sqlBuilder.tableSchema(t),r=await u(this.db,s),o={};for(let l of r){let a=l.name;a.startsWith("__")||(o[a]=h(l.type))}return o}async viewColumnSize(t,e){let s=`SELECT COUNT() FROM system.columns WHERE table = '${t}'`,r=await u(this.db,s),o=e.group_by?.length||0,l=Number(r[0]["COUNT()"]);return console.log(l),l-(o===0?0:o+(e.split_by?.length===0?1:0))}async tableSize(t){let e=this.sqlBuilder.tableSize(t),s=await u(this.db,e);return Number(s[0]["COUNT()"])}async tableMakeView(t,e,s){let r=this.sqlBuilder.tableMakeView(t,e,s);await u(this.db,r,{execute:!0})}async tableValidateExpression(t,e){let s=this.sqlBuilder.tableValidateExpression(t,e),r=await u(this.db,s);return h(r[0].type)}async viewDelete(t){let e=this.sqlBuilder.viewDelete(t);await u(this.db,e,{execute:!0})}async viewGetData(t,e,s,r,o){let l=e.group_by?.length>0,a=e.split_by?.length>0,k=this.sqlBuilder.viewGetData(t,e,r,s),{rows:_,columns:d,dtypes:f}=await u(this.db,k,{columns:!0});for(let c=0;c<d.length;c++){if(c===0&&l&&!a)continue;let m=d[c];a&&!m.startsWith("__ROW_PATH_")&&(m=m.replaceAll("_","|"));let b=h(f[c]),S=f[c].startsWith("Decimal");for(let g=0;g<_.length;g++){let v=_[g],I=v.__GROUPING_ID__,n=v[d[c]];S&&(n=q(n,f[c])),typeof n=="bigint"&&(n=Number(n)),b==="datetime"&&typeof n=="string"&&(n=+new Date(n)),b==="string"&&typeof n!="string"&&(n=`${n}`),o.setCol(b,m,g,n,I)}}}};export{T as ClickhouseHandler};
|
|
2
2
|
//# sourceMappingURL=clickhouse.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/ts/virtual_servers/clickhouse.ts"],
|
|
4
|
-
"sourcesContent": ["// \u250F\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2513\n// \u2503 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588 \u2588 \u2588 \u2588 \u2588 \u2588\u2584 \u2580\u2588\u2588\u2588 \u2588 \u2503\n// \u2503 \u2584\u2584\u2584\u2584\u2584\u2588 \u2588\u2584\u2584\u2584\u2584\u2584 \u2584\u2584\u2584\u2584\u2584\u2588 \u2580\u2580\u2580\u2580\u2580\u2588\u2580\u2580\u2580\u2580\u2580 \u2588 \u2580\u2580\u2580\u2580\u2580\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u258C\u2590\u2588\u2588\u2588 \u2588\u2588\u2588\u2584 \u2580\u2588 \u2588 \u2580\u2580\u2580\u2580\u2580 \u2503\n// \u2503 \u2588\u2580\u2580\u2580\u2580\u2580 \u2588\u2580\u2580\u2580\u2580\u2580 \u2588\u2580\u2588\u2588\u2580\u2580 \u2584\u2584\u2584\u2584\u2584 \u2588 \u2584\u2584\u2584\u2584\u2584\u2588 \u2584\u2584\u2584\u2584\u2584\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u258C\u2590\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2584 \u2588 \u2584\u2584\u2584\u2584\u2584 \u2503\n// \u2503 \u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588 \u2580\u2588\u2584 \u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588 \u2588\u2588\u2588\u258C\u2590\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2584 \u2588 \u2503\n// \u2523\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u252B\n// \u2503 Copyright (c) 2017, the Perspective Authors. \u2503\n// \u2503 \u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C \u2503\n// \u2503 This file is part of the Perspective library, distributed under the terms \u2503\n// \u2503 of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). \u2503\n// \u2517\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u251B\n\n/**\n * An implementation of a Perspective Virtual Server for DuckDB.\n *\n * This import is optional, and so must be imported manually from either\n * `@perspective-dev/client/dist/esm/virtual_servers/duckdb.js` or\n * `@perspective-dev/client/src/ts/virtual_servers/duckdb.ts`, it is not\n * exported from the package root `@perspective-dev/client`\n *\n * @module\n */\n\nimport type * as perspective from \"@perspective-dev/client\";\nimport type { ColumnType } from \"@perspective-dev/client/dist/esm/ts-rs/ColumnType.d.ts\";\nimport type { ViewConfig } from \"@perspective-dev/client/dist/esm/ts-rs/ViewConfig.d.ts\";\nimport type { ViewWindow } from \"@perspective-dev/client/dist/esm/ts-rs/ViewWindow.d.ts\";\nimport type * as clickhouse from \"@clickhouse/client-web\";\n\nconst NUMBER_AGGS = [\n \"sum\",\n \"count\",\n \"any_value\",\n \"arbitrary\",\n \"array_agg\",\n \"avg\",\n \"bit_and\",\n \"bit_or\",\n \"bit_xor\",\n \"bitstring_agg\",\n \"bool_and\",\n \"bool_or\",\n \"countif\",\n \"favg\",\n \"fsum\",\n \"geomean\",\n \"kahan_sum\",\n \"last\",\n \"max\",\n \"min\",\n \"product\",\n \"string_agg\",\n \"sumkahan\",\n];\n\nconst STRING_AGGS = [\n \"count\",\n \"any_value\",\n \"arbitrary\",\n \"first\",\n \"countif\",\n \"last\",\n \"string_agg\",\n];\n\nconst FILTER_OPS = [\n \"==\",\n \"!=\",\n \"LIKE\",\n \"IS DISTINCT FROM\",\n \"IS NOT DISTINCT FROM\",\n \">=\",\n \"<=\",\n \">\",\n \"<\",\n];\n\nfunction duckdbTypeToPsp(name: string): ColumnType {\n if (name.startsWith(\"Nullable\")) {\n name = name.match(/Nullable\\((.+?)\\)/)![1];\n }\n\n if (name.startsWith(\"Array\")) {\n return \"string\";\n }\n\n if (name === \"Int64\" || name === \"UInt64\" || name === \"Float64\") {\n return \"float\";\n }\n\n if (name === \"String\") {\n return \"string\";\n }\n\n if (name === \"DateTime\") {\n return \"datetime\";\n }\n\n if (name === \"Date\") {\n return \"date\";\n }\n\n throw new Error(`Unknown type '${name}'`);\n}\n\nfunction convertDecimalToNumber(value: any, dtypeString: string) {\n if (!(value instanceof Uint32Array || value instanceof Int32Array)) {\n return value;\n }\n\n let bigIntValue = BigInt(0);\n for (let i = 0; i < value.length; i++) {\n bigIntValue |= BigInt(value[i]) << BigInt(i * 32);\n }\n\n const scaleMatch = dtypeString.match(/Decimal\\[\\d+e(\\d+)\\]/);\n if (scaleMatch) {\n const scale = parseInt(scaleMatch[1]);\n return Number(bigIntValue) / Math.pow(10, scale);\n } else {\n return Number(bigIntValue);\n }\n}\n\nclass Lock {\n lockPromise: Promise<void>;\n constructor() {\n this.lockPromise = Promise.resolve();\n }\n\n acquire() {\n let releaseLock: (value: void) => void;\n const newLockPromise: Promise<void> = new Promise((resolve) => {\n releaseLock = resolve;\n });\n\n const acquirePromise = this.lockPromise.then(() => releaseLock);\n this.lockPromise = newLockPromise;\n return acquirePromise;\n }\n}\n\nconst LOCK = new Lock();\n\nasync function runQuery(\n db: clickhouse.ClickHouseClient,\n query: string,\n options: { columns?: true; execute?: boolean },\n): Promise<{\n rows: any[];\n columns: string[];\n dtypes: string[];\n}>;\n\nasync function runQuery(\n db: clickhouse.ClickHouseClient,\n query: string,\n options?: { columns?: false; execute?: boolean },\n): Promise<any[]>;\n\nasync function runQuery(\n db: clickhouse.ClickHouseClient,\n query: string,\n options: { columns?: boolean; execute?: boolean } = {},\n) {\n query = query.replace(/\\s+/g, \" \").trim();\n const release = await LOCK.acquire();\n try {\n const result = await db.query({ query });\n if (!options.execute) {\n const { data, meta } =\n (await result.json()) as clickhouse.ResponseJSON<unknown>;\n\n if (options.columns) {\n return {\n rows: data,\n columns: meta!.map((f) => f.name),\n dtypes: meta!.map((f) => f.type),\n };\n }\n\n return data;\n }\n } catch (error) {\n console.error(\"Query error:\", error);\n console.error(\"Query:\", query);\n throw error;\n } finally {\n release();\n }\n}\n\n/**\n * An implementation of Perspective's Virtual Server for `@duckdb/duckdb-wasm`.\n */\nexport class ClickhouseHandler implements perspective.VirtualServerHandler {\n private db: clickhouse.ClickHouseClient;\n private sqlBuilder: perspective.GenericSQLVirtualServerModel;\n constructor(db: clickhouse.ClickHouseClient, mod?: typeof perspective) {\n if (!mod) {\n if (customElements) {\n const viewer_class: any =\n customElements.get(\"perspective-viewer\");\n if (viewer_class) {\n mod = viewer_class.__wasm_module__;\n } else {\n throw new Error(\"Missing perspective-client.wasm\");\n }\n } else {\n }\n }\n\n this.db = db;\n this.sqlBuilder = new mod!.GenericSQLVirtualServerModel({\n create_entity: \"VIEW\",\n grouping_fn: \"GROUPING\",\n });\n }\n\n getFeatures() {\n return {\n group_by: true,\n split_by: false,\n sort: true,\n expressions: true,\n filter_ops: {\n integer: FILTER_OPS,\n float: FILTER_OPS,\n string: FILTER_OPS,\n boolean: FILTER_OPS,\n date: FILTER_OPS,\n datetime: FILTER_OPS,\n },\n aggregates: {\n integer: NUMBER_AGGS,\n float: NUMBER_AGGS,\n string: STRING_AGGS,\n boolean: STRING_AGGS,\n date: STRING_AGGS,\n datetime: STRING_AGGS,\n },\n };\n }\n\n async getHostedTables() {\n const query = \"SHOW TABLES\";\n const results = await runQuery(this.db, query);\n return results.map((row) => {\n return `${row.name}`;\n });\n }\n\n async tableSchema(tableId: string, config?: ViewConfig) {\n const query = this.sqlBuilder.tableSchema(tableId);\n const results = await runQuery(this.db, query);\n const schema = {} as Record<string, ColumnType>;\n for (const result of results) {\n const colName = result.name;\n if (!colName.startsWith(\"__\")) {\n schema[colName] = duckdbTypeToPsp(result.type) as ColumnType;\n }\n }\n\n return schema;\n }\n\n async viewColumnSize(viewId: string, config: ViewConfig) {\n const query = `SELECT COUNT() FROM system.columns WHERE table = '${viewId}'`;\n const results = await runQuery(this.db, query);\n const gs = config.group_by?.length || 0;\n const count = Number(results[0][\"COUNT()\"]);\n console.log(count);\n return (\n count -\n (gs === 0 ? 0 : gs + (config.split_by?.length === 0 ? 1 : 0))\n );\n }\n\n async tableSize(tableId: string) {\n const query = this.sqlBuilder.tableSize(tableId);\n const results = await runQuery(this.db, query);\n return Number(results[0][\"COUNT()\"]);\n }\n\n async tableMakeView(tableId: string, viewId: string, config: ViewConfig) {\n const query = this.sqlBuilder.tableMakeView(tableId, viewId, config);\n await runQuery(this.db, query, { execute: true });\n }\n\n async tableValidateExpression(tableId: string, expression: string) {\n const query = this.sqlBuilder.tableValidateExpression(\n tableId,\n expression,\n );\n const results = await runQuery(this.db, query);\n return duckdbTypeToPsp(results[0][\"type\"]) as ColumnType;\n }\n\n async viewDelete(viewId: string) {\n const query = this.sqlBuilder.viewDelete(viewId);\n await runQuery(this.db, query, { execute: true });\n }\n\n async viewGetData(\n viewId: string,\n config: ViewConfig,\n schema: Record<string, ColumnType>,\n viewport: ViewWindow,\n dataSlice: perspective.VirtualDataSlice,\n ) {\n const is_group_by = config.group_by?.length > 0;\n const is_split_by = config.split_by?.length > 0;\n const query = this.sqlBuilder.viewGetData(\n viewId,\n config,\n viewport,\n schema,\n );\n\n const { rows, columns, dtypes } = await runQuery(this.db, query, {\n columns: true,\n });\n\n for (let cidx = 0; cidx < columns.length; cidx++) {\n if (cidx === 0 && is_group_by && !is_split_by) {\n // This is the grouping_id column, skip it\n continue;\n }\n\n let col = columns[cidx];\n if (is_split_by && !col.startsWith(\"__ROW_PATH_\")) {\n col = col.replaceAll(\"_\", \"|\");\n }\n\n const dtype = duckdbTypeToPsp(dtypes[cidx]) as ColumnType;\n\n const isDecimal = dtypes[cidx].startsWith(\"Decimal\");\n for (let ridx = 0; ridx < rows.length; ridx++) {\n const row = rows[ridx];\n const grouping_id = row[\"__GROUPING_ID__\"];\n let value = row[columns[cidx]];\n if (isDecimal) {\n value = convertDecimalToNumber(value, dtypes[cidx]);\n }\n\n if (typeof value === \"bigint\") {\n value = Number(value);\n }\n\n if (dtype === \"datetime\" && typeof value === \"string\") {\n value = +new Date(value);\n }\n\n if (dtype === \"string\" && typeof value !== \"string\") {\n value = `${value}`;\n }\n\n dataSlice.setCol(dtype, col, ridx, value, grouping_id);\n }\n }\n }\n}\n"],
|
|
5
|
-
"mappings": "AA6BA,IAAMA,EAAc,CAChB,MACA,QACA,YACA,YACA,YACA,MACA,UACA,SACA,UACA,gBACA,WACA,UACA,UACA,OACA,OACA,UACA,YACA,OACA,MACA,MACA,UACA,aACA,UACJ,EAEMC,EAAc,CAChB,QACA,YACA,YACA,QACA,UACA,OACA,YACJ,EAEMC,EAAa,CACf,KACA,KACA,OACA,mBACA,uBACA,KACA,KACA,IACA,GACJ,EAEA,SAASC,EAAgBC,EAA0B,CAK/C,GAJIA,EAAK,WAAW,UAAU,IAC1BA,EAAOA,EAAK,MAAM,mBAAmB,EAAG,CAAC,GAGzCA,EAAK,WAAW,OAAO,EACvB,MAAO,SAGX,GAAIA,IAAS,SAAWA,IAAS,UAAYA,IAAS,UAClD,MAAO,QAGX,GAAIA,IAAS,SACT,MAAO,SAGX,GAAIA,IAAS,WACT,MAAO,WAGX,GAAIA,IAAS,OACT,MAAO,OAGX,MAAM,IAAI,MAAM,iBAAiBA,CAAI,GAAG,CAC5C,CAEA,SAASC,EAAuBC,EAAYC,EAAqB,CAC7D,GAAI,EAAED,aAAiB,aAAeA,aAAiB,YACnD,OAAOA,EAGX,IAAIE,EAAc,OAAO,CAAC,EAC1B,
|
|
6
|
-
"names": ["NUMBER_AGGS", "STRING_AGGS", "FILTER_OPS", "duckdbTypeToPsp", "name", "convertDecimalToNumber", "value", "dtypeString", "bigIntValue", "scaleMatch", "scale", "Lock", "releaseLock", "newLockPromise", "resolve", "acquirePromise", "LOCK", "runQuery", "db", "query", "options", "release", "result", "data", "meta", "f", "error", "ClickhouseHandler", "mod", "viewer_class", "row", "tableId", "config", "results", "schema", "colName", "viewId", "gs", "count", "expression", "viewport", "dataSlice", "is_group_by", "is_split_by", "rows", "columns", "dtypes", "cidx", "col", "dtype", "isDecimal", "ridx", "grouping_id"]
|
|
4
|
+
"sourcesContent": ["// \u250F\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2513\n// \u2503 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588 \u2588 \u2588 \u2588 \u2588 \u2588\u2584 \u2580\u2588\u2588\u2588 \u2588 \u2503\n// \u2503 \u2584\u2584\u2584\u2584\u2584\u2588 \u2588\u2584\u2584\u2584\u2584\u2584 \u2584\u2584\u2584\u2584\u2584\u2588 \u2580\u2580\u2580\u2580\u2580\u2588\u2580\u2580\u2580\u2580\u2580 \u2588 \u2580\u2580\u2580\u2580\u2580\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u258C\u2590\u2588\u2588\u2588 \u2588\u2588\u2588\u2584 \u2580\u2588 \u2588 \u2580\u2580\u2580\u2580\u2580 \u2503\n// \u2503 \u2588\u2580\u2580\u2580\u2580\u2580 \u2588\u2580\u2580\u2580\u2580\u2580 \u2588\u2580\u2588\u2588\u2580\u2580 \u2584\u2584\u2584\u2584\u2584 \u2588 \u2584\u2584\u2584\u2584\u2584\u2588 \u2584\u2584\u2584\u2584\u2584\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u258C\u2590\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2584 \u2588 \u2584\u2584\u2584\u2584\u2584 \u2503\n// \u2503 \u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588 \u2580\u2588\u2584 \u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588 \u2588\u2588\u2588\u258C\u2590\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2584 \u2588 \u2503\n// \u2523\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u252B\n// \u2503 Copyright (c) 2017, the Perspective Authors. \u2503\n// \u2503 \u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C \u2503\n// \u2503 This file is part of the Perspective library, distributed under the terms \u2503\n// \u2503 of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). \u2503\n// \u2517\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u251B\n\n/**\n * An implementation of a Perspective Virtual Server for DuckDB.\n *\n * This import is optional, and so must be imported manually from either\n * `@perspective-dev/client/dist/esm/virtual_servers/duckdb.js` or\n * `@perspective-dev/client/src/ts/virtual_servers/duckdb.ts`, it is not\n * exported from the package root `@perspective-dev/client`\n *\n * @module\n */\n\nimport type * as perspective from \"@perspective-dev/client\";\nimport type { ColumnType } from \"@perspective-dev/client/dist/esm/ts-rs/ColumnType.d.ts\";\nimport type { ViewConfig } from \"@perspective-dev/client/dist/esm/ts-rs/ViewConfig.d.ts\";\nimport type { ViewWindow } from \"@perspective-dev/client/dist/esm/ts-rs/ViewWindow.d.ts\";\nimport type * as clickhouse from \"@clickhouse/client-web\";\n\nconst NUMBER_AGGS = [\n \"sum\",\n \"count\",\n \"any_value\",\n \"arbitrary\",\n \"array_agg\",\n \"avg\",\n \"bit_and\",\n \"bit_or\",\n \"bit_xor\",\n \"bitstring_agg\",\n \"bool_and\",\n \"bool_or\",\n \"countif\",\n \"favg\",\n \"fsum\",\n \"geomean\",\n \"kahan_sum\",\n \"last\",\n \"max\",\n \"min\",\n \"product\",\n \"string_agg\",\n \"sumkahan\",\n];\n\nconst STRING_AGGS = [\n \"count\",\n \"any_value\",\n \"arbitrary\",\n \"first\",\n \"countif\",\n \"last\",\n \"string_agg\",\n];\n\nconst FILTER_OPS = [\n \"==\",\n \"!=\",\n \"LIKE\",\n \"IS DISTINCT FROM\",\n \"IS NOT DISTINCT FROM\",\n \">=\",\n \"<=\",\n \">\",\n \"<\",\n];\n\nfunction duckdbTypeToPsp(name: string): ColumnType {\n if (name.startsWith(\"Nullable\")) {\n name = name.match(/Nullable\\((.+?)\\)/)![1];\n }\n\n if (name.startsWith(\"Array\")) {\n return \"string\";\n }\n\n if (name === \"Int64\" || name === \"UInt64\" || name === \"Float64\") {\n return \"float\";\n }\n\n if (name === \"String\") {\n return \"string\";\n }\n\n if (name === \"DateTime\") {\n return \"datetime\";\n }\n\n if (name === \"Date\") {\n return \"date\";\n }\n\n throw new Error(`Unknown type '${name}'`);\n}\n\nfunction convertDecimalToNumber(value: any, dtypeString: string) {\n if (!(value instanceof Uint32Array || value instanceof Int32Array)) {\n return value;\n }\n\n let bigIntValue = BigInt(0);\n for (let i = 0; i < value.length; i++) {\n bigIntValue |= BigInt(value[i]) << BigInt(i * 32);\n }\n\n const scaleMatch = dtypeString.match(/Decimal\\[\\d+e(\\d+)\\]/);\n if (scaleMatch) {\n const scale = parseInt(scaleMatch[1]);\n return Number(bigIntValue) / Math.pow(10, scale);\n } else {\n return Number(bigIntValue);\n }\n}\n\nclass Lock {\n lockPromise: Promise<void>;\n constructor() {\n this.lockPromise = Promise.resolve();\n }\n\n acquire() {\n let releaseLock: (value: void) => void;\n const newLockPromise: Promise<void> = new Promise((resolve) => {\n releaseLock = resolve;\n });\n\n const acquirePromise = this.lockPromise.then(() => releaseLock);\n this.lockPromise = newLockPromise;\n return acquirePromise;\n }\n}\n\nconst LOCK = new Lock();\n\nasync function runQuery(\n db: clickhouse.ClickHouseClient,\n query: string,\n options: { columns?: true; execute?: boolean },\n): Promise<{\n rows: any[];\n columns: string[];\n dtypes: string[];\n}>;\n\nasync function runQuery(\n db: clickhouse.ClickHouseClient,\n query: string,\n options?: { columns?: false; execute?: boolean },\n): Promise<any[]>;\n\nasync function runQuery(\n db: clickhouse.ClickHouseClient,\n query: string,\n options: { columns?: boolean; execute?: boolean } = {},\n) {\n query = query.replace(/\\s+/g, \" \").trim();\n const release = await LOCK.acquire();\n try {\n const result = await db.query({ query });\n if (!options.execute) {\n const { data, meta } =\n (await result.json()) as clickhouse.ResponseJSON<unknown>;\n\n if (options.columns) {\n return {\n rows: data,\n columns: meta!.map((f) => f.name),\n dtypes: meta!.map((f) => f.type),\n };\n }\n\n return data;\n }\n } catch (error) {\n console.error(\"Query error:\", error);\n console.error(\"Query:\", query);\n throw error;\n } finally {\n release();\n }\n}\n\n/**\n * An implementation of Perspective's Virtual Server for `@duckdb/duckdb-wasm`.\n */\nexport class ClickhouseHandler implements perspective.VirtualServerHandler {\n private db: clickhouse.ClickHouseClient;\n private sqlBuilder: perspective.GenericSQLVirtualServerModel;\n constructor(db: clickhouse.ClickHouseClient, mod?: typeof perspective) {\n if (!mod) {\n if (customElements) {\n const viewer_class: any =\n customElements.get(\"perspective-viewer\");\n if (viewer_class) {\n mod = viewer_class.__wasm_module__;\n } else {\n throw new Error(\"Missing perspective-client.wasm\");\n }\n } else {\n }\n }\n\n this.db = db;\n this.sqlBuilder = new mod!.GenericSQLVirtualServerModel({\n create_entity: \"VIEW\",\n grouping_fn: \"GROUPING\",\n });\n }\n\n getFeatures() {\n return {\n group_by: true,\n split_by: false,\n sort: true,\n expressions: true,\n group_rollup_mode: [\"rollup\", \"flat\", \"total\"],\n filter_ops: {\n integer: FILTER_OPS,\n float: FILTER_OPS,\n string: FILTER_OPS,\n boolean: FILTER_OPS,\n date: FILTER_OPS,\n datetime: FILTER_OPS,\n },\n aggregates: {\n integer: NUMBER_AGGS,\n float: NUMBER_AGGS,\n string: STRING_AGGS,\n boolean: STRING_AGGS,\n date: STRING_AGGS,\n datetime: STRING_AGGS,\n },\n };\n }\n\n async getHostedTables() {\n const query = \"SHOW TABLES\";\n const results = await runQuery(this.db, query);\n return results.map((row) => {\n return `${row.name}`;\n });\n }\n\n async tableSchema(tableId: string, config?: ViewConfig) {\n const query = this.sqlBuilder.tableSchema(tableId);\n const results = await runQuery(this.db, query);\n const schema = {} as Record<string, ColumnType>;\n for (const result of results) {\n const colName = result.name;\n if (!colName.startsWith(\"__\")) {\n schema[colName] = duckdbTypeToPsp(result.type) as ColumnType;\n }\n }\n\n return schema;\n }\n\n async viewColumnSize(viewId: string, config: ViewConfig) {\n const query = `SELECT COUNT() FROM system.columns WHERE table = '${viewId}'`;\n const results = await runQuery(this.db, query);\n const gs = config.group_by?.length || 0;\n const count = Number(results[0][\"COUNT()\"]);\n console.log(count);\n return (\n count -\n (gs === 0 ? 0 : gs + (config.split_by?.length === 0 ? 1 : 0))\n );\n }\n\n async tableSize(tableId: string) {\n const query = this.sqlBuilder.tableSize(tableId);\n const results = await runQuery(this.db, query);\n return Number(results[0][\"COUNT()\"]);\n }\n\n async tableMakeView(tableId: string, viewId: string, config: ViewConfig) {\n const query = this.sqlBuilder.tableMakeView(tableId, viewId, config);\n await runQuery(this.db, query, { execute: true });\n }\n\n async tableValidateExpression(tableId: string, expression: string) {\n const query = this.sqlBuilder.tableValidateExpression(\n tableId,\n expression,\n );\n const results = await runQuery(this.db, query);\n return duckdbTypeToPsp(results[0][\"type\"]) as ColumnType;\n }\n\n async viewDelete(viewId: string) {\n const query = this.sqlBuilder.viewDelete(viewId);\n await runQuery(this.db, query, { execute: true });\n }\n\n async viewGetData(\n viewId: string,\n config: ViewConfig,\n schema: Record<string, ColumnType>,\n viewport: ViewWindow,\n dataSlice: perspective.VirtualDataSlice,\n ) {\n const is_group_by = config.group_by?.length > 0;\n const is_split_by = config.split_by?.length > 0;\n const query = this.sqlBuilder.viewGetData(\n viewId,\n config,\n viewport,\n schema,\n );\n\n const { rows, columns, dtypes } = await runQuery(this.db, query, {\n columns: true,\n });\n\n for (let cidx = 0; cidx < columns.length; cidx++) {\n if (cidx === 0 && is_group_by && !is_split_by) {\n // This is the grouping_id column, skip it\n continue;\n }\n\n let col = columns[cidx];\n if (is_split_by && !col.startsWith(\"__ROW_PATH_\")) {\n col = col.replaceAll(\"_\", \"|\");\n }\n\n const dtype = duckdbTypeToPsp(dtypes[cidx]) as ColumnType;\n\n const isDecimal = dtypes[cidx].startsWith(\"Decimal\");\n for (let ridx = 0; ridx < rows.length; ridx++) {\n const row = rows[ridx];\n const grouping_id = row[\"__GROUPING_ID__\"];\n let value = row[columns[cidx]];\n if (isDecimal) {\n value = convertDecimalToNumber(value, dtypes[cidx]);\n }\n\n if (typeof value === \"bigint\") {\n value = Number(value);\n }\n\n if (dtype === \"datetime\" && typeof value === \"string\") {\n value = +new Date(value);\n }\n\n if (dtype === \"string\" && typeof value !== \"string\") {\n value = `${value}`;\n }\n\n dataSlice.setCol(dtype, col, ridx, value, grouping_id);\n }\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["NUMBER_AGGS", "STRING_AGGS", "FILTER_OPS", "duckdbTypeToPsp", "name", "convertDecimalToNumber", "value", "dtypeString", "bigIntValue", "i", "scaleMatch", "scale", "Lock", "releaseLock", "newLockPromise", "resolve", "acquirePromise", "LOCK", "runQuery", "db", "query", "options", "release", "result", "data", "meta", "f", "error", "ClickhouseHandler", "mod", "viewer_class", "row", "tableId", "config", "results", "schema", "colName", "viewId", "gs", "count", "expression", "viewport", "dataSlice", "is_group_by", "is_split_by", "rows", "columns", "dtypes", "cidx", "col", "dtype", "isDecimal", "ridx", "grouping_id"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
1
|
+
var C=["sum","count","any_value","arbitrary","array_agg","avg","bit_and","bit_or","bit_xor","bitstring_agg","bool_and","bool_or","countif","favg","fsum","geomean","kahan_sum","last","max","min","product","string_agg","sumkahan"],m=["count","any_value","arbitrary","first","countif","last","string_agg"],d=["==","!=","LIKE","IS DISTINCT FROM","IS NOT DISTINCT FROM",">=","<=",">","<"];function f(s){return s=s.toLowerCase(),s==="varchar"||s=="utf8"?"string":s==="double"||s==="bigint"||s==="hugeint"||s==="float64"||s.startsWith("decimal")?"float":s.startsWith("int")?"integer":s.startsWith("date")?"date":s.startsWith("bool")?"boolean":s.startsWith("timestamp")?"datetime":(s.startsWith("json")||s.startsWith("struct")||console.warn(`Unknown type '${s}'`),"string")}function q(s,r){if(!(s instanceof Uint32Array||s instanceof Int32Array))return s;let t=BigInt(0);for(let i=0;i<s.length;i++)t|=BigInt(s[i])<<BigInt(i*32);let e=r.match(/Decimal\[\d+e(\d+)\]/);if(e){let i=parseInt(e[1]);return Number(t)/Math.pow(10,i)}else return Number(t)}async function a(s,r,t={}){r=r.replace(/\s+/g," ").trim();try{let e=await s.query(r);return t.columns?{rows:e.toArray(),columns:e.schema.fields.map(i=>i.name),dtypes:e.schema.fields.map(i=>i.type.toString())}:e.toArray()}catch(e){throw console.error("Query error:",e),console.error("Query:",r),e}}var T=class{db;sqlBuilder;constructor(r,t){if(!t&&customElements){let e=customElements.get("perspective-viewer");if(e)t=e.__wasm_module__;else throw new Error("Missing perspective-client.wasm")}this.db=r,this.sqlBuilder=new t.GenericSQLVirtualServerModel}getFeatures(){return{group_by:!0,split_by:!0,sort:!0,expressions:!0,group_rollup_mode:["rollup","flat","total"],filter_ops:{integer:d,float:d,string:d,boolean:d,date:d,datetime:d},aggregates:{integer:C,float:C,string:m,boolean:m,date:m,datetime:m}}}async getHostedTables(){let r=this.sqlBuilder.getHostedTables();return(await a(this.db,r)).map(e=>{let i=e.toJSON();return`${i.database||"memory"}.${i.name}`})}async tableSchema(r,t){let e=this.sqlBuilder.tableSchema(r),i=await a(this.db,e),l={};for(let c of i){let u=c.toJSON(),p=u.column_name;p.startsWith("__")||(l[p]=f(u.column_type))}return l}async viewColumnSize(r,t){let e=this.sqlBuilder.viewColumnSize(r),i=await a(this.db,e),l=Number(Object.values(i[0].toJSON())[0]),c=t.group_by?.length||0,u=t.group_rollup_mode==="flat";return l-(c===0?0:u?c:c+1)}async tableSize(r){let t=this.sqlBuilder.tableSize(r),e=await a(this.db,t);return Number(e[0].toJSON()["count_star()"])}async tableMakeView(r,t,e){let i=this.sqlBuilder.tableMakeView(r,t,e);await a(this.db,i)}async tableValidateExpression(r,t){let e=this.sqlBuilder.tableValidateExpression(r,t),i=await a(this.db,e);return f(i[0].toJSON().column_type)}async viewDelete(r){let t=this.sqlBuilder.viewDelete(r);await a(this.db,t)}async viewGetData(r,t,e,i,l){let c=t.group_by?.length>0,u=t.split_by?.length>0,p=t.group_rollup_mode==="flat",h=c&&!p,D=this.sqlBuilder.viewGetData(r,t,i,e),{rows:_,columns:w,dtypes:b}=await a(this.db,D,{columns:!0});for(let o=0;o<w.length;o++){if(o===0&&h)continue;let g=w[o];u&&!g.startsWith("__")&&(g=g.replaceAll("_","|"));let v=f(b[o]),N=b[o].startsWith("Decimal");for(let y=0;y<_.length;y++){let S=_[y].toArray(),k=h?Number(S[0]):void 0,n=S[o];if(N&&(n=q(n,b[o])),typeof n=="bigint"&&(n=Number(n)),typeof n!="string"&&v==="string")try{n=JSON.stringify(n)}catch{n=`${n}`}l.setCol(v,g,y,n,k)}}}};export{T as DuckDBHandler};
|
|
2
2
|
//# sourceMappingURL=duckdb.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/ts/virtual_servers/duckdb.ts"],
|
|
4
|
-
"sourcesContent": ["// \u250F\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2513\n// \u2503 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588 \u2588 \u2588 \u2588 \u2588 \u2588\u2584 \u2580\u2588\u2588\u2588 \u2588 \u2503\n// \u2503 \u2584\u2584\u2584\u2584\u2584\u2588 \u2588\u2584\u2584\u2584\u2584\u2584 \u2584\u2584\u2584\u2584\u2584\u2588 \u2580\u2580\u2580\u2580\u2580\u2588\u2580\u2580\u2580\u2580\u2580 \u2588 \u2580\u2580\u2580\u2580\u2580\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u258C\u2590\u2588\u2588\u2588 \u2588\u2588\u2588\u2584 \u2580\u2588 \u2588 \u2580\u2580\u2580\u2580\u2580 \u2503\n// \u2503 \u2588\u2580\u2580\u2580\u2580\u2580 \u2588\u2580\u2580\u2580\u2580\u2580 \u2588\u2580\u2588\u2588\u2580\u2580 \u2584\u2584\u2584\u2584\u2584 \u2588 \u2584\u2584\u2584\u2584\u2584\u2588 \u2584\u2584\u2584\u2584\u2584\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u258C\u2590\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2584 \u2588 \u2584\u2584\u2584\u2584\u2584 \u2503\n// \u2503 \u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588 \u2580\u2588\u2584 \u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588 \u2588\u2588\u2588\u258C\u2590\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2584 \u2588 \u2503\n// \u2523\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u252B\n// \u2503 Copyright (c) 2017, the Perspective Authors. \u2503\n// \u2503 \u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C \u2503\n// \u2503 This file is part of the Perspective library, distributed under the terms \u2503\n// \u2503 of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). \u2503\n// \u2517\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u251B\n\n/**\n * An implementation of a Perspective Virtual Server for DuckDB.\n *\n * This import is optional, and so must be imported manually from either\n * `@perspective-dev/client/dist/esm/virtual_servers/duckdb.js` or\n * `@perspective-dev/client/src/ts/virtual_servers/duckdb.ts`, it is not\n * exported from the package root `@perspective-dev/client`\n *\n * @module\n */\n\nimport type * as perspective from \"@perspective-dev/client\";\nimport type { ColumnType } from \"@perspective-dev/client/dist/esm/ts-rs/ColumnType.d.ts\";\nimport type { ViewConfig } from \"@perspective-dev/client/dist/esm/ts-rs/ViewConfig.d.ts\";\nimport type { ViewWindow } from \"@perspective-dev/client/dist/esm/ts-rs/ViewWindow.d.ts\";\nimport type * as duckdb from \"@duckdb/duckdb-wasm\";\n\nconst NUMBER_AGGS = [\n \"sum\",\n \"count\",\n \"any_value\",\n \"arbitrary\",\n \"array_agg\",\n \"avg\",\n \"bit_and\",\n \"bit_or\",\n \"bit_xor\",\n \"bitstring_agg\",\n \"bool_and\",\n \"bool_or\",\n \"countif\",\n \"favg\",\n \"fsum\",\n \"geomean\",\n \"kahan_sum\",\n \"last\",\n \"max\",\n \"min\",\n \"product\",\n \"string_agg\",\n \"sumkahan\",\n];\n\nconst STRING_AGGS = [\n \"count\",\n \"any_value\",\n \"arbitrary\",\n \"first\",\n \"countif\",\n \"last\",\n \"string_agg\",\n];\n\nconst FILTER_OPS = [\n \"==\",\n \"!=\",\n \"LIKE\",\n \"IS DISTINCT FROM\",\n \"IS NOT DISTINCT FROM\",\n \">=\",\n \"<=\",\n \">\",\n \"<\",\n];\n\nfunction duckdbTypeToPsp(name: string): ColumnType {\n if (name === \"VARCHAR\" || name == \"Utf8\") {\n return \"string\";\n }\n\n if (\n name === \"DOUBLE\" ||\n name === \"BIGINT\" ||\n name === \"HUGEINT\" ||\n name === \"Float64\" ||\n name.startsWith(\"Decimal\")\n ) {\n return \"float\";\n }\n\n if (name.startsWith(\"Int\") || name == \"INTEGER\") {\n return \"integer\";\n }\n\n if (name === \"INTEGER\") {\n return \"integer\";\n }\n\n if (name === \"DATE\" || name.startsWith(\"Date\")) {\n return \"date\";\n }\n\n if (name === \"BOOLEAN\" || name === \"Bool\") {\n return \"boolean\";\n }\n\n if (name === \"TIMESTAMP\" || name.startsWith(\"Timestamp\")) {\n return \"datetime\";\n }\n\n throw new Error(`Unknown type '${name}'`);\n}\n\nfunction convertDecimalToNumber(value: any, dtypeString: string) {\n if (!(value instanceof Uint32Array || value instanceof Int32Array)) {\n return value;\n }\n\n let bigIntValue = BigInt(0);\n for (let i = 0; i < value.length; i++) {\n bigIntValue |= BigInt(value[i]) << BigInt(i * 32);\n }\n\n const scaleMatch = dtypeString.match(/Decimal\\[\\d+e(\\d+)\\]/);\n if (scaleMatch) {\n const scale = parseInt(scaleMatch[1]);\n return Number(bigIntValue) / Math.pow(10, scale);\n } else {\n return Number(bigIntValue);\n }\n}\n\nasync function runQuery(\n db: duckdb.AsyncDuckDBConnection,\n query: string,\n options: { columns: true },\n): Promise<{\n rows: any[];\n columns: string[];\n dtypes: string[];\n}>;\n\nasync function runQuery(\n db: duckdb.AsyncDuckDBConnection,\n query: string,\n options?: { columns: false },\n): Promise<any[]>;\n\nasync function runQuery(\n db: duckdb.AsyncDuckDBConnection,\n query: string,\n options: { columns?: boolean } = {},\n) {\n query = query.replace(/\\s+/g, \" \").trim();\n try {\n const result = await db.query(query);\n if (options.columns) {\n return {\n rows: result.toArray(),\n columns: result.schema.fields.map((f) => f.name),\n dtypes: result.schema.fields.map((f) => f.type.toString()),\n };\n }\n\n return result.toArray();\n } catch (error) {\n console.error(\"Query error:\", error);\n console.error(\"Query:\", query);\n throw error;\n }\n}\n\n/**\n * An implementation of Perspective's Virtual Server for `@duckdb/duckdb-wasm`.\n */\nexport class DuckDBHandler implements perspective.VirtualServerHandler {\n private db: duckdb.AsyncDuckDBConnection;\n private sqlBuilder: perspective.GenericSQLVirtualServerModel;\n constructor(db: duckdb.AsyncDuckDBConnection, mod?: typeof perspective) {\n if (!mod) {\n if (customElements) {\n const viewer_class: any =\n customElements.get(\"perspective-viewer\");\n if (viewer_class) {\n mod = viewer_class.__wasm_module__;\n } else {\n throw new Error(\"Missing perspective-client.wasm\");\n }\n } else {\n }\n }\n\n this.db = db;\n this.sqlBuilder = new mod!.GenericSQLVirtualServerModel();\n }\n\n getFeatures() {\n return {\n group_by: true,\n split_by: true,\n sort: true,\n expressions: true,\n filter_ops: {\n integer: FILTER_OPS,\n float: FILTER_OPS,\n string: FILTER_OPS,\n boolean: FILTER_OPS,\n date: FILTER_OPS,\n datetime: FILTER_OPS,\n },\n aggregates: {\n integer: NUMBER_AGGS,\n float: NUMBER_AGGS,\n string: STRING_AGGS,\n boolean: STRING_AGGS,\n date: STRING_AGGS,\n datetime: STRING_AGGS,\n },\n };\n }\n\n async getHostedTables() {\n const query = this.sqlBuilder.getHostedTables();\n const results = await runQuery(this.db, query);\n return results.map((row) => {\n const json = row.toJSON();\n return `${json.database || \"memory\"}.${json.name}`;\n });\n }\n\n async tableSchema(tableId: string, config?: ViewConfig) {\n const query = this.sqlBuilder.tableSchema(tableId);\n const results = await runQuery(this.db, query);\n const schema = {} as Record<string, ColumnType>;\n for (const result of results) {\n const res = result.toJSON();\n const colName = res.column_name;\n if (!colName.startsWith(\"__\")) {\n schema[colName] = duckdbTypeToPsp(\n res.column_type,\n ) as ColumnType;\n }\n }\n\n return schema;\n }\n\n async viewColumnSize(viewId: string, config: ViewConfig) {\n const query = this.sqlBuilder.viewColumnSize(viewId);\n const results = await runQuery(this.db, query);\n const gs = config.group_by?.length || 0;\n const count = Number(Object.values(results[0].toJSON())[0]);\n return (\n count -\n (gs === 0 ? 0 : gs + (config.split_by?.length === 0 ? 1 : 0))\n );\n }\n\n async tableSize(tableId: string) {\n const query = this.sqlBuilder.tableSize(tableId);\n const results = await runQuery(this.db, query);\n return Number(results[0].toJSON()[\"count_star()\"]);\n }\n\n async tableMakeView(tableId: string, viewId: string, config: ViewConfig) {\n const query = this.sqlBuilder.tableMakeView(tableId, viewId, config);\n await runQuery(this.db, query);\n }\n\n async tableValidateExpression(tableId: string, expression: string) {\n const query = this.sqlBuilder.tableValidateExpression(\n tableId,\n expression,\n );\n const results = await runQuery(this.db, query);\n return duckdbTypeToPsp(\n results[0].toJSON()[\"column_type\"],\n ) as ColumnType;\n }\n\n async viewDelete(viewId: string) {\n const query = this.sqlBuilder.viewDelete(viewId);\n await runQuery(this.db, query);\n }\n\n async viewGetData(\n viewId: string,\n config: ViewConfig,\n schema: Record<string, ColumnType>,\n viewport: ViewWindow,\n dataSlice: perspective.VirtualDataSlice,\n ) {\n const is_group_by = config.group_by?.length > 0;\n const is_split_by = config.split_by?.length > 0;\n const query = this.sqlBuilder.viewGetData(\n viewId,\n config,\n viewport,\n schema,\n );\n\n const { rows, columns, dtypes } = await runQuery(this.db, query, {\n columns: true,\n });\n\n for (let cidx = 0; cidx < columns.length; cidx++) {\n if (cidx === 0 && is_group_by && !is_split_by) {\n // This is the grouping_id column, skip it\n continue;\n }\n\n let col = columns[cidx];\n if (is_split_by && !col.startsWith(\"__ROW_PATH_\")) {\n col = col.replaceAll(\"_\", \"|\");\n }\n\n const dtype = duckdbTypeToPsp(dtypes[cidx]) as ColumnType;\n\n const isDecimal = dtypes[cidx].startsWith(\"Decimal\");\n for (let ridx = 0; ridx < rows.length; ridx++) {\n const rowArray = rows[ridx].toArray();\n const grouping_id = Number(rowArray[0]);\n let value = rowArray[cidx];\n if (isDecimal) {\n value = convertDecimalToNumber(value, dtypes[cidx]);\n }\n\n if (typeof value === \"bigint\") {\n value = Number(value);\n }\n\n dataSlice.setCol(dtype, col, ridx, value, grouping_id);\n }\n }\n }\n}\n"],
|
|
5
|
-
"mappings": "AA6BA,IAAMA,EAAc,CAChB,MACA,QACA,YACA,YACA,YACA,MACA,UACA,SACA,UACA,gBACA,WACA,UACA,UACA,OACA,OACA,UACA,YACA,OACA,MACA,MACA,UACA,aACA,UACJ,EAEMC,EAAc,CAChB,QACA,YACA,YACA,QACA,UACA,OACA,YACJ,EAEMC,EAAa,CACf,KACA,KACA,OACA,mBACA,uBACA,KACA,KACA,IACA,GACJ,EAEA,SAASC,EAAgBC,EAA0B,
|
|
6
|
-
"names": ["NUMBER_AGGS", "STRING_AGGS", "FILTER_OPS", "duckdbTypeToPsp", "name", "convertDecimalToNumber", "value", "dtypeString", "bigIntValue", "scaleMatch", "scale", "runQuery", "db", "query", "options", "result", "f", "error", "DuckDBHandler", "mod", "viewer_class", "row", "json", "tableId", "config", "results", "schema", "res", "colName", "viewId", "gs", "expression", "viewport", "dataSlice", "is_group_by", "is_split_by", "rows", "columns", "dtypes", "cidx", "col", "dtype", "isDecimal", "ridx", "rowArray", "grouping_id"]
|
|
4
|
+
"sourcesContent": ["// \u250F\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2513\n// \u2503 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588 \u2588 \u2588 \u2588 \u2588 \u2588\u2584 \u2580\u2588\u2588\u2588 \u2588 \u2503\n// \u2503 \u2584\u2584\u2584\u2584\u2584\u2588 \u2588\u2584\u2584\u2584\u2584\u2584 \u2584\u2584\u2584\u2584\u2584\u2588 \u2580\u2580\u2580\u2580\u2580\u2588\u2580\u2580\u2580\u2580\u2580 \u2588 \u2580\u2580\u2580\u2580\u2580\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u258C\u2590\u2588\u2588\u2588 \u2588\u2588\u2588\u2584 \u2580\u2588 \u2588 \u2580\u2580\u2580\u2580\u2580 \u2503\n// \u2503 \u2588\u2580\u2580\u2580\u2580\u2580 \u2588\u2580\u2580\u2580\u2580\u2580 \u2588\u2580\u2588\u2588\u2580\u2580 \u2584\u2584\u2584\u2584\u2584 \u2588 \u2584\u2584\u2584\u2584\u2584\u2588 \u2584\u2584\u2584\u2584\u2584\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u258C\u2590\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2584 \u2588 \u2584\u2584\u2584\u2584\u2584 \u2503\n// \u2503 \u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588 \u2580\u2588\u2584 \u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588 \u2588\u2588\u2588\u258C\u2590\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2584 \u2588 \u2503\n// \u2523\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u252B\n// \u2503 Copyright (c) 2017, the Perspective Authors. \u2503\n// \u2503 \u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C\u254C \u2503\n// \u2503 This file is part of the Perspective library, distributed under the terms \u2503\n// \u2503 of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). \u2503\n// \u2517\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u251B\n\n/**\n * An implementation of a Perspective Virtual Server for DuckDB.\n *\n * This import is optional, and so must be imported manually from either\n * `@perspective-dev/client/dist/esm/virtual_servers/duckdb.js` or\n * `@perspective-dev/client/src/ts/virtual_servers/duckdb.ts`, it is not\n * exported from the package root `@perspective-dev/client`\n *\n * @module\n */\n\nimport type * as perspective from \"@perspective-dev/client\";\nimport type { ColumnType } from \"@perspective-dev/client/dist/esm/ts-rs/ColumnType.d.ts\";\nimport type { ViewConfig } from \"@perspective-dev/client/dist/esm/ts-rs/ViewConfig.d.ts\";\nimport type { ViewWindow } from \"@perspective-dev/client/dist/esm/ts-rs/ViewWindow.d.ts\";\nimport type * as duckdb from \"@duckdb/duckdb-wasm\";\n\nconst NUMBER_AGGS = [\n \"sum\",\n \"count\",\n \"any_value\",\n \"arbitrary\",\n \"array_agg\",\n \"avg\",\n \"bit_and\",\n \"bit_or\",\n \"bit_xor\",\n \"bitstring_agg\",\n \"bool_and\",\n \"bool_or\",\n \"countif\",\n \"favg\",\n \"fsum\",\n \"geomean\",\n \"kahan_sum\",\n \"last\",\n \"max\",\n \"min\",\n \"product\",\n \"string_agg\",\n \"sumkahan\",\n];\n\nconst STRING_AGGS = [\n \"count\",\n \"any_value\",\n \"arbitrary\",\n \"first\",\n \"countif\",\n \"last\",\n \"string_agg\",\n];\n\nconst FILTER_OPS = [\n \"==\",\n \"!=\",\n \"LIKE\",\n \"IS DISTINCT FROM\",\n \"IS NOT DISTINCT FROM\",\n \">=\",\n \"<=\",\n \">\",\n \"<\",\n];\n\nfunction duckdbTypeToPsp(name: string): ColumnType {\n name = name.toLowerCase();\n if (name === \"varchar\" || name == \"utf8\") {\n return \"string\";\n }\n\n if (\n name === \"double\" ||\n name === \"bigint\" ||\n name === \"hugeint\" ||\n name === \"float64\" ||\n name.startsWith(\"decimal\")\n ) {\n return \"float\";\n }\n\n if (name.startsWith(\"int\")) {\n return \"integer\";\n }\n\n if (name.startsWith(\"date\")) {\n return \"date\";\n }\n\n if (name.startsWith(\"bool\")) {\n return \"boolean\";\n }\n\n if (name.startsWith(\"timestamp\")) {\n return \"datetime\";\n }\n\n if (name.startsWith(\"json\")) {\n return \"string\";\n }\n\n if (name.startsWith(\"struct\")) {\n return \"string\";\n }\n\n console.warn(`Unknown type '${name}'`);\n return \"string\";\n}\n\nfunction convertDecimalToNumber(value: any, dtypeString: string) {\n if (!(value instanceof Uint32Array || value instanceof Int32Array)) {\n return value;\n }\n\n let bigIntValue = BigInt(0);\n for (let i = 0; i < value.length; i++) {\n bigIntValue |= BigInt(value[i]) << BigInt(i * 32);\n }\n\n const scaleMatch = dtypeString.match(/Decimal\\[\\d+e(\\d+)\\]/);\n if (scaleMatch) {\n const scale = parseInt(scaleMatch[1]);\n return Number(bigIntValue) / Math.pow(10, scale);\n } else {\n return Number(bigIntValue);\n }\n}\n\nasync function runQuery(\n db: duckdb.AsyncDuckDBConnection,\n query: string,\n options: { columns: true },\n): Promise<{\n rows: any[];\n columns: string[];\n dtypes: string[];\n}>;\n\nasync function runQuery(\n db: duckdb.AsyncDuckDBConnection,\n query: string,\n options?: { columns: false },\n): Promise<any[]>;\n\nasync function runQuery(\n db: duckdb.AsyncDuckDBConnection,\n query: string,\n options: { columns?: boolean } = {},\n) {\n query = query.replace(/\\s+/g, \" \").trim();\n try {\n const result = await db.query(query);\n if (options.columns) {\n return {\n rows: result.toArray(),\n columns: result.schema.fields.map((f) => f.name),\n dtypes: result.schema.fields.map((f) => f.type.toString()),\n };\n }\n\n return result.toArray();\n } catch (error) {\n console.error(\"Query error:\", error);\n console.error(\"Query:\", query);\n throw error;\n }\n}\n\n/**\n * An implementation of Perspective's Virtual Server for `@duckdb/duckdb-wasm`.\n */\nexport class DuckDBHandler implements perspective.VirtualServerHandler {\n private db: duckdb.AsyncDuckDBConnection;\n private sqlBuilder: perspective.GenericSQLVirtualServerModel;\n constructor(db: duckdb.AsyncDuckDBConnection, mod?: typeof perspective) {\n if (!mod) {\n if (customElements) {\n const viewer_class: any =\n customElements.get(\"perspective-viewer\");\n if (viewer_class) {\n mod = viewer_class.__wasm_module__;\n } else {\n throw new Error(\"Missing perspective-client.wasm\");\n }\n } else {\n }\n }\n\n this.db = db;\n this.sqlBuilder = new mod!.GenericSQLVirtualServerModel();\n }\n\n getFeatures() {\n return {\n group_by: true,\n split_by: true,\n sort: true,\n expressions: true,\n group_rollup_mode: [\"rollup\", \"flat\", \"total\"],\n filter_ops: {\n integer: FILTER_OPS,\n float: FILTER_OPS,\n string: FILTER_OPS,\n boolean: FILTER_OPS,\n date: FILTER_OPS,\n datetime: FILTER_OPS,\n },\n aggregates: {\n integer: NUMBER_AGGS,\n float: NUMBER_AGGS,\n string: STRING_AGGS,\n boolean: STRING_AGGS,\n date: STRING_AGGS,\n datetime: STRING_AGGS,\n },\n };\n }\n\n async getHostedTables() {\n const query = this.sqlBuilder.getHostedTables();\n const results = await runQuery(this.db, query);\n return results.map((row) => {\n const json = row.toJSON();\n return `${json.database || \"memory\"}.${json.name}`;\n });\n }\n\n async tableSchema(tableId: string, config?: ViewConfig) {\n const query = this.sqlBuilder.tableSchema(tableId);\n const results = await runQuery(this.db, query);\n const schema = {} as Record<string, ColumnType>;\n for (const result of results) {\n const res = result.toJSON();\n const colName = res.column_name;\n if (!colName.startsWith(\"__\")) {\n schema[colName] = duckdbTypeToPsp(\n res.column_type,\n ) as ColumnType;\n }\n }\n\n return schema;\n }\n\n async viewColumnSize(viewId: string, config: ViewConfig) {\n const query = this.sqlBuilder.viewColumnSize(viewId);\n const results = await runQuery(this.db, query);\n const count = Number(Object.values(results[0].toJSON())[0]);\n const gs = config.group_by?.length || 0;\n const is_flat = config.group_rollup_mode === \"flat\";\n return count - (gs === 0 ? 0 : is_flat ? gs : gs + 1);\n }\n\n async tableSize(tableId: string) {\n const query = this.sqlBuilder.tableSize(tableId);\n const results = await runQuery(this.db, query);\n return Number(results[0].toJSON()[\"count_star()\"]);\n }\n\n async tableMakeView(tableId: string, viewId: string, config: ViewConfig) {\n const query = this.sqlBuilder.tableMakeView(tableId, viewId, config);\n await runQuery(this.db, query);\n }\n\n async tableValidateExpression(tableId: string, expression: string) {\n const query = this.sqlBuilder.tableValidateExpression(\n tableId,\n expression,\n );\n const results = await runQuery(this.db, query);\n return duckdbTypeToPsp(\n results[0].toJSON()[\"column_type\"],\n ) as ColumnType;\n }\n\n async viewDelete(viewId: string) {\n const query = this.sqlBuilder.viewDelete(viewId);\n await runQuery(this.db, query);\n }\n\n async viewGetData(\n viewId: string,\n config: ViewConfig,\n schema: Record<string, ColumnType>,\n viewport: ViewWindow,\n dataSlice: perspective.VirtualDataSlice,\n ) {\n const is_group_by = config.group_by?.length > 0;\n const is_split_by = config.split_by?.length > 0;\n const is_flat = config.group_rollup_mode === \"flat\";\n const has_grouping_id = is_group_by && !is_flat;\n const query = this.sqlBuilder.viewGetData(\n viewId,\n config,\n viewport,\n schema,\n );\n\n const { rows, columns, dtypes } = await runQuery(this.db, query, {\n columns: true,\n });\n\n for (let cidx = 0; cidx < columns.length; cidx++) {\n if (cidx === 0 && has_grouping_id) {\n // This is the grouping_id column, skip it\n continue;\n }\n\n let col = columns[cidx];\n if (is_split_by && !col.startsWith(\"__\")) {\n col = col.replaceAll(\"_\", \"|\");\n }\n\n const dtype = duckdbTypeToPsp(dtypes[cidx]) as ColumnType;\n const isDecimal = dtypes[cidx].startsWith(\"Decimal\");\n for (let ridx = 0; ridx < rows.length; ridx++) {\n const rowArray = rows[ridx].toArray();\n const grouping_id = has_grouping_id\n ? Number(rowArray[0])\n : undefined;\n let value = rowArray[cidx];\n if (isDecimal) {\n value = convertDecimalToNumber(value, dtypes[cidx]);\n }\n\n if (typeof value === \"bigint\") {\n value = Number(value);\n }\n\n if (typeof value !== \"string\" && dtype === \"string\") {\n try {\n value = JSON.stringify(value);\n } catch (e) {\n value = `${value}`;\n }\n }\n\n dataSlice.setCol(dtype, col, ridx, value, grouping_id);\n }\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["NUMBER_AGGS", "STRING_AGGS", "FILTER_OPS", "duckdbTypeToPsp", "name", "convertDecimalToNumber", "value", "dtypeString", "bigIntValue", "scaleMatch", "scale", "runQuery", "db", "query", "options", "result", "f", "error", "DuckDBHandler", "mod", "viewer_class", "row", "json", "tableId", "config", "results", "schema", "res", "colName", "viewId", "count", "gs", "is_flat", "expression", "viewport", "dataSlice", "is_group_by", "is_split_by", "has_grouping_id", "rows", "columns", "dtypes", "cidx", "col", "dtype", "isDecimal", "ridx", "rowArray", "grouping_id"]
|
|
7
7
|
}
|
|
@@ -792,11 +792,11 @@ export interface InitOutput {
|
|
|
792
792
|
readonly virtualdataslice_setStringCol: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
|
|
793
793
|
readonly virtualserver_handleRequest: (a: number, b: number, c: number) => number;
|
|
794
794
|
readonly virtualserver_new: (a: number, b: number) => void;
|
|
795
|
-
readonly
|
|
796
|
-
readonly
|
|
797
|
-
readonly
|
|
798
|
-
readonly
|
|
799
|
-
readonly
|
|
795
|
+
readonly __wasm_bindgen_func_elem_813: (a: number, b: number) => void;
|
|
796
|
+
readonly __wasm_bindgen_func_elem_3857: (a: number, b: number) => void;
|
|
797
|
+
readonly __wasm_bindgen_func_elem_5713: (a: number, b: number, c: number, d: number) => void;
|
|
798
|
+
readonly __wasm_bindgen_func_elem_3874: (a: number, b: number, c: number) => void;
|
|
799
|
+
readonly __wasm_bindgen_func_elem_1689: (a: number, b: number) => number;
|
|
800
800
|
readonly __wbindgen_export: (a: number, b: number) => number;
|
|
801
801
|
readonly __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
|
|
802
802
|
readonly __wbindgen_export3: (a: number) => void;
|
|
@@ -1864,7 +1864,7 @@ function __wbg_get_imports() {
|
|
|
1864
1864
|
const a = state0.a;
|
|
1865
1865
|
state0.a = 0;
|
|
1866
1866
|
try {
|
|
1867
|
-
return
|
|
1867
|
+
return __wasm_bindgen_func_elem_5713(a, state0.b, arg0, arg1);
|
|
1868
1868
|
} finally {
|
|
1869
1869
|
state0.a = a;
|
|
1870
1870
|
}
|
|
@@ -2018,13 +2018,13 @@ function __wbg_get_imports() {
|
|
|
2018
2018
|
console.warn(getObject(arg0));
|
|
2019
2019
|
},
|
|
2020
2020
|
__wbindgen_cast_0000000000000001: function(arg0, arg1) {
|
|
2021
|
-
// Cast intrinsic for `Closure(Closure { dtor_idx:
|
|
2022
|
-
const ret = makeClosure(arg0, arg1, wasm.
|
|
2021
|
+
// Cast intrinsic for `Closure(Closure { dtor_idx: 12, function: Function { arguments: [], shim_idx: 29, ret: NamedExternref("Promise<any>"), inner_ret: Some(NamedExternref("Promise<any>")) }, mutable: false }) -> Externref`.
|
|
2022
|
+
const ret = makeClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_813, __wasm_bindgen_func_elem_1689);
|
|
2023
2023
|
return addHeapObject(ret);
|
|
2024
2024
|
},
|
|
2025
2025
|
__wbindgen_cast_0000000000000002: function(arg0, arg1) {
|
|
2026
|
-
// Cast intrinsic for `Closure(Closure { dtor_idx:
|
|
2027
|
-
const ret = makeMutClosure(arg0, arg1, wasm.
|
|
2026
|
+
// Cast intrinsic for `Closure(Closure { dtor_idx: 549, function: Function { arguments: [Externref], shim_idx: 550, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
2027
|
+
const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_3857, __wasm_bindgen_func_elem_3874);
|
|
2028
2028
|
return addHeapObject(ret);
|
|
2029
2029
|
},
|
|
2030
2030
|
__wbindgen_cast_0000000000000003: function(arg0) {
|
|
@@ -2081,17 +2081,17 @@ function __wbg_get_imports() {
|
|
|
2081
2081
|
};
|
|
2082
2082
|
}
|
|
2083
2083
|
|
|
2084
|
-
function
|
|
2085
|
-
const ret = wasm.
|
|
2084
|
+
function __wasm_bindgen_func_elem_1689(arg0, arg1) {
|
|
2085
|
+
const ret = wasm.__wasm_bindgen_func_elem_1689(arg0, arg1);
|
|
2086
2086
|
return takeObject(ret);
|
|
2087
2087
|
}
|
|
2088
2088
|
|
|
2089
|
-
function
|
|
2090
|
-
wasm.
|
|
2089
|
+
function __wasm_bindgen_func_elem_3874(arg0, arg1, arg2) {
|
|
2090
|
+
wasm.__wasm_bindgen_func_elem_3874(arg0, arg1, addHeapObject(arg2));
|
|
2091
2091
|
}
|
|
2092
2092
|
|
|
2093
|
-
function
|
|
2094
|
-
wasm.
|
|
2093
|
+
function __wasm_bindgen_func_elem_5713(arg0, arg1, arg2, arg3) {
|
|
2094
|
+
wasm.__wasm_bindgen_func_elem_5713(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
|
|
2095
2095
|
}
|
|
2096
2096
|
|
|
2097
2097
|
const ClientFinalization = (typeof FinalizationRegistry === 'undefined')
|
|
Binary file
|
|
@@ -87,11 +87,11 @@ export const virtualdataslice_setIntegerCol: (a: number, b: number, c: number, d
|
|
|
87
87
|
export const virtualdataslice_setStringCol: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
|
|
88
88
|
export const virtualserver_handleRequest: (a: number, b: number, c: number) => number;
|
|
89
89
|
export const virtualserver_new: (a: number, b: number) => void;
|
|
90
|
-
export const
|
|
91
|
-
export const
|
|
92
|
-
export const
|
|
93
|
-
export const
|
|
94
|
-
export const
|
|
90
|
+
export const __wasm_bindgen_func_elem_813: (a: number, b: number) => void;
|
|
91
|
+
export const __wasm_bindgen_func_elem_3857: (a: number, b: number) => void;
|
|
92
|
+
export const __wasm_bindgen_func_elem_5713: (a: number, b: number, c: number, d: number) => void;
|
|
93
|
+
export const __wasm_bindgen_func_elem_3874: (a: number, b: number, c: number) => void;
|
|
94
|
+
export const __wasm_bindgen_func_elem_1689: (a: number, b: number) => number;
|
|
95
95
|
export const __wbindgen_export: (a: number, b: number) => number;
|
|
96
96
|
export const __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
|
|
97
97
|
export const __wbindgen_export3: (a: number) => void;
|
package/package.json
CHANGED
|
@@ -90,12 +90,7 @@ where
|
|
|
90
90
|
Result<T, JsValue>: IntoJsResult + 'static,
|
|
91
91
|
{
|
|
92
92
|
fn from(fut: ApiFuture<T>) -> Self {
|
|
93
|
-
future_to_promise(async move {
|
|
94
|
-
match fut.0.await.ignore_view_delete()? {
|
|
95
|
-
Some(x) => Ok(x).into_js_result(),
|
|
96
|
-
None => Err("View not found".into()).into_js_result(),
|
|
97
|
-
}
|
|
98
|
-
})
|
|
93
|
+
future_to_promise(async move { Ok(fut.0.await?).into_js_result() })
|
|
99
94
|
}
|
|
100
95
|
}
|
|
101
96
|
|
|
@@ -3,6 +3,7 @@ import type { Aggregate } from "./Aggregate.js";
|
|
|
3
3
|
import type { Expressions } from "./Expressions.js";
|
|
4
4
|
import type { Filter } from "./Filter.js";
|
|
5
5
|
import type { FilterReducer } from "./FilterReducer.js";
|
|
6
|
+
import type { GroupRollupMode } from "./GroupRollupMode.js";
|
|
6
7
|
import type { Sort } from "./Sort.js";
|
|
7
8
|
|
|
8
|
-
export type ViewConfig = { group_by: Array<string>, split_by: Array<string>, sort: Array<Sort>, filter: Array<Filter>, filter_op?: FilterReducer, expressions: Expressions, columns: Array<string | null>, aggregates: { [key in string]?: Aggregate }, group_by_depth?: number | null, };
|
|
9
|
+
export type ViewConfig = { group_by: Array<string>, split_by: Array<string>, sort: Array<Sort>, filter: Array<Filter>, group_rollup_mode: GroupRollupMode, filter_op?: FilterReducer, expressions: Expressions, columns: Array<string | null>, aggregates: { [key in string]?: Aggregate }, group_by_depth?: number | null, };
|
|
@@ -3,6 +3,7 @@ import type { Aggregate } from "./Aggregate.js";
|
|
|
3
3
|
import type { Expressions } from "./Expressions.js";
|
|
4
4
|
import type { Filter } from "./Filter.js";
|
|
5
5
|
import type { FilterReducer } from "./FilterReducer.js";
|
|
6
|
+
import type { GroupRollupMode } from "./GroupRollupMode.js";
|
|
6
7
|
import type { Sort } from "./Sort.js";
|
|
7
8
|
|
|
8
9
|
export type ViewConfigUpdate = {
|
|
@@ -84,4 +85,4 @@ expressions?: Expressions,
|
|
|
84
85
|
* applied to columns in the `View` constructor using a dictionary of
|
|
85
86
|
* column name to aggregate function name.
|
|
86
87
|
*/
|
|
87
|
-
aggregates?: { [key in string]?: Aggregate }, group_by_depth?: number, filter_op?: FilterReducer, };
|
|
88
|
+
aggregates?: { [key in string]?: Aggregate }, group_by_depth?: number, filter_op?: FilterReducer, group_rollup_mode?: GroupRollupMode, };
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Some fields of [`ViewWindow`] are only applicable to specific methods of
|
|
7
7
|
* [`View`].
|
|
8
8
|
*/
|
|
9
|
-
export type ViewWindow = { start_row?: number, start_col?: number, end_row?: number, end_col?: number, id?: boolean, index?: boolean,
|
|
9
|
+
export type ViewWindow = { start_row?: number, start_col?: number, end_row?: number, end_col?: number, id?: boolean, index?: boolean,
|
|
10
10
|
/**
|
|
11
11
|
* Only impacts [`View::to_csv`]
|
|
12
12
|
*/
|
|
@@ -223,6 +223,7 @@ export class ClickhouseHandler implements perspective.VirtualServerHandler {
|
|
|
223
223
|
split_by: false,
|
|
224
224
|
sort: true,
|
|
225
225
|
expressions: true,
|
|
226
|
+
group_rollup_mode: ["rollup", "flat", "total"],
|
|
226
227
|
filter_ops: {
|
|
227
228
|
integer: FILTER_OPS,
|
|
228
229
|
float: FILTER_OPS,
|