@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.
@@ -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
  };
@@ -11,7 +11,6 @@ export type ViewWindow = {
11
11
  end_col?: number;
12
12
  id?: boolean;
13
13
  index?: boolean;
14
- leaves_only?: boolean;
15
14
  /**
16
15
  * Only impacts [`View::to_csv`]
17
16
  */
@@ -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(r){if(r.startsWith("Nullable")&&(r=r.match(/Nullable\((.+?)\)/)[1]),r.startsWith("Array"))return"string";if(r==="Int64"||r==="UInt64"||r==="Float64")return"float";if(r==="String")return"string";if(r==="DateTime")return"datetime";if(r==="Date")return"date";throw new Error(`Unknown type '${r}'`)}function q(r,t){if(!(r instanceof Uint32Array||r instanceof Int32Array))return r;let e=BigInt(0);for(let i=0;i<r.length;i++)e|=BigInt(r[i])<<BigInt(i*32);let s=t.match(/Decimal\[\d+e(\d+)\]/);if(s){let i=parseInt(s[1]);return Number(e)/Math.pow(10,i)}else return Number(e)}var w=class{lockPromise;constructor(){this.lockPromise=Promise.resolve()}acquire(){let t,e=new Promise(i=>{t=i}),s=this.lockPromise.then(()=>t);return this.lockPromise=e,s}},N=new w;async function u(r,t,e={}){t=t.replace(/\s+/g," ").trim();let s=await N.acquire();try{let i=await r.query({query:t});if(!e.execute){let{data:o,meta:l}=await i.json();return e.columns?{rows:o,columns:l.map(a=>a.name),dtypes:l.map(a=>a.type)}:o}}catch(i){throw console.error("Query error:",i),console.error("Query:",t),i}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,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),i=await u(this.db,s),o={};for(let l of i){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}'`,i=await u(this.db,s),o=e.group_by?.length||0,l=Number(i[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 i=this.sqlBuilder.tableMakeView(t,e,s);await u(this.db,i,{execute:!0})}async tableValidateExpression(t,e){let s=this.sqlBuilder.tableValidateExpression(t,e),i=await u(this.db,s);return h(i[0].type)}async viewDelete(t){let e=this.sqlBuilder.viewDelete(t);await u(this.db,e,{execute:!0})}async viewGetData(t,e,s,i,o){let l=e.group_by?.length>0,a=e.split_by?.length>0,k=this.sqlBuilder.viewGetData(t,e,i,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};
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": "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",
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
  }
