@perspective-dev/client 4.0.1 → 4.1.1

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 (45) hide show
  1. package/dist/cdn/perspective-server.worker.js +1 -1
  2. package/dist/cdn/perspective-server.worker.js.map +3 -3
  3. package/dist/cdn/perspective.js +2 -2
  4. package/dist/cdn/perspective.js.map +4 -4
  5. package/dist/esm/perspective.browser.d.ts +5 -1
  6. package/dist/esm/perspective.inline.js +2 -2
  7. package/dist/esm/perspective.inline.js.map +4 -4
  8. package/dist/esm/perspective.js +2 -2
  9. package/dist/esm/perspective.js.map +4 -4
  10. package/dist/esm/perspective.node.d.ts +6 -1
  11. package/dist/esm/perspective.node.js +721 -352
  12. package/dist/esm/perspective.node.js.map +4 -4
  13. package/dist/esm/ts-rs/ColumnType.d.ts +4 -0
  14. package/dist/esm/ts-rs/ViewConfig.d.ts +18 -0
  15. package/dist/esm/ts-rs/ViewWindow.d.ts +9 -9
  16. package/dist/esm/virtual_server.d.ts +47 -0
  17. package/dist/esm/virtual_servers/duckdb.d.ts +39 -0
  18. package/dist/esm/virtual_servers/duckdb.js +12 -0
  19. package/dist/esm/virtual_servers/duckdb.js.map +7 -0
  20. package/dist/esm/wasm/browser.d.ts +1 -1
  21. package/dist/wasm/perspective-js.d.ts +52 -13
  22. package/dist/wasm/perspective-js.js +648 -367
  23. package/dist/wasm/perspective-js.wasm +0 -0
  24. package/dist/wasm/perspective-js.wasm.d.ts +20 -8
  25. package/package.json +4 -1
  26. package/src/rust/client.rs +14 -5
  27. package/src/rust/lib.rs +11 -1
  28. package/src/rust/table.rs +3 -2
  29. package/src/rust/table_data.rs +19 -14
  30. package/src/rust/utils/browser.rs +0 -4
  31. package/src/rust/utils/console_logger.rs +3 -2
  32. package/src/rust/utils/errors.rs +10 -28
  33. package/src/rust/utils/futures.rs +10 -4
  34. package/src/rust/utils/json.rs +4 -4
  35. package/src/rust/virtual_server.rs +746 -0
  36. package/src/ts/perspective-server.worker.ts +33 -23
  37. package/src/ts/perspective.browser.ts +17 -2
  38. package/src/ts/perspective.node.ts +46 -11
  39. package/src/ts/ts-rs/ColumnType.ts +6 -0
  40. package/src/ts/ts-rs/ViewConfig.ts +8 -0
  41. package/src/ts/ts-rs/ViewWindow.ts +3 -3
  42. package/src/ts/virtual_server.ts +126 -0
  43. package/src/ts/virtual_servers/duckdb.ts +516 -0
  44. package/src/ts/wasm/browser.ts +17 -9
  45. package/tsconfig.json +1 -0
@@ -0,0 +1,4 @@
1
+ /**
2
+ * View types
3
+ */
4
+ export type ColumnType = "string" | "date" | "datetime" | "integer" | "float" | "boolean";
@@ -0,0 +1,18 @@
1
+ import type { Aggregate } from "./Aggregate.js";
2
+ import type { Expressions } from "./Expressions.js";
3
+ import type { Filter } from "./Filter.js";
4
+ import type { FilterReducer } from "./FilterReducer.js";
5
+ import type { Sort } from "./Sort.js";
6
+ export type ViewConfig = {
7
+ group_by: Array<string>;
8
+ split_by: Array<string>;
9
+ sort: Array<Sort>;
10
+ filter: Array<Filter>;
11
+ filter_op?: FilterReducer;
12
+ expressions: Expressions;
13
+ columns: Array<string | null>;
14
+ aggregates: {
15
+ [key in string]?: Aggregate;
16
+ };
17
+ group_by_depth?: number | null;
18
+ };
@@ -5,19 +5,19 @@
5
5
  * [`View`].
