Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 21 additions & 18 deletions examples/blocks/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,25 @@ const __dirname = url.fileURLToPath(new URL(".", import.meta.url)).slice(0, -1);
// directly to the assets.
const replacements = {
"/node_modules/": `https://cdn.jsdelivr.net/npm/`,
"perspective/dist/cdn/perspective.js": `perspective@${version}/dist/cdn/perspective.js`,
"perspective-viewer/dist/cdn/perspective-viewer.js": `perspective-viewer@${version}/dist/cdn/perspective-viewer.js`,
"perspective-viewer-datagrid/dist/cdn/perspective-viewer-datagrid.js": `perspective-viewer-datagrid@${version}/dist/cdn/perspective-viewer-datagrid.js`,
"perspective-viewer-d3fc/dist/cdn/perspective-viewer-d3fc.js": `perspective-viewer-d3fc@${version}/dist/cdn/perspective-viewer-d3fc.js`,
"perspective-workspace/dist/cdn/perspective-workspace.js": `perspective-workspace@${version}/dist/cdn/perspective-workspace.js`,
"perspective/dist/cdn/perspective.cpp.wasm": `perspective@${version}/dist/cdn/perspective.cpp.wasm`,
"perspective-viewer/dist/cdn/perspective.rx.wasm": `perspective-viewer@${version}/dist/cdn/perspective.rx.wasm`,
"perspective/dist/cdn/perspective.worker.js": `perspective@${version}/dist/cdn/perspective.worker.js`,
"@perspective-dev/client/dist/cdn/perspective.js": `@perspective-dev/client@${version}/dist/cdn/perspective.js`,
"@perspective-dev/viewer/dist/cdn/perspective-viewer.js": `@perspective-dev/viewer@${version}/dist/cdn/perspective-viewer.js`,
"@perspective-dev/viewer-datagrid/dist/cdn/perspective-viewer-datagrid.js": `@perspective-dev/viewer-datagrid@${version}/dist/cdn/perspective-viewer-datagrid.js`,
"@perspective-dev/viewer-d3fc/dist/cdn/perspective-viewer-d3fc.js": `@perspective-dev/viewer-d3fc@${version}/dist/cdn/perspective-viewer-d3fc.js`,
"@perspective-dev/workspace/dist/cdn/perspective-workspace.js": `@perspective-dev/workspace@${version}/dist/cdn/perspective-workspace.js`,
"@perspective-dev/server/dist/cdn/perspective.cpp.wasm": `@perspective-dev/client@${version}/dist/cdn/perspective.cpp.wasm`,
"@perspective-dev/viewer/dist/cdn/perspective.rx.wasm": `@perspective-dev/viewer@${version}/dist/cdn/perspective.rx.wasm`,
"@perspective-dev/client/dist/cdn/perspective.worker.js": `@perspective-dev/client@${version}/dist/cdn/perspective.worker.js`,
};

