@perspective-dev/client 4.1.0 → 4.2.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.
@@ -30,7 +30,7 @@ export interface VirtualServerHandler {
30
30
  tableSize(tableId: string): number | Promise<number>;
31
31
  tableMakeView(tableId: string, viewId: string, config: ViewConfig): void | Promise<void>;
32
32
  viewDelete(viewId: string): void | Promise<void>;
33
- viewGetData(viewId: string, config: ViewConfig, viewport: ViewWindow, dataSlice: perspective.JsVirtualDataSlice): void | Promise<void>;
33
+ viewGetData(viewId: string, config: ViewConfig, schema: Record<string, ColumnType>, viewport: ViewWindow, dataSlice: perspective.VirtualDataSlice): void | Promise<void>;
34
34
  viewSchema?(viewId: string, config?: ViewConfig): Record<string, ColumnType> | Promise<Record<string, ColumnType>>;
35
35
  viewSize?(viewId: string): number | Promise<number>;
36
36
  tableValidateExpression?(tableId: string, expression: string): ColumnType | Promise<ColumnType>;
@@ -38,10 +38,3 @@ export interface VirtualServerHandler {
38
38
  makeTable?(tableId: string, data: string | Uint8Array): void | Promise<void>;
39
39
  }
40
40
  export declare function createMessageHandler(mod: typeof perspective, handler: VirtualServerHandler): MessagePort;
41
- /**
42
- * Re-export the WASM VirtualServer and VirtualDataSlice classes with better names.
43
- *
44
- * VirtualServer: Handles Perspective protocol messages using your custom handler
45
- * VirtualDataSlice: Used to fill data in viewGetData callbacks
46
- */
47
- export { JsVirtualServer as VirtualServer, JsVirtualDataSlice as VirtualDataSlice, } from "../../dist/wasm/perspective-js.js";
@@ -0,0 +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};
2
+ //# sourceMappingURL=clickhouse.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 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"]
7
+ }
@@ -1,11 +1,25 @@
1
- import type { VirtualDataSlice, VirtualServerHandler } from "@perspective-dev/client";
1
+ /**
2
+ * An implementation of a Perspective Virtual Server for DuckDB.
3
+ *
4
+ * This import is optional, and so must be imported manually from either
5
+ * `@perspective-dev/client/dist/esm/virtual_servers/duckdb.js` or
6
+ * `@perspective-dev/client/src/ts/virtual_servers/duckdb.ts`, it is not
7
+ * exported from the package root `@perspective-dev/client`
8
+ *
9
+ * @module
10
+ */
11
+ import type * as perspective from "@perspective-dev/client";
2
12
  import type { ColumnType } from "@perspective-dev/client/dist/esm/ts-rs/ColumnType.d.ts";
3
13
  import type { ViewConfig } from "@perspective-dev/client/dist/esm/ts-rs/ViewConfig.d.ts";
4
14
  import type { ViewWindow } from "@perspective-dev/client/dist/esm/ts-rs/ViewWindow.d.ts";
5
15
  import type * as duckdb from "@duckdb/duckdb-wasm";
