@ynor/ynor 1.0.2 â 1.0.3
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 +95 -0
- package/package.json +2 -2
- package/src/App.ynor +67 -0
- package/src/app.d.ts +13 -0
- package/src/lib/assets/favicon.ico +0 -0
- package/src/lib/assets/logo.png +0 -0
- package/src/lib/components/Counter.ynor +117 -0
- package/src/lib/components/MyComponent.ynor +24 -0
- package/src/lib/components/TodoList.ynor +241 -0
- package/src/lib/core/index.js +3 -9
- package/src/main.js +44 -0
- package/src/routes/+layout.svelte +22 -0
- package/src/routes/+page.svelte +54 -0
- package/src/styles/global.css +57 -0
- package/src/utils/errors.js +115 -0
package/README.md
CHANGED
|
@@ -14,3 +14,98 @@ A lightweight, next-generation JavaScript extension framework inspired by Svelte
|
|
|
14
14
|
- **đ Cross-browser**: Works in all modern browsers
|
|
15
15
|
|
|
16
16
|
## Project Structure
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
`đ ynor/
|
|
20
|
+
âââ đ .svelte-kit/
|
|
21
|
+
â âââ đ generated/
|
|
22
|
+
â â âââ đ client/
|
|
23
|
+
â â â âââ đ nodes/
|
|
24
|
+
â â â â âââ đ 0.js [.js] (1 lines)
|
|
25
|
+
â â â â âââ đ 1.js [.js] (1 lines)
|
|
26
|
+
â â â â âââ đ 2.js [.js] (1 lines)
|
|
27
|
+
â â â âââ đ app.js [.js] (39 lines)
|
|
28
|
+
â â â âââ đ matchers.js [.js] (1 lines)
|
|
29
|
+
â â âââ đ server/
|
|
30
|
+
â â â âââ đ internal.js [.js] (56 lines)
|
|
31
|
+
â â âââ đ shared/
|
|
32
|
+
â â â âââ đ error-template.js [.js] (1 lines)
|
|
33
|
+
â â âââ đ root.js [.js] (3 lines)
|
|
34
|
+
â â âââ đ root.svelte [.svelte] (68 lines)
|
|
35
|
+
â âââ đ types/
|
|
36
|
+
â â âââ đ src/
|
|
37
|
+
â â â âââ đ routes/
|
|
38
|
+
â â â âââ đ $types.d.ts [.ts] (23 lines)
|
|
39
|
+
â â âââ đ route_meta_data.json [.json] (3 lines)
|
|
40
|
+
â âââ đ ambient.d.ts [.ts] (361 lines)
|
|
41
|
+
â âââ đ env.d.ts [.ts] (1 lines)
|
|
42
|
+
â âââ đ non-ambient.d.ts [.ts] (43 lines)
|
|
43
|
+
â âââ đ tsconfig.json [.json] (56 lines)
|
|
44
|
+
âââ đ .vscode/
|
|
45
|
+
â âââ đ extensions.json [.json] (4 lines)
|
|
46
|
+
âââ đ scripts/
|
|
47
|
+
â âââ đ gen_readme.js [.js] (473 lines)
|
|
48
|
+
â âââ đ gen_tree.cjs [.cjs]
|
|
49
|
+
â âââ đ git_init.js [.js] (508 lines)
|
|
50
|
+
â âââ đ git_update.js [.js] (565 lines)
|
|
51
|
+
âââ đ src/
|
|
52
|
+
â âââ đ lib/
|
|
53
|
+
â â âââ đ assets/
|
|
54
|
+
â â â âââ đ favicon.ico [.ico]
|
|
55
|
+
â â â âââ đ logo.png [.png]
|
|
56
|
+
â â âââ đ components/
|
|
57
|
+
â â â âââ đ Counter.ynor [.ynor]
|
|
58
|
+
â â â âââ đ MyComponent.ynor [.ynor]
|
|
59
|
+
â â â âââ đ TodoList.ynor [.ynor]
|
|
60
|
+
â â âââ đ core/
|
|
61
|
+
â â âââ đ compiler.d.ts [.ts] (294 lines)
|
|
62
|
+
â â âââ đ compiler.js [.js] (842 lines)
|
|
63
|
+
â â âââ đ index.js [.js] (43 lines)
|
|
64
|
+
â â âââ đ plugin.js [.js] (109 lines)
|
|
65
|
+
â â âââ đ runtime.js [.js] (102 lines)
|
|
66
|
+
â âââ đ routes/
|
|
67
|
+
â â âââ đ +layout.svelte [.svelte] (22 lines)
|
|
68
|
+
â â âââ đ +page.svelte [.svelte] (54 lines)
|
|
69
|
+
â âââ đ styles/
|
|
70
|
+
â â âââ đ global.css [.css] (57 lines)
|
|
71
|
+
â âââ đ app.d.ts [.ts] (14 lines)
|
|
72
|
+
â âââ đ App.ynor [.ynor]
|
|
73
|
+
â âââ đ main.js [.js] (28 lines)
|
|
74
|
+
âââ đ static/
|
|
75
|
+
â âââ đ favicon.ico [.ico]
|
|
76
|
+
â âââ đ logo.png [.png]
|
|
77
|
+
â âââ đ robots.txt [.txt] (4 lines)
|
|
78
|
+
âââ đ .gitignore [(no extension)]
|
|
79
|
+
âââ đ .npmrc [(no extension)]
|
|
80
|
+
âââ đ index.html [.html] (30 lines)
|
|
81
|
+
âââ đ jsconfig.json [.json] (20 lines)
|
|
82
|
+
âââ đ package.json [.json] (53 lines)
|
|
83
|
+
âââ đ README.md [.md] (17 lines)
|
|
84
|
+
âââ đ svelte.config.js [.js] (15 lines)
|
|
85
|
+
âââ đ vite.config.js [.js] (27 lines)
|
|
86
|
+
âââ đ ynor.config.js [.js] (23 lines)
|
|
87
|
+
|
|
88
|
+
đ SUMMARY
|
|
89
|
+
===========
|
|
90
|
+
Total Directories: 19
|
|
91
|
+
Total Files: 48
|
|
92
|
+
Total Lines of Code: 3962
|
|
93
|
+
|
|
94
|
+
đ FILE EXTENSIONS
|
|
95
|
+
==================
|
|
96
|
+
.js: 19 files
|
|
97
|
+
.ts: 6 files
|
|
98
|
+
.json: 5 files
|
|
99
|
+
.ynor: 4 files
|
|
100
|
+
.svelte: 3 files
|
|
101
|
+
no extension: 2 files
|
|
102
|
+
.ico: 2 files
|
|
103
|
+
.png: 2 files
|
|
104
|
+
.html: 1 file
|
|
105
|
+
.md: 1 file
|
|
106
|
+
.cjs: 1 file
|
|
107
|
+
.css: 1 file
|
|
108
|
+
.txt: 1 file
|
|
109
|
+
|
|
110
|
+
Generated: 29/06/2026, 11:57:18 am
|
|
111
|
+
`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ynor/ynor",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "⥠Lightweight next-gen JS extension framework like Svelte",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/lib/core/index.js",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"ynor": "./bin/ynor.js"
|
|
27
27
|
},
|
|
28
28
|
"files": [
|
|
29
|
-
"src/
|
|
29
|
+
"src/",
|
|
30
30
|
"bin/",
|
|
31
31
|
"README.md",
|
|
32
32
|
"LICENSE",
|
package/src/App.ynor
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<!-- src/App.ynor -->
|
|
2
|
+
<script>
|
|
3
|
+
// Define variables on 'this'
|
|
4
|
+
this.count = 0;
|
|
5
|
+
|
|
6
|
+
// Define function - make sure it's properly bound
|
|
7
|
+
this.increment = function() {
|
|
8
|
+
this.count = this.count + 1;
|
|
9
|
+
console.log('Count:', this.count);
|
|
10
|
+
this._update();
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
console.log('đ§ App.ynor script loaded');
|
|
14
|
+
console.log('đ§ this.increment:', this.increment);
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<style>
|
|
18
|
+
.app {
|
|
19
|
+
padding: 40px;
|
|
20
|
+
text-align: center;
|
|
21
|
+
font-family: system-ui, sans-serif;
|
|
22
|
+
background: white;
|
|
23
|
+
border-radius: 20px;
|
|
24
|
+
max-width: 600px;
|
|
25
|
+
margin: 20px auto;
|
|
26
|
+
box-shadow: 0 8px 30px rgba(0,0,0,0.08);
|
|
27
|
+
}
|
|
28
|
+
.app h1 {
|
|
29
|
+
color: #4f46e5;
|
|
30
|
+
font-size: 2.5rem;
|
|
31
|
+
margin-bottom: 10px;
|
|
32
|
+
}
|
|
33
|
+
.app p {
|
|
34
|
+
font-size: 1.2rem;
|
|
35
|
+
color: #1e293b;
|
|
36
|
+
}
|
|
37
|
+
.count {
|
|
38
|
+
font-size: 3rem;
|
|
39
|
+
font-weight: 700;
|
|
40
|
+
color: #4f46e5;
|
|
41
|
+
margin: 20px 0;
|
|
42
|
+
}
|
|
43
|
+
.app button {
|
|
44
|
+
padding: 10px 24px;
|
|
45
|
+
border: none;
|
|
46
|
+
border-radius: 40px;
|
|
47
|
+
background: #4f46e5;
|
|
48
|
+
color: white;
|
|
49
|
+
font-weight: 600;
|
|
50
|
+
cursor: pointer;
|
|
51
|
+
font-size: 16px;
|
|
52
|
+
transition: all 0.2s;
|
|
53
|
+
}
|
|
54
|
+
.app button:hover {
|
|
55
|
+
background: #4338ca;
|
|
56
|
+
transform: scale(1.02);
|
|
57
|
+
}
|
|
58
|
+
</style>
|
|
59
|
+
|
|
60
|
+
<template>
|
|
61
|
+
<div class="app">
|
|
62
|
+
<h1>⥠.ynor</h1>
|
|
63
|
+
<p>Framework is working!</p>
|
|
64
|
+
<div class="count">{count}</div>
|
|
65
|
+
<button on:click={increment}>Increment</button>
|
|
66
|
+
</div>
|
|
67
|
+
</template>
|
package/src/app.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// See https://svelte.dev/docs/kit/types#app.d.ts
|
|
2
|
+
// for information about these interfaces
|
|
3
|
+
declare global {
|
|
4
|
+
namespace App {
|
|
5
|
+
// interface Error {}
|
|
6
|
+
// interface Locals {}
|
|
7
|
+
// interface PageData {}
|
|
8
|
+
// interface PageState {}
|
|
9
|
+
// interface Platform {}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export {};
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
<!-- src/components/Counter.ynor -->
|
|
2
|
+
<script>
|
|
3
|
+
let count = 0;
|
|
4
|
+
let step = 1;
|
|
5
|
+
|
|
6
|
+
// Reactive statement
|
|
7
|
+
$: console.log(`Count is now: ${count}`);
|
|
8
|
+
|
|
9
|
+
function increment() {
|
|
10
|
+
count += step;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function decrement() {
|
|
14
|
+
count -= step;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function reset() {
|
|
18
|
+
count = 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function setCount(value) {
|
|
22
|
+
count = value;
|
|
23
|
+
}
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<style>
|
|
27
|
+
.counter-container {
|
|
28
|
+
background: white;
|
|
29
|
+
border-radius: 20px;
|
|
30
|
+
padding: 30px;
|
|
31
|
+
box-shadow: 0 8px 30px rgba(0,0,0,0.08);
|
|
32
|
+
text-align: center;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.counter-number {
|
|
36
|
+
font-size: 4rem;
|
|
37
|
+
font-weight: 700;
|
|
38
|
+
margin: 20px 0;
|
|
39
|
+
color: #4f46e5;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.counter-controls {
|
|
43
|
+
display: flex;
|
|
44
|
+
gap: 12px;
|
|
45
|
+
justify-content: center;
|
|
46
|
+
flex-wrap: wrap;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.counter-controls button {
|
|
50
|
+
padding: 10px 24px;
|
|
51
|
+
border: none;
|
|
52
|
+
border-radius: 40px;
|
|
53
|
+
font-weight: 600;
|
|
54
|
+
cursor: pointer;
|
|
55
|
+
transition: all 0.2s;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.btn-primary {
|
|
59
|
+
background: #4f46e5;
|
|
60
|
+
color: white;
|
|
61
|
+
box-shadow: 0 4px 12px rgba(79,70,229,0.25);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.btn-secondary {
|
|
65
|
+
background: #e2e8f0;
|
|
66
|
+
color: #1e293b;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.btn-primary:hover, .btn-secondary:hover {
|
|
70
|
+
transform: scale(1.05);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.step-control {
|
|
74
|
+
margin-top: 20px;
|
|
75
|
+
display: flex;
|
|
76
|
+
align-items: center;
|
|
77
|
+
gap: 16px;
|
|
78
|
+
justify-content: center;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.step-control input[type="range"] {
|
|
82
|
+
width: 200px;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.badge {
|
|
86
|
+
background: #eef2ff;
|
|
87
|
+
color: #4f46e5;
|
|
88
|
+
padding: 4px 16px;
|
|
89
|
+
border-radius: 40px;
|
|
90
|
+
font-size: 0.9rem;
|
|
91
|
+
font-weight: 500;
|
|
92
|
+
}
|
|
93
|
+
</style>
|
|
94
|
+
|
|
95
|
+
<template>
|
|
96
|
+
<div class="counter-container">
|
|
97
|
+
<h2>Counter</h2>
|
|
98
|
+
<div class="counter-number">{count}</div>
|
|
99
|
+
|
|
100
|
+
<div class="counter-controls">
|
|
101
|
+
<button class="btn-secondary" on:click={decrement}>-</button>
|
|
102
|
+
<button class="btn-primary" on:click={increment}>+</button>
|
|
103
|
+
<button class="btn-secondary" on:click={reset}>Reset</button>
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
<div class="step-control">
|
|
107
|
+
<span>Step:</span>
|
|
108
|
+
<input
|
|
109
|
+
type="range"
|
|
110
|
+
min="1"
|
|
111
|
+
max="10"
|
|
112
|
+
bind:value={step}
|
|
113
|
+
/>
|
|
114
|
+
<span class="badge">+{step}</span>
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
</template>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<!-- src/components/MyComponent.ynor -->
|
|
2
|
+
<script>
|
|
3
|
+
let count = 0;
|
|
4
|
+
$: console.log(`Count: ${count}`);
|
|
5
|
+
|
|
6
|
+
function increment() {
|
|
7
|
+
count++;
|
|
8
|
+
}
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<style>
|
|
12
|
+
.my-component {
|
|
13
|
+
padding: 20px;
|
|
14
|
+
background: white;
|
|
15
|
+
border-radius: 10px;
|
|
16
|
+
}
|
|
17
|
+
</style>
|
|
18
|
+
|
|
19
|
+
<template>
|
|
20
|
+
<div class="my-component">
|
|
21
|
+
<h2>Count: {count}</h2>
|
|
22
|
+
<button on:click={increment}>+</button>
|
|
23
|
+
</div>
|
|
24
|
+
</template>
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
<!-- src/components/TodoList.ynor -->
|
|
2
|
+
<script>
|
|
3
|
+
import { store } from '../lib/runtime.js';
|
|
4
|
+
|
|
5
|
+
let newTodo = '';
|
|
6
|
+
let filter = 'all';
|
|
7
|
+
let todos = [];
|
|
8
|
+
|
|
9
|
+
// Get store
|
|
10
|
+
const todosStore = store('todos', []);
|
|
11
|
+
|
|
12
|
+
// Subscribe to store
|
|
13
|
+
todosStore.subscribe(value => {
|
|
14
|
+
todos = value;
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
function addTodo() {
|
|
18
|
+
if (!newTodo.trim()) return;
|
|
19
|
+
const newTodos = [...todos, {
|
|
20
|
+
id: Date.now(),
|
|
21
|
+
text: newTodo.trim(),
|
|
22
|
+
done: false
|
|
23
|
+
}];
|
|
24
|
+
todosStore.set(newTodos);
|
|
25
|
+
newTodo = '';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function toggleTodo(id) {
|
|
29
|
+
const newTodos = todos.map(t =>
|
|
30
|
+
t.id === id ? { ...t, done: !t.done } : t
|
|
31
|
+
);
|
|
32
|
+
todosStore.set(newTodos);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function deleteTodo(id) {
|
|
36
|
+
const newTodos = todos.filter(t => t.id !== id);
|
|
37
|
+
todosStore.set(newTodos);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function getFilteredTodos() {
|
|
41
|
+
if (filter === 'active') return todos.filter(t => !t.done);
|
|
42
|
+
if (filter === 'done') return todos.filter(t => t.done);
|
|
43
|
+
return todos;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function getStats() {
|
|
47
|
+
const total = todos.length;
|
|
48
|
+
const done = todos.filter(t => t.done).length;
|
|
49
|
+
return { total, done };
|
|
50
|
+
}
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
<style>
|
|
54
|
+
.todo-container {
|
|
55
|
+
background: white;
|
|
56
|
+
border-radius: 20px;
|
|
57
|
+
padding: 30px;
|
|
58
|
+
box-shadow: 0 8px 30px rgba(0,0,0,0.08);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.todo-header {
|
|
62
|
+
display: flex;
|
|
63
|
+
justify-content: space-between;
|
|
64
|
+
align-items: center;
|
|
65
|
+
margin-bottom: 20px;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.todo-stats {
|
|
69
|
+
color: #64748b;
|
|
70
|
+
font-size: 0.9rem;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.todo-input {
|
|
74
|
+
display: flex;
|
|
75
|
+
gap: 12px;
|
|
76
|
+
margin-bottom: 20px;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.todo-input input {
|
|
80
|
+
flex: 1;
|
|
81
|
+
padding: 10px 18px;
|
|
82
|
+
border: 2px solid #e2e8f0;
|
|
83
|
+
border-radius: 40px;
|
|
84
|
+
font-size: 1rem;
|
|
85
|
+
outline: none;
|
|
86
|
+
transition: all 0.2s;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.todo-input input:focus {
|
|
90
|
+
border-color: #4f46e5;
|
|
91
|
+
box-shadow: 0 0 0 4px rgba(79,70,229,0.15);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.todo-input button {
|
|
95
|
+
padding: 10px 24px;
|
|
96
|
+
border: none;
|
|
97
|
+
border-radius: 40px;
|
|
98
|
+
background: #4f46e5;
|
|
99
|
+
color: white;
|
|
100
|
+
font-weight: 600;
|
|
101
|
+
cursor: pointer;
|
|
102
|
+
transition: all 0.2s;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.todo-input button:hover {
|
|
106
|
+
background: #4338ca;
|
|
107
|
+
transform: scale(1.02);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.todo-filters {
|
|
111
|
+
display: flex;
|
|
112
|
+
gap: 8px;
|
|
113
|
+
margin-bottom: 20px;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.todo-filters button {
|
|
117
|
+
padding: 6px 16px;
|
|
118
|
+
border: none;
|
|
119
|
+
border-radius: 40px;
|
|
120
|
+
background: #e2e8f0;
|
|
121
|
+
color: #1e293b;
|
|
122
|
+
cursor: pointer;
|
|
123
|
+
transition: all 0.2s;
|
|
124
|
+
font-size: 0.9rem;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.todo-filters button.active {
|
|
128
|
+
background: #4f46e5;
|
|
129
|
+
color: white;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.todo-item {
|
|
133
|
+
display: flex;
|
|
134
|
+
align-items: center;
|
|
135
|
+
justify-content: space-between;
|
|
136
|
+
padding: 10px 0;
|
|
137
|
+
border-bottom: 1px solid #f1f5f9;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.todo-item:last-child {
|
|
141
|
+
border-bottom: none;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.todo-item-left {
|
|
145
|
+
display: flex;
|
|
146
|
+
align-items: center;
|
|
147
|
+
gap: 12px;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.todo-item input[type="checkbox"] {
|
|
151
|
+
width: 20px;
|
|
152
|
+
height: 20px;
|
|
153
|
+
cursor: pointer;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.todo-item .todo-text {
|
|
157
|
+
font-size: 1rem;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.todo-item .todo-text.done {
|
|
161
|
+
text-decoration: line-through;
|
|
162
|
+
color: #94a3b8;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.todo-item .delete-btn {
|
|
166
|
+
padding: 4px 12px;
|
|
167
|
+
border: none;
|
|
168
|
+
border-radius: 40px;
|
|
169
|
+
background: #fee2e2;
|
|
170
|
+
color: #dc2626;
|
|
171
|
+
cursor: pointer;
|
|
172
|
+
transition: all 0.2s;
|
|
173
|
+
font-size: 0.8rem;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.todo-item .delete-btn:hover {
|
|
177
|
+
background: #fecaca;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.todo-empty {
|
|
181
|
+
text-align: center;
|
|
182
|
+
color: #94a3b8;
|
|
183
|
+
padding: 20px 0;
|
|
184
|
+
}
|
|
185
|
+
</style>
|
|
186
|
+
|
|
187
|
+
<template>
|
|
188
|
+
<div class="todo-container">
|
|
189
|
+
<div class="todo-header">
|
|
190
|
+
<h2>Todo List</h2>
|
|
191
|
+
<span class="todo-stats">{getStats().done} / {getStats().total} done</span>
|
|
192
|
+
</div>
|
|
193
|
+
|
|
194
|
+
<div class="todo-input">
|
|
195
|
+
<input
|
|
196
|
+
type="text"
|
|
197
|
+
placeholder="Add a new task..."
|
|
198
|
+
bind:value={newTodo}
|
|
199
|
+
on:keydown={(e) => e.key === 'Enter' && addTodo()}
|
|
200
|
+
/>
|
|
201
|
+
<button on:click={addTodo}>Add</button>
|
|
202
|
+
</div>
|
|
203
|
+
|
|
204
|
+
<div class="todo-filters">
|
|
205
|
+
{#each ['all', 'active', 'done'] as f}
|
|
206
|
+
<button
|
|
207
|
+
class:active={filter === f}
|
|
208
|
+
on:click={() => filter = f}
|
|
209
|
+
>
|
|
210
|
+
{f.toUpperCase()}
|
|
211
|
+
</button>
|
|
212
|
+
{/each}
|
|
213
|
+
</div>
|
|
214
|
+
|
|
215
|
+
<div class="todo-list">
|
|
216
|
+
{#each getFilteredTodos() as todo}
|
|
217
|
+
<div class="todo-item">
|
|
218
|
+
<div class="todo-item-left">
|
|
219
|
+
<input
|
|
220
|
+
type="checkbox"
|
|
221
|
+
checked={todo.done}
|
|
222
|
+
on:change={() => toggleTodo(todo.id)}
|
|
223
|
+
/>
|
|
224
|
+
<span class:done={todo.done} class="todo-text">
|
|
225
|
+
{todo.text}
|
|
226
|
+
</span>
|
|
227
|
+
</div>
|
|
228
|
+
<button class="delete-btn" on:click={() => deleteTodo(todo.id)}>
|
|
229
|
+
â
|
|
230
|
+
</button>
|
|
231
|
+
</div>
|
|
232
|
+
{/each}
|
|
233
|
+
|
|
234
|
+
{#if getFilteredTodos().length === 0}
|
|
235
|
+
<div class="todo-empty">
|
|
236
|
+
No tasks in this filter
|
|
237
|
+
</div>
|
|
238
|
+
{/if}
|
|
239
|
+
</div>
|
|
240
|
+
</div>
|
|
241
|
+
</template>
|
package/src/lib/core/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { VERSION, YnorCompiler, AST } from './compiler.js';
|
|
|
3
3
|
import { YnorRuntime, YnorComponent, runtime, store, mount } from './runtime.js';
|
|
4
4
|
import { ynorPlugin } from './plugin.js';
|
|
5
5
|
|
|
6
|
-
// Error handling utilities
|
|
6
|
+
// Error handling utilities - FIXED PATH
|
|
7
7
|
import {
|
|
8
8
|
YnorError,
|
|
9
9
|
YnorCompilerError,
|
|
@@ -14,10 +14,7 @@ import {
|
|
|
14
14
|
warn,
|
|
15
15
|
info,
|
|
16
16
|
success
|
|
17
|
-
} from './utils/errors.js'
|
|
18
|
-
|
|
19
|
-
// CLI utilities
|
|
20
|
-
import { createProject, buildProject, devProject } from './cli.js';
|
|
17
|
+
} from '../utils/errors.js'; // Changed from './src/utils/errors.js' to '../utils/errors.js'
|
|
21
18
|
|
|
22
19
|
// Export everything
|
|
23
20
|
export {
|
|
@@ -38,10 +35,7 @@ export {
|
|
|
38
35
|
handleError,
|
|
39
36
|
warn,
|
|
40
37
|
info,
|
|
41
|
-
success
|
|
42
|
-
createProject,
|
|
43
|
-
buildProject,
|
|
44
|
-
devProject
|
|
38
|
+
success
|
|
45
39
|
};
|
|
46
40
|
|
|
47
41
|
// Default export
|
package/src/main.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// src/main.js
|
|
2
|
+
import { runtime, mount, store } from './lib/core/runtime.js';
|
|
3
|
+
import App from './App.ynor';
|
|
4
|
+
|
|
5
|
+
console.log('đ Starting .ynor application...');
|
|
6
|
+
|
|
7
|
+
// Initialize stores (not using export inside try)
|
|
8
|
+
const todos = store('todos', [
|
|
9
|
+
{ id: 1, text: 'Learn .ynor', done: true },
|
|
10
|
+
{ id: 2, text: 'Build something great', done: false },
|
|
11
|
+
{ id: 3, text: 'Share with community', done: false }
|
|
12
|
+
]);
|
|
13
|
+
|
|
14
|
+
console.log('đĻ Store initialized:', todos.get());
|
|
15
|
+
|
|
16
|
+
// Mount app with error handling
|
|
17
|
+
try {
|
|
18
|
+
const app = mount(App, document.getElementById('app'), {
|
|
19
|
+
todos: todos
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
console.log('⥠.ynor framework initialized');
|
|
23
|
+
console.log('đ Components loaded:', Array.from(runtime.components.keys()));
|
|
24
|
+
|
|
25
|
+
// Export for HMR
|
|
26
|
+
if (import.meta.hot) {
|
|
27
|
+
import.meta.hot.accept('./App.ynor', ({ default: NewApp }) => {
|
|
28
|
+
app.$destroy();
|
|
29
|
+
mount(NewApp, document.getElementById('app'), { todos });
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.error('â Error starting .ynor application:', error);
|
|
34
|
+
document.getElementById('app').innerHTML = `
|
|
35
|
+
<div style="color: red; padding: 20px; font-family: system-ui;">
|
|
36
|
+
<h2>Error loading .ynor app</h2>
|
|
37
|
+
<pre style="background: #f1f1f1; padding: 10px; border-radius: 5px; overflow: auto;">${error.message}</pre>
|
|
38
|
+
<p>Check console for details</p>
|
|
39
|
+
</div>
|
|
40
|
+
`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Export todos for use in other modules if needed
|
|
44
|
+
export { todos };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<!-- src/routes/+layout.svelte -->
|
|
2
|
+
<script>
|
|
3
|
+
import '../styles/global.css';
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<slot />
|
|
7
|
+
|
|
8
|
+
<style>
|
|
9
|
+
/* Global layout styles */
|
|
10
|
+
:global(*) {
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
margin: 0;
|
|
13
|
+
padding: 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
:global(body) {
|
|
17
|
+
font-family: system-ui, -apple-system, sans-serif;
|
|
18
|
+
background: #f5f7fb;
|
|
19
|
+
color: #1e293b;
|
|
20
|
+
line-height: 1.6;
|
|
21
|
+
}
|
|
22
|
+
</style>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<!-- src/routes/+page.svelte -->
|
|
2
|
+
<script>
|
|
3
|
+
import { onMount } from 'svelte';
|
|
4
|
+
import { mount } from '$lib/core/runtime.js';
|
|
5
|
+
import Counter from '$lib/components/Counter.ynor';
|
|
6
|
+
import TodoList from '$lib/components/TodoList.ynor';
|
|
7
|
+
|
|
8
|
+
let counterInstance;
|
|
9
|
+
let todoInstance;
|
|
10
|
+
|
|
11
|
+
onMount(() => {
|
|
12
|
+
// Mount .ynor components in SvelteKit
|
|
13
|
+
const counterContainer = document.getElementById('counter-container');
|
|
14
|
+
const todoContainer = document.getElementById('todo-container');
|
|
15
|
+
|
|
16
|
+
if (counterContainer) {
|
|
17
|
+
counterInstance = mount(Counter, counterContainer);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (todoContainer) {
|
|
21
|
+
todoInstance = mount(TodoList, todoContainer);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return () => {
|
|
25
|
+
if (counterInstance) counterInstance.$destroy();
|
|
26
|
+
if (todoInstance) todoInstance.$destroy();
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<div class="container">
|
|
32
|
+
<h1>Welcome to .ynor + SvelteKit</h1>
|
|
33
|
+
|
|
34
|
+
<div id="counter-container"></div>
|
|
35
|
+
<div id="todo-container"></div>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<style>
|
|
39
|
+
.container {
|
|
40
|
+
max-width: 1200px;
|
|
41
|
+
margin: 0 auto;
|
|
42
|
+
padding: 20px;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
h1 {
|
|
46
|
+
color: #4f46e5;
|
|
47
|
+
margin-bottom: 30px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
#counter-container,
|
|
51
|
+
#todo-container {
|
|
52
|
+
margin: 20px 0;
|
|
53
|
+
}
|
|
54
|
+
</style>
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/* src/styles/global.css */
|
|
2
|
+
* {
|
|
3
|
+
box-sizing: border-box;
|
|
4
|
+
margin: 0;
|
|
5
|
+
padding: 0;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
body {
|
|
9
|
+
font-family: system-ui, -apple-system, sans-serif;
|
|
10
|
+
background: #f5f7fb;
|
|
11
|
+
color: #1e293b;
|
|
12
|
+
line-height: 1.6;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
#app {
|
|
16
|
+
min-height: 100vh;
|
|
17
|
+
padding: 20px;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* Utility classes */
|
|
21
|
+
.container {
|
|
22
|
+
max-width: 1200px;
|
|
23
|
+
margin: 0 auto;
|
|
24
|
+
padding: 0 20px;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.text-center {
|
|
28
|
+
text-align: center;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.mt-4 {
|
|
32
|
+
margin-top: 2rem;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.mb-4 {
|
|
36
|
+
margin-bottom: 2rem;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/* Scrollbar styling */
|
|
40
|
+
::-webkit-scrollbar {
|
|
41
|
+
width: 8px;
|
|
42
|
+
height: 8px;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
::-webkit-scrollbar-track {
|
|
46
|
+
background: #f1f1f1;
|
|
47
|
+
border-radius: 10px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
::-webkit-scrollbar-thumb {
|
|
51
|
+
background: #cbd5e1;
|
|
52
|
+
border-radius: 10px;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
::-webkit-scrollbar-thumb:hover {
|
|
56
|
+
background: #94a3b8;
|
|
57
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// src/utils/errors.js
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
|
|
4
|
+
export class YnorError extends Error {
|
|
5
|
+
constructor(message, code, details = {}) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = 'YnorError';
|
|
8
|
+
this.code = code;
|
|
9
|
+
this.details = details;
|
|
10
|
+
Error.captureStackTrace(this, this.constructor);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
toString() {
|
|
14
|
+
return `${chalk.red('â')} ${chalk.bold(this.code)}: ${this.message}`;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class YnorCompilerError extends YnorError {
|
|
19
|
+
constructor(message, details = {}) {
|
|
20
|
+
super(message, 'COMPILER_ERROR', details);
|
|
21
|
+
this.name = 'YnorCompilerError';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export class YnorRuntimeError extends YnorError {
|
|
26
|
+
constructor(message, details = {}) {
|
|
27
|
+
super(message, 'RUNTIME_ERROR', details);
|
|
28
|
+
this.name = 'YnorRuntimeError';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export class YnorTemplateError extends YnorError {
|
|
33
|
+
constructor(message, details = {}) {
|
|
34
|
+
super(message, 'TEMPLATE_ERROR', details);
|
|
35
|
+
this.name = 'YnorTemplateError';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export class YnorComponentError extends YnorError {
|
|
40
|
+
constructor(message, details = {}) {
|
|
41
|
+
super(message, 'COMPONENT_ERROR', details);
|
|
42
|
+
this.name = 'YnorComponentError';
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function handleError(error, context = {}) {
|
|
47
|
+
console.error('');
|
|
48
|
+
if (error instanceof YnorError) {
|
|
49
|
+
console.error(chalk.red(' â ī¸ ') + chalk.bold(error.code));
|
|
50
|
+
console.error(chalk.dim(' ââââââââââââââââââââââââââââââ'));
|
|
51
|
+
console.error(' ' + error.message);
|
|
52
|
+
|
|
53
|
+
if (error.details && Object.keys(error.details).length > 0) {
|
|
54
|
+
console.error(chalk.dim('\n đ Details:'));
|
|
55
|
+
Object.entries(error.details).forEach(([key, value]) => {
|
|
56
|
+
console.error(` ${chalk.dim(key)}: ${value}`);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (context.file) {
|
|
61
|
+
console.error(chalk.dim(`\n đ File: ${context.file}`));
|
|
62
|
+
}
|
|
63
|
+
if (context.line) {
|
|
64
|
+
console.error(chalk.dim(` đ Line: ${context.line}`));
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
console.error(chalk.red(' â ') + chalk.bold('Unexpected Error'));
|
|
68
|
+
console.error(chalk.dim(' ââââââââââââââââââââââââââââââ'));
|
|
69
|
+
console.error(' ' + error.message);
|
|
70
|
+
if (error.stack) {
|
|
71
|
+
console.error(chalk.dim('\n đ Stack Trace:'));
|
|
72
|
+
console.error(error.stack.split('\n').slice(1, 5).join('\n'));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
console.error('');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function warn(message, details = {}) {
|
|
79
|
+
console.warn(chalk.yellow(' â ī¸ ') + chalk.bold('Warning'));
|
|
80
|
+
console.warn(chalk.dim(' ââââââââââââââââââââââââââââââ'));
|
|
81
|
+
console.warn(' ' + message);
|
|
82
|
+
if (Object.keys(details).length > 0) {
|
|
83
|
+
console.warn(chalk.dim('\n đ Details:'));
|
|
84
|
+
Object.entries(details).forEach(([key, value]) => {
|
|
85
|
+
console.warn(` ${chalk.dim(key)}: ${value}`);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
console.warn('');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function info(message, details = {}) {
|
|
92
|
+
console.log(chalk.blue(' âšī¸ ') + chalk.bold('Info'));
|
|
93
|
+
console.log(chalk.dim(' ââââââââââââââââââââââââââââââ'));
|
|
94
|
+
console.log(' ' + message);
|
|
95
|
+
if (Object.keys(details).length > 0) {
|
|
96
|
+
console.log(chalk.dim('\n đ Details:'));
|
|
97
|
+
Object.entries(details).forEach(([key, value]) => {
|
|
98
|
+
console.log(` ${chalk.dim(key)}: ${value}`);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
console.log('');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function success(message, details = {}) {
|
|
105
|
+
console.log(chalk.green(' â
') + chalk.bold('Success'));
|
|
106
|
+
console.log(chalk.dim(' ââââââââââââââââââââââââââââââ'));
|
|
107
|
+
console.log(' ' + message);
|
|
108
|
+
if (Object.keys(details).length > 0) {
|
|
109
|
+
console.log(chalk.dim('\n đ Details:'));
|
|
110
|
+
Object.entries(details).forEach(([key, value]) => {
|
|
111
|
+
console.log(` ${chalk.dim(key)}: ${value}`);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
console.log('');
|
|
115
|
+
}
|