vaderjs 1.5.5 → 1.5.7

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/bundler/index.js CHANGED
@@ -38,9 +38,10 @@ await Bun.build({
38
38
  minify: false,
39
39
  root: process.cwd() + "/dist/",
40
40
  outdir: process.cwd() + "/dist/",
41
+
41
42
  format: "esm",
42
43
  ...(process.env.DEV ? { sourcemap: "inline" } : {}),
43
- external:['*.jsx', '*.js']
44
+ external:['*.jsx', '*.js', '*.ts']
44
45
  });
45
46
 
46
47
  let builtCode = fs.readFileSync(path.join(process.cwd(), 'dist', process.env.filePath), 'utf-8')
@@ -52,18 +53,25 @@ function handleReplacements(code) {
52
53
  if(hasImport && line.includes('from')){
53
54
  try {
54
55
  let url = line.includes("'") ? line.split("'")[1] : line.split('"')[1]
55
- let exactFile = path.resolve(url)
56
- // replace url with exact file path
57
- line = line.replace(url, exactFile)
56
+
57
+ line = line.replace(url, url.replace('.jsx', '.js'))
58
+ line = line.replace(url, url.replace('.ts', '.js'))
59
+ newLines.push(line)
58
60
  } catch (error) {
59
61
  continue;
60
62
  }
63
+ }else{
64
+ newLines.push(line)
61
65
  }
66
+
62
67
  }
63
- return lines.join("\n");
68
+ return newLines.join('\n')
64
69
  }
70
+ if(!process.env.isTs){
71
+
65
72
  builtCode = handleReplacements(builtCode)
66
73
  fs.writeFileSync(path.join(process.cwd(), 'dist', process.env.filePath), builtCode)
74
+ }
67
75
  let isClass = function (element) {
68
76
  return element.toString().startsWith("class");
69
77
  };