6
- export declare class DuckDBHandler implements VirtualServerHandler {
16
+ /**
17
+ * An implementation of Perspective's Virtual Server for `@duckdb/duckdb-wasm`.
18
+ */
19
+ export declare class DuckDBHandler implements perspective.VirtualServerHandler {
7
20
  private db;
8
- constructor(db: duckdb.AsyncDuckDBConnection);
21
+ private sqlBuilder;
22
+ constructor(db: duckdb.AsyncDuckDBConnection, mod?: typeof perspective);
9
23
  getFeatures(): {
10
24
  group_by: boolean;
11
25
  split_by: boolean;
@@ -28,12 +42,12 @@ export declare class DuckDBHandler implements VirtualServerHandler {
28
42
  datetime: string[];
29
43
  };
30
44
  };
31
- getHostedTables(): Promise<any[]>;
32
- tableSchema(tableId: string): Promise<Record<string, ColumnType>>;
45
+ getHostedTables(): Promise<string[]>;
46
+ tableSchema(tableId: string, config?: ViewConfig): Promise<Record<string, perspective.ColumnType>>;
33
47
  viewColumnSize(viewId: string, config: ViewConfig): Promise<number>;
34
48
  tableSize(tableId: string): Promise<number>;
35
49
  tableMakeView(tableId: string, viewId: string, config: ViewConfig): Promise<void>;
36
- tableValidateExpression(tableId: string, expression: string): Promise<ColumnType>;
50
+ tableValidateExpression(tableId: string, expression: string): Promise<perspective.ColumnType>;
37
51
  viewDelete(viewId: string): Promise<void>;
38
- viewGetData(viewId: string, config: ViewConfig, viewport: ViewWindow, dataSlice: VirtualDataSlice): Promise<void>;
52
+ viewGetData(viewId: string, config: ViewConfig, schema: Record<string, ColumnType>, viewport: ViewWindow, dataSlice: perspective.VirtualDataSlice): Promise<void>;
39
53
  }
@@ -1,12 +1,2 @@
1
- var P=["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"],A=["count","any_value","arbitrary","first","countif","last","string_agg"],I=["==","!=","LIKE","IS DISTINCT FROM","IS NOT DISTINCT FROM",">=","<=",">","<"];function N(o){if(o==="VARCHAR")return"string";if(o==="DOUBLE"||o==="BIGINT"||o==="HUGEINT"||o.startsWith("Decimal"))return"float";if(o.startsWith("Int")||o==="INTEGER")return"integer";if(o==="Utf8")return"string";if(o==="Date32<DAY>")return"date";if(o==="Float64")return"float";if(o==="DATE")return"date";if(o==="BOOLEAN")return"boolean";if(o==="TIMESTAMP")return"datetime";throw new Error(`Unknown type '${o}'`)}function V(o,r){if(o==null||!(o instanceof Uint32Array||o instanceof Int32Array))return o;let i=BigInt(0);for(let u=0;u<o.length;u++)i|=BigInt(o[u])<<BigInt(u*32);let n=BigInt(2)**BigInt(127);i>=n&&(i-=BigInt(2)**BigInt(128));let a=r.match(/Decimal\[\d+e(\d+)\]/),s=a?parseInt(a[1]):0;return s>0?Number(i)/Math.pow(10,s):Number(i)}async function m(o,r,i={}){r=r.replace(/\s+/g," ").trim();try{let n=await o.query(r);return i.columns?{rows:n.toArray(),columns:n.schema.fields.map(a=>a.name),dtypes:n.schema.fields.map(a=>a.type.toString())}:n.toArray()}catch(n){throw console.error("Query error:",n),console.error("Query:",r),n}}var G=class{db;constructor(r){this.db=r}getFeatures(){return{group_by:!0,split_by:!0,sort:!0,expressions:!0,filter_ops:{integer:I,float:I,string:I,boolean:I,date:I,datetime:I},aggregates:{integer:P,float:P,string:A,boolean:A,date:A,datetime:A}}}async getHostedTables(){return(await m(this.db,"SHOW ALL TABLES")).map(i=>i.toJSON().name)}async tableSchema(r){let i=`DESCRIBE ${r}`,n=await m(this.db,i),a={};for(let s of n){let u=s.toJSON(),y=u.column_name;if(!y.startsWith("__")||!y.endsWith("__")){let h=y.split("_").slice(-1)[0];a[h]=N(u.column_type)}}return a}async viewColumnSize(r,i){let n=`SELECT COUNT(*) FROM (DESCRIBE ${r})`,a=await m(this.db,n),s=i.group_by?.length||0;return Number(Object.values(a[0].toJSON())[0])-(s===0?0:s+(i.split_by?.length===0?1:0))}async tableSize(r){let i=`SELECT COUNT(*) FROM ${r}`,n=await m(this.db,i);return Number(n[0].toJSON()["count_star()"])}async tableMakeView(r,i,n){let a=n.columns||[],s=n.group_by||[],u=n.split_by||[],y=n.aggregates||{},h=n.sort||[],E=n.expressions||{},O=n.filter||[],_=t=>E[t]||`"${t}"`,T=t=>y[t]||null,C=()=>{let t=[];if(s.length>0){for(let c of a)if(c!==null){let l=T(c)||"any_value";t.push(`${l}(${_(c)}) as "${c}"`)}if(u.length===0){for(let l=0;l<s.length;l++)t.push(`${_(s[l])} as __ROW_PATH_${l}__`);let c=s.map(_).join(", ");t.push(`GROUPING_ID(${c}) AS __GROUPING_ID__`)}}else if(a.length>0)for(let c of a)c!==null&&t.push(`${_(c)} as "${c.replace(/"/g,'""')}"`);return t},f=[],S=[],$=[];if(s.length>0)for(let t=0;t<s.length;t++){let c=s.slice(0,t+1).map(_).join(", ");u.length===0&&f.push(`GROUPING_ID(${c}) DESC`);for(let[l,p]of h)if(p!=="none"){let e=T(l)||"any_value";t>=s.length-1?f.push(`${e}(${_(l)}) ${p}`):f.push(`first(${e}(${_(l)})) OVER __WINDOW_${t}__ ${p}`)}f.push(`__ROW_PATH_${t}__ ASC`)}else for(let[t,c]of h)c&&f.push(`${_(t)} ${c}`);if(h.length>0&&s.length>1)for(let t=0;t<s.length-1;t++){let c=Array.from({length:t+1},(e,d)=>`__ROW_PATH_${d}__`).join(", "),l=s.slice(0,t+1).map(_).join(", "),p=s.map(_).join(", ");S.push(`__WINDOW_${t}__ AS (PARTITION BY GROUPING_ID(${l}), ${c} ORDER BY ${p})`)}for(let[t,c,l]of O)if(l!=null){let p=typeof l=="string"?`'${l}'`:String(l);$.push(`${_(t)} ${c} ${p}`)}let g;if(u.length>0?g=`SELECT * FROM ${r}`:g=`SELECT ${C().join(", ")} FROM ${r}`,$.length>0&&(g=`${g} WHERE ${$.join(" AND ")}`),u.length>0){let t=s.map(_).join(", "),c=s.map((e,d)=>`${_(e)} AS __ROW_PATH_${d}__`).join(", "),l=u.map(e=>`"${e}"`).join(", "),p=C().join(", ");g=`
2
- SELECT * EXCLUDE (${t}), ${c} FROM (
3
- PIVOT (${g})
4
- ON ${l}
5
- USING ${p}
6
- GROUP BY ${t}
7
- )
8
- `}else if(s.length>0){let t=s.map(_).join(", ");g=`${g} GROUP BY ROLLUP(${t})`}S.length>0&&(g=`${g} WINDOW ${S.join(", ")}`),f.length>0&&(g=`${g} ORDER BY ${f.join(", ")}`),g=`CREATE TABLE ${i} AS (${g})`,await m(this.db,g)}async tableValidateExpression(r,i){let n=`DESCRIBE (select ${i} from ${r})`,a=await m(this.db,n);return N(a[0].toJSON().column_type)}async viewDelete(r){let i=`DROP TABLE IF EXISTS ${r}`;await m(this.db,i)}async viewGetData(r,i,n,a){let s=i.group_by||[],u=i.split_by||[],y=n.start_col,h=n.end_col,E=n.start_row||0,O=n.end_row,_="";O!=null&&(_=`LIMIT ${O-E} OFFSET ${E}`);let T=`DESCRIBE ${r}`,C=await m(this.db,T),f=new Map;for(let e of C){let d=e.toJSON();f.set(d.column_name,d.column_type)}let S=Array.from(f.entries()).filter(([e])=>!e.startsWith("__")).slice(y,h),$=[];if(s.length>0){u.length===0&&$.push("__GROUPING_ID__");for(let e=0;e<s.length;e++)$.push(`__ROW_PATH_${e}__`)}let t=`
9
- SELECT ${[...$.map(e=>`"${e}"`),...S.map(([e])=>`"${e}"`)].join(", ")}
10
- FROM ${r} ${_}
11
- `,{rows:c,columns:l,dtypes:p}=await m(this.db,t,{columns:!0});for(let e=0;e<l.length;e++){let d=l[e];if(e===0&&s.length>0&&u.length===0)continue;let R=null,D=null,B=d.match(/__ROW_PATH_(\d+)__/);B&&(R=parseInt(B[1]),D=2**(s.length-R)-1);let L=N(p[e]),U=p[e].startsWith("Decimal"),x=R!==null?"__ROW_PATH__":d.replace(/_/g,"|");for(let w=0;w<c.length;w++){let W=c[w].toArray();if(u.length>0||D===null||W[0]<D){let b=W[e];U&&(b=V(b,p[e])),typeof b=="bigint"&&(b=Number(b)),a.setCol(L,x,w,b,R)}}}}};export{G as DuckDBHandler};
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};
12
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\nimport type {\n VirtualDataSlice,\n VirtualServerHandler,\n} 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\") return \"string\";\n if (name === \"DOUBLE\" || name === \"BIGINT\" || name === \"HUGEINT\")\n return \"float\";\n if (name.startsWith(\"Decimal\")) return \"float\";\n if (name.startsWith(\"Int\")) return \"integer\";\n if (name === \"INTEGER\") return \"integer\";\n if (name === \"Utf8\") return \"string\";\n if (name === \"Date32<DAY>\") return \"date\";\n if (name === \"Float64\") return \"float\";\n if (name === \"DATE\") return \"date\";\n if (name === \"BOOLEAN\") return \"boolean\";\n if (name === \"TIMESTAMP\") return \"datetime\";\n throw new Error(`Unknown type '${name}'`);\n}\n\nfunction convertDecimalToNumber(value: any, dtypeString: string) {\n if (\n value === null ||\n value === undefined ||\n !(value instanceof Uint32Array || value instanceof Int32Array)\n ) {\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 maxInt128 = BigInt(2) ** BigInt(127);\n if (bigIntValue >= maxInt128) {\n bigIntValue -= BigInt(2) ** BigInt(128);\n }\n\n const scaleMatch = dtypeString.match(/Decimal\\[\\d+e(\\d+)\\]/);\n const scale = scaleMatch ? parseInt(scaleMatch[1]) : 0;\n\n if (scale > 0) {\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: boolean },\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 // console.log(\"Query:\", query);\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\nexport class DuckDBHandler implements VirtualServerHandler {\n private db: duckdb.AsyncDuckDBConnection;\n\n constructor(db: duckdb.AsyncDuckDBConnection) {\n this.db = db;\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 results = await runQuery(this.db, \"SHOW ALL TABLES\");\n return results.map((row) => row.toJSON().name);\n }\n\n async tableSchema(tableId: string) {\n const query = `DESCRIBE ${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(\"__\") || !colName.endsWith(\"__\")) {\n const cleanName = colName.split(\"_\").slice(-1)[0] as string;\n schema[cleanName] = duckdbTypeToPsp(res.column_type);\n }\n }\n\n return schema;\n }\n\n async viewColumnSize(viewId: string, config: ViewConfig) {\n const query = `SELECT COUNT(*) FROM (DESCRIBE ${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 = `SELECT COUNT(*) FROM ${tableId}`;\n const results = await runQuery(this.db, query);\n return Number(results[0].toJSON()[\"count_star()\"]);\n }\n\n // async viewSchema(viewId: string, config: ViewConfig) {\n // return this.tableSchema(viewId);\n // }\n\n // async viewSize(viewId: string) {\n // return this.tableSize(viewId);\n // }\n\n async tableMakeView(tableId: string, viewId: string, config: ViewConfig) {\n const columns = config.columns || [];\n const group_by = config.group_by || [];\n const split_by = config.split_by || [];\n const aggregates = config.aggregates || {};\n const sort = config.sort || [];\n const expressions = config.expressions || {};\n const filter = config.filter || [];\n\n const colName = (col: string) => {\n const expr = expressions[col];\n return expr || `\"${col}\"`;\n };\n\n const getAggregate = (col: string) => aggregates[col] || null;\n\n const generateSelectClauses = () => {\n const clauses = [];\n if (group_by.length > 0) {\n for (const col of columns) {\n if (col !== null) {\n // TODO texodus\n const agg = getAggregate(col) || \"any_value\";\n clauses.push(`${agg}(${colName(col)}) as \"${col}\"`);\n }\n }\n\n if (split_by.length === 0) {\n for (let idx = 0; idx < group_by.length; idx++) {\n clauses.push(\n `${colName(group_by[idx])} as __ROW_PATH_${idx}__`,\n );\n }\n\n const groups = group_by.map(colName).join(\", \");\n clauses.push(`GROUPING_ID(${groups}) AS __GROUPING_ID__`);\n }\n } else if (columns.length > 0) {\n for (const col of columns) {\n if (col !== null) {\n // TODO texodus\n clauses.push(\n `${colName(col)} as \"${col.replace(/\"/g, '\"\"')}\"`,\n );\n }\n }\n }\n\n return clauses;\n };\n\n const orderByClauses = [];\n const windowClauses = [];\n const whereClauses = [];\n\n if (group_by.length > 0) {\n for (let gidx = 0; gidx < group_by.length; gidx++) {\n const groups = group_by\n .slice(0, gidx + 1)\n .map(colName)\n .join(\", \");\n if (split_by.length === 0) {\n orderByClauses.push(`GROUPING_ID(${groups}) DESC`);\n }\n\n for (const [sort_col, sort_dir] of sort) {\n if (sort_dir !== \"none\") {\n const agg = getAggregate(sort_col) || \"any_value\";\n if (gidx >= group_by.length - 1) {\n orderByClauses.push(\n `${agg}(${colName(sort_col)}) ${sort_dir}`,\n );\n } else {\n orderByClauses.push(\n `first(${agg}(${colName(sort_col)})) OVER __WINDOW_${gidx}__ ${sort_dir}`,\n );\n }\n }\n }\n\n orderByClauses.push(`__ROW_PATH_${gidx}__ ASC`);\n }\n } else {\n for (const [sort_col, sort_dir] of sort) {\n if (sort_dir) {\n orderByClauses.push(`${colName(sort_col)} ${sort_dir}`);\n }\n }\n }\n\n if (sort.length > 0 && group_by.length > 1) {\n for (let gidx = 0; gidx < group_by.length - 1; gidx++) {\n const partition = Array.from(\n { length: gidx + 1 },\n (_, i) => `__ROW_PATH_${i}__`,\n ).join(\", \");\n const sub_groups = group_by\n .slice(0, gidx + 1)\n .map(colName)\n .join(\", \");\n const groups = group_by.map(colName).join(\", \");\n windowClauses.push(\n `__WINDOW_${gidx}__ AS (PARTITION BY GROUPING_ID(${sub_groups}), ${partition} ORDER BY ${groups})`,\n );\n }\n }\n\n for (const [name, op, value] of filter) {\n if (value !== null && value !== undefined) {\n const term_lit =\n typeof value === \"string\" ? `'${value}'` : String(value);\n whereClauses.push(`${colName(name)} ${op} ${term_lit}`);\n }\n }\n\n let query;\n if (split_by.length > 0) {\n query = `SELECT * FROM ${tableId}`;\n } else {\n const selectClauses = generateSelectClauses();\n query = `SELECT ${selectClauses.join(\", \")} FROM ${tableId}`;\n }\n\n if (whereClauses.length > 0) {\n query = `${query} WHERE ${whereClauses.join(\" AND \")}`;\n }\n\n if (split_by.length > 0) {\n const groups = group_by.map(colName).join(\", \");\n const group_aliases = group_by\n .map((x, i) => `${colName(x)} AS __ROW_PATH_${i}__`)\n .join(\", \");\n const pivotOn = split_by.map((c) => `\"${c}\"`).join(\", \");\n const pivotUsing = generateSelectClauses().join(\", \");\n\n query = `\n SELECT * EXCLUDE (${groups}), ${group_aliases} FROM (\n PIVOT (${query})\n ON ${pivotOn}\n USING ${pivotUsing}\n GROUP BY ${groups}\n )\n `;\n } else if (group_by.length > 0) {\n const groups = group_by.map(colName).join(\", \");\n query = `${query} GROUP BY ROLLUP(${groups})`;\n }\n\n if (windowClauses.length > 0) {\n query = `${query} WINDOW ${windowClauses.join(\", \")}`;\n }\n\n if (orderByClauses.length > 0) {\n query = `${query} ORDER BY ${orderByClauses.join(\", \")}`;\n }\n\n query = `CREATE TABLE ${viewId} AS (${query})`;\n await runQuery(this.db, query);\n }\n\n async tableValidateExpression(tableId: string, expression: string) {\n const query = `DESCRIBE (select ${expression} from ${tableId})`;\n const results = await runQuery(this.db, query);\n return duckdbTypeToPsp(results[0].toJSON()[\"column_type\"]);\n }\n\n async viewDelete(viewId: string) {\n const query = `DROP TABLE IF EXISTS ${viewId}`;\n await runQuery(this.db, query);\n }\n\n async viewGetData(\n viewId: string,\n config: ViewConfig,\n viewport: ViewWindow,\n dataSlice: VirtualDataSlice,\n ) {\n const group_by = config.group_by || [];\n const split_by = config.split_by || [];\n const start_col = viewport.start_col;\n const end_col = viewport.end_col;\n const start_row = viewport.start_row || 0;\n const end_row = viewport.end_row;\n\n let limit = \"\";\n if (end_row !== null && end_row !== undefined) {\n limit = `LIMIT ${end_row - start_row} OFFSET ${start_row}`;\n }\n\n const schemaQuery = `DESCRIBE ${viewId}`;\n const schemaResults = await runQuery(this.db, schemaQuery);\n const columnTypes = new Map();\n for (const result of schemaResults) {\n const res = result.toJSON();\n columnTypes.set(res.column_name, res.column_type);\n }\n\n const dataColumns = Array.from(columnTypes.entries())\n .filter(([colName]) => !colName.startsWith(\"__\"))\n .slice(start_col, end_col);\n\n const groupByColsList = [];\n if (group_by.length > 0) {\n if (split_by.length === 0) {\n groupByColsList.push(\"__GROUPING_ID__\");\n }\n for (let idx = 0; idx < group_by.length; idx++) {\n groupByColsList.push(`__ROW_PATH_${idx}__`);\n }\n }\n\n const allColumns = [\n ...groupByColsList.map((col) => `\"${col}\"`),\n ...dataColumns.map(([colName]) => `\"${colName}\"`),\n ];\n\n const query = `\n SELECT ${allColumns.join(\", \")}\n FROM ${viewId} ${limit}\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 const col = columns[cidx];\n\n if (cidx === 0 && group_by.length > 0 && split_by.length === 0) {\n continue;\n }\n\n let group_by_index = null;\n let max_grouping_id = null;\n const row_path_match = col.match(/__ROW_PATH_(\\d+)__/);\n if (row_path_match) {\n group_by_index = parseInt(row_path_match[1]);\n max_grouping_id = 2 ** (group_by.length - group_by_index) - 1;\n }\n\n const dtype = duckdbTypeToPsp(dtypes[cidx]);\n const isDecimal = dtypes[cidx].startsWith(\"Decimal\");\n const colName =\n group_by_index !== null\n ? \"__ROW_PATH__\"\n : col.replace(/_/g, \"|\");\n\n for (let ridx = 0; ridx < rows.length; ridx++) {\n const row = rows[ridx];\n const rowArray = row.toArray();\n const shouldSet =\n split_by.length > 0 ||\n max_grouping_id === null ||\n rowArray[0] < max_grouping_id;\n\n if (shouldSet) {\n let value = rowArray[cidx];\n\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(\n dtype,\n colName,\n ridx,\n value,\n group_by_index,\n );\n }\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", "maxInt128", "scaleMatch", "scale", "runQuery", "db", "query", "options", "result", "f", "error", "DuckDBHandler", "row", "tableId", "results", "schema", "res", "colName", "cleanName", "viewId", "config", "gs", "columns", "group_by", "split_by", "aggregates", "sort", "expressions", "filter", "col", "getAggregate", "generateSelectClauses", "clauses", "agg", "idx", "groups", "orderByClauses", "windowClauses", "whereClauses", "gidx", "sort_col", "sort_dir", "partition", "_", "sub_groups", "op", "term_lit", "group_aliases", "x", "pivotOn", "c", "pivotUsing", "expression", "viewport", "dataSlice", "start_col", "end_col", "start_row", "end_row", "limit", "schemaQuery", "schemaResults", "columnTypes", "dataColumns", "groupByColsList", "rows", "dtypes", "cidx", "group_by_index", "max_grouping_id", "row_path_match", "dtype", "isDecimal", "ridx", "rowArray"]
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"]
7
7
  }