jpsx 0.1.16

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.
Files changed (45) hide show
  1. package/README.md +242 -0
  2. package/dist/api/__tests__/compile.test.d.ts +2 -0
  3. package/dist/api/__tests__/compile.test.d.ts.map +1 -0
  4. package/dist/api/__tests__/compile.test.js +336 -0
  5. package/dist/api/__tests__/runtime.test.d.ts +2 -0
  6. package/dist/api/__tests__/runtime.test.d.ts.map +1 -0
  7. package/dist/api/__tests__/runtime.test.js +275 -0
  8. package/dist/api/advanced.d.ts +100 -0
  9. package/dist/api/advanced.d.ts.map +1 -0
  10. package/dist/api/advanced.js +192 -0
  11. package/dist/api/benchmark.d.ts +87 -0
  12. package/dist/api/benchmark.d.ts.map +1 -0
  13. package/dist/api/benchmark.js +147 -0
  14. package/dist/api/index.d.ts +88 -0
  15. package/dist/api/index.d.ts.map +1 -0
  16. package/dist/api/index.js +304 -0
  17. package/dist/ast/types.d.ts +141 -0
  18. package/dist/ast/types.d.ts.map +1 -0
  19. package/dist/ast/types.js +1 -0
  20. package/dist/cli/index.d.ts +3 -0
  21. package/dist/cli/index.d.ts.map +1 -0
  22. package/dist/cli/index.js +155 -0
  23. package/dist/cli.js +30 -0
  24. package/dist/generator/generator.d.ts +3 -0
  25. package/dist/generator/generator.d.ts.map +1 -0
  26. package/dist/generator/generator.js +175 -0
  27. package/dist/lexer/lexer.d.ts +3 -0
  28. package/dist/lexer/lexer.d.ts.map +1 -0
  29. package/dist/lexer/lexer.js +23 -0
  30. package/dist/lexer/tokenizer.d.ts +9 -0
  31. package/dist/lexer/tokenizer.d.ts.map +1 -0
  32. package/dist/lexer/tokenizer.js +240 -0
  33. package/dist/parser/grammar.d.ts +29 -0
  34. package/dist/parser/grammar.d.ts.map +1 -0
  35. package/dist/parser/grammar.js +312 -0
  36. package/dist/parser/parser.d.ts +4 -0
  37. package/dist/parser/parser.d.ts.map +1 -0
  38. package/dist/parser/parser.js +47 -0
  39. package/dist/runtime/index.d.ts +24 -0
  40. package/dist/runtime/index.d.ts.map +1 -0
  41. package/dist/runtime/index.js +108 -0
  42. package/dist/transformer/transformer.d.ts +3 -0
  43. package/dist/transformer/transformer.d.ts.map +1 -0
  44. package/dist/transformer/transformer.js +318 -0
  45. package/package.json +54 -0
