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 CHANGED
@@ -4,13 +4,30 @@ A high-precision JavaScript wrapper for the Swiss Ephemeris WebAssembly module,
4
4
 
5
5
  ## ๐ŸŒŸ Features
6
6
 
7
- - **High Precision**: Based on the renowned Swiss Ephemeris
8
- - **WebAssembly Performance**: Fast calculations in the browser and Node.js
9
- - **Comprehensive API**: Full access to Swiss Ephemeris functions
10
- - **Modern JavaScript**: ES6+ with async/await support
11
- - **Well Tested**: 106 tests with 86% coverage
12
- - **Complete Documentation**: Extensive guides and examples
13
- - **Professional Grade**: Suitable for commercial applications
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() {
@@ -296,6 +296,7 @@ export {
296
296
  };
297
297
 
298
298
  // Run examples if this file is executed directly
299
- if (import.meta.url === `file://${process.argv[1]}`) {
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
  }
@@ -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 (import.meta.url === `file://${process.argv[1]}`) {
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
  }