6
6
  */
7
7
  export type ViewWindow = {
8
- start_row: number | null;
9
- start_col: number | null;
10
- end_row: number | null;
11
- end_col: number | null;
12
- id: boolean | null;
13
- index: boolean | null;
14
- leaves_only: boolean | null;
8
+ start_row?: number;
9
+ start_col?: number;
10
+ end_row?: number;
11
+ end_col?: number;
12
+ id?: boolean;
13
+ index?: boolean;
14
+ leaves_only?: boolean;
15
15
  /**
16
16
  * Only impacts [`View::to_csv`]
17
17
  */
18
- formatted: boolean | null;
18
+ formatted?: boolean;
19
19
  /**
20
20
  * Only impacts [`View::to_arrow`]
21
21
  */
22
- compression: string | null;
22
+ compression?: string;
23
23
  };
@@ -0,0 +1,47 @@
1
+ import { ColumnType } from "./ts-rs/ColumnType.ts";
2
+ import { ViewConfig } from "./ts-rs/ViewConfig.ts";
3
+ import { ViewWindow } from "./ts-rs/ViewWindow.ts";
4
+ import type * as perspective from "../../dist/wasm/perspective-js.js";
5
+ /**
6
+ * VirtualServer API for implementing custom data sources in JavaScript/WASM.
7
+ *
8
+ * The VirtualServer pattern allows you to create custom data sources that
9
+ * integrate with Perspective's protocol. This is useful for:
10
+ * - Connecting to external databases (DuckDB, PostgreSQL, etc.)
11
+ * - Streaming data from APIs or message queues
12
+ * - Implementing custom aggregation or transformation logic
13
+ * - Creating data adapters without copying data into Perspective tables
14
+ *
15
+ * @module virtual_server
16
+ */
17
+ export interface ServerFeatures {
18
+ expressions?: boolean;
19
+ }
20
+ /**
21
+ * Handler interface that you implement to provide custom data sources.
22
+ *
23
+ * All methods will be called by the VirtualServer when handling protocol
24
+ * messages from Perspective clients. Methods can return values directly or
25
+ * return Promises for asynchronous operations (e.g., database queries).
26
+ */
27
+ export interface VirtualServerHandler {
28
+ getHostedTables(): string[] | Promise<string[]>;
29
+ tableSchema(tableId: string): Record<string, ColumnType> | Promise<Record<string, ColumnType>>;
30
+ tableSize(tableId: string): number | Promise<number>;
31
+ tableMakeView(tableId: string, viewId: string, config: ViewConfig): void | Promise<void>;
32
+ viewDelete(viewId: string): void | Promise<void>;
33
+ viewGetData(viewId: string, config: ViewConfig, viewport: ViewWindow, dataSlice: perspective.JsVirtualDataSlice): void | Promise<void>;
34
+ viewSchema?(viewId: string, config?: ViewConfig): Record<string, ColumnType> | Promise<Record<string, ColumnType>>;
35
+ viewSize?(viewId: string): number | Promise<number>;
36
+ tableValidateExpression?(tableId: string, expression: string): ColumnType | Promise<ColumnType>;
37
+ getFeatures?(): ServerFeatures | Promise<ServerFeatures>;
38
+ makeTable?(tableId: string, data: string | Uint8Array): void | Promise<void>;
39
+ }
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,39 @@
1
+ import type { VirtualDataSlice, VirtualServerHandler } from "@perspective-dev/client";
2
+ import type { ColumnType } from "@perspective-dev/client/dist/esm/ts-rs/ColumnType.d.ts";
3
+ import type { ViewConfig } from "@perspective-dev/client/dist/esm/ts-rs/ViewConfig.d.ts";
4
+ import type { ViewWindow } from "@perspective-dev/client/dist/esm/ts-rs/ViewWindow.d.ts";
5
+ import type * as duckdb from "@duckdb/duckdb-wasm";
6
+ export declare class DuckDBHandler implements VirtualServerHandler {
7
+ private db;
8
+ constructor(db: duckdb.AsyncDuckDBConnection);
9
+ getFeatures(): {
10
+ group_by: boolean;
11
+ split_by: boolean;
12
+ sort: boolean;
13
+ expressions: boolean;
14
+ filter_ops: {
15
+ integer: string[];
16
+ float: string[];
17
+ string: string[];
18
+ boolean: string[];
19
+ date: string[];
20
+ datetime: string[];
21
+ };
22
+ aggregates: {
23
+ integer: string[];
24
+ float: string[];
25
+ string: string[];
26
+ boolean: string[];
27
+ date: string[];
28
+ datetime: string[];
29
+ };
30
+ };
31
+ getHostedTables(): Promise<any[]>;
32
+ tableSchema(tableId: string): Promise<Record<string, ColumnType>>;
33
+ viewColumnSize(viewId: string, config: ViewConfig): Promise<number>;
34
+ tableSize(tableId: string): Promise<number>;
35
+ tableMakeView(tableId: string, viewId: string, config: ViewConfig): Promise<void>;
36
+ tableValidateExpression(tableId: string, expression: string): Promise<ColumnType>;
37
+ viewDelete(viewId: string): Promise<void>;
38
+ viewGetData(viewId: string, config: ViewConfig, viewport: ViewWindow, dataSlice: VirtualDataSlice): Promise<void>;
39
+ }
@@ -0,0 +1,12 @@
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"],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")||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"||o.startsWith("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 s=BigInt(2)**BigInt(127);i>=s&&(i-=BigInt(2)**BigInt(128));let a=r.match(/Decimal\[\d+e(\d+)\]/),n=a?parseInt(a[1]):0;return n>0?Number(i)/Math.pow(10,n):Number(i)}async function m(o,r,i={}){r=r.replace(/\s+/g," ").trim();try{let s=await o.query(r);return i.columns?{rows:s.toArray(),columns:s.schema.fields.map(a=>a.name),dtypes:s.schema.fields.map(a=>a.type.toString())}:s.toArray()}catch(s){throw console.error("Query error:",s),console.error("Query:",r),s}}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:D,boolean:D,date:D,datetime:D}}}async getHostedTables(){return(await m(this.db,"SHOW ALL TABLES")).map(i=>i.toJSON().name)}async tableSchema(r){let i=`DESCRIBE ${r}`,s=await m(this.db,i),a={};for(let n of s){let u=n.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 s=`SELECT COUNT(*) FROM (DESCRIBE ${r})`,a=await m(this.db,s),n=i.group_by?.length||0;return Number(Object.values(a[0].toJSON())[0])-(n===0?0:n+(i.split_by?.length===0?1:0))}async tableSize(r){let i=`SELECT COUNT(*) FROM ${r}`,s=await m(this.db,i);return Number(s[0].toJSON()["count_star()"])}async tableMakeView(r,i,s){let a=s.columns||[],n=s.group_by||[],u=s.split_by||[],y=s.aggregates||{},h=s.sort||[],T=s.expressions||{},O=s.filter||[],_=t=>T[t]||`"${t}"`,E=t=>y[t]||null,C=()=>{let t=[];if(n.length>0){for(let c of a)if(c!==null){let l=E(c)||"any_value";t.push(`${l}(${_(c)}) as "${c}"`)}if(u.length===0){for(let l=0;l<n.length;l++)t.push(`${_(n[l])} as __ROW_PATH_${l}__`);let c=n.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(n.length>0)for(let t=0;t<n.length;t++){let c=n.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=E(l)||"any_value";t>=n.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&&n.length>1)for(let t=0;t<n.length-1;t++){let c=Array.from({length:t+1},(e,d)=>`__ROW_PATH_${d}__`).join(", "),l=n.slice(0,t+1).map(_).join(", "),p=n.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=n.map(_).join(", "),c=n.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(n.length>0){let t=n.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 s=`DESCRIBE (select ${i} from ${r})`,a=await m(this.db,s);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,s,a){let n=i.group_by||[],u=i.split_by||[],y=s.start_col,h=s.end_col,T=s.start_row||0,O=s.end_row,_="";O!=null&&(_=`LIMIT ${O-T} OFFSET ${T}`);let E=`DESCRIBE ${r}`,C=await m(this.db,E),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(n.length>0){u.length===0&&$.push("__GROUPING_ID__");for(let e=0;e<n.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&&n.length>0&&u.length===0)continue;let R=null,A=null,B=d.match(/__ROW_PATH_(\d+)__/);B&&(R=parseInt(B[1]),A=2**(n.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||A===null||W[0]<A){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};
12
+ //# sourceMappingURL=duckdb.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 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 (\n name === \"DOUBLE\" ||\n name === \"BIGINT\" ||\n name === \"HUGEINT\" ||\n name.startsWith(\"Decimal\")\n )\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\" || name.startsWith(\"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"]
7
+ }
@@ -5,7 +5,7 @@ import type * as psp from "../../../dist/wasm/perspective-js.d.ts";
5
5
  * @param module
6
6
  * @returns
7
7
  */
8
- export declare function worker(module: Promise<typeof psp>, server_wasm: Promise<WebAssembly.Module>, perspective_wasm_worker: Promise<SharedWorker | ServiceWorker | Worker>): Promise<psp.Client>;
8
+ export declare function worker(module: Promise<typeof psp>, server_wasm: Promise<WebAssembly.Module> | undefined, perspective_wasm_worker: Promise<SharedWorker | ServiceWorker | Worker | MessagePort>): Promise<psp.Client>;
9
9
  /**
10
10
  * Create a new client connected via WebSocket to a server implemnting the
11
11
  * Perspective Protocol.
@@ -3,6 +3,7 @@
3
3
  export function init(): void;
4
4
 
5
5
  export type * from "../../src/ts/ts-rs/ViewWindow.d.ts";
6
+ export type * from "../../src/ts/ts-rs/ColumnType.d.ts";
6
7
  export type * from "../../src/ts/ts-rs/ColumnWindow.d.ts";
7
8
  export type * from "../../src/ts/ts-rs/TableInitOptions.d.ts";
8
9
  export type * from "../../src/ts/ts-rs/ViewConfigUpdate.d.ts";
@@ -10,9 +11,14 @@ export type * from "../../src/ts/ts-rs/ViewOnUpdateResp.d.ts";
10
11
  export type * from "../../src/ts/ts-rs/OnUpdateOptions.d.ts";
11
12
  export type * from "../../src/ts/ts-rs/UpdateOptions.d.ts";
12
13
  export type * from "../../src/ts/ts-rs/DeleteOptions.d.ts";
14
+ export type * from "../../src/ts/ts-rs/Scalar.d.ts";
13
15
  export type * from "../../src/ts/ts-rs/SystemInfo.d.ts";
16
+ export type * from "../../src/ts/ts-rs/SortDir.d.ts";
17
+ export type * from "../../src/ts/ts-rs/Filter.d.ts";
18
+ export type * from "../../src/ts/ts-rs/ViewConfig.d.ts";
14
19
 
15
20
  import type {ColumnWindow} from "../../src/ts/ts-rs/ColumnWindow.d.ts";
21
+ import type {ColumnType} from "../../src/ts/ts-rs/ColumnType.d.ts";
16
22
  import type {ViewWindow} from "../../src/ts/ts-rs/ViewWindow.d.ts";
17
23
  import type {TableInitOptions} from "../../src/ts/ts-rs/TableInitOptions.d.ts";
18
24
  import type {ViewConfigUpdate} from "../../src/ts/ts-rs/ViewConfigUpdate.d.ts";
@@ -63,6 +69,7 @@ import type {SystemInfo} from "../../src/ts/ts-rs/SystemInfo.d.ts";
63
69
  */
64
70
  export class Client {
65
71
  free(): void;
72
+ [Symbol.dispose](): void;
66
73
  __getClassname(): string;
67
74
  constructor(send_request: Function, close?: Function | null);
68
75
  new_proxy_session(on_response: Function): ProxySession;
@@ -144,7 +151,7 @@ export class Client {
144
151
  * const table = await client.table(data, { index: "Row ID" });
145
152
  * ```
146
153
  */
147
- table(value: string | ArrayBuffer | Record<string, unknown[]> | Record<string, unknown>[], options?: TableInitOptions | null): Promise<Table>;
154
+ table(value: string | ArrayBuffer | Record<string, unknown[]> | Record<string, unknown>[] | Record<string, ColumnType>, options?: TableInitOptions | null): Promise<Table>;
148
155
  /**
149
156
  * Terminates this [`Client`], cleaning up any [`crate::View`] handles the
150
157
  * [`Client`] has open as well as its callbacks.
@@ -181,7 +188,7 @@ export class Client {
181
188
  * const tables = await client.get_hosted_table_names();
182
189
  * ```
183
190
  */
184
- get_hosted_table_names(): Promise<any>;
191
+ get_hosted_table_names(): Promise<string[]>;
185
192
  /**
186
193
  * Register a callback which is invoked whenever [`Client::table`] (on this
187
194
  * [`Client`]) or [`Table::delete`] (on a [`Table`] belinging to this
@@ -208,8 +215,26 @@ export class Client {
208
215
  */
209
216
  system_info(): Promise<SystemInfo>;
210
217
  }
218
+ export class JsVirtualDataSlice {
219
+ free(): void;
220
+ [Symbol.dispose](): void;
221
+ constructor();
222
+ setCol(dtype: string, name: string, index: number, val: any, group_by_index?: number | null): void;
223
+ setStringCol(name: string, index: number, val: any, group_by_index?: number | null): void;
224
+ setIntegerCol(name: string, index: number, val: any, group_by_index?: number | null): void;
225
+ setFloatCol(name: string, index: number, val: any, group_by_index?: number | null): void;
226
+ setBooleanCol(name: string, index: number, val: any, group_by_index?: number | null): void;
227
+ setDatetimeCol(name: string, index: number, val: any, group_by_index?: number | null): void;
228
+ }
229
+ export class JsVirtualServer {
230
+ free(): void;
231
+ [Symbol.dispose](): void;
232
+ constructor(handler: object);
233
+ handleRequest(bytes: Uint8Array): Promise<any>;
234
+ }
211
235
  export class ProxySession {
212
236
  free(): void;
237
+ [Symbol.dispose](): void;
213
238
  constructor(client: Client, on_response: Function);
214
239
  handle_request(value: any): Promise<void>;
215
240
  close(): Promise<void>;
@@ -217,6 +242,7 @@ export class ProxySession {
217
242
  export class Table {
218
243
  private constructor();
219
244
  free(): void;
245
+ [Symbol.dispose](): void;
220
246
  __getClassname(): string;
221
247
  /**
222
248
  * Returns the name of the index column for the table.
@@ -228,7 +254,7 @@ export class Table {
228
254
  * const index = table.get_index(); // "x"
229
255
  * ```
230
256
  */
231
- get_index(): Promise<string | undefined>;
257
+ get_index(): Promise<string>;
232
258
  /**
233
259
  * Get a copy of the [`Client`] this [`Table`] came from.
234
260
  */
@@ -304,7 +330,7 @@ export class Table {
304
330
  * Note that all [`Table`] columns are _nullable_, regardless of the data
305
331
  * type.
306
332
  */
307
- schema(): Promise<any>;
333
+ schema(): Promise<Record<string, ColumnType>>;
308
334
  /**
309
335
  * Returns the column names of this [`Table`] in "natural" order (the
310
336
  * ordering implied by the input format).
@@ -393,7 +419,7 @@ export class Table {
393
419
  * await table.update("x,y\n1,2");
394
420
  * ```
395
421
  */
396
- update(input: string | ArrayBuffer | Record<string, unknown[]> | Record<string, unknown>[], options?: UpdateOptions | null): Promise<any>;
422
+ update(input: string | ArrayBuffer | Record<string, unknown[]> | Record<string, unknown>[] | Record<string, ColumnType>, options?: UpdateOptions | null): Promise<any>;
397
423
  /**
398
424
  * Create a new [`View`] from this table with a specified
399
425
  * [`ViewConfigUpdate`].
@@ -435,6 +461,7 @@ export class Table {
435
461
  export class View {
436
462
  private constructor();
437
463
  free(): void;
464
+ [Symbol.dispose](): void;
438
465
  __get_model(): View;
439
466
  /**
440
467
  * Returns an array of strings containing the column paths of the [`View`]
@@ -677,17 +704,29 @@ export interface InitOutput {
677
704
  readonly view_collapse: (a: number, b: number) => number;
678
705
  readonly view_expand: (a: number, b: number) => number;
679
706
  readonly view_set_depth: (a: number, b: number) => number;
707
+ readonly __wbg_jsvirtualdataslice_free: (a: number, b: number) => void;
708
+ readonly jsvirtualdataslice_new: () => number;
709
+ readonly jsvirtualdataslice_setCol: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => void;
710
+ readonly jsvirtualdataslice_setStringCol: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
711
+ readonly jsvirtualdataslice_setIntegerCol: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
712
+ readonly jsvirtualdataslice_setFloatCol: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
713
+ readonly jsvirtualdataslice_setBooleanCol: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
714
+ readonly jsvirtualdataslice_setDatetimeCol: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
715
+ readonly __wbg_jsvirtualserver_free: (a: number, b: number) => void;
716
+ readonly jsvirtualserver_new: (a: number, b: number) => void;
717
+ readonly jsvirtualserver_handleRequest: (a: number, b: number, c: number) => number;
680
718
  readonly init: () => void;
681
719
  readonly proxysession_new: (a: number, b: number) => number;
682
- readonly __wbindgen_export_0: (a: number, b: number) => number;
683
- readonly __wbindgen_export_1: (a: number, b: number, c: number, d: number) => number;
684
- readonly __wbindgen_export_2: (a: number) => void;
685
- readonly __wbindgen_export_3: (a: number, b: number, c: number) => void;
686
- readonly __wbindgen_export_4: WebAssembly.Table;
720
+ readonly __wasm_bindgen_func_elem_553: (a: number, b: number) => number;
721
+ readonly __wasm_bindgen_func_elem_123: (a: number, b: number) => void;
722
+ readonly __wasm_bindgen_func_elem_3515: (a: number, b: number, c: number) => void;
723
+ readonly __wasm_bindgen_func_elem_3500: (a: number, b: number) => void;
724
+ readonly __wasm_bindgen_func_elem_5070: (a: number, b: number, c: number, d: number) => void;
725
+ readonly __wbindgen_export: (a: number, b: number) => number;
726
+ readonly __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
727
+ readonly __wbindgen_export3: (a: number) => void;
728
+ readonly __wbindgen_export4: (a: number, b: number, c: number) => void;
687
729
  readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
688
- readonly __wbindgen_export_5: (a: number, b: number) => number;
689
- readonly __wbindgen_export_6: (a: number, b: number, c: number) => void;
690
- readonly __wbindgen_export_7: (a: number, b: number, c: number, d: number) => void;
691
730
  }
692
731
 
693
732
  export type SyncInitInput = BufferSource | WebAssembly.Module;