swisseph-wasm 0.0.1 โ 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +329 -7
- package/examples/basic-usage.js +2 -1
- package/examples/birth-chart.js +2 -1
- package/examples/demo.html +691 -23
- package/package.json +4 -4
- package/wsam/swisseph.js +160 -14
package/README.md
CHANGED
|
@@ -4,13 +4,30 @@ A high-precision JavaScript wrapper for the Swiss Ephemeris WebAssembly module,
|
|
|
4
4
|
|
|
5
5
|
## ๐ Features
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
7
|
+
- **๐ฏ High Precision**: Based on the renowned Swiss Ephemeris
|
|
8
|
+
- **โก WebAssembly Performance**: Fast calculations in browser and Node.js
|
|
9
|
+
- **๐ Cross-Platform**: Works in Node.js, browsers, Vue.js, React, and more
|
|
10
|
+
- **๐ฆ Zero Dependencies**: Self-contained with embedded WASM
|
|
11
|
+
- **๐ง Easy Integration**: Simple import, works with all modern bundlers
|
|
12
|
+
- **๐ Comprehensive API**: Full access to Swiss Ephemeris functions
|
|
13
|
+
- **๐ป Modern JavaScript**: ES6+ with async/await support
|
|
14
|
+
- **๐งช Well Tested**: 106 tests with 86% coverage
|
|
15
|
+
- **๐ Complete Documentation**: Extensive guides and examples
|
|
16
|
+
- **๐ข Professional Grade**: Suitable for commercial applications
|
|
17
|
+
- **๐ CDN Ready**: Available via jsdelivr CDN for quick prototyping
|
|
18
|
+
|
|
19
|
+
## ๐ Live Demo
|
|
20
|
+
|
|
21
|
+
**Try it now**: [Interactive SwissEph Demo](https://prolaxu.github.io/swisseph-wasm/examples/demo.html)
|
|
22
|
+
|
|
23
|
+
Experience all features including:
|
|
24
|
+
- ๐ Real-time planetary positions
|
|
25
|
+
- ๐ Birth chart calculations
|
|
26
|
+
- โ๏ธ Sidereal vs Tropical comparisons
|
|
27
|
+
- ๐ House system calculations
|
|
28
|
+
- ๐ Planetary aspects analysis
|
|
29
|
+
- ๐ง Interactive API explorer
|
|
30
|
+
- ๐ Visual astrological charts
|
|
14
31
|
|
|
15
32
|
## ๐ฆ Installation
|
|
16
33
|
|
|
@@ -29,6 +46,14 @@ yarn add swisseph-wasm
|
|
|
29
46
|
pnpm add swisseph-wasm
|
|
30
47
|
```
|
|
31
48
|
|
|
49
|
+
### CDN (Browser)
|
|
50
|
+
```html
|
|
51
|
+
<script type="module">
|
|
52
|
+
import SwissEph from 'https://cdn.jsdelivr.net/gh/prolaxu/swisseph-wasm@main/src/swisseph.js';
|
|
53
|
+
// Your code here
|
|
54
|
+
</script>
|
|
55
|
+
```
|
|
56
|
+
|
|
32
57
|
## ๐ฆ What's Included
|
|
33
58
|
|
|
34
59
|
- **Core Library** (`src/swisseph.js`) - Main JavaScript wrapper
|
|
@@ -41,6 +66,8 @@ pnpm add swisseph-wasm
|
|
|
41
66
|
|
|
42
67
|
## ๐ Quick Start
|
|
43
68
|
|
|
69
|
+
> **๐ Want to see it in action first?** Try the [Interactive Demo](https://prolaxu.github.io/swisseph-wasm/examples/demo.html)
|
|
70
|
+
|
|
44
71
|
### Basic Usage
|
|
45
72
|
|
|
46
73
|
```javascript
|
|
@@ -84,6 +111,218 @@ Object.entries(chart.planets).forEach(([name, planet]) => {
|
|
|
84
111
|
calculator.destroy();
|
|
85
112
|
```
|
|
86
113
|
|
|
114
|
+
## ๐ Cross-Platform Usage
|
|
115
|
+
|
|
116
|
+
SwissEph WebAssembly works seamlessly across different environments. Here are platform-specific setup instructions:
|
|
117
|
+
|
|
118
|
+
### Node.js
|
|
119
|
+
```javascript
|
|
120
|
+
import SwissEph from 'swisseph-wasm';
|
|
121
|
+
|
|
122
|
+
async function nodeExample() {
|
|
123
|
+
const swe = new SwissEph();
|
|
124
|
+
await swe.initSwissEph();
|
|
125
|
+
|
|
126
|
+
const jd = swe.julday(2023, 6, 15, 12.0);
|
|
127
|
+
const sunPos = swe.calc_ut(jd, swe.SE_SUN, swe.SEFLG_SWIEPH);
|
|
128
|
+
|
|
129
|
+
console.log(`Sun longitude: ${sunPos[0].toFixed(2)}ยฐ`);
|
|
130
|
+
swe.close();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
nodeExample().catch(console.error);
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Vite (Vue.js, React, etc.)
|
|
137
|
+
Add this configuration to your `vite.config.js`:
|
|
138
|
+
|
|
139
|
+
```javascript
|
|
140
|
+
import { defineConfig } from 'vite'
|
|
141
|
+
import vue from '@vitejs/plugin-vue' // or react, etc.
|
|
142
|
+
|
|
143
|
+
export default defineConfig({
|
|
144
|
+
plugins: [vue()],
|
|
145
|
+
server: {
|
|
146
|
+
fs: {
|
|
147
|
+
allow: ['..']
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
assetsInclude: ['**/*.wasm'],
|
|
151
|
+
optimizeDeps: {
|
|
152
|
+
exclude: ['swisseph-wasm']
|
|
153
|
+
}
|
|
154
|
+
})
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Vue.js Component
|
|
158
|
+
```vue
|
|
159
|
+
<script setup>
|
|
160
|
+
import SwissEph from 'swisseph-wasm';
|
|
161
|
+
import { onMounted, onUnmounted, ref } from 'vue';
|
|
162
|
+
|
|
163
|
+
const swe = ref(null);
|
|
164
|
+
const isInitialized = ref(false);
|
|
165
|
+
const result = ref('');
|
|
166
|
+
|
|
167
|
+
onMounted(async () => {
|
|
168
|
+
try {
|
|
169
|
+
swe.value = new SwissEph();
|
|
170
|
+
await swe.value.initSwissEph();
|
|
171
|
+
isInitialized.value = true;
|
|
172
|
+
} catch (error) {
|
|
173
|
+
console.error('Failed to initialize SwissEph:', error);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
onUnmounted(() => {
|
|
178
|
+
if (swe.value) {
|
|
179
|
+
swe.value.close();
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
const calculate = () => {
|
|
184
|
+
if (!isInitialized.value) return;
|
|
185
|
+
|
|
186
|
+
const jd = swe.value.julday(2023, 6, 15, 12.0);
|
|
187
|
+
const sunPos = swe.value.calc_ut(jd, swe.value.SE_SUN, swe.value.SEFLG_SWIEPH);
|
|
188
|
+
result.value = `Sun: ${sunPos[0].toFixed(2)}ยฐ`;
|
|
189
|
+
};
|
|
190
|
+
</script>
|
|
191
|
+
|
|
192
|
+
<template>
|
|
193
|
+
<div>
|
|
194
|
+
<button @click="calculate" :disabled="!isInitialized">
|
|
195
|
+
Calculate Sun Position
|
|
196
|
+
</button>
|
|
197
|
+
<p>{{ result }}</p>
|
|
198
|
+
</div>
|
|
199
|
+
</template>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### React Component
|
|
203
|
+
```jsx
|
|
204
|
+
import React, { useState, useEffect } from 'react';
|
|
205
|
+
import SwissEph from 'swisseph-wasm';
|
|
206
|
+
|
|
207
|
+
function AstrologyCalculator() {
|
|
208
|
+
const [swe, setSwe] = useState(null);
|
|
209
|
+
const [isInitialized, setIsInitialized] = useState(false);
|
|
210
|
+
const [result, setResult] = useState('');
|
|
211
|
+
|
|
212
|
+
useEffect(() => {
|
|
213
|
+
const initSwissEph = async () => {
|
|
214
|
+
try {
|
|
215
|
+
const swissEph = new SwissEph();
|
|
216
|
+
await swissEph.initSwissEph();
|
|
217
|
+
setSwe(swissEph);
|
|
218
|
+
setIsInitialized(true);
|
|
219
|
+
} catch (error) {
|
|
220
|
+
console.error('Failed to initialize SwissEph:', error);
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
initSwissEph();
|
|
225
|
+
|
|
226
|
+
return () => {
|
|
227
|
+
if (swe) {
|
|
228
|
+
swe.close();
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
}, []);
|
|
232
|
+
|
|
233
|
+
const calculate = () => {
|
|
234
|
+
if (!isInitialized || !swe) return;
|
|
235
|
+
|
|
236
|
+
const jd = swe.julday(2023, 6, 15, 12.0);
|
|
237
|
+
const sunPos = swe.calc_ut(jd, swe.SE_SUN, swe.SEFLG_SWIEPH);
|
|
238
|
+
setResult(`Sun: ${sunPos[0].toFixed(2)}ยฐ`);
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
return (
|
|
242
|
+
<div>
|
|
243
|
+
<button onClick={calculate} disabled={!isInitialized}>
|
|
244
|
+
Calculate Sun Position
|
|
245
|
+
</button>
|
|
246
|
+
<p>{result}</p>
|
|
247
|
+
</div>
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export default AstrologyCalculator;
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Vanilla HTML + JavaScript
|
|
255
|
+
```html
|
|
256
|
+
<!DOCTYPE html>
|
|
257
|
+
<html>
|
|
258
|
+
<head>
|
|
259
|
+
<title>SwissEph Example</title>
|
|
260
|
+
</head>
|
|
261
|
+
<body>
|
|
262
|
+
<button id="calculate">Calculate Sun Position</button>
|
|
263
|
+
<div id="result"></div>
|
|
264
|
+
|
|
265
|
+
<script type="module">
|
|
266
|
+
import SwissEph from 'https://cdn.jsdelivr.net/gh/prolaxu/swisseph-wasm@main/src/swisseph.js';
|
|
267
|
+
|
|
268
|
+
let swe = null;
|
|
269
|
+
let isInitialized = false;
|
|
270
|
+
|
|
271
|
+
// Initialize SwissEph
|
|
272
|
+
(async () => {
|
|
273
|
+
try {
|
|
274
|
+
swe = new SwissEph();
|
|
275
|
+
await swe.initSwissEph();
|
|
276
|
+
isInitialized = true;
|
|
277
|
+
console.log('SwissEph initialized successfully');
|
|
278
|
+
} catch (error) {
|
|
279
|
+
console.error('Failed to initialize SwissEph:', error);
|
|
280
|
+
}
|
|
281
|
+
})();
|
|
282
|
+
|
|
283
|
+
// Calculate button handler
|
|
284
|
+
document.getElementById('calculate').addEventListener('click', () => {
|
|
285
|
+
if (!isInitialized || !swe) {
|
|
286
|
+
document.getElementById('result').textContent = 'SwissEph not initialized';
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const jd = swe.julday(2023, 6, 15, 12.0);
|
|
291
|
+
const sunPos = swe.calc_ut(jd, swe.SE_SUN, swe.SEFLG_SWIEPH);
|
|
292
|
+
document.getElementById('result').textContent = `Sun: ${sunPos[0].toFixed(2)}ยฐ`;
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
// Cleanup on page unload
|
|
296
|
+
window.addEventListener('beforeunload', () => {
|
|
297
|
+
if (swe) {
|
|
298
|
+
swe.close();
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
</script>
|
|
302
|
+
</body>
|
|
303
|
+
</html>
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Webpack Configuration
|
|
307
|
+
If using Webpack, add this to your `webpack.config.js`:
|
|
308
|
+
|
|
309
|
+
```javascript
|
|
310
|
+
module.exports = {
|
|
311
|
+
// ... other config
|
|
312
|
+
experiments: {
|
|
313
|
+
asyncWebAssembly: true,
|
|
314
|
+
},
|
|
315
|
+
module: {
|
|
316
|
+
rules: [
|
|
317
|
+
{
|
|
318
|
+
test: /\.wasm$/,
|
|
319
|
+
type: 'webassembly/async',
|
|
320
|
+
},
|
|
321
|
+
],
|
|
322
|
+
},
|
|
323
|
+
};
|
|
324
|
+
```
|
|
325
|
+
|
|
87
326
|
## ๐ Documentation
|
|
88
327
|
|
|
89
328
|
| Document | Description |
|
|
@@ -178,8 +417,91 @@ swiss-wasm/
|
|
|
178
417
|
- ES6 modules support
|
|
179
418
|
- Async/await support
|
|
180
419
|
|
|
420
|
+
## ๐ง Troubleshooting
|
|
421
|
+
|
|
422
|
+
### Common Issues and Solutions
|
|
423
|
+
|
|
424
|
+
#### WASM Loading Errors in Vite/Vue.js
|
|
425
|
+
**Error**: `WebAssembly.instantiate(): expected magic word 00 61 73 6d, found 3c 21 64 6f`
|
|
426
|
+
|
|
427
|
+
**Solution**: Add Vite configuration to your `vite.config.js`:
|
|
428
|
+
```javascript
|
|
429
|
+
export default defineConfig({
|
|
430
|
+
plugins: [vue()],
|
|
431
|
+
server: {
|
|
432
|
+
fs: { allow: ['..'] }
|
|
433
|
+
},
|
|
434
|
+
assetsInclude: ['**/*.wasm'],
|
|
435
|
+
optimizeDeps: {
|
|
436
|
+
exclude: ['swisseph-wasm']
|
|
437
|
+
}
|
|
438
|
+
})
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
#### Import Errors in Node.js
|
|
442
|
+
**Error**: `Cannot read properties of undefined (reading 'ccall')`
|
|
443
|
+
|
|
444
|
+
**Solution**: Always call `await swe.initSwissEph()` before using any methods:
|
|
445
|
+
```javascript
|
|
446
|
+
const swe = new SwissEph();
|
|
447
|
+
await swe.initSwissEph(); // Required!
|
|
448
|
+
const jd = swe.julday(2023, 6, 15, 12.0);
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
#### Browser Process Errors
|
|
452
|
+
**Error**: `process is not defined` in browser
|
|
453
|
+
|
|
454
|
+
**Solution**: This is fixed in the latest version. Update to the latest version:
|
|
455
|
+
```bash
|
|
456
|
+
npm update swisseph-wasm
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
#### Memory Issues
|
|
460
|
+
**Error**: Out of memory or performance issues
|
|
461
|
+
|
|
462
|
+
**Solution**: Always call `swe.close()` when done:
|
|
463
|
+
```javascript
|
|
464
|
+
try {
|
|
465
|
+
const swe = new SwissEph();
|
|
466
|
+
await swe.initSwissEph();
|
|
467
|
+
// ... your calculations
|
|
468
|
+
} finally {
|
|
469
|
+
swe.close(); // Always clean up!
|
|
470
|
+
}
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
#### CDN Import Issues
|
|
474
|
+
**Error**: Module not found when using CDN
|
|
475
|
+
|
|
476
|
+
**Solution**: Use the correct CDN URL:
|
|
477
|
+
```javascript
|
|
478
|
+
// โ
Correct
|
|
479
|
+
import SwissEph from 'https://cdn.jsdelivr.net/gh/prolaxu/swisseph-wasm@main/src/swisseph.js';
|
|
480
|
+
|
|
481
|
+
// โ Incorrect
|
|
482
|
+
import SwissEph from 'https://cdn.jsdelivr.net/npm/swisseph-wasm';
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
#### TypeScript Errors
|
|
486
|
+
**Error**: Type definitions not found
|
|
487
|
+
|
|
488
|
+
**Solution**: Types are included in the package:
|
|
489
|
+
```typescript
|
|
490
|
+
import SwissEph from 'swisseph-wasm';
|
|
491
|
+
// Types are automatically available
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
### Performance Tips
|
|
495
|
+
|
|
496
|
+
1. **Reuse instances**: Create one SwissEph instance and reuse it for multiple calculations
|
|
497
|
+
2. **Batch calculations**: Calculate multiple planets in one session rather than creating new instances
|
|
498
|
+
3. **Memory management**: Always call `close()` when done
|
|
499
|
+
4. **Async initialization**: Use `await swe.initSwissEph()` only once per instance
|
|
500
|
+
|
|
181
501
|
## ๐ก Examples
|
|
182
502
|
|
|
503
|
+
> **๐ Interactive Examples**: Try all these examples and more in the [Live Demo](https://prolaxu.github.io/swisseph-wasm/examples/demo.html)
|
|
504
|
+
|
|
183
505
|
### Current Planetary Positions
|
|
184
506
|
```javascript
|
|
185
507
|
async function getCurrentPositions() {
|
package/examples/basic-usage.js
CHANGED
|
@@ -296,6 +296,7 @@ export {
|
|
|
296
296
|
};
|
|
297
297
|
|
|
298
298
|
// Run examples if this file is executed directly
|
|
299
|
-
if
|
|
299
|
+
// Check if running in Node.js and if this is the main module
|
|
300
|
+
if (typeof process !== 'undefined' && process.argv && import.meta.url === `file://${process.argv[1]}`) {
|
|
300
301
|
runAllExamples().catch(console.error);
|
|
301
302
|
}
|
package/examples/birth-chart.js
CHANGED
|
@@ -381,6 +381,7 @@ async function exampleBirthChart() {
|
|
|
381
381
|
export { BirthChartCalculator, exampleBirthChart };
|
|
382
382
|
|
|
383
383
|
// Run example if this file is executed directly
|
|
384
|
-
if
|
|
384
|
+
// Check if running in Node.js and if this is the main module
|
|
385
|
+
if (typeof process !== 'undefined' && process.argv && import.meta.url === `file://${process.argv[1]}`) {
|
|
385
386
|
exampleBirthChart().catch(console.error);
|
|
386
387
|
}
|