valyrian.js 7.2.1 → 7.2.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/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +35 -32
- package/dist/hooks/index.mjs +35 -32
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +55 -52
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/index.mjs +55 -52
- package/dist/interfaces.d.ts +1 -0
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/signal/index.d.ts +19 -1
- package/dist/signal/index.d.ts.map +1 -1
- package/dist/signal/index.js +49 -32
- package/dist/signal/index.mjs +52 -35
- package/lib/hooks/index.ts +43 -54
- package/lib/index.ts +88 -79
- package/lib/interfaces.ts +1 -0
- package/lib/signal/index.ts +114 -55
- package/package.json +1 -1
package/lib/signal/index.ts
CHANGED
|
@@ -1,29 +1,64 @@
|
|
|
1
|
-
import { VnodeWithDom, current,
|
|
1
|
+
import { VnodeWithDom, current, onUnmount, updateVnode, v } from "valyrian.js";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
interface GetterInterface {
|
|
4
|
+
(): any;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface SetterInterface {
|
|
8
|
+
(value: any): void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface SubscribeInterface {
|
|
12
|
+
(callback: Function): void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface SubscriptionsInterface extends Array<Function> {}
|
|
16
|
+
|
|
17
|
+
export interface SignalInterface extends Array<any> {
|
|
18
|
+
0: GetterInterface;
|
|
19
|
+
1: SetterInterface;
|
|
20
|
+
2: SubscribeInterface;
|
|
21
|
+
3: SubscriptionsInterface;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
25
|
+
export function Signal(initialValue): SignalInterface {
|
|
4
26
|
// Create a copy of the current context object
|
|
5
|
-
const
|
|
27
|
+
const { vnode, component } = { ...current };
|
|
6
28
|
|
|
7
29
|
// Check if the context object has a vnode property
|
|
8
|
-
if (
|
|
30
|
+
if (vnode) {
|
|
9
31
|
// Is first call
|
|
10
|
-
if (!
|
|
11
|
-
// Set the
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
context.vnode.calls = -1;
|
|
15
|
-
// Set the subscribers property to the subscribers property of the oldVnode object, or an empty array if that doesn't exist
|
|
16
|
-
context.vnode.subscribers = context.oldVnode?.subscribers || [];
|
|
32
|
+
if (!vnode.components) {
|
|
33
|
+
// Set the components property to an empty array
|
|
34
|
+
vnode.components = [];
|
|
35
|
+
}
|
|
17
36
|
|
|
18
|
-
|
|
19
|
-
|
|
37
|
+
// Check if the components array of the vnode object does not contain the component object
|
|
38
|
+
if (vnode.components.indexOf(component) === -1) {
|
|
39
|
+
// Set the calls property to -1
|
|
40
|
+
vnode.signal_calls = -1;
|
|
41
|
+
// Add the component to the components array
|
|
42
|
+
vnode.components.push(component);
|
|
43
|
+
|
|
44
|
+
// Check if the component object has a signals property
|
|
45
|
+
if (!component.signals) {
|
|
46
|
+
// Set the signals property of the component object to an empty array
|
|
47
|
+
component.signals = [];
|
|
48
|
+
// Add a function to the cleanup stack that removes the signals property from the component object
|
|
49
|
+
onUnmount(() => Reflect.deleteProperty(component, "signals"));
|
|
50
|
+
}
|
|
20
51
|
}
|
|
21
52
|
|
|
22
53
|
// Assign the signal variable to the signal stored at the index of the vnode object's calls property in the vnode's signals array
|
|
23
|
-
let signal =
|
|
54
|
+
let signal: SignalInterface = component.signals[++vnode.signal_calls];
|
|
24
55
|
|
|
25
56
|
// If a signal has already been assigned to the signal variable, return it
|
|
26
57
|
if (signal) {
|
|
58
|
+
// Remove all subscriptions because we come from a new render
|
|
59
|
+
signal[3].length = 0;
|
|
60
|
+
|
|
61
|
+
// Return the signal
|
|
27
62
|
return signal;
|
|
28
63
|
}
|
|
29
64
|
}
|
|
@@ -32,69 +67,93 @@ export function Signal(initialValue) {
|
|
|
32
67
|
let value = initialValue;
|
|
33
68
|
|
|
34
69
|
// Create an array to store functions that have subscribed to changes to the Signal's value
|
|
35
|
-
const
|
|
70
|
+
const subscriptions: SubscriptionsInterface = [];
|
|
36
71
|
|
|
37
72
|
// Define a function that allows other parts of the code to subscribe to changes to the Signal's value
|
|
38
73
|
const subscribe = (callback) => {
|
|
39
|
-
// Add the callback function to the
|
|
40
|
-
if (
|
|
41
|
-
|
|
74
|
+
// Add the callback function to the subscriptions array if it is not already in the array
|
|
75
|
+
if (subscriptions.indexOf(callback) === -1) {
|
|
76
|
+
subscriptions.push(callback);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// Set the vnodes to update when the Signal's value changes
|
|
81
|
+
let vnodesToUpdate: Array<VnodeWithDom> = [];
|
|
82
|
+
|
|
83
|
+
// This is the function that will be called when the Signal's value changes
|
|
84
|
+
const updateVnodes = () => {
|
|
85
|
+
// Create a copy of the vnodesToUpdate array and filter out any duplicate vnodes
|
|
86
|
+
let vnodesToUpdateCopy = vnodesToUpdate.filter((vnode, index, self) => {
|
|
87
|
+
return self.findIndex((v) => v.dom === vnode.dom) === index;
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Loop through the vnodesToUpdate array
|
|
91
|
+
for (let i = 0, l = vnodesToUpdateCopy.length; i < l; i++) {
|
|
92
|
+
const vnode2 = vnodesToUpdateCopy[i];
|
|
93
|
+
// If it does, create a new vnode object based on the original vnode, its children, and its DOM and SVG properties
|
|
94
|
+
let newVnode = v(vnode2.tag, vnode2.props, ...vnode2.initialChildren) as VnodeWithDom;
|
|
95
|
+
newVnode.dom = vnode2.dom; // Set the new vnode object's DOM property to the old vnode object's DOM property
|
|
96
|
+
newVnode.isSVG = vnode2.isSVG; // Set the new vnode object's isSVG property to the old vnode object's isSVG property
|
|
97
|
+
|
|
98
|
+
// Update the vnode object
|
|
99
|
+
updateVnode(newVnode, vnode2);
|
|
42
100
|
}
|
|
43
101
|
};
|
|
44
102
|
|
|
45
103
|
// Define a function that returns the current value of the Signal
|
|
46
104
|
function get() {
|
|
105
|
+
// Get the current vnode from the context object
|
|
106
|
+
const { vnode: vnode2 } = current;
|
|
107
|
+
|
|
108
|
+
// If we have a current vnode, it means that a get function is being called from within a component
|
|
109
|
+
// so we subscribe the vnode to be updated when the Signal's value changes
|
|
110
|
+
if (vnode2 && vnodesToUpdate.indexOf(vnode2) === -1) {
|
|
111
|
+
// We set the initialChildren to a copy of the vnode's children array
|
|
112
|
+
// This is the case when the vnode is a component that has not been rendered yet and we need the initial children
|
|
113
|
+
// because they could have the components that are using the Signal
|
|
114
|
+
if (!vnode2.initialChildren) {
|
|
115
|
+
vnode2.initialChildren = [...vnode2.children];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Add the vnode to the vnodesToUpdate array
|
|
119
|
+
vnodesToUpdate.push(vnode2);
|
|
120
|
+
|
|
121
|
+
// Subscribe the updateVnodes function to the Signal
|
|
122
|
+
subscribe(updateVnodes);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Return the current value of the Signal
|
|
47
126
|
return value;
|
|
48
127
|
}
|
|
49
|
-
// Add value, toJSON, valueOf, and toString properties to the get function
|
|
50
|
-
get.value = value;
|
|
51
|
-
get.toJSON = get.valueOf = get;
|
|
52
|
-
get.toString = () => `${value}`;
|
|
53
128
|
|
|
54
129
|
// Define a function that allows the value of the Signal to be updated and notifies any subscribed functions of the change
|
|
55
130
|
const set = (newValue) => {
|
|
56
|
-
//
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
get.value = value;
|
|
60
|
-
// Call each subscribed function with the new value of the Signal as an argument
|
|
61
|
-
for (let i = 0, l = subscribers.length; i < l; i++) {
|
|
62
|
-
subscribers[i](value);
|
|
131
|
+
// If we have a current event on going, prevent the default action
|
|
132
|
+
if (current.event) {
|
|
133
|
+
current.event.preventDefault();
|
|
63
134
|
}
|
|
64
135
|
|
|
65
|
-
//
|
|
66
|
-
if (
|
|
67
|
-
|
|
68
|
-
let newVnode = v(context.vnode.tag, context.vnode.props, ...context.vnode.initialChildren) as VnodeWithDom;
|
|
69
|
-
newVnode.dom = context.vnode.dom;
|
|
70
|
-
newVnode.isSVG = context.vnode.isSVG;
|
|
71
|
-
|
|
72
|
-
// Clear the subscribers array by setting the length property to 0
|
|
73
|
-
context.vnode.subscribers.forEach(
|
|
74
|
-
(subscribers) =>
|
|
75
|
-
// Setting the length property to 0 is faster than clearing the array with a loop
|
|
76
|
-
(subscribers.length = 0)
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
// Clear the subscribers array by setting it to an empty array
|
|
80
|
-
context.vnode.subscribers = [];
|
|
81
|
-
|
|
82
|
-
// Return the result of updating the original vnode with the new vnode
|
|
83
|
-
return updateVnode(newVnode, context.vnode);
|
|
136
|
+
// Just return if the new value is the same as the current value
|
|
137
|
+
if (newValue === value) {
|
|
138
|
+
return;
|
|
84
139
|
}
|
|
85
140
|
|
|
86
|
-
//
|
|
87
|
-
|
|
141
|
+
// Update the value of the Signal
|
|
142
|
+
value = newValue;
|
|
143
|
+
|
|
144
|
+
// Call each subscribed function with the new value of the Signal as an argument
|
|
145
|
+
for (let i = 0, l = subscriptions.length; i < l; i++) {
|
|
146
|
+
subscriptions[i](value);
|
|
147
|
+
}
|
|
88
148
|
};
|
|
89
149
|
|
|
90
150
|
// Assign the signal variable an array containing the get, set, and subscribe functions
|
|
91
|
-
let signal = [get, set, subscribe];
|
|
151
|
+
let signal: SignalInterface = [get, set, subscribe, subscriptions];
|
|
92
152
|
|
|
93
153
|
// If the context object has a vnode property, add the signal to the vnode's signals array
|
|
94
|
-
// and add the
|
|
95
|
-
if (
|
|
96
|
-
|
|
97
|
-
context.vnode.subscribers.push(subscribers);
|
|
154
|
+
// and add the subscriptions array to the vnode's subscriptions array
|
|
155
|
+
if (vnode) {
|
|
156
|
+
component.signals.push(signal);
|
|
98
157
|
}
|
|
99
158
|
|
|
100
159
|
// Return the signal
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "valyrian.js",
|
|
3
|
-
"version": "7.2.
|
|
3
|
+
"version": "7.2.3",
|
|
4
4
|
"description": "Lightweight steel to forge PWAs. (Minimal Frontend Framework with server side rendering and other capabilities)",
|
|
5
5
|
"repository": "git@github.com:Masquerade-Circus/valyrian.js.git",
|
|
6
6
|
"author": "Masquerade <christian@masquerade-circus.net>",
|