export async function dist_examples(
outpath = `${__dirname}/../../docs/static/blocks`
outpath = `${__dirname}/../../docs/static/blocks`,
) {
execSync(`mkdir -p ${outpath}`, {stdio:"inherit"});
execSync(`mkdir -p ${outpath}`, { stdio: "inherit" });
const readme = generate_readme();
let existing = fs.readFileSync(`${__dirname}/../../README.md`).toString();
existing = existing.replace(
/<\!\-\- Examples \-\->([\s\S]+?)<\!\-\- Examples \-\->/gm,
`<!-- Examples -->\n${readme}\n<!-- Examples -->`
`<!-- Examples -->\n${readme}\n<!-- Examples -->`,
);

fs.writeFileSync(`${__dirname}/../../README.md`, existing);
Expand All @@ -51,7 +51,7 @@ export async function dist_examples(
if (fs.existsSync(`${__dirname}/src/${name}`)) {
// Copy
for (const filename of fs.readdirSync(`${__dirname}/src/${name}`)) {
execSync(`mkdir -p ${outpath}/${name}`, {stdio:"inherit"});
execSync(`mkdir -p ${outpath}/${name}`, { stdio: "inherit" });
if (
filename.endsWith(".mjs") ||
filename.endsWith(".js") ||
Expand All @@ -63,23 +63,26 @@ export async function dist_examples(
for (const pattern of Object.keys(replacements)) {
filecontents = filecontents.replace(
new RegExp(pattern, "g"),
replacements[pattern]
replacements[pattern],
);
}
fs.writeFileSync(
`${outpath}/${name}/${filename}`,
filecontents
filecontents,
);
} else if (filename !== ".git") {
execSync(`cp ${__dirname}/src/${name}/${filename} ${outpath}/${name}/${filename}`, {stdio:"inherit"});
execSync(
`cp ${__dirname}/src/${name}/${filename} ${outpath}/${name}/${filename}`,
{ stdio: "inherit" },
);
}
}

// build
if (fs.existsSync(path.join(outpath, name, "build.mjs"))) {
console.log("Building " + name);
const script = `${outpath}/${name}/build.mjs`;
execSync(`node ${script}`, {stdio:"inherit"});
execSync(`node ${script}`, { stdio: "inherit" });
}
}
}
Expand All @@ -104,9 +107,9 @@ function generate_readme() {
.join("")}</tr><tr>${row
.map(
(y) =>
`<td><a href="${y.url}"><img height="125" src="${y.img}"></img></a></td>`
`<td><a href="${y.url}"><img height="125" src="${y.img}"></img></a></td>`,
)
.join("")}</tr>`
.join("")}</tr>`,
)
.join("")}</tbody></table>`;
}
76 changes: 39 additions & 37 deletions examples/blocks/src/market/layouts.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,29 +107,38 @@
"aggregates": { "bucket(\"timestamp\", 'm')": "dominant" }
},
{
"plugin": "Datagrid",
"plugin_config": {
"columns": {
"Change since market open": {
"fg_gradient": 16.29,
"number_fg_mode": "bar"
},
"Diff from market open": {
"bg_gradient": 16.29,
"fg_gradient": 20,
"number_bg_mode": "gradient",
"number_fg_mode": "bar"
},
"price": { "bg_gradient": 34.55, "number_bg_mode": "gradient" },
"side": { "color": "#3daa27", "string_color_mode": "series" },
"status": { "string_color_mode": "series" }
"version": "4.1.0",
"columns_config": {
"Diff from market open": {
"number_fg_mode": "bar",
"fg_gradient": 12.9
},
"if(\"side\"=='buy'){-1}else{1}": {
"number_fg_mode": "bar",
"fg_gradient": 8,
"aggregate_depth": 1
},
"editable": false,
"scroll_lock": false
"status": {
"string_color_mode": "series",
"color": "#94aa27"
},
"side": {
"string_color_mode": "series"
}
},
"plugin": "Datagrid",
"plugin_config": {},
"settings": true,
"title": "Blotter",
"group_by": [],
"split_by": [],
"sort": [["timestamp", "desc"]],
"filter": [],
"expressions": {
"bucket(\"price\", 1)": "bucket(\"price\", 1)",
"bucket(\"timestamp\", 'm')": "bucket(\"timestamp\", 'm')",
"Diff from market open": "\"price\" - 20"
},
"columns": [
"timestamp",
"id",
Expand All @@ -138,37 +147,30 @@
"status",
"side"
],
"filter": [],
"sort": [["timestamp", "desc"]],
"expressions": {
"bucket(\"timestamp\", 'm')": "bucket(\"timestamp\", 'm')",
"bucket(\"price\", 1)": "bucket(\"price\", 1)",
"Diff from market open": "\"price\" - 20"
},
"aggregates": {}
},
{
"plugin": "Datagrid",
"plugin_config": {
"columns": {
"if(\"side\"=='buy'){-1}else{1}": {
"fg_gradient": 20,
"number_fg_mode": "bar"
}
},
"editable": false,
"scroll_lock": false
"version": "4.1.0",
"columns_config": {
"if(\"side\"=='buy'){-1}else{1}": {
"aggregate_depth": 1,
"number_fg_mode": "bar",
"fg_gradient": 8
}
},
"plugin": "Datagrid",
"plugin_config": {},
"settings": true,
"title": "Order Book",
"group_by": ["bucket(\"price\", 0.5)"],
"split_by": ["side"],
"columns": ["if(\"side\"=='buy'){-1}else{1}"],
"filter": [["status", "==", "open"]],
"sort": [["bucket(\"price\", 0.5)", "desc"]],
"filter": [["status", "==", "open"]],
"expressions": {
"if(\"side\"=='buy'){-1}else{1}": "if(\"side\"=='buy'){-1}else{1}",
"bucket(\"price\", 0.5)": "bucket(\"price\", 0.5)"
},
"columns": ["if(\"side\"=='buy'){-1}else{1}"],
"aggregates": {}
},
{
Expand Down
8 changes: 6 additions & 2 deletions examples/blocks/src/market/market.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,11 @@ async function init_tables() {
const gui_worker = await perspective.worker();
const market_table = await market_worker.table(SCHEMA, { index: "id" });
const market_view = await market_table.view();
const gui_table = await gui_worker.table(market_view, { index: "id" });
const gui_table = await gui_worker.table(market_view, {
index: "id",
name: "gui",
});

return { market_table, gui_table };
}

Expand All @@ -268,7 +272,7 @@ const select = document.querySelector("select");
const button = document.querySelector("button");
const viewer = document.querySelector("perspective-viewer");
viewer.load(gui_table);
viewer.restore({ theme: "Pro Dark", settings, ...layouts[0] });
viewer.restore({ theme: "Pro Dark", table: "gui", settings, ...layouts[0] });
await market.poll(progress);
for (const layout of layouts) {
const option = document.createElement("option");
Expand Down
2 changes: 1 addition & 1 deletion examples/python-aiohttp/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

here = os.path.abspath(os.path.dirname(__file__))
file_path = os.path.join(
here, "..", "..", "node_modules", "superstore-arrow", "superstore.lz4.arrow"
here, ".", "node_modules", "superstore-arrow", "superstore.lz4.arrow"
)


Expand Down
2 changes: 1 addition & 1 deletion examples/python-starlette/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

here = os.path.abspath(os.path.dirname(__file__))
file_path = os.path.join(
here, "..", "..", "node_modules", "superstore-arrow", "superstore.lz4.arrow"
here, ".", "node_modules", "superstore-arrow", "superstore.lz4.arrow"
)


Expand Down
2 changes: 1 addition & 1 deletion examples/python-tornado/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

here = os.path.abspath(os.path.dirname(__file__))
file_path = os.path.join(
here, "..", "..", "node_modules", "superstore-arrow", "superstore.lz4.arrow"
here, ".", "node_modules", "superstore-arrow", "superstore.lz4.arrow"
)


Expand Down
2 changes: 1 addition & 1 deletion packages/workspace/src/ts/workspace/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export const createCommands = (
execute: async (args) => {
const widget = await workspace._createWidgetAndNode({
config: {
table: Array.isArray(args.table) ? args.table[0] : null,
table: args.table as string,
},
slot: undefined,
});
Expand Down
12 changes: 6 additions & 6 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pnpm-workspace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ catalog:
"pro_self_extracting_wasm": "0.0.9"
"react-dom": "^18"
"react": "^18"
"regular-table": "=0.7.3"
"regular-table": "=0.8.0"
"stoppable": "=1.1.0"
"ws": "^8.17.0"

Expand Down
2 changes: 1 addition & 1 deletion rust/perspective-client/src/rust/virtual_server/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub enum VirtualServerError<T: std::fmt::Debug> {
#[error("{0}")]
EncodeError(EncodeError),

#[error("Unknown view '{0}'")]
#[error("View not found '{0}'")]
UnknownViewId(String),

#[error("Invalid JSON'{0}'")]
Expand Down
27 changes: 20 additions & 7 deletions rust/perspective-client/src/rust/virtual_server/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ use crate::config::{ViewConfig, ViewConfigUpdate};
use crate::proto::response::ClientResp;
use crate::proto::table_validate_expr_resp::ExprValidationError;
use crate::proto::{
GetFeaturesResp, GetHostedTablesResp, MakeTableResp, Request, Response, TableMakePortResp,
TableMakeViewResp, TableOnDeleteResp, TableRemoveDeleteResp, TableSchemaResp, TableSizeResp,
TableValidateExprResp, ViewColumnPathsResp, ViewDeleteResp, ViewDimensionsResp,
ViewExpressionSchemaResp, ViewGetConfigResp, ViewOnDeleteResp, ViewOnUpdateResp,
ViewRemoveDeleteResp, ViewRemoveOnUpdateResp, ViewSchemaResp, ViewToColumnsStringResp,
ViewToRowsStringResp,
GetFeaturesResp, GetHostedTablesResp, MakeTableResp, Request, Response, ServerError,
TableMakePortResp, TableMakeViewResp, TableOnDeleteResp, TableRemoveDeleteResp,
TableSchemaResp, TableSizeResp, TableValidateExprResp, ViewColumnPathsResp, ViewDeleteResp,
ViewDimensionsResp, ViewExpressionSchemaResp, ViewGetConfigResp, ViewOnDeleteResp,
ViewOnUpdateResp, ViewRemoveDeleteResp, ViewRemoveOnUpdateResp, ViewSchemaResp,
ViewToColumnsStringResp, ViewToRowsStringResp,
};

macro_rules! respond {
Expand Down Expand Up @@ -76,14 +76,27 @@ impl<T: VirtualServerHandler> VirtualServer<T> {
&mut self,
bytes: Bytes,
) -> Result<Bytes, VirtualServerError<T::Error>> {
use crate::proto::request::ClientReq::*;
let msg = Request::decode(bytes).map_err(VirtualServerError::DecodeError)?;
tracing::debug!(
"Handling request: entity_id={}, req={:?}",
msg.entity_id,
msg.client_req
);

match self.internal_handle_request(msg.clone()).await {
Ok(resp) => Ok(resp),
Err(err) => Ok(respond!(msg, ServerError {
message: err.to_string(),
status_code: 1
})),
}
}

async fn internal_handle_request(
&mut self,
msg: Request,
) -> Result<Bytes, VirtualServerError<T::Error>> {
use crate::proto::request::ClientReq::*;
let resp = match msg.client_req.unwrap() {
GetFeaturesReq(_) => {
let features = self.handler.get_features().await?;
Expand Down
8 changes: 7 additions & 1 deletion rust/perspective-js/src/rust/utils/futures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ where
pub fn new<U: Future<Output = ApiResult<T>> + 'static>(x: U) -> Self {
Self(Box::pin(x))
}

pub fn new_throttled<U: Future<Output = ApiResult<T>> + 'static>(x: U) -> ApiFuture<()> {
ApiFuture::<()>(Box::pin(
async move { x.await.ignore_view_delete().map(|_| ()) },
))
}
}

impl<T> ApiFuture<T>
Expand Down Expand Up @@ -87,7 +93,7 @@ where
future_to_promise(async move {
match fut.0.await.ignore_view_delete()? {
Some(x) => Ok(x).into_js_result(),
None => Ok::<_, JsValue>(()).into_js_result(),
None => Err("View not found".into()).into_js_result(),
}
})
}
Expand Down
Loading
Loading