vaderjs 1.4.1-ui7iuy47 → 1.4.2-bml56

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.
@@ -0,0 +1,99 @@
1
+ import { Document, Element} from "../../../@server/Kalix/index.js"
2
+ class Component {
3
+ constructor(props){
4
+ this.props = props
5
+ this._key = Math.random().toString(36).substring(7)
6
+ this.state = {}
7
+ this.htmlNode = null
8
+ this.firstChild = null
9
+ this.Element = Element
10
+ }
11
+
12
+
13
+ setState(newState){
14
+ this.state = newState
15
+ }
16
+
17
+
18
+ useState(name, initialValue){
19
+ if(!this.state[name]){
20
+ this.state[name] = initialValue
21
+ }
22
+
23
+ let getState = () => this.state[name]
24
+ let setState = (newValue) => {
25
+
26
+
27
+ }
28
+ return [getState, setState]
29
+
30
+ }
31
+ useReducer(name, reducer, initialState){
32
+ let [state, setState] = this.useState(name, initialState)
33
+ let dispatch = (action) => {
34
+ let newState = reducer(state(), action)
35
+ setState(newState)
36
+ }
37
+
38
+ return [state, dispatch]
39
+ }
40
+
41
+ useEffect(effect, deps){
42
+ return effect()
43
+ }
44
+
45
+ render(){
46
+ return null
47
+ }
48
+
49
+ }
50
+ export async function renderToString(element, args = []) {
51
+ let data = typeof element === 'function' ? await element(...args) : element
52
+ let doc = new Document()
53
+ let el = doc.createElement(data)
54
+
55
+ return el.toString()
56
+
57
+ }
58
+
59
+ export async function generatePage(element, options = {entry:"", props: ()=>{}}, args = []) {
60
+ //@ts-ignore
61
+ globalThis.isServer = true
62
+ // @ts-ignore
63
+ let serverSideProps = await options.props({req: args[0], res: args[1]}, args.slice(2))
64
+ let name = element.name
65
+
66
+ let comp = new Component(serverSideProps?.props)
67
+ element = element.bind(comp)
68
+ comp.render = (props)=> {
69
+ return element(props)
70
+ }
71
+ let data = new Document().createElement(comp.render({props: serverSideProps.props, ...args}))
72
+ let document = new Document()
73
+ document.documentElement.setContent(data.querySelector('html') ? data.querySelector('html').innerHTML : '')
74
+ document.head.setContent(data.querySelector('head') ? data.querySelector('head').innerHTML : '')
75
+ data.removeChild(data.querySelector('head'))
76
+ let div = new Document().createElement('div')
77
+ div.setAttribute('id', 'app')
78
+ div.setContent(data.innerHTML)
79
+ document.body.appendChild(div)
80
+ let script = new Document().createElement('script')
81
+ script.setAttribute('type', 'module')
82
+
83
+ script.setContent(script.innerHTML + '\n' + `
84
+
85
+ import ${name} from "${options?.entry}"
86
+ import {render} from '/src/client.js'
87
+ import Kuai from '/src/router.js'
88
+ let kuai = new Kuai({container: document.getElementById('app')})
89
+ kuai.get('/', (c) => {
90
+ c.html(render(${name}, document.getElementById('app'), {...c, props: ${JSON.stringify(serverSideProps.props)}}))
91
+ })
92
+ kuai.use('/', () => console.log('Middleware'))
93
+ kuai.listen()
94
+ `)
95
+ document.body.appendChild(script)
96
+ return `<!DOCTYPE html>${document.head.toString()}${document.body.innerHTML}`
97
+ }
98
+
99
+ export default renderToString
@@ -0,0 +1,432 @@
1
+ window.vader = {
2
+ version: '1.0.0'
3
+ }
4
+ globalThis.isServer = false
5
+ window.hasRan = []
6
+ globalThis.memoizedFunctions = []
7
+ const memoizedRefs = []
8
+ /**
9
+ * @description This function is used to calculate the difference between two nodes - and return the elements in which the difference is found
10
+ * @param {HTMLElement} oldNode
11
+ * @param {HTMLElement} newNode
12
+ * @returns
13
+ */
14
+ function calculateDiff(oldNode, newNode){
15
+ if(oldNode === undefined || newNode === undefined){
16
+ return []
17
+ }
18
+ let diff = []
19
+ if(oldNode?.children.length > 0){
20
+ for(var i = 0; i < oldNode.children.length; i++){
21
+ diff.push(...calculateDiff(oldNode.children[i], newNode.children[i]))
22
+
23
+ }
24
+ return diff
25
+ }
26
+ if(!oldNode?._isRoot){
27
+ if(oldNode.nodeType === 3 && oldNode.nodeValue !== newNode.nodeValue){
28
+ diff.push({type: 'REPLACE', oldNode, newNode})
29
+ }
30
+ else if(oldNode.nodeType === 1 && oldNode.innerHTML !== newNode.innerHTML
31
+ ){
32
+ diff.push({type: 'REPLACE', oldNode, newNode})
33
+ }
34
+ else if(oldNode.nodeType === 1 && oldNode.tagName === newNode.tagName){
35
+ for(var i = 0; i < oldNode.attributes.length; i++){
36
+ if(oldNode.attributes[i].value !== newNode.attributes[i].value){
37
+ diff.push({type: 'PROPS', oldNode, newNode})
38
+ }
39
+ }
40
+ }
41
+ }
42
+
43
+
44
+
45
+ return diff
46
+ }
47
+
48
+ /**
49
+ * @description This function is used to generate functonal components
50
+ * @param {Function} tag
51
+ * @param {Object} props
52
+ * @param {...any} children
53
+ * @returns {Object} - The first child of the functional component
54
+ */
55
+ function generateJSX(tag, props, ...children){
56
+ let node = {
57
+ state: {},
58
+ mainFunction: tag,
59
+ _key: tag.name || Math.random().toString(36).substring(7),
60
+ $$typeof: 'JSX_CHILD',
61
+ firstChild:null,
62
+ children: children,
63
+ _name: tag.name,
64
+ }
65
+
66
+ node.firstChild = tag()
67
+ node.firstChild.htmlNode._key = node._key
68
+ node.firstChild.htmlRoot = node
69
+ node.firstChild.htmlNode._isRoot = true
70
+ node.firstChild.props = props || {}
71
+ node.firstChild._isRoot = true
72
+ node.firstChild._key = node._key
73
+ node.firstChild.props['key'] = node._key
74
+ return node.firstChild
75
+
76
+
77
+ }
78
+ function handleStyles(styles, nodeEl) {
79
+
80
+ for (let key in styles) {
81
+ if(typeof styles[key] === 'object'){
82
+ handleStyles(styles[key], nodeEl)
83
+ }
84
+ nodeEl.style[key] = styles[key];
85
+ }
86
+
87
+ }
88
+
89
+
90
+ let hasBeenCalled = []
91
+ /**
92
+ * @description Create a virtual DOM element
93
+ * @param {string | Function} tag
94
+ * @param {Object} props
95
+ * @param {...any} children
96
+ * @returns {Object} - The virtual DOM element
97
+ */
98
+ function Element(tag, props, ...children){
99
+ !props ? props = {} : null
100
+ if(!props?.['$$key']){
101
+ props['$$key'] = tag.name || Math.random().toString(36).substring(7)
102
+ }
103
+
104
+ if(typeof tag === 'function'){
105
+ return generateJSX(tag, props, children)
106
+ }
107
+ let node = {
108
+ tag: tag,
109
+ props: props,
110
+ children: children,
111
+ _key: props['$$key'],
112
+ events: [],
113
+ staticEl: document.createElement(tag),
114
+ parentNode: null
115
+ }
116
+ for(var i = 0; i < children.length; i++){
117
+ if(typeof children[i] === 'string' || typeof children[i] === 'number'){
118
+ children[i] = {
119
+ tag: 'TEXT_ELEMENT',
120
+ props: {nodeValue: children[i]},
121
+ _key: props['$$key'],
122
+ parentNode: {tag: tag, props: props, children: children, _key: props['$$key']},
123
+ children: []
124
+ }
125
+ }else{
126
+ if(children[i]){
127
+ children[i].parentNode = {tag: tag, props: props, children: children}
128
+ }
129
+ }
130
+ }
131
+ let nodeEl = node.tag === 'TEXT_ELEMENT' ? document.createTextNode('') : document.createElement(node.tag)
132
+ node.staticEl = nodeEl
133
+
134
+ for(var key in props){
135
+ if(key.toLowerCase().startsWith('on')){
136
+ nodeEl.addEventListener(key.substring(2).toLowerCase(), props[key])
137
+ node.events.push({type: key.substring(2).toLowerCase(), listener: props[key]})
138
+ continue
139
+ }
140
+ if(key === '$$key' && !nodeEl._key && nodeEl.nodeType === 1
141
+ ){
142
+ Object.defineProperty(nodeEl, '_key', {
143
+ value: props[key],
144
+ writable: true
145
+ })
146
+ continue
147
+ }
148
+
149
+ if(nodeEl && nodeEl.nodeType === 1){
150
+ nodeEl.setAttribute(key, props[key])
151
+ }
152
+
153
+ }
154
+ if(props.style){
155
+ handleStyles(props.style, nodeEl)
156
+ }
157
+
158
+ if(props.id){
159
+ nodeEl.id = props.id
160
+ }
161
+ if(props.ref){
162
+ switch(true){
163
+ case Array.isArray(props.ref.current):
164
+ if(!props.ref.current.find((el) => el === nodeEl)){
165
+ props.ref.current.push(nodeEl)
166
+ }
167
+ break;
168
+ case props.ref.current === HTMLElement:
169
+ props.ref.current = nodeEl
170
+ break;
171
+ case props.ref.current === null:
172
+ props.ref.current = nodeEl
173
+ break;
174
+ case typeof props.ref === 'function' && !window.hasRan.includes(props.ref):
175
+ window.hasRan.push(props.ref)
176
+ props.ref(nodeEl)
177
+ setTimeout(() => {
178
+ window.hasRan.filter((el) => el !== props.ref)
179
+ }, 0)
180
+ break;
181
+ default:
182
+ props.ref.current = nodeEl
183
+ break;
184
+
185
+ }
186
+ }
187
+ node['htmlNode'] = nodeEl
188
+
189
+
190
+ if(nodeEl.nodeType === 1){
191
+ for(var i = 0; i < children.length; i++){
192
+ if(children[i]){
193
+ if(children[i].tag === 'TEXT_ELEMENT'){
194
+ nodeEl.appendChild(document.createTextNode(children[i].props.nodeValue))
195
+ }
196
+ nodeEl.appendChild(Element(children[i].tag, children[i].props, ...children[i].children).htmlNode)
197
+ }
198
+ }
199
+
200
+ }
201
+
202
+ return node;
203
+ }
204
+
205
+
206
+ function handleDiff(diff){
207
+ for(var i = 0; i < diff.length; i++){
208
+ switch(true){
209
+ case diff[i].type === 'REPLACE' && !diff[i].oldNode._isRoot:
210
+ let parent = diff[i].oldNode.parentNode
211
+ diff[i].oldNode.parentNode.replaceChild(diff[i].newNode, diff[i].oldNode)
212
+ break;
213
+ case diff[i].type === 'PROPS':
214
+ break;
215
+ }
216
+ }
217
+
218
+ }
219
+ let states = {}
220
+ export const useState = (name, initialValue) => {}
221
+ export function useRef(name, initialValue){
222
+ let ref = initialValue
223
+ if(!memoizedRefs.find((el) => el.name === name)){
224
+ memoizedRefs.push({name, ref})
225
+ }
226
+ let getRef = () => memoizedRefs.find((el) => el.name === name).ref
227
+ let setRef = (newValue) => {
228
+ memoizedRefs.find((el) => el.name === name).ref = newValue
229
+ }
230
+ return {
231
+ current: getRef(),
232
+ name,
233
+ }
234
+ }
235
+ export function Mounted(fn, node){
236
+ let el = Array.from(document.querySelectorAll('*')).find((el) => el._key === memoizedFunctions.find((el) => el.mainFunction === node)._key)
237
+ if(el && !hasBeenCalled.find((el) => el === node)){
238
+ fn()
239
+ hasBeenCalled.push(node)
240
+ }
241
+ else{
242
+ setTimeout(() => {
243
+ Mounted(fn, node)
244
+ }, 0)
245
+ }
246
+ }
247
+
248
+
249
+ let effects = [];
250
+
251
+ export function useEffect(fn, deps){
252
+ if(!effects.find((el) => el.fn.toString() === fn.toString())){
253
+ effects.push({fn, deps})
254
+ }
255
+ else{
256
+ let effect = effects.find((el) => el.fn.toString() === fn.toString())
257
+ if(effect.deps.toString() !== deps.toString()){
258
+ effect.deps = deps
259
+ effect.fn()
260
+ }
261
+ }
262
+ return () => {
263
+ effects = effects.filter((el) => el.fn !== fn)
264
+ }
265
+
266
+ }
267
+ export function useReducer(name, reducer, vnode, initialState){
268
+ let [state, setState] = useState(name, vnode, initialState)
269
+ let dispatch = (action) => {
270
+ let newState = reducer(state, action)
271
+ setState(newState)
272
+ }
273
+
274
+ return [state, dispatch]
275
+
276
+ }
277
+
278
+ class Component {
279
+ constructor(props){
280
+ this.props = props
281
+ this._key = props['$$key'] || Math.random().toString(36).substring(7)
282
+ this.state = {}
283
+ this.htmlNode = null
284
+ this.firstChild = null
285
+ this.Element = Element
286
+ this.effects = []
287
+ }
288
+
289
+
290
+ setState(newState){
291
+ this.state = newState
292
+ }
293
+
294
+ handleDiff(diff){
295
+ for(var i = 0; i < diff.length; i++){
296
+ switch(true){
297
+ case diff[i].type === 'REPLACE' && !diff[i].oldNode._isRoot:
298
+ let parent = diff[i].oldNode.parentNode
299
+ diff[i].oldNode.parentNode.replaceChild(diff[i].newNode, diff[i].oldNode)
300
+ break;
301
+ case diff[i].type === 'PROPS':
302
+ break;
303
+ }
304
+ }
305
+ }
306
+ calculateDiff(oldNode, newNode){
307
+ if(oldNode === undefined || newNode === undefined){
308
+ return []
309
+ }
310
+ let diff = []
311
+ if(oldNode?.children.length > 0){
312
+ for(var i = 0; i < oldNode.children.length; i++){
313
+ diff.push(...this.calculateDiff(oldNode.children[i], newNode.children[i]))
314
+
315
+ }
316
+ return diff
317
+ }
318
+ if(!oldNode?._isRoot){
319
+ if(oldNode.nodeType === 3 && oldNode.nodeValue !== newNode.nodeValue){
320
+ diff.push({type: 'REPLACE', oldNode, newNode})
321
+ }
322
+ else if(oldNode.nodeType === 1 && oldNode.innerHTML !== newNode.innerHTML
323
+ ){
324
+ diff.push({type: 'REPLACE', oldNode, newNode})
325
+ }
326
+ else if(oldNode.nodeType === 1 && oldNode.tagName === newNode.tagName){
327
+ for(var i = 0; i < oldNode.attributes.length; i++){
328
+ if(oldNode.attributes[i].value !== newNode.attributes[i].value){
329
+ diff.push({type: 'PROPS', oldNode, newNode})
330
+ }
331
+ }
332
+ }
333
+ }
334
+
335
+
336
+
337
+ return diff
338
+ }
339
+ useEffect(fn, deps){
340
+ if(!this.effects.find((el) => el.fn.toString() === fn.toString())){
341
+ this.effects.push({fn, deps})
342
+ }
343
+ else{
344
+ let effect = this.effects.find((el) => el.fn.toString() === fn.toString())
345
+ if(effect.deps.toString() !== deps.toString()){
346
+ effect.deps = deps
347
+ effect.fn()
348
+ }
349
+ }
350
+ return () => {
351
+ this.effects = this.effects.filter((el) => el.fn !== fn)
352
+ }
353
+ }
354
+ useState(name, initialValue){
355
+ if(!this.state[name]){
356
+ this.state[name] = initialValue
357
+ }
358
+
359
+ let getState = () => this.state[name]
360
+ let setState = (newValue) => {
361
+ let dEl = this.firstChild.htmlNode
362
+ if(dEl.tagName === 'HTML'){
363
+ let firstChild = dEl.querySelector('body').firstChild
364
+ dEl = firstChild
365
+ }
366
+ this.state[name] = newValue
367
+ let el = Array.from(document.querySelectorAll('*')).find((el) =>{
368
+ return el._key === dEl._key
369
+ })
370
+ let diff = calculateDiff(el, this.render().htmlNode.tagName === 'HTML' ? this.render().htmlNode.querySelector('body').firstChild : this.render().htmlNode)
371
+ handleDiff(diff)
372
+
373
+ }
374
+ return [getState, setState]
375
+
376
+ }
377
+ useReducer(name, reducer, initialState){
378
+ let [state, setState] = this.useState(name, initialState)
379
+ let dispatch = (action) => {
380
+ let newState = reducer(state(), action)
381
+ setState(newState)
382
+ }
383
+
384
+ return [state, dispatch]
385
+ }
386
+
387
+ render(){
388
+ return null
389
+ }
390
+
391
+ }
392
+
393
+ export async function render(vnode, container, ...passProps){
394
+
395
+ if(!vnode){
396
+ throw new Error('No vnode was provided')
397
+ }
398
+ // create an object for the node then bind to firstChild
399
+ let comp = new Component({$$key: vnode.name || Math.random().toString(36).substring(7)})
400
+ vnode = vnode.bind(comp)
401
+ comp.render = () => {
402
+ return vnode(...passProps)
403
+ }
404
+
405
+ comp.firstChild = comp.render()
406
+
407
+ if(comp.firstChild.htmlNode.tagName === 'HTML'){
408
+ let hasHead = comp.firstChild.htmlNode.querySelector('head') ? true : false
409
+ let hasBody = comp.firstChild.htmlNode.querySelector('body') ? true : false
410
+
411
+ if(hasHead){
412
+ document.head.innerHTML = comp.firstChild.htmlNode.querySelector('head').innerHTML
413
+ comp.firstChild.children = comp.firstChild.children.filter((el) =>{
414
+ return el.htmlNode.tagName !== 'HEAD'
415
+ })
416
+ }
417
+ if(hasBody){
418
+ comp.firstChild.children = comp.firstChild.children.filter((el) =>{
419
+ if(el.htmlNode.tagName == 'BODY'){
420
+ comp.firstChild = el.children[0]
421
+ }
422
+ })
423
+ }
424
+ }
425
+ container.innerHTML = ''
426
+
427
+ container.appendChild(comp.firstChild.htmlNode)
428
+
429
+
430
+ }
431
+
432
+ export default Element