@perspective-dev/client 4.3.0 → 4.4.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.
Files changed (35) hide show
  1. package/dist/cdn/perspective.js +2 -2
  2. package/dist/cdn/perspective.js.map +3 -3
  3. package/dist/esm/perspective.inline.js +2 -2
  4. package/dist/esm/perspective.inline.js.map +3 -3
  5. package/dist/esm/perspective.js +2 -2
  6. package/dist/esm/perspective.js.map +3 -3
  7. package/dist/esm/perspective.node.d.ts +10 -0
  8. package/dist/esm/perspective.node.js +95 -9
  9. package/dist/esm/perspective.node.js.map +2 -2
  10. package/dist/esm/ts-rs/JoinOptions.d.ts +9 -0
  11. package/dist/esm/ts-rs/JoinType.d.ts +1 -0
  12. package/dist/esm/virtual_server.d.ts +7 -0
  13. package/dist/esm/virtual_servers/clickhouse.js +1 -1
  14. package/dist/esm/virtual_servers/clickhouse.js.map +3 -3
  15. package/dist/esm/virtual_servers/duckdb.d.ts +4 -0
  16. package/dist/esm/virtual_servers/duckdb.js +1 -1
  17. package/dist/esm/virtual_servers/duckdb.js.map +3 -3
  18. package/dist/wasm/perspective-js.d.ts +41 -5
  19. package/dist/wasm/perspective-js.js +89 -10
  20. package/dist/wasm/perspective-js.wasm +0 -0
  21. package/dist/wasm/perspective-js.wasm.d.ts +8 -5
  22. package/package.json +5 -5
  23. package/src/rust/client.rs +70 -1
  24. package/src/rust/generic_sql_model.rs +16 -0
  25. package/src/rust/lib.rs +4 -0
  26. package/src/rust/utils/errors.rs +4 -0
  27. package/src/rust/utils/futures.rs +4 -0
  28. package/src/rust/view.rs +13 -4
  29. package/src/rust/virtual_server.rs +68 -1
  30. package/src/ts/perspective.node.ts +18 -0
  31. package/src/ts/ts-rs/JoinOptions.ts +7 -0
  32. package/src/ts/ts-rs/JoinType.ts +3 -0
  33. package/src/ts/virtual_server.ts +5 -0
  34. package/src/ts/virtual_servers/clickhouse.ts +2 -13
  35. package/src/ts/virtual_servers/duckdb.ts +18 -64
@@ -0,0 +1,9 @@
1
+ import type { JoinType } from "./JoinType.js";
2
+ /**
3
+ * Options for [`Client::join`].
4
+ */
5
+ export type JoinOptions = {
6
+ join_type?: JoinType;
7
+ name?: string;
8
+ right_on?: string;
9
+ };
@@ -0,0 +1 @@
1
+ export type JoinType = "inner" | "left" | "outer";
@@ -34,6 +34,13 @@ export interface VirtualServerHandler {
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>;
37
+ viewGetMinMax?(viewId: string, columnName: string, config: ViewConfig): {
38
+ min: any;
39
+ max: any;
40
+ } | Promise<{
41
+ min: any;
42
+ max: any;
43
+ }>;
37
44
  getFeatures?(): ServerFeatures | Promise<ServerFeatures>;
38
45
  makeTable?(tableId: string, data: string | Uint8Array): void | Promise<void>;
39
46
  }
