vaderjs 1.3.6 → 1.3.7-alpha-1

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 ADDED
@@ -0,0 +1,167 @@
1
+ <p align="center">
2
+ <a href="https://vader-js.pages.dev">
3
+ <picture>
4
+ <source media="(prefers-color-scheme: dark)" srcset="/icon.jpeg">
5
+ <img src="logo.png" height="128">
6
+ </picture>
7
+ <h1 align="center">Vader.js</h1>
8
+ </a>
9
+ </p>
10
+
11
+ # VaderJS: A Powerful Reactive Framework for SPAs inspired by react.js!
12
+
13
+ [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/Postr-Inc/Vader.js/blob/main/LICENSE) [![npm version](https://img.shields.io/npm/v/vaderjs.svg?style=flat)](https://www.npmjs.com/package/vaderjs)
14
+
15
+
16
+
17
+ ## Get Started
18
+
19
+ 1. Install Bun.js
20
+
21
+ Need more help? [Bun guide](https://bun.sh/docs/installation)
22
+
23
+ ```sh
24
+ curl -fsSL https://bun.sh/install | bash # for macOS, Linux, and WSL
25
+ ```
26
+
27
+ > Skip if you are not using windows!
28
+ [How to open folder in wsl](https://code.visualstudio.com/docs/remote/wsl)
29
+
30
+ 1. Open a WSL terminal window (using the start menu item or by typing wsl from a command prompt / PowerShell).
31
+
32
+ 2. Navigate to a folder you'd like to open in VS Code (including, but not limited to, Windows filesystem mounts like /mnt/c)
33
+
34
+ 3. Type code . in the terminal. When doing this for the first time, you should see VS Code fetching components needed to run in WSL. This should only take a short while, and is only needed once.
35
+
36
+ Open folder in vsc - open terminal and type wsl then type `code .` and continue to the next step
37
+
38
+ 2. Installing vaderjs
39
+
40
+ ```bash
41
+ npm i vaderjs
42
+ ```
43
+
44
+ 3. Create Proper Folders
45
+
46
+ Create a pages folder - which allows you to have nextjs page like routing via buns file based router
47
+
48
+ ```bash
49
+ /pages/index.jsx = /
50
+ /pages/home/[page].jsx = /home/:page
51
+ /pages/path/index.jsx = /path/file
52
+ ```
53
+ Keyword folders - all files are passed from these folders to the `dist` folder
54
+
55
+ ```bash
56
+
57
+ pages - used for jsx route files
58
+ src - used for your jsx components / javascript files
59
+ public - used for anything
60
+
61
+ ```
62
+
63
+
64
+
65
+ 4. And your done - Run `npm run build` and the compiled output is visible inside of the `/dist/` folder!
66
+
67
+ ## Key Features & Examples
68
+
69
+ ### File based routing
70
+ vader's compiler automatically handles routing so you wont need to!
71
+ below is valid paths for parsing per [Buns fileSystem Routing Api](https://bun.sh/docs/api/file-system-router)
72
+
73
+ ```bash
74
+ /pages/index.jsx = /
75
+ /pages/home/[page].jsx = /home/:page
76
+ /pages/path/index.jsx = /path/file
77
+
78
+
79
+ ```
80
+ You can grab the request object from `this.request` and response object from `this.response!`
81
+
82
+
83
+ ### Simplified Component Creation
84
+
85
+ ```jsx
86
+ // pages/home.jsx
87
+ let {Component, useState} = await import('./vader.js') // always use ./vader.js as files reference vaders main file
88
+ let Mycomponent = await require('./pages/mycomponent')
89
+ class Home extends Vader {
90
+ constructor() {
91
+ super();
92
+ this.key = '2'
93
+ }
94
+ render() {
95
+ return <>
96
+ <div key={this.key}>
97
+ <p>Hello World</p>
98
+ </div>
99
+ <Mycomponent ..props />
100
+ </>
101
+ }
102
+ }
103
+
104
+ return {default:Home}
105
+ ```
106
+
107
+
108
+
109
+ ### State Management
110
+
111
+ ```jsx
112
+ let {Component, useState} = await import('./vader.js')
113
+
114
+ class MyApp extends Component{
115
+ contructor(){
116
+ super()
117
+ this.key = 'static key for state changes'
118
+ }
119
+
120
+ render(){
121
+ let [count, setCount] = useState(0)
122
+ function increment(){
123
+ setCount(count()+ 1)
124
+ }
125
+ return <>
126
+ <p>Count is ${count}</p>
127
+ <button onclick={()=>increment()}>Increment</button>
128
+ </>
129
+
130
+ }
131
+ }
132
+
133
+ return {default:MyApp}
134
+ ```
135
+
136
+
137
+ ### Function Binding
138
+
139
+ Vaderjs allows you to bind functions directly to html elements just like react
140
+
141
+ ```javascript
142
+ // vader uses params[0] as the event target object and other parameters resolve after
143
+
144
+ function click(event, otherparams){
145
+ console.log(event.target, otherparams)
146
+ }
147
+
148
+ return <>
149
+ <button onclick={()=>click()}>Click Me</button>
150
+ </>
151
+ ```
152
+
153
+
154
+
155
+
156
+
157
+
158
+
159
+
160
+
161
+ ## License
162
+
163
+ VaderJS is released under the MIT License. See the [LICENSE](https://github.com/Postr-Inc/Vader.js/blob/main/LICENSE) file for details.
164
+
165
+ ## Join the Community
166
+
167
+ Connect with the VaderJS community on [GitHub](https://github.com/Postr-Inc/Vader.js). Contribute, share feedback, and improve VaderJS for SPA development.
package/logo.png CHANGED
File without changes
package/package.json CHANGED
@@ -1,29 +1,21 @@
1
1
  {
2
2
  "name": "vaderjs",
3
- "version": "1.3.6",
4
- "description": "A Reactive Framework for Building Content Rich Single-Page Applications (SPA)",
5
- "main": "index.js",
6
- "scripts": {
7
- "test": "tsc --noEmit "
8
- },
9
- "repository": {
10
- "type": "git",
11
- "url": "git+https://github.com/Postr-Inc/Vader.js.git"
3
+ "description": "A Reactive library aimed to helping you build reactive applications inspired by react.js",
4
+ "module": "vader.js",
5
+ "version": "1.3.7-alpha-1",
6
+ "bin": {
7
+ "vader": "./vader"
12
8
  },
13
- "keywords": [
14
- "Reactjs",
15
- "Vuejs",
16
- "Reduxjs.",
17
- "Nextjs",
18
- "Vaderjs"
19
- ],
20
- "author": "Malikwhitten67",
21
- "license": "MIT",
22
- "bugs": {
23
- "url": "https://github.com/Postr-Inc/Vader.js/issues"
9
+ "scripts": {
10
+ "build": "bunx vader --build",
11
+ "watch": "bun run vader --watch",
12
+ "help": "bunx vader"
24
13
  },
25
- "homepage": "https://vader-js.pages.dev",
14
+ "type": "module",
26
15
  "devDependencies": {
27
- "typescript": "^5.2.2"
16
+ "@types/bun": "latest"
17
+ },
18
+ "peerDependencies": {
19
+ "typescript": "^5.0.0"
28
20
  }
29
- }
21
+ }
@@ -0,0 +1,261 @@
1
+ import { Component } from "./vader.js";
2
+
3
+
4
+
5
+
6
+
7
+ /**
8
+ * @class VaderRouter
9
+ * @description - creates an instance of Vader Express Router
10
+ *
11
+ * @param {String} path
12
+ * @param {Function} handler
13
+ * @param {object} req request object
14
+ * @param {object} res response object
15
+ * @returns {Object} Express
16
+ *
17
+ */
18
+ class VaderRouter{
19
+ /**
20
+ * @constructor
21
+ * @param {*} basePath
22
+ *
23
+ */
24
+ constructor(/**@type {string}**/basePath, /**@type {number}**/port) {
25
+ this.routes = [];
26
+ this.middlewares = [];
27
+ this.errorMiddlewares = [];
28
+ this.listeners = [];
29
+
30
+ this.basePath = basePath;
31
+
32
+ }
33
+
34
+ /**
35
+ * @method get
36
+ * @param {String} path
37
+ * @param {Function} handler
38
+ * @param {{a:b}} req request object
39
+ * @description This method is used to register a get route
40
+ * @returns {void}
41
+ * @memberof Express
42
+ */
43
+ get(path, handler) {
44
+
45
+ this.routes.push({
46
+ path,
47
+ handler,
48
+ method: 'get',
49
+ });
50
+ }
51
+ /**
52
+ * @method use
53
+ * @description This method allows you to use middlewares
54
+ * @param {Function} middleware
55
+ */
56
+
57
+ use(/* path, */ middleware) {
58
+ this.middlewares.push(middleware);
59
+ }
60
+
61
+ /**
62
+ * @method listen
63
+ * @param {String} port - unique id for the listener
64
+ * @param {Function} callback - callback function
65
+ * @description This method is used to start listening to the routes
66
+ * @returns {void}
67
+ *
68
+ */
69
+
70
+ listen(port, callback) {
71
+ if(!port){
72
+ port = Math.random().toString(36).substring(7);
73
+ }
74
+ this.listeners.push(port);
75
+ if (this.listeners.length === 1) {
76
+ this.handleRoute(window.location.hash);
77
+ }else{
78
+ this.listeners.pop();
79
+ }
80
+ if (callback) {
81
+ callback();
82
+ }
83
+ window.onhashchange = () => {
84
+ this.handleRoute(window.location.hash);
85
+ }
86
+ }
87
+ /**
88
+ * @method extractParams
89
+ * @description This method is used to extract parameters from the route path
90
+ * @param {*} routePath
91
+ * @param {*} hash
92
+ * @returns {Object} params
93
+ * @memberof Express
94
+ */
95
+
96
+ extractParams(routePath, hash) {
97
+ const routeParts = routePath.split('/');
98
+ const hashParts = hash.split('/');
99
+ const params = {};
100
+ routeParts.forEach((part, index) => {
101
+ if (part.startsWith(':')) {
102
+ const paramName = part.slice(1);
103
+ params[paramName] = hashParts[index];
104
+ }else if(part.startsWith('*')){
105
+ // remove queries from this par
106
+ params[0] = hashParts.slice(index).join('/').split('?')[0];
107
+ }
108
+ });
109
+ return params;
110
+ }
111
+ extractQueryParams(hash){
112
+
113
+ const queryParams = hash.split('?')[1];
114
+ if(!queryParams){
115
+ return {};
116
+ }
117
+ const params = {};
118
+ queryParams.split('&').forEach((param)=>{
119
+ const [key, value] = param.split('=');
120
+ params[key] = value;
121
+ })
122
+ return params;
123
+ }
124
+
125
+ /**
126
+ * @method handleRoute
127
+ * @param {String} hash
128
+ * @description This method is used to handle the route
129
+ */
130
+
131
+ handleRoute(hash) {
132
+ hash = hash.slice(1);
133
+ let status = 200;
134
+ let route = this.routes.find((route) => {
135
+
136
+ if (route.path === hash) {
137
+ return true;
138
+ }
139
+ const routePathParts = route.path.split('/');
140
+ const hashParts = hash.split('/');
141
+ if (routePathParts.length !== hashParts.length) {
142
+ return false;
143
+ }else if(routePathParts[routePathParts.length-1].startsWith('*')){
144
+ return true;
145
+ }
146
+ const params = this.extractParams( route.path, hash);
147
+ return Object.keys(params).length > 0;
148
+ });
149
+
150
+ if (!route) {
151
+ route = this.routes.find((route) => {
152
+
153
+ if(route.path === '/404'){
154
+ return true;
155
+ }else{
156
+ window.location.hash = this.basePath
157
+ }
158
+ });
159
+
160
+ route ? status = 200 :
161
+
162
+ status = 404;
163
+ }
164
+
165
+
166
+ const queryParams = this.extractQueryParams(hash);
167
+ const params = route && route.path ? this.extractParams(route.path, hash) : {};
168
+ const req = {
169
+ headers: {},
170
+ params: params,
171
+ query: queryParams,
172
+ path: hash,
173
+ method: route ? route.method : 'get',
174
+ };
175
+
176
+ // @ts-ignore
177
+ window.$CURRENT_URL = req.path
178
+
179
+ // @ts-ignore
180
+ window.$FULL_URL = window.location.href.replace('#', '')
181
+
182
+ const res = {
183
+ status: status,
184
+ /**
185
+ * @method log
186
+ * @param {String} type
187
+ * @description This method is used to log the request and response
188
+ */
189
+ log: (type) => {
190
+ if(type === undefined){
191
+ console.log(`${req.path} ${req.method} ${res.status} ${req.timestamp}`);
192
+ }else{
193
+ console.table({
194
+ 'Request Path': req.path,
195
+ 'Request Method': route.method,
196
+ 'Response Status': res.status,
197
+ 'Request Timestamp': req.timestamp,
198
+ });
199
+ }
200
+ },
201
+ render: async (/**@type {Component} */ Component, req, res) => {
202
+
203
+ if(!Component.default || !Component.constructor){
204
+ let message = !Component.default ? 'default' : 'constructor';
205
+ switch(message){
206
+ case 'default':
207
+ throw new Error(`Component must have a default export ex: return {default: Component}`);
208
+
209
+ case 'constructor':
210
+ throw new Error(`Component is invalid, please check the constructor`);
211
+
212
+ }
213
+
214
+ }
215
+
216
+ Component = Component.default ? new Component.default() : Component.constructor ? new Component() : Component;
217
+
218
+
219
+ Component.mounted = true;
220
+
221
+ if(!document.querySelector('#root')){
222
+ throw new Error('Root element not found, please add an element with id root');
223
+ }
224
+ Component.request = req;
225
+ Component.response = res;
226
+ document.querySelector('#root').innerHTML = Component.render()
227
+ Component.bindMount();
228
+ Component.onMount()
229
+
230
+ },
231
+ send: (data) => {
232
+ document.querySelector('#root').innerHTML = data;
233
+ },
234
+ json: (selector, data) => {
235
+
236
+ if(typeof selector === 'string'){
237
+ // @ts-ignore
238
+ let obj = document.createElement('object');
239
+ // data url
240
+ obj.data = URL.createObjectURL(new Blob([JSON.stringify(data)], {type: 'application/json'}));
241
+ // @ts-ignore
242
+ document.querySelector(selector).appendChild(obj);
243
+ }else{
244
+ throw new Error('Selector must be a string');
245
+ }
246
+ },
247
+ };
248
+ this.middlewares.forEach((middleware) => {
249
+ middleware(req, res);
250
+ });
251
+
252
+ route ? route.handler(req, res) : null;
253
+
254
+ }
255
+
256
+ }
257
+
258
+ window.VaderRouter = VaderRouter;
259
+
260
+ export default VaderRouter;
261
+
@@ -0,0 +1,21 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Vaderjs v1.3.3</title>
7
+ <meta name="description" content="Vader.js is a modern web framework for building web applications.">
8
+ <link rel="shortcut icon" href="https://raw.githubusercontent.com/Postr-Inc/Vader.js/vader1.3.3-beta/logo.png" type="image/x-icon">
9
+ </head>
10
+ <body>
11
+ <div id="root"></div>
12
+ <script type="module">
13
+ import VaderRouter from './public/vader/router.js'
14
+
15
+ const router = new VaderRouter('/', 3000)
16
+ window.router = router
17
+ await import('./app.js')
18
+ router.listen(3000)
19
+ </script>
20
+ </body>
21
+ </html>
package/vader ADDED
Binary file
@@ -1,5 +0,0 @@
1
- {
2
- "liveServer.settings.port": 5501,
3
- "js/ts.implicitProjectConfig.checkJs": true,
4
- "js/ts.implicitProjectConfig.experimentalDecorators": true
5
- }
@@ -1,5 +0,0 @@
1
- {
2
- "className":{
3
- "name":"className"
4
- }
5
- }
package/index.js DELETED
@@ -1,12 +0,0 @@
1
- /**
2
- * @file index.js
3
- * @description This is the entry point for the library. This file exports all the necessary classes and functions.
4
- * @version 1.1.5
5
- *
6
- */
7
- import Vader, { include} from './vader.js';
8
- // @ts-ignore
9
- import VaderRouter from './vaderRouter.js';
10
-
11
- export { include, VaderRouter };
12
- export default Vader;
package/jsconfig.json DELETED
@@ -1,17 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "allowJs": true,
4
- "checkJs": true,
5
- "target": "es6",
6
- "module": "commonjs",
7
- "alwaysStrict": true
8
-
9
- },
10
- "exclude": [
11
- "node_modules",
12
- "dist"
13
- ],
14
- "include": [
15
- "**/*.js"
16
- ]
17
- }