chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
# ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
# ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
||||
# ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
||||
# ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
||||
# ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
||||
# ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
||||
# ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
||||
# ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
||||
# ┃ This file is part of the Perspective library, distributed under the terms ┃
|
||||
# ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
||||
# ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
||||
|
||||
[package]
|
||||
name = "rust-axum"
|
||||
version = "4.5.2"
|
||||
edition = "2024"
|
||||
publish = false
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
# TODO(texodus): Due to feature unification and `wasm_bindgen_futures`
|
||||
# requirements for `Send` bounds interacting poorly with `rust-analyzer`,
|
||||
# this cannot require the "axum-ws" feature by defualt without impacting
|
||||
# developer sanity. In a stand-alone project outside the perspective repo, this
|
||||
# hack is not necessary.
|
||||
#
|
||||
# This feature flag is passed on the CLI by `package.json` instead.
|
||||
_hack = ["perspective/axum-ws"]
|
||||
|
||||
[dependencies]
|
||||
perspective = { version = "4.5.2", default-features = false }
|
||||
axum = { version = ">=0.8,<0.9", features = ["ws"] }
|
||||
futures = "0.3"
|
||||
tokio = { version = "1.0", features = ["full"] }
|
||||
tower-http = { version = "0.5.0", features = ["fs", "trace"] }
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "rust-axum",
|
||||
"private": true,
|
||||
"version": "4.5.2",
|
||||
"description": "An example of a Rust/Axum virtual Perspective server",
|
||||
"scripts": {
|
||||
"start": "cargo run --target=$(rustc -vV | sed -n 's|host: ||p') --features=_hack"
|
||||
},
|
||||
"keywords": [],
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"superstore-arrow": "catalog:"
|
||||
},
|
||||
"devDependencies": {}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
|
||||
|
||||
<script type="module" src="/node_modules/@perspective-dev/viewer/dist/cdn/perspective-viewer.js"></script>
|
||||
<script type="module" src="/node_modules/@perspective-dev/viewer-datagrid/dist/cdn/perspective-viewer-datagrid.js"></script>
|
||||
<script type="module" src="/node_modules/@perspective-dev/viewer-charts/dist/cdn/perspective-viewer-charts.js"></script>
|
||||
|
||||
<link rel="preload" href="/node_modules/@perspective-dev/viewer/dist/wasm/perspective-viewer.wasm" as="fetch" type="application/wasm" crossorigin="anonymous" />
|
||||
<link rel="stylesheet" crossorigin="anonymous" href="/node_modules/@perspective-dev/viewer/dist/css/themes.css" />
|
||||
|
||||
<script type="module">
|
||||
import "/node_modules/@perspective-dev/viewer/dist/cdn/perspective-viewer.js";
|
||||
import perspective from "/node_modules/@perspective-dev/client/dist/cdn/perspective.js";
|
||||
const socket = await perspective.websocket("/ws");
|
||||
const table = socket.open_table("my_data_source");
|
||||
const viewer = document.getElementsByTagName("perspective-viewer")[0];
|
||||
|
||||
viewer.load(table);
|
||||
viewer.restore({ settings: true, plugin_config: { edit_mode: "EDIT" } });
|
||||
</script>
|
||||
|
||||
<style>
|
||||
perspective-viewer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<perspective-viewer></perspective-viewer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,91 @@
|
||||
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
||||
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
||||
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
||||
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
||||
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
||||
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
||||
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
||||
// ┃ This file is part of the Perspective library, distributed under the terms ┃
|
||||
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
||||
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
#[cfg(feature = "_hack")]
|
||||
use std::net::SocketAddr;
|
||||
|
||||
#[cfg(feature = "_hack")]
|
||||
use axum::Router;
|
||||
#[cfg(feature = "_hack")]
|
||||
use axum::routing::get_service;
|
||||
use perspective::client::{TableInitOptions, UpdateData};
|
||||
use perspective::server::Server;
|
||||
#[cfg(feature = "_hack")]
|
||||
use tower_http::{
|
||||
services::{ServeDir, ServeFile},
|
||||
trace::TraceLayer,
|
||||
};
|
||||
use tracing_subscriber::filter::LevelFilter;
|
||||
use tracing_subscriber::fmt::layer;
|
||||
use tracing_subscriber::prelude::*;
|
||||
use tracing_subscriber::registry;
|
||||
|
||||
const ROOT_PATH: &str = ".";
|
||||
const ARROW_FILE_PATH: &str = "node_modules/superstore-arrow/superstore.arrow";
|
||||
|
||||
#[cfg(feature = "_hack")]
|
||||
const SERVER_ADDRESS: &str = "0.0.0.0:3000";
|
||||
|
||||
/// A local error synonym for this module only.
|
||||
type AppError = Box<dyn std::error::Error + Send + Sync>;
|
||||
|
||||
/// Load the example Apache Arrow file from disk and create a
|
||||
/// [`perspective::Table`] named "my_data_source".
|
||||
async fn load_server_arrow(server: &Server) -> Result<(), AppError> {
|
||||
let client = server.new_local_client();
|
||||
let mut file = File::open(std::path::Path::new(ROOT_PATH).join(ARROW_FILE_PATH))?;
|
||||
let mut feather = Vec::with_capacity(file.metadata()?.len() as usize);
|
||||
file.read_to_end(&mut feather)?;
|
||||
let data = UpdateData::Arrow(feather.into());
|
||||
let mut options = TableInitOptions::default();
|
||||
options.set_name("my_data_source");
|
||||
client.table(data.into(), options).await?;
|
||||
client.close().await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Host a combination HTTP file server + WebSocket server, which serves a
|
||||
/// simple Perspective application. The app's HTML, etc., assets are served
|
||||
/// from the root, while the app's embedded WebAssembly [`perspective::Client`]
|
||||
/// will connect to this server over a WebSocket via the path `/ws`.
|
||||
async fn start_web_server_and_block(_server: Server) -> Result<(), AppError> {
|
||||
#[cfg(feature = "_hack")]
|
||||
{
|
||||
let app = Router::new()
|
||||
.route("/", get_service(ServeFile::new("src/index.html")))
|
||||
.route("/ws", perspective::axum::websocket_handler())
|
||||
.fallback_service(ServeDir::new(ROOT_PATH))
|
||||
.with_state(_server)
|
||||
.layer(TraceLayer::new_for_http());
|
||||
|
||||
let service = app.into_make_service_with_connect_info::<SocketAddr>();
|
||||
let listener = tokio::net::TcpListener::bind(SERVER_ADDRESS).await?;
|
||||
tracing::info!("listening on {}", listener.local_addr()?);
|
||||
axum::serve(listener, service).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::main(flavor = "multi_thread")]
|
||||
async fn main() -> Result<(), AppError> {
|
||||
registry()
|
||||
.with(layer().compact().with_filter(LevelFilter::INFO))
|
||||
.init();
|
||||
|
||||
let server = Server::new(None);
|
||||
load_server_arrow(&server).await?;
|
||||
start_web_server_and_block(server).await?;
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user