@@ -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(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};
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"],g=["count","any_value","arbitrary","first","countif","last","string_agg"],p=["==","!=","LIKE","IS DISTINCT FROM","IS NOT DISTINCT FROM",">=","<=",">","<"];function f(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 S(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 b=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}},I=new b;async function c(i,t,e={}){t=t.replace(/\s+/g," ").trim();let s=await I.acquire();try{let r=await i.query({query:t});if(!e.execute){let{data:o,meta:a}=await r.json();return e.columns?{rows:o,columns:a.map(l=>l.name),dtypes:a.map(l=>l.type)}:o}}catch(r){throw console.error("Query error:",r),console.error("Query:",t),r}finally{s()}}var C=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:v,float:v,string:g,boolean:g,date:g,datetime:g}}}async getHostedTables(){return(await c(this.db,"SHOW TABLES")).map(s=>`${s.name}`)}async tableSchema(t,e){let s=this.sqlBuilder.tableSchema(t),r=await c(this.db,s),o={};for(let a of r){let l=a.name;l.startsWith("__")||(o[l]=f(a.type))}return o}async viewColumnSize(t,e){let s=`SELECT COUNT() FROM system.columns WHERE table = '${t}'`,r=await c(this.db,s),o=e.group_by?.length||0,a=Number(r[0]["COUNT()"]);return console.log(a),a-(o===0?0:o+(e.split_by?.length===0?1:0))}async tableSize(t){let e=this.sqlBuilder.tableSize(t),s=await c(this.db,e);return Number(s[0]["COUNT()"])}async tableMakeView(t,e,s){let r=this.sqlBuilder.tableMakeView(t,e,s);await c(this.db,r,{execute:!0})}async tableValidateExpression(t,e){let s=this.sqlBuilder.tableValidateExpression(t,e),r=await c(this.db,s);return f(r[0].type)}async viewDelete(t){let e=this.sqlBuilder.viewDelete(t);await c(this.db,e,{execute:!0})}async viewGetData(t,e,s,r,o){let a=this.sqlBuilder.viewGetData(t,e,r,s),{rows:l,columns:w,dtypes:y}=await c(this.db,a,{columns:!0});for(let u=0;u<w.length;u++){let h=w[u],d=f(y[u]),T=y[u].startsWith("Decimal");for(let m=0;m<l.length;m++){let _=l[m],k=_.__GROUPING_ID__,n=_[h];T&&(n=S(n,y[u])),typeof n=="bigint"&&(n=Number(n)),d==="datetime"&&typeof n=="string"&&(n=+new Date(n)),d==="string"&&typeof n!="string"&&(n=`${n}`),o.setCol(d,h,m,n,k)}}}};export{C 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 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"]
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 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 const col = columns[cidx];\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[col];\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", "rows", "columns", "dtypes", "cidx", "col", "dtype", "isDecimal", "ridx", "grouping_id"]
7
7
  }
@@ -50,5 +50,9 @@ export declare class DuckDBHandler implements perspective.VirtualServerHandler {
50
50
  tableMakeView(tableId: string, viewId: string, config: ViewConfig): Promise<void>;
51
51
  tableValidateExpression(tableId: string, expression: string): Promise<perspective.ColumnType>;
52
52
  viewDelete(viewId: string): Promise<void>;
53
+ viewGetMinMax(viewId: string, columnName: string, config: ViewConfig): Promise<{
54
+ min: {} | null;
55
+ max: {} | null;
56
+ }>;
53
57
  viewGetData(viewId: string, config: ViewConfig, schema: Record<string, ColumnType>, viewport: ViewWindow, dataSlice: perspective.VirtualDataSlice): Promise<void>;
54
58
  }
