1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#![doc(
    html_favicon_url = "https://observation.tools/img/favicon.svg",
    html_logo_url = "https://observation.tools/img/logo.svg",
    issue_tracker_base_url = "https://github.com/Dig-Doug/observation-tools-client/issues/"
)]
//!
//! # Quickstart
//!
//! Observation Tools helps you quickly inspect complex data without needing to
//! build your own visualization tools.
//!
//! Integrating Observation Tools into your program takes about 5 minutes. You
//! need to:
//!
//! 1. Create a project
//! 2. Install a client library
//! 3. Export your data
//! 5. Visualize your data
//!
//! ### Organizing your data
//!
//! We use four different concepts to organize your data:
//!
//! - **Artifacts** are individual pieces of data, e.g. an image
//! - **Artifact groups** help organize artifacts and can define how artifacts
//!   can be visualized together.
//! - **Runs** are the top level artifact groups. The normally correspond to one
//!   program execution or http request.
//! - **Projects** allow you to define common settings used across runs.
//!
//! ## Create a project
//!
//! All data uploaded to Observation Tools is associated with a project.
//! Projects have a unique ID that you'll use to initialize the client in the
//! next step.
//!
//! To create a project, do the following:
//! 1. Sign in to the [dashboard](https://app.observation.tools/)
//! 1. Click "Create project"
//!
//! You should see your project's ID on the following screen. You can also find
//! it on the "Settings" page. Project IDs are not sensitive, so you can embed
//! them in your source code.
//!
//! ## Install a client library
//!
//! We have client libraries for a few different languages:
//!
//! | Language | Package | Version|
//! |----------|---------| -------|
//! | Rust     | `observation-tools` | [![Crates.io](https://img.shields.io/crates/v/observation-tools)](https://crates.io/crates/observation-tools) |
//! | JavaScript **experimental** | `@observation-tools/client` | [![npm(scoped)](https://img.shields.io/npm/v/%40observation-tools/client)](https://www.npmjs.com/package/@observation-tools/client) |
//!
//! Don't see the language you're looking for? Let us know! File a [feature request](https://github.com/Dig-Doug/observation-tools-client/issues) or [email us](mailto:help@observation.tools).
//!
//! Install the Rust client with the following command:
//!
//! ```sh
//! cargo add observation-tools
//! ```
//!
//! ## Export your data
//!
//! To start exporting data from your program, we need to set up a client for
//! your project and create a run. After that, we can create groups to organize
//! artifacts during different parts of our program and export artifacts:
//!
//! ```rust
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! use observation_tools_client::artifacts::Point2Builder;
//! use observation_tools_client::artifacts::Segment2Builder;
//! use observation_tools_client::Client;
//! use observation_tools_client::ClientOptions;
//! use observation_tools_client::TokenGenerator;
//!
//! let client = Client::new(
//!     std::env::var("OBSERVATION_TOOLS_PROJECT_ID")?,
//!     ClientOptions::default(),
//! )?;
//!
//! /// The name of the run will show up in the UI. You can optionally add key-value metadata to
//! /// all objects, see [`builders::UserMetadataBuilder::add_metadata`].
//! let run_uploader = client.create_run("getting-started-example")?;
//! /// ArtifactGroups are represented as "uploaders"
//! let uploader_2d = run_uploader.child_uploader_2d("shapes")?;
//! uploader_2d.create_object2(
//!     "segment2",
//!     Segment2Builder::new(Point2Builder::new(-1.0, 1.0), Point2Builder::new(1.0, -1.0)),
//! )?;
//!
//! println!("See the output at: {}", run_uploader.viewer_url());
//! # Ok(())
//! # }
//! ```
//!
//! For more information on the types of data you can upload, see the
//! documentation for the [`artifacts`] module.
//!
//! ## Visualize your data
//!
//! To view the exported data, you can either find the run on the [dashboard](https://app.observation.tools/) or generate a direct url with [`groups::RunUploader::viewer_url`].
//!
//! # Examples
//! For more examples, check out the [examples](https://github.com/Dig-Doug/observation-tools-client/tree/main/examples) directory in the repository.
extern crate alloc;
extern crate core;

pub mod artifacts;
mod client;
mod generated;
pub mod groups;
mod run_id;
mod task_handle;
mod task_loop;
mod token_generator;
mod util;
// TODO: https://github.com/rust-lang/rust/issues/67295
pub mod test_utils;

pub use crate::client::Client;
pub use crate::client::ClientOptions;
use crate::generated::ArtifactId;
pub use crate::task_handle::ArtifactUploadHandle;
pub use crate::task_handle::ArtifactUploader2dTaskHandle;
pub use crate::task_handle::ArtifactUploader3dTaskHandle;
pub(crate) use crate::task_handle::BaseArtifactUploaderTaskHandle;
pub use crate::task_handle::GenericArtifactUploaderTaskHandle;
pub use crate::task_handle::PublicArtifactIdTaskHandle;
pub use crate::task_handle::PublicSeriesIdTaskHandle;
pub use crate::task_handle::RunUploaderTaskHandle;
pub use crate::token_generator::TokenGenerator;
pub use crate::util::ClientError;
use tracing_wasm::WASMLayerConfigBuilder;
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
#[derive(Debug, Clone)]
pub struct PublicArtifactId {
    pub(crate) id: ArtifactId,
}

#[wasm_bindgen(start)]
pub fn start() -> Result<(), JsValue> {
    // print pretty errors in wasm https://github.com/rustwasm/console_error_panic_hook
    // This is not needed for tracing_wasm to work, but it is a common tool for
    // getting proper error line numbers for panics.
    console_error_panic_hook::set_once();

    let mut config_builder = WASMLayerConfigBuilder::new();
    #[cfg(not(debug_assertions))]
    config_builder.set_max_level(tracing::Level::WARN);
    tracing_wasm::set_as_global_default_with_config(config_builder.build());

    Ok(())
}