@@ -25,6 +25,7 @@ export declare class DuckDBHandler implements perspective.VirtualServerHandler {
25
25
  split_by: boolean;
26
26
  sort: boolean;
27
27
  expressions: boolean;
28
+ group_rollup_mode: string[];
28
29
  filter_ops: {
29
30
  integer: string[];
30
31
  float: string[];
@@ -1,2 +1,2 @@
1
- var v=["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"],l=["==","!=","LIKE","IS DISTINCT FROM","IS NOT DISTINCT FROM",">=","<=",">","<"];function f(e){if(e==="VARCHAR"||e=="Utf8")return"string";if(e==="DOUBLE"||e==="BIGINT"||e==="HUGEINT"||e==="Float64"||e.startsWith("Decimal"))return"float";if(e.startsWith("Int")||e=="INTEGER"||e==="INTEGER")return"integer";if(e==="DATE"||e.startsWith("Date"))return"date";if(e==="BOOLEAN"||e==="Bool")return"boolean";if(e==="TIMESTAMP"||e.startsWith("Timestamp"))return"datetime";throw new Error(`Unknown type '${e}'`)}function N(e,r){if(!(e instanceof Uint32Array||e instanceof Int32Array))return e;let s=BigInt(0);for(let i=0;i<e.length;i++)s|=BigInt(e[i])<<BigInt(i*32);let t=r.match(/Decimal\[\d+e(\d+)\]/);if(t){let i=parseInt(t[1]);return Number(s)/Math.pow(10,i)}else return Number(s)}async function o(e,r,s={}){r=r.replace(/\s+/g," ").trim();try{let t=await e.query(r);return s.columns?{rows:t.toArray(),columns:t.schema.fields.map(i=>i.name),dtypes:t.schema.fields.map(i=>i.type.toString())}:t.toArray()}catch(t){throw console.error("Query error:",t),console.error("Query:",r),t}}var T=class{db;sqlBuilder;constructor(r,s){if(!s&&customElements){let t=customElements.get("perspective-viewer");if(t)s=t.__wasm_module__;else throw new Error("Missing perspective-client.wasm")}this.db=r,this.sqlBuilder=new s.GenericSQLVirtualServerModel}getFeatures(){return{group_by:!0,split_by:!0,sort:!0,expressions:!0,filter_ops:{integer:l,float:l,string:l,boolean:l,date:l,datetime:l},aggregates:{integer:v,float:v,string:m,boolean:m,date:m,datetime:m}}}async getHostedTables(){let r=this.sqlBuilder.getHostedTables();return(await o(this.db,r)).map(t=>{let i=t.toJSON();return`${i.database||"memory"}.${i.name}`})}async tableSchema(r,s){let t=this.sqlBuilder.tableSchema(r),i=await o(this.db,t),a={};for(let d of i){let u=d.toJSON(),p=u.column_name;p.startsWith("__")||(a[p]=f(u.column_type))}return a}async viewColumnSize(r,s){let t=this.sqlBuilder.viewColumnSize(r),i=await o(this.db,t),a=s.group_by?.length||0;return Number(Object.values(i[0].toJSON())[0])-(a===0?0:a+(s.split_by?.length===0?1:0))}async tableSize(r){let s=this.sqlBuilder.tableSize(r),t=await o(this.db,s);return Number(t[0].toJSON()["count_star()"])}async tableMakeView(r,s,t){let i=this.sqlBuilder.tableMakeView(r,s,t);await o(this.db,i)}async tableValidateExpression(r,s){let t=this.sqlBuilder.tableValidateExpression(r,s),i=await o(this.db,t);return f(i[0].toJSON().column_type)}async viewDelete(r){let s=this.sqlBuilder.viewDelete(r);await o(this.db,s)}async viewGetData(r,s,t,i,a){let d=s.group_by?.length>0,u=s.split_by?.length>0,p=this.sqlBuilder.viewGetData(r,s,i,t),{rows:h,columns:w,dtypes:b}=await o(this.db,p,{columns:!0});for(let n=0;n<w.length;n++){if(n===0&&d&&!u)continue;let y=w[n];u&&!y.startsWith("__ROW_PATH_")&&(y=y.replaceAll("_","|"));let S=f(b[n]),C=b[n].startsWith("Decimal");for(let g=0;g<h.length;g++){let _=h[g].toArray(),D=Number(_[0]),c=_[n];C&&(c=N(c,b[n])),typeof c=="bigint"&&(c=Number(c)),a.setCol(S,y,g,c,D)}}}};export{T as DuckDBHandler};
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": "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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", "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 __wasm_bindgen_func_elem_1421: (a: number, b: number) => void;
796
- readonly __wasm_bindgen_func_elem_3793: (a: number, b: number) => void;
797
- readonly __wasm_bindgen_func_elem_5384: (a: number, b: number, c: number, d: number) => void;
798
- readonly __wasm_bindgen_func_elem_3795: (a: number, b: number, c: number) => void;
799
- readonly __wasm_bindgen_func_elem_1668: (a: number, b: number) => number;
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 __wasm_bindgen_func_elem_5384(a, state0.b, arg0, arg1);
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: 13, function: Function { arguments: [], shim_idx: 30, ret: NamedExternref("Promise<any>"), inner_ret: Some(NamedExternref("Promise<any>")) }, mutable: false }) -> Externref`.
2022
- const ret = makeClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_1421, __wasm_bindgen_func_elem_1668);
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: 551, function: Function { arguments: [Externref], shim_idx: 552, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
2027
- const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_3793, __wasm_bindgen_func_elem_3795);
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 __wasm_bindgen_func_elem_1668(arg0, arg1) {
2085
- const ret = wasm.__wasm_bindgen_func_elem_1668(arg0, arg1);
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 __wasm_bindgen_func_elem_3795(arg0, arg1, arg2) {
2090
- wasm.__wasm_bindgen_func_elem_3795(arg0, arg1, addHeapObject(arg2));
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 __wasm_bindgen_func_elem_5384(arg0, arg1, arg2, arg3) {
2094
- wasm.__wasm_bindgen_func_elem_5384(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
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 __wasm_bindgen_func_elem_1421: (a: number, b: number) => void;
91
- export const __wasm_bindgen_func_elem_3793: (a: number, b: number) => void;
92
- export const __wasm_bindgen_func_elem_5384: (a: number, b: number, c: number, d: number) => void;
93
- export const __wasm_bindgen_func_elem_3795: (a: number, b: number, c: number) => void;
94
- export const __wasm_bindgen_func_elem_1668: (a: number, b: number) => number;
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@perspective-dev/client",
3
- "version": "4.2.0",
3
+ "version": "4.3.0",
4
4
  "description": "",
5
5
  "repository": {
6
6
  "type": "git",
@@ -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
 
@@ -0,0 +1,3 @@
1
+ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2
+
3
+ export type GroupRollupMode = "rollup" | "flat" | "total";
@@ -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, leaves_only?: 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,