@@ -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"],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};
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"],d=["count","any_value","arbitrary","first","countif","last","string_agg"],l=["==","!=","LIKE","IS DISTINCT FROM","IS NOT DISTINCT FROM",">=","<=",">","<"];function g(r){return r=r.toLowerCase(),r==="varchar"||r=="utf8"?"string":r==="double"||r==="bigint"||r==="hugeint"||r==="float64"||r.startsWith("decimal")?"float":r.startsWith("int")?"integer":r.startsWith("date")?"date":r.startsWith("bool")?"boolean":r.startsWith("timestamp")?"datetime":(r.startsWith("json")||r.startsWith("struct")||console.warn(`Unknown type '${r}'`),"string")}async function u(r,e,s={}){e=e.replace(/\s+/g," ").trim();try{let t=await r.query(e);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:",e),t}}var y=class{db;sqlBuilder;constructor(e,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=e,this.sqlBuilder=new s.GenericSQLVirtualServerModel}getFeatures(){return{group_by:!0,split_by:!0,sort:!0,expressions:!0,group_rollup_mode:["rollup","flat","total"],filter_ops:{integer:l,float:l,string:l,boolean:l,date:l,datetime:l},aggregates:{integer:p,float:p,string:d,boolean:d,date:d,datetime:d}}}async getHostedTables(){let e=this.sqlBuilder.getHostedTables();return(await u(this.db,e)).map(t=>{let i=t.toJSON();return`${i.database||"memory"}.${i.name}`})}async tableSchema(e,s){let t=this.sqlBuilder.tableSchema(e),i=await u(this.db,t),c={};for(let o of i){let n=o.toJSON(),a=n.column_name;a.startsWith("__")||(c[a]=g(n.column_type))}return c}async viewColumnSize(e,s){let t=this.sqlBuilder.viewColumnSize(e),i=await u(this.db,t),c=Number(Object.values(i[0].toJSON())[0]),o=s.group_by?.length||0,n=s.group_rollup_mode==="flat";return c-(o===0?0:n?o:o+1)}async tableSize(e){let s=this.sqlBuilder.tableSize(e),t=await u(this.db,s);return Number(t[0].toJSON()["count_star()"])}async tableMakeView(e,s,t){let i=this.sqlBuilder.tableMakeView(e,s,t);await u(this.db,i)}async tableValidateExpression(e,s){let t=this.sqlBuilder.tableValidateExpression(e,s),i=await u(this.db,t);return g(i[0].toJSON().column_type)}async viewDelete(e){let s=this.sqlBuilder.viewDelete(e);await u(this.db,s)}async viewGetMinMax(e,s,t){let i=this.sqlBuilder.viewGetMinMax(e,s,t),o=(await u(this.db,i))[0].toJSON(),[n,a]=Object.values(o);return typeof n=="bigint"&&(n=Number(n)),typeof a=="bigint"&&(a=Number(a)),{min:n??null,max:a??null}}async viewGetData(e,s,t,i,c){let o=this.sqlBuilder.viewGetData(e,s,i,t),n=await this.db.useUnsafe((a,m)=>a.runQuery(m,o));c.fromArrowIpc(n)}};export{y 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 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"]
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\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 viewGetMinMax(\n viewId: string,\n columnName: string,\n config: ViewConfig,\n ) {\n const query = this.sqlBuilder.viewGetMinMax(viewId, columnName, config);\n const results = await runQuery(this.db, query);\n const row = results[0].toJSON();\n let [min, max] = Object.values(row);\n if (typeof min === \"bigint\") min = Number(min);\n if (typeof max === \"bigint\") max = Number(max);\n return { min: min ?? null, max: max ?? null };\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 query = this.sqlBuilder.viewGetData(\n viewId,\n config,\n viewport,\n schema,\n );\n\n const ipc = await this.db.useUnsafe((bindings, conn) =>\n bindings.runQuery(conn, query),\n );\n\n dataSlice.fromArrowIpc(ipc);\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["NUMBER_AGGS", "STRING_AGGS", "FILTER_OPS", "duckdbTypeToPsp", "name", "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", "columnName", "min", "max", "viewport", "dataSlice", "ipc", "bindings", "conn"]
7
7
  }
@@ -15,11 +15,15 @@ export type * from "../../src/ts/ts-rs/SystemInfo.d.ts";
15
15
  export type * from "../../src/ts/ts-rs/SortDir.d.ts";
16
16
  export type * from "../../src/ts/ts-rs/Filter.d.ts";
17
17
  export type * from "../../src/ts/ts-rs/ViewConfig.d.ts";
18
+ export type * from "../../src/ts/ts-rs/JoinOptions.ts";
19
+ export type * from "../../src/ts/ts-rs/JoinType.ts";
18
20
 
19
21
  import type {ColumnWindow} from "../../src/ts/ts-rs/ColumnWindow.d.ts";
20
22
  import type {ColumnType} from "../../src/ts/ts-rs/ColumnType.d.ts";
21
23
  import type {ViewWindow} from "../../src/ts/ts-rs/ViewWindow.d.ts";
22
24
  import type {TableInitOptions} from "../../src/ts/ts-rs/TableInitOptions.d.ts";
25
+ import type {JoinOptions} from "../../src/ts/ts-rs/JoinOptions.ts";
26
+ import type {JoinType} from "../../src/ts/ts-rs/JoinType.ts";
23
27
  import type {ViewConfigUpdate} from "../../src/ts/ts-rs/ViewConfigUpdate.d.ts";
24
28
  import type * as on_update_args from "../../src/ts/ts-rs/ViewOnUpdateResp.d.ts";
25
29
  import type {OnUpdateOptions} from "../../src/ts/ts-rs/OnUpdateOptions.d.ts";
@@ -88,6 +92,30 @@ export class Client {
88
92
  get_hosted_table_names(): Promise<string[]>;
89
93
  handle_error(error: string, reconnect?: Function | null): Promise<void>;
90
94
  handle_response(value: any): Promise<void>;
95
+ /**
96
+ * Creates a new read-only [`Table`] by performing an INNER JOIN on two
97
+ * source tables. The resulting table is reactive: when either source
98
+ * table is updated, the join is automatically recomputed.
99
+ *
100
+ * # Arguments
101
+ *
102
+ * - `left` - The left source table (a [`Table`] instance or a table name
103
+ * string).
104
+ * - `right` - The right source table (a [`Table`] instance or a table name
105
+ * string).
106
+ * - `on` - The column name to join on. Must exist in both tables with the
107
+ * same type.
108
+ * - `options` - Optional join configuration: `{ join_type?: "inner" |
109
+ * "left" | "outer", name?: string }`.
110
+ *
111
+ * # JavaScript Examples
112
+ *
113
+ * ```javascript
114
+ * const joined = await client.join(orders_table, products_table, "Product ID", { join_type: "left" });
115
+ * const joined = await client.join("orders", "products", "Product ID", { join_type: "left" });
116
+ * ```
117
+ */
118
+ join(left: any, right: any, on: string, options?: JoinOptions | null): Promise<Table>;
91
119
  constructor(send_request: Function, close?: Function | null);
92
120
  new_proxy_session(on_response: Function): ProxySession;
93
121
  on_error(callback: Function): Promise<number>;
@@ -262,6 +290,10 @@ export class GenericSQLVirtualServerModel {
262
290
  * Returns the SQL query to fetch data from a view with the given viewport.
263
291
  */
264
292
  viewGetData(view_id: string, config: any, viewport: any, schema: any): string;
293
+ /**
294
+ * Returns the SQL query to get the min and max values of a column.
295
+ */
296
+ viewGetMinMax(view_id: string, column_name: string, config: any): string;
265
297
  /**
266
298
  * Returns the SQL query to describe a view's schema.
267
299
  */
@@ -684,6 +716,7 @@ export class View {
684
716
  export class VirtualDataSlice {
685
717
  free(): void;
686
718
  [Symbol.dispose](): void;
719
+ fromArrowIpc(ipc: Uint8Array): void;
687
720
  constructor(config: ViewConfigUpdate);
688
721
  setBooleanCol(name: string, index: number, val: any, group_by_index?: number | null): void;
689
722
  setCol(dtype: string, name: string, index: number, val: any, group_by_index?: number | null): void;
@@ -717,6 +750,7 @@ export interface InitOutput {
717
750
  readonly client_get_hosted_table_names: (a: number) => number;
718
751
  readonly client_handle_error: (a: number, b: number, c: number, d: number) => number;
719
752
  readonly client_handle_response: (a: number, b: number) => number;
753
+ readonly client_join: (a: number, b: number, c: number, d: number, e: number, f: number) => number;
720
754
  readonly client_new: (a: number, b: number, c: number) => void;
721
755
  readonly client_new_proxy_session: (a: number, b: number) => number;
722
756
  readonly client_on_error: (a: number, b: number) => number;
@@ -735,6 +769,7 @@ export interface InitOutput {
735
769
  readonly genericsqlvirtualservermodel_viewColumnSize: (a: number, b: number, c: number, d: number) => void;
736
770
  readonly genericsqlvirtualservermodel_viewDelete: (a: number, b: number, c: number, d: number) => void;
737
771
  readonly genericsqlvirtualservermodel_viewGetData: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
772
+ readonly genericsqlvirtualservermodel_viewGetMinMax: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
738
773
  readonly genericsqlvirtualservermodel_viewSchema: (a: number, b: number, c: number, d: number) => void;
739
774
  readonly genericsqlvirtualservermodel_viewSize: (a: number, b: number, c: number, d: number) => void;
740
775
  readonly init: () => void;
@@ -783,6 +818,7 @@ export interface InitOutput {
783
818
  readonly view_to_json: (a: number, b: number) => number;
784
819
  readonly view_to_json_string: (a: number, b: number) => number;
785
820
  readonly view_to_ndjson: (a: number, b: number) => number;
821
+ readonly virtualdataslice_fromArrowIpc: (a: number, b: number, c: number) => void;
786
822
  readonly virtualdataslice_new: (a: number) => number;
787
823
  readonly virtualdataslice_setBooleanCol: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
788
824
  readonly virtualdataslice_setCol: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => void;
@@ -792,11 +828,11 @@ export interface InitOutput {
792
828
  readonly virtualdataslice_setStringCol: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
793
829
  readonly virtualserver_handleRequest: (a: number, b: number, c: number) => number;
794
830
  readonly virtualserver_new: (a: number, b: number) => void;
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;
831
+ readonly __wasm_bindgen_func_elem_838: (a: number, b: number) => void;
832
+ readonly __wasm_bindgen_func_elem_3910: (a: number, b: number) => void;
833
+ readonly __wasm_bindgen_func_elem_10782: (a: number, b: number, c: number, d: number) => void;
834
+ readonly __wasm_bindgen_func_elem_3927: (a: number, b: number, c: number) => void;
835
+ readonly __wasm_bindgen_func_elem_1727: (a: number, b: number) => number;
800
836
  readonly __wbindgen_export: (a: number, b: number) => number;
801
837
  readonly __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
802
838
  readonly __wbindgen_export3: (a: number) => void;
@@ -110,6 +110,40 @@ export class Client {
110
110
  const ret = wasm.client_handle_response(this.__wbg_ptr, addHeapObject(value));
111
111
  return takeObject(ret);
112
112
  }
113
+ /**
114
+ * Creates a new read-only [`Table`] by performing an INNER JOIN on two
115
+ * source tables. The resulting table is reactive: when either source
116
+ * table is updated, the join is automatically recomputed.
117
+ *
118
+ * # Arguments
119
+ *
120
+ * - `left` - The left source table (a [`Table`] instance or a table name
121
+ * string).
122
+ * - `right` - The right source table (a [`Table`] instance or a table name
123
+ * string).
124
+ * - `on` - The column name to join on. Must exist in both tables with the
125
+ * same type.
126
+ * - `options` - Optional join configuration: `{ join_type?: "inner" |
127
+ * "left" | "outer", name?: string }`.
128
+ *
129
+ * # JavaScript Examples
130
+ *
131
+ * ```javascript
132
+ * const joined = await client.join(orders_table, products_table, "Product ID", { join_type: "left" });
133
+ * const joined = await client.join("orders", "products", "Product ID", { join_type: "left" });
134
+ * ```
135
+ * @param {any} left
136
+ * @param {any} right
137
+ * @param {string} on
138
+ * @param {JoinOptions | null} [options]
139
+ * @returns {Promise<Table>}
140
+ */
141
+ join(left, right, on, options) {
142
+ const ptr0 = passStringToWasm0(on, wasm.__wbindgen_export, wasm.__wbindgen_export2);
143
+ const len0 = WASM_VECTOR_LEN;
144
+ const ret = wasm.client_join(this.__wbg_ptr, addHeapObject(left), addHeapObject(right), ptr0, len0, isLikeNone(options) ? 0 : addHeapObject(options));
145
+ return takeObject(ret);
146
+ }
113
147
  /**
114
148
  * @param {Function} send_request
115
149
  * @param {Function | null} [close]
@@ -565,6 +599,35 @@ export class GenericSQLVirtualServerModel {
565
599
  wasm.__wbindgen_add_to_stack_pointer(16);
566
600
  }
567
601
  }
602
+ /**
603
+ * Returns the SQL query to get the min and max values of a column.
604
+ * @param {string} view_id
605
+ * @param {string} column_name
606
+ * @param {any} config
607
+ * @returns {string}
608
+ */
609
+ viewGetMinMax(view_id, column_name, config) {
610
+ try {
611
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
612
+ const ptr0 = passStringToWasm0(view_id, wasm.__wbindgen_export, wasm.__wbindgen_export2);
613
+ const len0 = WASM_VECTOR_LEN;
614
+ const ptr1 = passStringToWasm0(column_name, wasm.__wbindgen_export, wasm.__wbindgen_export2);
615
+ const len1 = WASM_VECTOR_LEN;
616
+ wasm.genericsqlvirtualservermodel_viewGetMinMax(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1, addHeapObject(config));
617
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
618
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
619
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
620
+ var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
621
+ if (r3) {
622
+ throw takeObject(r2);
623
+ }
624
+ var v3 = getCachedStringFromWasm0(r0, r1);
625
+ if (r0 !== 0) { wasm.__wbindgen_export4(r0, r1, 1); }
626
+ return v3;
627
+ } finally {
628
+ wasm.__wbindgen_add_to_stack_pointer(16);
629
+ }
630
+ }
568
631
  /**
569
632
  * Returns the SQL query to describe a view's schema.
570
633
  * @param {string} view_id
@@ -1338,6 +1401,22 @@ export class VirtualDataSlice {
1338
1401
  const ptr = this.__destroy_into_raw();
1339
1402
  wasm.__wbg_virtualdataslice_free(ptr, 0);
1340
1403
  }
1404
+ /**
1405
+ * @param {Uint8Array} ipc
1406
+ */
1407
+ fromArrowIpc(ipc) {
1408
+ try {
1409
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1410
+ wasm.virtualdataslice_fromArrowIpc(retptr, this.__wbg_ptr, addHeapObject(ipc));
1411
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1412
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1413
+ if (r1) {
1414
+ throw takeObject(r0);
1415
+ }
1416
+ } finally {
1417
+ wasm.__wbindgen_add_to_stack_pointer(16);
1418
+ }
1419
+ }
1341
1420
  /**
1342
1421
  * @param {ViewConfigUpdate} config
1343
1422
  */
@@ -1864,7 +1943,7 @@ function __wbg_get_imports() {
1864
1943
  const a = state0.a;
1865
1944
  state0.a = 0;
1866
1945
  try {
1867
- return __wasm_bindgen_func_elem_5713(a, state0.b, arg0, arg1);
1946
+ return __wasm_bindgen_func_elem_10782(a, state0.b, arg0, arg1);
1868
1947
  } finally {
1869
1948
  state0.a = a;
1870
1949
  }
@@ -2019,12 +2098,12 @@ function __wbg_get_imports() {
2019
2098
  },
2020
2099
  __wbindgen_cast_0000000000000001: function(arg0, arg1) {
2021
2100
  // 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);
2101
+ const ret = makeClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_838, __wasm_bindgen_func_elem_1727);
2023
2102
  return addHeapObject(ret);
2024
2103
  },
2025
2104
  __wbindgen_cast_0000000000000002: function(arg0, arg1) {
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);
2105
+ // Cast intrinsic for `Closure(Closure { dtor_idx: 559, function: Function { arguments: [Externref], shim_idx: 560, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
2106
+ const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_3910, __wasm_bindgen_func_elem_3927);
2028
2107
  return addHeapObject(ret);
2029
2108
  },
2030
2109
  __wbindgen_cast_0000000000000003: function(arg0) {
@@ -2081,17 +2160,17 @@ function __wbg_get_imports() {
2081
2160
  };
2082
2161
  }
2083
2162
 
2084
- function __wasm_bindgen_func_elem_1689(arg0, arg1) {
2085
- const ret = wasm.__wasm_bindgen_func_elem_1689(arg0, arg1);
2163
+ function __wasm_bindgen_func_elem_1727(arg0, arg1) {
2164
+ const ret = wasm.__wasm_bindgen_func_elem_1727(arg0, arg1);
2086
2165
  return takeObject(ret);
2087
2166
  }
2088
2167
 
2089
- function __wasm_bindgen_func_elem_3874(arg0, arg1, arg2) {
2090
- wasm.__wasm_bindgen_func_elem_3874(arg0, arg1, addHeapObject(arg2));
2168
+ function __wasm_bindgen_func_elem_3927(arg0, arg1, arg2) {
2169
+ wasm.__wasm_bindgen_func_elem_3927(arg0, arg1, addHeapObject(arg2));
2091
2170
  }
2092
2171
 
2093
- function __wasm_bindgen_func_elem_5713(arg0, arg1, arg2, arg3) {
2094
- wasm.__wasm_bindgen_func_elem_5713(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
2172
+ function __wasm_bindgen_func_elem_10782(arg0, arg1, arg2, arg3) {
2173
+ wasm.__wasm_bindgen_func_elem_10782(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
2095
2174
  }
2096
2175
 
2097
2176
  const ClientFinalization = (typeof FinalizationRegistry === 'undefined')
Binary file
@@ -12,6 +12,7 @@ export const client___getClassname: (a: number, b: number) => void;
12
12
  export const client_get_hosted_table_names: (a: number) => number;
13
13
  export const client_handle_error: (a: number, b: number, c: number, d: number) => number;
14
14
  export const client_handle_response: (a: number, b: number) => number;
15
+ export const client_join: (a: number, b: number, c: number, d: number, e: number, f: number) => number;
15
16
  export const client_new: (a: number, b: number, c: number) => void;
16
17
  export const client_new_proxy_session: (a: number, b: number) => number;
17
18
  export const client_on_error: (a: number, b: number) => number;
@@ -30,6 +31,7 @@ export const genericsqlvirtualservermodel_tableValidateExpression: (a: number, b
30
31
  export const genericsqlvirtualservermodel_viewColumnSize: (a: number, b: number, c: number, d: number) => void;
31
32
  export const genericsqlvirtualservermodel_viewDelete: (a: number, b: number, c: number, d: number) => void;
32
33
  export const genericsqlvirtualservermodel_viewGetData: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
34
+ export const genericsqlvirtualservermodel_viewGetMinMax: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
33
35
  export const genericsqlvirtualservermodel_viewSchema: (a: number, b: number, c: number, d: number) => void;
34
36
  export const genericsqlvirtualservermodel_viewSize: (a: number, b: number, c: number, d: number) => void;
35
37
  export const init: () => void;
@@ -78,6 +80,7 @@ export const view_to_csv: (a: number, b: number) => number;
78
80
  export const view_to_json: (a: number, b: number) => number;
79
81
  export const view_to_json_string: (a: number, b: number) => number;
80
82
  export const view_to_ndjson: (a: number, b: number) => number;
83
+ export const virtualdataslice_fromArrowIpc: (a: number, b: number, c: number) => void;
81
84
  export const virtualdataslice_new: (a: number) => number;
82
85
  export const virtualdataslice_setBooleanCol: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
83
86
  export const virtualdataslice_setCol: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => void;
@@ -87,11 +90,11 @@ export const virtualdataslice_setIntegerCol: (a: number, b: number, c: number, d
87
90
  export const virtualdataslice_setStringCol: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
88
91
  export const virtualserver_handleRequest: (a: number, b: number, c: number) => number;
89
92
  export const virtualserver_new: (a: number, b: number) => void;
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;
93
+ export const __wasm_bindgen_func_elem_838: (a: number, b: number) => void;
94
+ export const __wasm_bindgen_func_elem_3910: (a: number, b: number) => void;
95
+ export const __wasm_bindgen_func_elem_10782: (a: number, b: number, c: number, d: number) => void;
96
+ export const __wasm_bindgen_func_elem_3927: (a: number, b: number, c: number) => void;
97
+ export const __wasm_bindgen_func_elem_1727: (a: number, b: number) => number;
95
98
  export const __wbindgen_export: (a: number, b: number) => number;
96
99
  export const __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
97
100
  export const __wbindgen_export3: (a: number) => void;