vaderjs 2.0.0 → 2.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/bundler/index.js CHANGED
@@ -132,14 +132,13 @@ const handleReplacements = (code) => {
132
132
  line = updatedLine;
133
133
  }
134
134
 
135
- if (!hasImport && line.match(/\buseRef\d*\(/) && !line.includes("this")) {
136
-
137
-
138
- let key = line.split(' ')[1].split('=')[0];
139
-
140
- let updatedLine = line.replace(/\buseRef\d*\(/, `this.useRef('${key}',`);
141
-
142
- line = updatedLine;
135
+ if (!hasImport && line.match(/\buseRef\d*\(/) && line.includes('[') && !line.includes("this")) {
136
+ line = line.replace(' ', '')
137
+ let b4 = line
138
+ let key = line.split('=')[0].split(' ').filter(Boolean)[1]
139
+ console.log(key)
140
+ b4 = line.replace('useRef(', `this.useRef('${key}',`)
141
+ line = b4
143
142
  }
144
143
 
145
144
 
package/index.ts CHANGED
@@ -3,8 +3,6 @@ let isClassComponent = function (element) {
3
3
  return element.toString().startsWith("class");
4
4
  };
5
5
 
6
-
7
-
8
6
 
9
7
 
10
8
  const memoizes = new Map();
@@ -61,6 +59,19 @@ export const useFetch = (url: string, options: any) => {
61
59
  return [null, true, null];
62
60
  };
63
61
 
62
+ /**
63
+ * @description - useRef allows you to store a reference to a DOM element
64
+ * @param value
65
+ * @returns {current: HTMLElement}
66
+ * @example
67
+ * const inputRef = useRef();
68
+ * <input ref={inputRef} />
69
+ * console.log(inputRef.current) // <input />
70
+ */
71
+ export const useRef = (value) => {
72
+ return { key: crypto.randomUUID(), current: value };
73
+ }
74
+
64
75
  /**
65
76
  * @description - Handle asyncronous promises and return the data or error;
66
77
  * @param promise
@@ -69,7 +80,7 @@ export const useFetch = (url: string, options: any) => {
69
80
  export const useAsyncState = (promise: Promise<any>) => {
70
81
  return [null, () => { }];
71
82
  }
72
- export const useEffect = (callback: any, dependencies: any[] = []) => {
83
+ export const useEffect = (callback: any, dependencies: any[] = []) => {
73
84
  dependencies = dependencies.map((dep) => JSON.stringify(dep));
74
85
  if (dependencies.length === 0) {
75
86
  callback();
@@ -158,8 +169,8 @@ export const e = (element, props, ...children) => {
158
169
  instance.children = children;
159
170
  if (!firstEl)
160
171
  firstEl = { type: "div", props: { key: instance.key, ...props }, children };
161
- firstEl.props = { key: instance.key, ...firstEl.props, ...props };
162
- firstEl.props["idKey"] = instance.key;
172
+ firstEl.props = { key: instance.key, ...firstEl.props, ...props };
173
+ firstEl.props["idKey"] = instance.props?.ref?.key || instance.key;
163
174
  instance.props = firstEl.props;
164
175
  return firstEl;
165
176
  default:
@@ -168,7 +179,7 @@ export const e = (element, props, ...children) => {
168
179
  }
169
180
  let el = { type: element, props: props || {}, children: children || [] };
170
181
  if (el.type !== "head") {
171
- el.props = { idKey: crypto.randomUUID(), ...el.props };
182
+ el.props = { idKey: el.props?.ref?.key || crypto.randomUUID(), ...el.props };
172
183
  }
173
184
 
174
185
  // if element == false return empty string
@@ -194,11 +205,11 @@ interface SwitchProps {
194
205
  }
195
206
 
196
207
  // make children optional
197
- export function Switch({ children = [] }: SwitchProps) {
208
+ export function Switch({children}, key) {
198
209
  for (let child of children) {
199
210
  if (child.props.when) {
200
211
  return { type: "div", props: {
201
- idKey: crypto.randomUUID()
212
+ idKey: key || crypto.randomUUID()
202
213
  }, children: [child] };
203
214
  }
204
215
  }
@@ -291,16 +302,17 @@ export class Component {
291
302
  }
292
303
  useRef = (key, value) => {
293
304
  if (!this.refs.find((r) => r.key == key)) {
294
- this.refs.push({ key, value });
305
+ this.refs.push({ key, current: value});
295
306
  }
296
307
 
297
- return this.refs.find((r) => r.key == key).value;
308
+ return { key, current: this.refs.find((r) => r.key == key).current };
298
309
  }
299
310
  useEffect(callback, dependencies = []) {
300
311
  const callbackId = callback.toString(); // Unique ID based on callback string representation
301
312
 
313
+ // Ensure effect is tracked only once per callback function
302
314
  if (!this.effectCalls.some((effect) => effect.id === callbackId)) {
303
- // Add the initial effect call if it doesn't exist
315
+ // Initialize the effect call tracking
304
316
  this.effectCalls.push({
305
317
  id: callbackId,
306
318
  count: 0,
@@ -312,7 +324,7 @@ export class Component {
312
324
 
313
325
  const effectCall = this.effectCalls.find((effect) => effect.id === callbackId);
314
326
 
315
- const executeCallback = () => {
327
+ const executeCallback = async () => {
316
328
  const now = Date.now();
317
329
  const timeSinceLastCall = now - effectCall.lastCall;
318
330
 
@@ -330,22 +342,21 @@ export class Component {
330
342
 
331
343
  effectCall.lastCall = now;
332
344
 
333
- setTimeout(() => {
334
- try {
335
- effects.push(callbackId); // Track executed effects
336
- callback(); // Execute the callback
337
- } catch (error) {
338
- console.error(error);
339
- }
340
- }, 0);
345
+ try {
346
+ // Wait for async callback to finish before continuing
347
+ await callback();
348
+ effects.push(callbackId); // Track executed effects after callback completion
349
+ } catch (error) {
350
+ console.error("Effect callback failed:", error);
351
+ }
341
352
  };
342
353
 
343
354
  // First time: Run the effect and mark it as run
344
355
  if (!effectCall.hasRun && dependencies.length === 0) {
345
- executeCallback();
346
- effectCall.hasRun = true;
347
- effectCall.dependencies = dependencies;
348
- return;
356
+ executeCallback(); // Run async callback
357
+ effectCall.hasRun = true;
358
+ effectCall.dependencies = dependencies;
359
+ return;
349
360
  }
350
361
 
351
362
  // If there are no dependencies, do nothing after the first run
@@ -353,7 +364,7 @@ export class Component {
353
364
  return;
354
365
  }
355
366
 
356
- // Check if dependencies have changed
367
+ // Check if dependencies have changed by deep comparison (improve this if necessary)
357
368
  let dependenciesChanged = false;
358
369
  for (let i = 0; i < dependencies.length; i++) {
359
370
  const previousDependencies = effectCall.dependencies || [];
@@ -367,14 +378,20 @@ export class Component {
367
378
 
368
379
  // If dependencies have changed, run the effect and update dependencies
369
380
  if (dependenciesChanged) {
370
- executeCallback();
381
+ executeCallback(); // Run async callback
371
382
  effectCall.dependencies = dependencies;
372
383
  }
373
384
  }
374
385
 
386
+
375
387
 
376
388
  useState(key, defaultValue, persist = false) {
377
389
  let value = this.state[key] || defaultValue;
390
+ if(value === "true" || value === "false") {
391
+ value = JSON.parse(value);
392
+ }
393
+ // if value is boolean store as string
394
+
378
395
  if (persist) {
379
396
  value = sessionStorage.getItem(key) ? JSON.parse(sessionStorage.getItem(key)).value : defaultValue;
380
397
  }
@@ -382,13 +399,14 @@ export class Component {
382
399
  if(typeof newValue === "function") {
383
400
  newValue = newValue(this.state[key]);
384
401
  }
385
- this.state[key] = newValue;
402
+ this.state[key] = typeof newValue === "boolean" ? newValue.toString() : newValue;
386
403
  if (persist) {
387
404
  sessionStorage.setItem(key, JSON.stringify({ value: newValue }));
388
405
  }
389
406
  this.forceUpdate(this.key);
390
407
  };
391
- value = this.state[key] || defaultValue;
408
+ value = typeof value === "boolean" ? value === "true" : value;
409
+
392
410
  return [value, setValue];
393
411
  }
394
412
  useFetch(url, options) {
@@ -619,11 +637,18 @@ export class Component {
619
637
 
620
638
  // Set attributes
621
639
  let attributes = element.props || {};
622
- for (let key in attributes) {
623
- if(typeof attributes[key] === "object" && key !== "style"){
624
- continue;
625
- }
626
- if (key === "key") {
640
+ for (let key in attributes) {
641
+ if(key === "ref") {
642
+ let _key = attributes[key].key;
643
+ // update the ref
644
+ let ref = this.refs.find((r) => r.key == _key);
645
+ if(ref) {
646
+ ref.current = document.querySelector(`[idKey="${_key}"]`) || el;
647
+ }
648
+ el.setAttribute("idKey", _key);
649
+ element.props.idKey = _key
650
+ }
651
+ else if (key === "key") {
627
652
  el.key = attributes[key];
628
653
  } else if (key === "className") {
629
654
  el.setAttribute("class", attributes[key]);
@@ -647,7 +672,9 @@ export class Component {
647
672
  } catch (error) {
648
673
 
649
674
  }
650
- }
675
+ } else if(typeof attributes[key] === "object" && key !== "style"){
676
+ continue;
677
+ }
651
678
  }
652
679
 
653
680
  // Handle children
package/main.js CHANGED
@@ -167,8 +167,9 @@ const handleReplacements = (code) => {
167
167
  line = b4
168
168
  }
169
169
  if (!hasImport && line.includes('useRef')) {
170
+ line = line.replace(' ', '')
170
171
  let b4 = line
171
- let key = line.split(' ')[1].split('=')[0]
172
+ let key = line.split('=')[0].split(' ').filter(Boolean)[1]
172
173
  b4 = line.replace('useRef(', `this.useRef('${key}',`)
173
174
  line = b4
174
175
  }
@@ -186,8 +187,7 @@ if (!fs.existsSync(process.cwd() + '/dev/bundler.js')) {
186
187
  let start = Date.now()
187
188
  async function generateApp() {
188
189
  globalThis.isBuilding = true;
189
- console.log(ansiColors.green('Building...'))
190
- console.log(`Starting build at ${new Date().toLocaleTimeString()}`)
190
+ console.log(ansiColors.green('Building...'))
191
191
  let plugins = config.plugins || []
192
192
  for (let plugin of plugins) {
193
193
  if (plugin.onBuildStart) {
@@ -275,8 +275,7 @@ async function generateApp() {
275
275
  },
276
276
  onExit({ exitCode: code }) {
277
277
  if (code === 0) {
278
- bindes = []
279
- console.log(`Built ${r} in ${Date.now() - start}ms`)
278
+ bindes = []
280
279
  resolve()
281
280
  } else {
282
281
  reject()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vaderjs",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "A simple and powerful JavaScript library for building modern web applications.",
5
5
  "bin": {
6
6
  "vaderjs": "./main.js"