package/README.md ADDED
@@ -0,0 +1,242 @@
1
+ # JPS (Just Python Script)
2
+
3
+ A Python-like language that compiles to JavaScript, designed to integrate seamlessly with **any frontend framework**.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/jps.svg)](https://www.npmjs.com/package/jps)
6
+ [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](LICENSE)
7
+
8
+ ## ✨ Features
9
+
10
+ - 🐍 **Python-like syntax** that compiles to clean JavaScript
11
+ - ⚡ **Standalone file integration** - Import `.jps` files like `.jsx/.tsx` files!
12
+ - 🔥 **Hot Module Replacement (HMR)** - Instant feedback during development
13
+ - ⚡ **Zero-config integration** with React, Vue, Svelte, Angular, and more
14
+ - 📦 **Multiple output formats**: ESM, CommonJS, IIFE, UMD
15
+ - 🔌 **Flexible runtime modes**: Inline, external, CDN, or custom
16
+ - 🛠️ **Build tool plugins** for Vite, Webpack, Rollup, esbuild
17
+ - 🌐 **Browser-ready**: Works without any build step
18
+ - 📝 **TypeScript support** with auto-generated declarations
19
+
20
+ ## 🚀 Quick Start
21
+
22
+ ### Standalone File Integration (⚡ Recommended)
23
+
24
+ Import `.jps` files directly in your code - just like `.tsx` files!
25
+
26
+ ```python
27
+ # math.jps - a real file!
28
+ def add(a, b):
29
+ return a + b
30
+
31
+ class Calculator:
32
+ def __init__(self):
33
+ self.value = 0
34
+ ```
35
+
36
+ ```typescript
37
+ // App.tsx - just import and use!
38
+ import { add, Calculator } from './math.jps';
39
+
40
+ const sum = add(10, 20);
41
+ const calc = new Calculator();
42
+ ```
43
+
44
+ **[See full example →](examples/react-vite-standalone/)**
45
+
46
+ ---
47
+
48
+ ### As a CLI Tool
49
+
50
+ ```bash
51
+ # Install globally
52
+ npm install -g jps
53
+
54
+ # Create a new project
55
+ jps init my-project
56
+ cd my-project
57
+ jps run main.jps
58
+ ```
59
+
60
+ ### As a Library (Runtime Compilation)
61
+
62
+ ```bash
63
+ # Install in your project
64
+ npm install jps
65
+ ```
66
+
67
+ #### React
68
+
69
+ ```javascript
70
+ import { compile } from 'jps';
71
+
72
+ function App() {
73
+ const jpsCode = `
74
+ def greet(name):
75
+ return "Hello, " + name
76
+
77
+ print(greet("React"))
78
+ `;
79
+
80
+ const result = compile(jpsCode, {
81
+ format: 'iife',
82
+ runtimeMode: 'inline'
83
+ });
84
+
85
+ eval(result.code); // Outputs: Hello, React
86
+ }
87
+ ```
88
+
89
+ #### Vue
90
+
91
+ ```vue
92
+ <script setup>
93
+ import { compile } from 'jps';
94
+ const result = compile('print("Hello Vue!")', {
95
+ format: 'iife',
96
+ runtimeMode: 'inline'
97
+ });
98
+ eval(result.code);
99
+ </script>
100
+ ```
101
+
102
+ #### Browser (No Build Step)
103
+
104
+ ```html
105
+ <script type="module">
106
+ import { compile } from 'https://cdn.jsdelivr.net/npm/jps@latest/dist/api/index.js';
107
+ const result = compile('print("Hello Browser!")', {
108
+ format: 'iife',
109
+ runtimeMode: 'inline'
110
+ });
111
+ eval(result.code);
112
+ </script>
113
+ ```
114
+
115
+ ## 📖 Documentation
116
+
117
+ - **[Standalone File Integration](docs/STANDALONE_INTEGRATION.md)** - ⚡ Import .jps like .tsx (recommended!)
118
+ - **[Integration Guide](docs/INTEGRATION.md)** - Complete guide for all frameworks
119
+ - **[Quick Start](docs/QUICKSTART.md)** - 30-second integration examples
120
+ - **[Syntax Guide](docs/syntax.md)** - JPS language syntax
121
+ - **[Standard Library](docs/stdlib.md)** - Built-in functions
122
+ - **[API Reference](docs/API.md)** - Programmatic API
123
+
124
+ ## 🎯 Use Cases
125
+
126
+ - **Code Playgrounds**: Build interactive Python-like editors
127
+ - **Educational Tools**: Teach Python concepts in the browser
128
+ - **Scripting**: Add Python-like scripting to your JavaScript app
129
+ - **DSL**: Create domain-specific languages with Python syntax
130
+ - **Prototyping**: Rapid development with Python-like syntax
131
+
132
+ ## 📦 CLI Commands
133
+
134
+ - `jps build <file>` - Compile JPS to JavaScript
135
+ - `jps run <file>` - Compile and execute
136
+ - `jps watch <file>` - Watch for changes and recompile
137
+ - `jps init [name]` - Initialize a new JPS project
138
+ - `jps doctor` - Verify environment setup
139
+
140
+ ## 🔧 Programmatic API
141
+
142
+ ```javascript
143
+ import { compile, compileToJS, getRuntime } from 'jps';
144
+
145
+ // Full API with metadata
146
+ const result = compile(source, {
147
+ format: 'esm', // Output format: 'esm' | 'cjs' | 'iife' | 'umd'
148
+ runtimeMode: 'inline', // Runtime: 'inline' | 'external' | 'cdn' | 'none'
149
+ moduleName: 'MyApp', // For IIFE/UMD
150
+ sourceMap: true, // Include source maps
151
+ standalone: false // Bundle everything
152
+ });
153
+
154
+ // Simple API (just returns code)
155
+ const jsCode = compileToJS(source);
156
+
157
+ // Get runtime library code
158
+ const runtime = getRuntime();
159
+ ```
160
+
161
+ ## 🎨 Framework Examples
162
+
163
+ Check out the [examples/](examples/) directory for complete working examples:
164
+
165
+ - **React** - Vite plugin, Webpack loader, runtime compilation
166
+ - **Vue 3** - Composition API integration
167
+ - **Svelte** - Component integration
168
+ - **Angular** - Service integration
169
+ - **Next.js** - App Router and Pages Router
170
+ - **Vanilla Browser** - No build step required
171
+
172
+ ## 🛠️ Build Tool Plugins
173
+
174
+ ### Vite
175
+
176
+ ```javascript
177
+ // vite.config.js
178
+ import { jpsPlugin } from './vite-plugin-jps';
179
+
180
+ export default {
181
+ plugins: [jpsPlugin()]
182
+ };
183
+ ```
184
+
185
+ ### Webpack
186
+
187
+ ```javascript
188
+ // webpack.config.js
189
+ module.exports = {
190
+ module: {
191
+ rules: [
192
+ { test: /\.jps$/, use: 'jps-loader' }
193
+ ]
194
+ }
195
+ };
196
+ ```
197
+
198
+ See [INTEGRATION.md](docs/INTEGRATION.md) for Rollup, esbuild, and more.
199
+
200
+ ## 🌟 Why JPS?
201
+
202
+ 1. **Framework Agnostic**: Works with React, Vue, Svelte, Angular, and vanilla JS
203
+ 2. **Flexible Output**: Choose the format that fits your needs
204
+ 3. **Modern & Production-Ready**: Built with TypeScript, full test coverage
205
+ 4. **Developer Friendly**: Simple API, great error messages, comprehensive docs
206
+ 5. **Lightweight**: Minimal dependencies, tree-shakeable
207
+
208
+ ## 🏗️ Development
209
+
210
+ Prerequisites: Node.js 18+
211
+
212
+ ```bash
213
+ # Clone the repository
214
+ git clone https://github.com/your-repo/jps.git
215
+ cd jps
216
+
217
+ # Install dependencies
218
+ npm install
219
+
220
+ # Build the project
221
+ npm run build
222
+
223
+ # Run tests
224
+ npm test
225
+ ```
226
+
227
+ ## 📄 License
228
+
229
+ ISC - See [LICENSE](LICENSE) file for details
230
+
231
+ ## 🤝 Contributing
232
+
233
+ Contributions are welcome! Please read our contributing guidelines first.
234
+
235
+ ## 📮 Support
236
+
237
+ - **Issues**: [GitHub Issues](https://github.com/your-repo/jps/issues)
238
+ - **Discussions**: [GitHub Discussions](https://github.com/your-repo/jps/discussions)
239
+
240
+ ---
241
+
242
+ **Made with ❤️ by Loaii abdalslam**
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=compile.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.test.d.ts","sourceRoot":"","sources":["../../../src/api/__tests__/compile.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,336 @@
1
+ import { compile, compileToJS, getRuntime } from "../index.js";
2
+ describe("compile() - Basic Functionality", () => {
3
+ test("should compile simple JPS code", () => {
4
+ const source = 'print("Hello World")';
5
+ const result = compile(source);
6
+ expect(result.code).toBeDefined();
7
+ expect(result.code).toContain("print");
8
+ expect(result.code).toContain("Hello World");
9
+ });
10
+ test("should return CompileResult with code property", () => {
11
+ const source = 'x = 5';
12
+ const result = compile(source);
13
+ expect(result).toHaveProperty("code");
14
+ expect(typeof result.code).toBe("string");
15
+ });
16
+ test("should compile function definitions", () => {
17
+ const source = `
18
+ def greet(name):
19
+ return "Hello, " + name
20
+
21
+ print(greet("World"))
22
+ `;
23
+ const result = compile(source);
24
+ expect(result.code).toContain("function greet");
25
+ expect(result.code).toContain("return");
26
+ });
27
+ test("should compile list comprehensions", () => {
28
+ const source = '[x * 2 for x in range(5)]';
29
+ const result = compile(source);
30
+ expect(result.code).toContain("for");
31
+ expect(result.code).toContain("push");
32
+ });
33
+ test("should handle multiple statements", () => {
34
+ const source = `
35
+ x = 10
36
+ y = 20
37
+ z = x + y
38
+ print(z)
39
+ `;
40
+ const result = compile(source);
41
+ expect(result.code).toContain("var x");
42
+ expect(result.code).toContain("var y");
43
+ expect(result.code).toContain("var z");
44
+ });
45
+ });
46
+ describe("compile() - Output Formats", () => {
47
+ const source = 'print("test")';
48
+ test("should generate ESM format by default", () => {
49
+ const result = compile(source);
50
+ expect(result.code).toContain("import");
51
+ });
52
+ test("should generate ESM format when specified", () => {
53
+ const result = compile(source, { format: "esm" });
54
+ expect(result.code).toContain("import {");
55
+ expect(result.code).toMatch(/from\s+['"]/);
56
+ });
57
+ test("should generate CommonJS format", () => {
58
+ const result = compile(source, { format: "cjs" });
59
+ expect(result.code).toContain("require");
60
+ expect(result.code).toMatch(/const\s+{.*}\s*=\s*require/);
61
+ });
62
+ test("should generate IIFE format", () => {
63
+ const result = compile(source, { format: "iife", moduleName: "TestModule" });
64
+ expect(result.code).toContain("(function");
65
+ expect(result.code).toContain("TestModule");
66
+ });
67
+ test("should generate UMD format", () => {
68
+ const result = compile(source, { format: "umd", moduleName: "TestLib" });
69
+ expect(result.code).toContain("define.amd");
70
+ expect(result.code).toContain("module.exports");
71
+ expect(result.code).toContain("TestLib");
72
+ });
73
+ });
74
+ describe("compile() - Runtime Modes", () => {
75
+ const source = 'print("test")';
76
+ test("should use external runtime by default", () => {
77
+ const result = compile(source);
78
+ expect(result.code).toContain("./jps_runtime.js");
79
+ });
80
+ test("should use external runtime mode", () => {
81
+ const result = compile(source, { runtimeMode: "external" });
82
+ expect(result.code).toContain("jps_runtime");
83
+ });
84
+ test("should inline runtime code", () => {
85
+ const result = compile(source, { runtimeMode: "inline" });
86
+ expect(result.code).toContain("function print");
87
+ expect(result.code).toContain("function range");
88
+ expect(result.code).not.toContain("import");
89
+ });
90
+ test("should use CDN runtime with custom URL", () => {
91
+ const cdnUrl = "https://example.com/runtime.js";
92
+ const result = compile(source, { runtimeMode: "cdn", cdnUrl });
93
+ expect(result.code).toContain(cdnUrl);
94
+ });
95
+ test("should use default CDN URL", () => {
96
+ const result = compile(source, { runtimeMode: "cdn" });
97
+ expect(result.code).toContain("cdn.jsdelivr.net");
98
+ });
99
+ test("should exclude runtime when mode is none", () => {
100
+ const result = compile(source, { runtimeMode: "none" });
101
+ expect(result.code).not.toContain("import");
102
+ expect(result.code).not.toContain("require");
103
+ expect(result.code).not.toContain("function print");
104
+ });
105
+ });
106
+ describe("compile() - Source Maps", () => {
107
+ const source = 'x = 10';
108
+ test("should not include source map by default", () => {
109
+ const result = compile(source);
110
+ expect(result.map).toBeUndefined();
111
+ expect(result.ast).toBeUndefined();
112
+ });
113
+ test("should include AST when sourceMap is enabled", () => {
114
+ const result = compile(source, { sourceMap: true });
115
+ expect(result.ast).toBeDefined();
116
+ expect(result.ast).toHaveProperty("body");
117
+ });
118
+ });
119
+ describe("compile() - Module Names", () => {
120
+ const source = 'print("test")';
121
+ test("should use custom module name in IIFE", () => {
122
+ const result = compile(source, {
123
+ format: "iife",
124
+ moduleName: "MyCustomApp",
125
+ runtimeMode: "inline"
126
+ });
127
+ expect(result.code).toContain("MyCustomApp");
128
+ });
129
+ test("should use custom module name in UMD", () => {
130
+ const result = compile(source, {
131
+ format: "umd",
132
+ moduleName: "MyLibrary"
133
+ });
134
+ expect(result.code).toContain("MyLibrary");
135
+ });
136
+ test("should use default module name when not specified", () => {
137
+ const result = compile(source, {
138
+ format: "iife",
139
+ runtimeMode: "inline"
140
+ });
141
+ expect(result.code).toContain("JPSModule");
142
+ });
143
+ });
144
+ describe("compile() - Error Handling", () => {
145
+ test("should throw error for invalid syntax", () => {
146
+ const source = "def invalid syntax here";
147
+ expect(() => compile(source)).toThrow();
148
+ });
149
+ test("should provide error details", () => {
150
+ const source = "this is not valid jps";
151
+ try {
152
+ compile(source);
153
+ fail("Should have thrown an error");
154
+ }
155
+ catch (error) {
156
+ expect(error).toBeDefined();
157
+ }
158
+ });
159
+ });
160
+ describe("compile() - Complex Programs", () => {
161
+ test("should compile classes", () => {
162
+ const source = `
163
+ class Person:
164
+ def __init__(self, name):
165
+ self.name = name
166
+
167
+ def greet(self):
168
+ return "Hello, " + self.name
169
+ `;
170
+ const result = compile(source);
171
+ expect(result.code).toContain("class Person");
172
+ });
173
+ test("should compile control flow", () => {
174
+ const source = `
175
+ if x > 5:
176
+ print("big")
177
+ else:
178
+ print("small")
179
+ `;
180
+ const result = compile(source);
181
+ expect(result.code).toContain("if");
182
+ expect(result.code).toContain("else");
183
+ });
184
+ test("should compile loops", () => {
185
+ const source = `
186
+ for i in range(10):
187
+ print(i)
188
+ `;
189
+ const result = compile(source);
190
+ expect(result.code).toContain("for");
191
+ });
192
+ test("should compile while loops", () => {
193
+ const source = `
194
+ while x < 10:
195
+ x = x + 1
196
+ `;
197
+ const result = compile(source);
198
+ expect(result.code).toContain("while");
199
+ });
200
+ test("should compile try-catch", () => {
201
+ const source = `
202
+ try:
203
+ risky_operation()
204
+ except:
205
+ print("error")
206
+ `;
207
+ const result = compile(source);
208
+ expect(result.code).toContain("try");
209
+ expect(result.code).toContain("catch");
210
+ });
211
+ });
212
+ describe("compileToJS() - Simplified API", () => {
213
+ test("should return only JavaScript code as string", () => {
214
+ const source = 'print("test")';
215
+ const result = compileToJS(source);
216
+ expect(typeof result).toBe("string");
217
+ expect(result).toContain("print");
218
+ });
219
+ test("should accept options", () => {
220
+ const source = 'print("test")';
221
+ const result = compileToJS(source, {
222
+ format: "iife",
223
+ runtimeMode: "inline"
224
+ });
225
+ expect(result).toContain("function");
226
+ expect(result).toContain("print");
227
+ });
228
+ });
229
+ describe("getRuntime()", () => {
230
+ test("should return runtime code as string", () => {
231
+ const runtime = getRuntime();
232
+ expect(typeof runtime).toBe("string");
233
+ expect(runtime).toContain("function print");
234
+ });
235
+ test("should include all runtime functions", () => {
236
+ const runtime = getRuntime();
237
+ expect(runtime).toContain("function print");
238
+ expect(runtime).toContain("function range");
239
+ expect(runtime).toContain("function sum");
240
+ expect(runtime).toContain("function len");
241
+ expect(runtime).toContain("function min");
242
+ expect(runtime).toContain("function max");
243
+ expect(runtime).toContain("function sorted");
244
+ expect(runtime).toContain("function str");
245
+ expect(runtime).toContain("function int");
246
+ expect(runtime).toContain("function float");
247
+ expect(runtime).toContain("function map");
248
+ expect(runtime).toContain("function filter");
249
+ expect(runtime).toContain("function list");
250
+ });
251
+ });
252
+ describe("Integration Tests - Runtime Execution", () => {
253
+ test("should execute compiled code with inline runtime", () => {
254
+ const source = `
255
+ def add(a, b):
256
+ return a + b
257
+
258
+ result = add(2, 3)
259
+ `;
260
+ const compiled = compile(source, {
261
+ format: "iife",
262
+ runtimeMode: "inline",
263
+ moduleName: "TestApp"
264
+ });
265
+ // This would need actual execution in a real test
266
+ expect(compiled.code).toContain("function add");
267
+ });
268
+ test("should handle runtime functions in compiled code", () => {
269
+ const source = `
270
+ numbers = range(5)
271
+ total = sum(numbers)
272
+ print(total)
273
+ `;
274
+ const compiled = compile(source, {
275
+ format: "iife",
276
+ runtimeMode: "inline"
277
+ });
278
+ expect(compiled.code).toContain("range");
279
+ expect(compiled.code).toContain("sum");
280
+ expect(compiled.code).toContain("print");
281
+ });
282
+ });
283
+ describe("Edge Cases", () => {
284
+ test("should handle empty source", () => {
285
+ const result = compile("");
286
+ expect(result.code).toBeDefined();
287
+ });
288
+ test("should handle source with only comments", () => {
289
+ const source = "# This is a comment";
290
+ const result = compile(source);
291
+ expect(result.code).toBeDefined();
292
+ });
293
+ test("should handle source with special characters", () => {
294
+ const source = 'print("Hello! @#$%^&*()")';
295
+ const result = compile(source);
296
+ expect(result.code).toContain("Hello");
297
+ });
298
+ test("should handle unicode characters", () => {
299
+ const source = 'print("こんにちは 世界")';
300
+ const result = compile(source);
301
+ expect(result.code).toContain("こんにちは");
302
+ });
303
+ });
304
+ describe("Format Combinations", () => {
305
+ const source = 'print("test")';
306
+ test("ESM + inline runtime", () => {
307
+ const result = compile(source, {
308
+ format: "esm",
309
+ runtimeMode: "inline"
310
+ });
311
+ expect(result.code).toContain("function print");
312
+ expect(result.code).not.toContain("import");
313
+ });
314
+ test("CommonJS + inline runtime", () => {
315
+ const result = compile(source, {
316
+ format: "cjs",
317
+ runtimeMode: "inline"
318
+ });
319
+ expect(result.code).toContain("function print");
320
+ expect(result.code).not.toContain("require");
321
+ });
322
+ test("IIFE + CDN runtime", () => {
323
+ const result = compile(source, {
324
+ format: "iife",
325
+ runtimeMode: "cdn"
326
+ });
327
+ expect(result.code).toContain("function");
328
+ });
329
+ test("UMD + external runtime", () => {
330
+ const result = compile(source, {
331
+ format: "umd",
332
+ runtimeMode: "external"
333
+ });
334
+ expect(result.code).toContain("define.amd");
335
+ });
336
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=runtime.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.test.d.ts","sourceRoot":"","sources":["../../../src/api/__tests__/runtime.test.ts"],"names":[],"mappings":""}