A lightweight, reactive JavaScript library for embedding and controlling EIDOS visualizations in web applications. Built with Valtio for natural object mutations and AJV for comprehensive schema validation.
npm install @oceanum/eidosA lightweight, reactive JavaScript library for embedding and controlling EIDOS visualizations in web applications. Built with Valtio for natural object mutations and AJV for comprehensive schema validation.
- 🚀 Natural API: Mutate EIDOS specs using standard JavaScript object assignment
- ⚡ Reactive Updates: Changes automatically propagate to the renderer via JSON patches
- 🔍 Schema Validation: Comprehensive validation using AJV with detailed error messages
- 🎯 Framework Agnostic: Works with React, Vue, Svelte, and vanilla JavaScript
- 📦 Lightweight: Small bundle size with efficient reactivity
- 🔒 Type Safe: Full TypeScript support
``bash`
npm install @oceanum/eidos
`tsx
import { EidosProvider, useEidosSpec } from "@oceanum/eidos";
// Define your EIDOS specification
const initialSpec = {
version: "0.9",
id: "my-app",
name: "My Visualization",
root: {
id: "root",
nodeType: "world",
children: [],
},
data: [],
};
function App() {
return (
options={{
renderer: "https://render.eidos.oceanum.io",
eventListener: (event) => console.log("Event:", event),
}}
>
);
}
// In any child component
function YourComponent() {
const spec = useEidosSpec();
const addLayer = () => {
// Mutate spec directly - changes propagate automatically to iframe
spec.root.children.push({
id: "new-layer",
nodeType: "worldlayer",
layerType: "track",
});
};
return ;
}
`
`javascript
import { render } from "@oceanum/eidos";
// Define your EIDOS specification
const spec = {
version: "0.9",
id: "my-app",
name: "My Visualization",
root: {
id: "root",
nodeType: "world",
children: [],
},
data: [],
};
// Render in a container element
const container = document.getElementById("eidos-container");
const result = await render(container, spec, {
renderer: "https://render.eidos.oceanum.io",
eventListener: (event) => {
console.log("Received event:", event);
},
});
// Mutate the spec naturally - changes propagate automatically
result.spec.name = "Updated Visualization";
result.spec.root.children.push({
id: "layer-1",
nodeType: "worldlayer",
layerType: "track",
});
// Clean up when done
result.destroy();
`
The React Context API allows you to easily manage multiple EIDOS instances in the same application. Each EidosProvider creates its own isolated context with its own iframe and spec.
Option 1: Multiple Providers (Recommended)
`tsx
import { EidosProvider, useEidosSpec } from "@oceanum/eidos";
function App() {
return (
{/ Chart view /}
options={{ renderer: EIDOS_URL }}
>
function MapControls() {
const spec = useEidosSpec(); // Gets mapSpec from nearest provider
// Mutations only affect this instance
const zoomIn = () => {
spec.root.viewState.zoom += 1;
};
return ;
}
function ChartControls() {
const spec = useEidosSpec(); // Gets chartSpec from nearest provider
// Completely isolated from MapControls
const updateData = () => {
spec.data[0].dataSpec = newData;
};
return ;
}
`
Option 2: Low-Level Render API
For more control, use the render() function directly:
`tsx
import { render } from "@oceanum/eidos";
import { useEffect, useRef, useState } from "react";
function MultiInstance() {
const container1 = useRef(null);
const container2 = useRef(null);
const [specs, setSpecs] = useState({ map: null, chart: null });
useEffect(() => {
const init = async () => {
const map = await render(container1.current, mapSpec, { renderer: EIDOS_URL });
const chart = await render(container2.current, chartSpec, { renderer: EIDOS_URL });
setSpecs({ map: map.spec, chart: chart.spec });
return () => {
map.destroy();
chart.destroy();
};
};
init();
}, []);
const updateMap = () => {
if (specs.map) {
specs.map.root.viewState.zoom += 1;
}
};
return (
Key Points for Multiple Instances:
- ✅ Each instance has its own iframe and spec proxy
- ✅ Changes to one instance don't affect others
- ✅
useEidosSpec() always returns the spec from the nearest EidosProvider ancestor
- ✅ Use unique id values in your specs to avoid conflicts
- ✅ Each instance can connect to the same or different renderer URLsFramework Integration
- React Integration - Hooks, components, and patterns
- Vue.js Integration - Composition API and component examples
- Svelte Integration - Stores and reactive patterns
- Vanilla JavaScript - Pure JavaScript examples
API Reference
$3
####
Renders an EIDOS iframe and provides the spec proxy to all child components via React Context.
Props:
-
initialSpec (required): The EIDOS specification object
- options (optional): Render options
- renderer (string): URL of the EIDOS renderer (default: https://render.eidos.oceanum.io)
- eventListener (function): Callback for events from the renderer
- authToken (string | function): Authentication token for data fetching
- containerStyle (optional): CSS styles for the iframe container (default: { width: '100%', height: '100%', position: 'absolute' })
- onInitialized (optional): Callback called with the spec proxy after initializationExample:
`tsx
initialSpec={mySpec}
options={{
renderer: "https://render.eidos.oceanum.io",
eventListener: (event) => console.log(event),
}}
containerStyle={{ width: '100vw', height: '100vh' }}
onInitialized={(spec) => console.log('Ready!', spec)}
>
####
useEidosSpec()Hook that returns the EIDOS spec proxy from the nearest
EidosProvider ancestor.Returns:
Proxy - The spec proxy (read and mutate directly)Throws: Error if not used within an
EidosProviderExample:
`tsx
function MyComponent() {
const spec = useEidosSpec(); // Read from spec
const layerCount = spec.root.children.length;
// Mutate spec - changes sync to iframe automatically
const addLayer = () => {
spec.root.children.push({
id: 'new-layer',
nodeType: 'worldlayer',
});
};
return ;
}
`$3
####
render(element, spec, options)Low-level function to render EIDOS in a DOM element. Use this for vanilla JavaScript or when you need more control than
EidosProvider offers.Parameters:
-
element (HTMLElement): Container element for the iframe
- spec (EidosSpec): The EIDOS specification
- options (RenderOptions): Configuration options
- renderer (string): Renderer URL
- eventListener (function): Event callback
- authToken (string | function): Auth token
- id (string): Optional override for spec IDReturns:
Promise
- spec: The reactive spec proxy
- iframe: The iframe element
- updateAuth(token): Function to update auth token
- destroy(): Cleanup functionExample:
`javascript
const result = await render(container, spec, {
renderer: EIDOS_URL,
eventListener: (e) => console.log(e),
});result.spec.data.push(newData);
// Clean up
result.destroy();
``- Core API - Complete API documentation
- Events - Event handling and communication
- Validation - Schema validation details
Check out the examples directory for complete working examples in different frameworks.
This library is part of the oceanum-js project. Please see the main repository for contribution guidelines.
MIT License - see the main oceanum-js repository for details.