# cspice **Repository Path**: llmllm/cspice ## Basic Information - **Project Name**: cspice - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-08-18 - **Last Updated**: 2025-08-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # CSPICE Toolkit This is unofficial copy of [NASA/JPL SPICE Toolkit for C](https://naif.jpl.nasa.gov/naif/toolkit.html) patched for cross-platform compatibility (Linux, macOS, Windows and Web). Please refer to the [original SPICE Toolkit for C documentation](https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/index.html).
## Build ### Linux ```sh cd src ./mk_linux.csh ``` The resulting library path is: `/lib/libcspice.a` ### macOS ```sh cd src ./mk_mac.csh ``` The resulting library path is: `/lib/libcspice.a` ### Windows #### Dynamic-Link Library (.dll) From Visual Studio command line: ```bat cd \src mk_dll.bat ``` The resulting library files are: - `\bin\cspice.dll` - `\lib\cspice_dll.lib` - `\lib\cspice_dll.exp` #### Static Library (.lib) From Visual Studio command line: ```bat cd \src mk_static.bat ``` The resulting library file is: `\lib\cspice.lib` ### WebAssembly 1. Install [Emscripten](https://emscripten.org) 2. Build the static library: ```sh cd src ./mk_wasm.csh ``` The resulting library path is: `/lib/libcspice_wasm.a` 3. Build `cspice.wasm` and JavaScript glue code for use in Web Workers (`cspice.worker.js`) and in Node.js (`cspice.node.js`) ```sh cd wasm ./build_wasm.sh ``` Modify `EXPORTED_FUNCTIONS` in `build_wasm.sh` to include all required SPICE functions into `.wasm`/`.js` files. Modify `kernels/wasm.tm` to select the SPICE kernels you want to load. Note that `wasm.tm` and `itrf93.tf` kernels are **embedded** into the JavaScript glue code. ### How to use CSpice WebAssembly in React app It is recommended to use [Create React App](https://create-react-app.dev/) (and don't eject it) since it's greatly simplifies the app maintenance. 1. Copy `cspice.worker.js` to `src/spice/cspice.js` (Development and Production) 2. Copy `cspice.node.js` to `src/spice/__mocks__/cspice.js` (Testing with Jest) 3. Copy (or symlink) `cspice.wasm` to `public/spice` and `src/spice/__mocks__` folders 4. Copy (or symlink) all SPICE kernels you want to use to the respective folders: `public/spice/kernels/(fk|lsk|pck|spk)` 5. Create file system initialization code, e.g.: `src/spice/filesystem.js` ```JavaScript export function mountFileSystem(instance) { const fs = instance.FS; fs.mkdir('/kernels'); fs.mount(instance.IDBFS, {}, '/kernels'); // initialize file system with data from persistent source fs.syncfs(true, (err) => { if (err) return; // link missing kernels try { fs.lookupPath('/kernels/leapseconds.tls', {}); } catch (err) { fs.createLazyFile('/kernels', 'leapseconds.tls', '/spice/kernels/lsk/leapseconds.tls', true, false)); } try { fs.lookupPath('/kernels/de440s.bsp', {}); } catch (err) { fs.createLazyFile('/kernels', 'de440s.bsp', '/spice/kernels/spk/de440s.bsp', true, false)); } // save file system to persistent source fs.syncfs(() => null); }); } ``` `src/spice/__mocks__/filesystem.js` ```JavaScript import { readFileSync } from 'fs'; function copyFile(fileSystem, dest, src) { const stream = fileSystem.open(dest, 'w'); const data = readFileSync(src); fileSystem.write(stream, data, 0, data.length, 0); fileSystem.close(stream); } export function mountFileSystem(instance) { instance.FS.mkdir('/kernels'); copyFile(instance.FS, '/kernels/leapseconds.tls', '/spice/kernels/lsk/leapseconds.tls'); copyFile(instance.FS, '/kernels/de440s.bsp', '/spice/kernels/spk/de440s.bsp'); } ``` **Make sure you created/copied all the required kernel files in both Web Worker and Node.js (mocked) code.** 6. Create Web Worker and its wrapper for Jest: `src/workers/spice.worker.js` ```JavaScript import cSpice from '../spice/cspice'; import { mountFileSystem } from '../spice/filesystem'; const instance = await cSpice(); mountFileSystem(instance); export tkvrsn_c = async (str) => instance.ccall('tkvrsn_c', 'string', ['string'], [str]); ``` `src/workers/__mocks__/spice.worker.js` ```JavaScript import * as SpiceWorker from '../spice.worker'; const spiceWorker = () => SpiceWorker; export default spiceWorker; ``` 7. Install [workerize-loader](https://github.com/developit/workerize-loader) 8. Add Jest config `moduleNameMapper` option to `package.json`: ```json "jest": { "moduleNameMapper": { "^.*/spice/(.*)": "/src/spice/__mocks__/$1", "^workerize-loader!(.*)/workers/(.*)": "/src/workers/__mocks__/$2" } } ``` 9. Create React hook and use it in functional components: `src/hooks/useSpiceWorker.js` ```JavaScript import createWorker from 'workerize-loader!../workers/spice.worker'; const spiceWorker = createWorker(); export const useSpiceWorker = () => spiceWorker; ``` `src/components/Component.jsx` ```JavaScript import React, { useState, useEffect } from 'react'; import { useSpiceWorker } from '../hooks/useSpiceWorker'; export const Component = () => { const { tkvrsn_c } = useSpiceWorker(); const [ver, setVer] = useState(); useEffect(() => { tkvrsn_c('TOOLKIT').then(setVer).catch(({ message }) => setVer(message)); }, [tkvrsn_c]); return
{ver || 'Loading...'}
; }; ``` 10. If you use [Storybook](https://storybook.js.org/): Set `globalObject` to `'this'` in Webpack config, e.g. in `.storybook/main.js`: ```JavaScript module.exports = { webpackFinal: (config) => { config.output.globalObject = 'this'; return config; } }; ```