@@ -104,11 +112,15 @@ const generatePage = async (
104
112
  `<!DOCTYPE html>
105
113
  <head>
106
114
  ${headHtml}
115
+ ${process.env.bindes}
116
+ <meta charset="UTF-8">
117
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
107
118
  </head>
108
119
  ${h}
109
120
  <script type="module">
110
121
  import c from '${process.env.filePath}'
111
- import {render} from '/src/vader/index.js'
122
+ import {render, e} from '/src/vader/index.js'
123
+ window.e = e
112
124
  render(c, document.body.firstChild)
113
125
  </script>
114
126
  `
@@ -123,7 +135,11 @@ const generatePage = async (
123
135
  process.exit(0);
124
136
  };
125
137
  try {
126
- process.env.isImport == undefined && generatePage({ path: process.env.INPUT, route: process.env.OUT });
138
+ if(process.env.isTs == undefined && process.env.isImport) {
139
+ generatePage({ path: process.env.INPUT, route: process.env.OUT })
140
+ }else if(process.env.isTs == undefined){
141
+ generatePage({ path: process.env.INPUT, route: process.env.OUT })
142
+ }
127
143
  } catch (error) {
128
144
  console.log(ansiColors.red(error))
129
145
  }
package/document/index.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  export const document = (element: any) => {
2
2
  let type = element.type;
3
- let el = type === null ? `` : `<${type}`
4
- console.log(el)
3
+ let el = type === null ? `` : `<${type}`
5
4
  let attributes = element.props;
6
5
  let children = element.children;
7
6
  if(type != null){
@@ -35,9 +34,11 @@ export const document = (element: any) => {
35
34
  }
36
35
  }
37
36
  el += type === null ? `` : `>`
37
+ if(children === null || children === undefined){
38
+ return el;
39
+ }
38
40
  for (let i = 0;i < children.length; i++) {
39
- let child = children[i];
40
- console.log(child)
41
+ let child = children[i];
41
42
  if (Array.isArray(child)) {
42
43
  child.forEach((c) => {
43
44
  el += document(c);
package/index.ts CHANGED
@@ -74,7 +74,7 @@ export const useEffect = (callback:any, dependencies: any[]) => {
74
74
 
75
75
 
76
76
 
77
- export const Fragment = (props: any, children: any) => {
77
+ export const Fragment = (props: any, children: any) => {
78
78
  return {
79
79
  type: isServer ? null : "div",
80
80
  props:{},
@@ -91,7 +91,7 @@ globalThis.Fragment = Fragment;
91
91
  * @param children
92
92
  * @returns
93
93
  */
94
- export const e = (element, props, ...children) => {
94
+ export const e = (element, props, ...children) => {
95
95
  let instance;
96
96
  switch (true) {
97
97
  case isClassComponent(element):
@@ -102,11 +102,10 @@ export const e = (element, props, ...children) => {
102
102
  case typeof element === "function":
103
103
  instance = new Component;
104
104
  instance.render = element;
105
- let firstEl = instance.render({key: instance.key, children: children, ...props});
105
+ let firstEl = instance.render({key: instance.key, children: children, ...props}, children);
106
106
  instance.children = children;
107
- if (!firstEl) firstEl = {type: "div", props: {key: instance.key, children: [], ...props}, children: []};
108
- firstEl.props = {key: instance.key, ...props};
109
- firstEl.children = children;
107
+ if (!firstEl) firstEl = {type: "div", props: {key: instance.key, ...props}, children: children};
108
+ firstEl.props = { key: instance.key, ...firstEl.props, ...props };
110
109
  return firstEl;
111
110
  default:
112
111
  return { type: element, props: props || {}, children: children || [] };
@@ -128,7 +127,7 @@ export function Switch({ children }) {
128
127
  return child;
129
128
  }
130
129
  }
131
- return null;
130
+ return { type: "div", props: {}, children: [] };
132
131
  }
133
132
 
134
133
  /**
@@ -137,7 +136,7 @@ export function Switch({ children }) {
137
136
  * @returns
138
137
  */
139
138
  export function Match({ when, children }) {
140
- return when ? children : null;
139
+ return when ? children : { type: "div", props: {}, children: [] };
141
140
  }
142
141
  /**
143
142
  * @description - Manage state and forceupdate specific affected elements
@@ -149,7 +148,11 @@ export const useState = <T>(initialState: T) => {
149
148
  const setState = (newState: T) => {
150
149
  initialState = newState;
151
150
  }
152
- return [initialState, setState];
151
+ const getVal = () => {
152
+ return initialState;
153
+ }
154
+
155
+ return [getVal, setState];
153
156
  }
154
157
 
155
158
  /**
@@ -202,7 +205,8 @@ export class Component {
202
205
  if (typeof window === "undefined")
203
206
  return [defaultValue, () => {
204
207
  }];
205
- let value = sessionStorage.getItem("state_" + key) ? JSON.parse(sessionStorage.getItem("state_" + key)).value : defaultValue;
208
+ let value = sessionStorage.getItem("state_" + key) ? JSON.parse(sessionStorage.getItem("state_" + key)).value : defaultValue;
209
+
206
210
  if (typeof value === "string") {
207
211
  try {
208
212
  value = JSON.parse(value);
@@ -216,11 +220,14 @@ export class Component {
216
220
  });
217
221
  }
218
222
  const setValue = (newValue) => {
219
- value = newValue;
220
- sessionStorage.setItem("state_" + key, JSON.stringify({ type: typeof newValue, value: newValue }));
223
+ console.log("setting value", newValue);
224
+ sessionStorage.setItem("state_" + key, JSON.stringify({ value: newValue }));
221
225
  this.forceUpdate(this.key);
222
226
  };
223
- return [value, setValue];
227
+ const getVal = () => {
228
+ return sessionStorage.getItem("state_" + key) ? JSON.parse(sessionStorage.getItem("state_" + key)).value : defaultValue;
229
+ }
230
+ return [getVal, setValue];
224
231
  }
225
232
  useFetch(url, options) {
226
233
  const loadingKey = "loading_" + url;
@@ -248,19 +255,18 @@ export class Component {
248
255
  let newl = this.toElement();
249
256
  if (newl.key !== key) {
250
257
  newl = Array.from(newl.children).filter((el2) => el2.key === key)[0];
251
- }
258
+ }
252
259
  this.Reconciler.update(el, newl);
253
260
  }
254
261
  Reconciler = {
255
262
  update: (oldElement, newElement) => {
256
- if (!oldElement || !newElement)
257
- return;
258
- if (this.Reconciler.shouldUpdate(oldElement, newElement) && oldElement.tagName == newElement.tagName) {
263
+
264
+ if (this.Reconciler.shouldUpdate(oldElement, newElement)) {
265
+ console.log("should update");
259
266
  oldElement.replaceWith(newElement);
260
267
  } else {
261
- let children = oldElement.childNodes;
262
- for (let i = 0;i < children.length; i++) {
263
- this.Reconciler.update(children[i], newElement.childNodes[i]);
268
+ for (let i = 0; i < newElement.childNodes.length; i++) {
269
+ this.Reconciler.update(oldElement.childNodes[i], newElement.childNodes[i]);
264
270
  }
265
271
  }
266
272
  },
@@ -274,6 +280,9 @@ export class Component {
274
280
  if (oldElement.nodeName !== newElement.nodeName) {
275
281
  return true;
276
282
  }
283
+ if (oldElement.innerHTML !== newElement.innerHTML) {
284
+ return true;
285
+ }
277
286
  if (oldElement.childNodes.length !== newElement.childNodes.length) {
278
287
  return true;
279
288
  }
@@ -281,18 +290,19 @@ export class Component {
281
290
  }
282
291
  };
283
292
  parseToElement = (element) => {
284
- if (!element)
285
- return document.createElement("div");
286
- let el = document.createElement(element.type);
293
+ if (!element) return document.createElement("div");
294
+ // create either a element or svg element
295
+ let svg = ["svg", "path", "circle", "rect", "line", "polyline", "polygon", "ellipse", "g"];
296
+ let el = svg.includes(element.type) ? document.createElementNS("http://www.w3.org/2000/svg", element.type) : document.createElement(element.type);
287
297
  let isText = typeof element === "string" || typeof element === "number" || typeof element === "boolean";
288
298
  if (isText) {
289
- el.textContent = element;
299
+ el.innerHTML = element;
290
300
  } else {
291
301
  let attributes = element.props;
292
302
  let children = element.children;
293
303
  for (let key in attributes) {
294
- if (key === "key") {
295
- el.key = attributes[key];
304
+ if (key === "key") {
305
+ el.key = attributes[key];
296
306
  continue;
297
307
  }
298
308
  if (key === "className") {
@@ -300,8 +310,12 @@ export class Component {
300
310
  continue;
301
311
  }
302
312
  if (key === "style") {
303
- for (let styleKey in attributes[key]) {
304
- el.style[styleKey] = attributes[key][styleKey];
313
+ try {
314
+ for (let styleKey in attributes[key]) {
315
+ el.style[styleKey] = attributes[key][styleKey];
316
+ }
317
+ } catch (error) {
318
+
305
319
  }
306
320
  continue;
307
321
  }
@@ -310,22 +324,23 @@ export class Component {
310
324
  continue;
311
325
  }
312
326
  el.setAttribute(key, attributes[key]);
313
- }
314
- if(children === undefined) return el;
315
- for (let i = 0;i < children.length; i++) {
327
+ }
328
+ if (children === undefined)
329
+ return el;
330
+ for (let i = 0;i < children.length; i++) {
316
331
  let child = children[i];
317
332
  if (Array.isArray(child)) {
318
333
  child.forEach((c) => {
319
334
  el.appendChild(this.parseToElement(c));
320
335
  });
321
336
  }
322
- if (typeof child === "function") {
337
+ if (typeof child === "function") {
323
338
  console.log("child is function");
324
339
  let comp = memoizeClassComponent(Component);
325
340
  comp.Mounted = true;
326
341
  comp.render = child;
327
342
  let el2 = comp.toElement();
328
- el2.setAttribute("key", comp.key);
343
+ el2.key = comp.key;
329
344
  el.appendChild(el2);
330
345
  } else if (typeof child === "object") {
331
346
  el.appendChild(this.parseToElement(child));
@@ -346,9 +361,7 @@ export class Component {
346
361
  }
347
362
  toElement() {
348
363
  let children = this.render();
349
- if (children.props["key"]) {
350
- this.key = children.props["key"];
351
- }
364
+
352
365
  let el = this.parseToElement(children);
353
366
  el.key = this.key;
354
367
  return el;
package/main.js CHANGED
@@ -12,6 +12,18 @@ if (!fs.existsSync(process.cwd() + '/app')) {
12
12
  if (!fs.existsSync(process.cwd() + '/public')) {
13
13
  fs.mkdirSync(process.cwd() + '/public')
14
14
  }
15
+ if(!fs.existsSync(process.cwd() + '/src')){
16
+ fs.mkdirSync(process.cwd() + '/src')
17
+ }
18
+ if(!fs.existsSync(process.cwd() + '/vader.config.ts')){
19
+ fs.writeFileSync(process.cwd() + '/vader.config.ts',
20
+ `
21
+ import defineConfig from 'vaderjs/config'
22
+ export default defineConfig({
23
+ port: 8080,
24
+ host_provider: 'apache'
25
+ })`)
26
+ }
15
27
  const mode = args.includes('dev') ? 'development' : args.includes('prod') || args.includes('build') ? 'production' : null
16
28
  if (!mode) {
17
29
  console.log(`
@@ -47,9 +59,9 @@ if (!fs.existsSync(process.cwd() + '/jsconfig.json')) {
47
59
  await Bun.write(process.cwd() + '/jsconfig.json', JSON.stringify(json, null, 4))
48
60
  }
49
61
 
50
- const bindes = []
62
+ var bindes = []
51
63
 
52
- const handleReplacements = (code, file) => {
64
+ const handleReplacements = (code ) => {
53
65
  let lines = code.split('\n')
54
66
  let newLines = []
55
67
  for (let line of lines) {
@@ -57,14 +69,23 @@ const handleReplacements = (code, file) => {
57
69
 
58
70
  if (hasImport && line.includes('.css')) {
59
71
  try {
60
- let url = path.join('/' + line.split("'")[1])
61
- let css = fs.readFileSync(process.cwd() + url, 'utf-8')
62
- line = '';
63
- if (!bindes.includes(`<link rel="stylesheet" href="${url}">`)) {
64
- bindes.push(`<link rel="stylesheet" href="${url}">`)
65
- }
66
- fs.mkdirSync(process.cwd() + '/dist' + path.dirname(url), { recursive: true })
67
- fs.writeFileSync(process.cwd() + '/dist' + url, css)
72
+ let isSmallColon = line.includes("'")
73
+ let url = isSmallColon ? line.split("'")[1] : line.split('"')[1]
74
+ // start from "/" not "/app"
75
+ // remvoe all ./ and ../
76
+ url = url.replaceAll('./', '/').replaceAll('../', '/')
77
+
78
+ let p = path.join(process.cwd() , '/', url)
79
+ line = '';
80
+ url = url.replace(process.cwd() + '/app', '')
81
+ url = url.replace(/\\/g, '/')
82
+ if (!bindes.includes(`<link rel="stylesheet" href="${url}">`)) {
83
+ bindes.push(`
84
+ <style>
85
+ ${fs.readFileSync(p, 'utf-8')}
86
+ </style>
87
+ `)
88
+ }
68
89
  } catch (error) {
69
90
  console.error(error)
70
91
  }
@@ -114,7 +135,7 @@ async function generateApp() {
114
135
  }
115
136
  return new Promise(async (resolve, reject) => {
116
137
  let routes = new Bun.FileSystemRouter({
117
- dir: process.cwd() + '/app',
138
+ dir: path.join(process.cwd(), '/app'),
118
139
  style: 'nextjs'
119
140
  })
120
141
  routes.reload()
@@ -132,7 +153,7 @@ async function generateApp() {
132
153
  let route = window.location.pathname.split('/').filter(v => v !== '')
133
154
  let params = {
134
155
  ${Object.keys(routes.match(route).params || {}).length > 0 ? Object.keys(routes.match(route).params || {}).map(p => {
135
- return `${p}: route[${Object.keys(routes.match(route).params).indexOf(p)}]`
156
+ return `${p}: route[${Object.keys(routes.match(route).params).indexOf(p) + Object.keys(routes.match(route).params).length}]`
136
157
  }).join(',') : ""}
137
158
  }
138
159
  \n${code}
@@ -160,11 +181,13 @@ async function generateApp() {
160
181
  file: process.cwd() + '/dist/' + path.dirname(r) + '/' + path.basename(r),
161
182
  DEV: mode === 'development',
162
183
  size,
184
+ bindes: bindes.join('\n'),
163
185
  filePath: r,
164
186
  INPUT: `../app/${r.replace('.js', '.jsx')}`,
165
187
  },
166
188
  onExit({ exitCode: code }) {
167
189
  if (code === 0) {
190
+ bindes = []
168
191
  console.log(`Built ${r} in ${Date.now() - start}ms`)
169
192
  resolve()
170
193
  } else {
@@ -222,7 +245,7 @@ function handleFiles() {
222
245
  }
223
246
  let glob2 = new Glob('src/**/*')
224
247
  for await (var i of glob2.scan()) {
225
- var file = i
248
+ var file = i
226
249
  fs.mkdirSync(path.join(process.cwd() + '/dist', path.dirname(file)), { recursive: true })
227
250
  // turn jsx to js
228
251
  if (file.includes('.jsx')) {
@@ -253,6 +276,34 @@ function handleFiles() {
253
276
  }
254
277
  }
255
278
  })
279
+ }else if(file.includes('.ts')){
280
+ let code = await Bun.file(file).text()
281
+ code = handleReplacements(code)
282
+ file = file.replace('.ts', '.js')
283
+ fs.writeFileSync(path.join(process.cwd() + '/dist', file.replace('.ts', '.js')), code)
284
+ await Bun.spawn({
285
+ cmd: ['bun', 'run', './dev/bundler.js'],
286
+ cwd: process.cwd(),
287
+ stdout: 'inherit',
288
+ env: {
289
+ ENTRYPOINT: path.join(process.cwd() + '/dist/' + file.replace('.ts', '.js')),
290
+ ROOT: process.cwd() + '/app/',
291
+ OUT: path.dirname(file),
292
+ file: process.cwd() + '/dist/' + file.replace('.ts', '.js'),
293
+ DEV: mode === 'development',
294
+ isTS: true,
295
+ size: code.length / 1024,
296
+ filePath: file.replace('.ts', '.js'),
297
+ INPUT: path.join(process.cwd() , file.replace('.js', '.jsx')),
298
+ },
299
+ onExit({ exitCode: code }) {
300
+ if (code === 0) {
301
+ resolve()
302
+ } else {
303
+ reject()
304
+ }
305
+ }
306
+ })
256
307
  }
257
308
 
258
309
  }
@@ -275,7 +326,8 @@ if (mode === 'development') {
275
326
 
276
327
  // Function to handle file changes with debounce
277
328
  const handleFileChangeDebounced = async (change, file) => {
278
- if(file.endsWith('.tsx') || file.endsWith('.jsx')){
329
+ if(file.endsWith('.tsx') || file.endsWith('.jsx') || file.endsWith('.css') || file.endsWith('.ts') ) {
330
+ if(file.includes('dist')) return
279
331
  clearTimeout(debounceTimeout);
280
332
  debounceTimeout = setTimeout(async () => {
281
333
  if (!isBuilding) { // Check if not already building
@@ -283,9 +335,12 @@ if (mode === 'development') {
283
335
  try {
284
336
  await generateApp();
285
337
  await handleFiles();
286
- clients.forEach(c => {
287
- c.send('reload');
288
- });
338
+ let t = setTimeout(() => {
339
+ clients.forEach(c => {
340
+ c.send('reload');
341
+ });
342
+ clearTimeout(t)
343
+ }, 1000)
289
344
  } catch (error) {
290
345
  console.error(error);
291
346
  } finally {
@@ -322,10 +377,12 @@ if (mode === 'development') {
322
377
  let p = url.pathname.replaceAll("%5B", "[").replaceAll("%5D", "]")
323
378
  let file = await Bun.file(path.join(process.cwd() + '/dist' + p))
324
379
  if (!await file.exists()) return new Response('Not found', { status: 404 })
325
- return new Response(await file.text(), {
380
+ let imageTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/svg+xml', 'image/webp', 'image/tiff', 'image/bmp', 'image/ico', 'image/cur', 'image/jxr', 'image/jpg']
381
+
382
+ return new Response(imageTypes.includes(file.type) ? await file.arrayBuffer() : await file.text(), {
326
383
  headers: {
327
384
  'Content-Type': file.type,
328
- 'Cache-Control': 'no-cache',
385
+ 'Cache-Control': imageTypes.includes(file.type) ? 'max-age=31536000' : 'no-cache',
329
386
  'Access-Control-Allow-Origin': '*'
330
387
  }
331
388
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vaderjs",
3
- "version": "1.5.5",
3
+ "version": "1.5.7",
4
4
  "description": "A simple and powerful JavaScript library for building modern web applications.",
5
5
  "bin": {
6
6
  "vaderjs": "./main.js"