valyrian.js 7.2.11 → 8.0.0
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 +6 -6
- package/dist/flux-store/index.d.ts +32 -0
- package/dist/flux-store/index.d.ts.map +1 -0
- package/dist/flux-store/index.js +258 -0
- package/dist/flux-store/index.js.map +7 -0
- package/dist/flux-store/index.min.js +1 -0
- package/dist/flux-store/index.min.js.map +1 -0
- package/dist/flux-store/index.mjs +237 -0
- package/dist/flux-store/index.mjs.map +7 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +42 -75
- package/dist/hooks/index.js.map +2 -2
- package/dist/hooks/index.min.js +1 -0
- package/dist/hooks/index.min.js.map +1 -0
- package/dist/hooks/index.mjs +43 -76
- package/dist/hooks/index.mjs.map +2 -2
- package/dist/index.d.ts +52 -54
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +397 -328
- package/dist/index.js.map +3 -3
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/index.mjs +397 -328
- package/dist/index.mjs.map +3 -3
- package/dist/native-store/index.d.ts +14 -0
- package/dist/native-store/index.d.ts.map +1 -0
- package/dist/native-store/index.js +103 -0
- package/dist/native-store/index.js.map +7 -0
- package/dist/native-store/index.min.js +1 -0
- package/dist/native-store/index.min.js.map +1 -0
- package/dist/native-store/index.mjs +82 -0
- package/dist/native-store/index.mjs.map +7 -0
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +223 -86
- package/dist/node/index.js.map +4 -4
- package/dist/node/index.mjs +223 -86
- package/dist/node/index.mjs.map +4 -4
- package/dist/node/node.sw.js +152 -0
- package/dist/node/utils/inline.d.ts.map +1 -1
- package/dist/node/utils/node.sw.js +152 -0
- package/dist/node/utils/session-storage.d.ts +22 -0
- package/dist/node/utils/session-storage.d.ts.map +1 -0
- package/dist/node/utils/sw.d.ts.map +1 -1
- package/dist/node/utils/tree-adapter.d.ts +9 -0
- package/dist/node/utils/tree-adapter.d.ts.map +1 -1
- package/dist/pulse-store/index.d.ts +13 -0
- package/dist/pulse-store/index.d.ts.map +1 -0
- package/dist/pulse-store/index.js +143 -0
- package/dist/pulse-store/index.js.map +7 -0
- package/dist/pulse-store/index.min.js +1 -0
- package/dist/pulse-store/index.min.js.map +1 -0
- package/dist/pulse-store/index.mjs +122 -0
- package/dist/pulse-store/index.mjs.map +7 -0
- package/dist/request/index.d.ts.map +1 -1
- package/dist/request/index.js +68 -89
- package/dist/request/index.js.map +2 -2
- package/dist/request/index.min.js +1 -0
- package/dist/request/index.min.js.map +1 -0
- package/dist/request/index.mjs +68 -89
- package/dist/request/index.mjs.map +2 -2
- package/dist/router/index.d.ts +32 -31
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +256 -104
- package/dist/router/index.js.map +3 -3
- package/dist/router/index.min.js +1 -0
- package/dist/router/index.min.js.map +1 -0
- package/dist/router/index.mjs +256 -104
- package/dist/router/index.mjs.map +3 -3
- package/dist/signals/index.d.ts +6 -0
- package/dist/signals/index.d.ts.map +1 -0
- package/dist/signals/index.js +92 -0
- package/dist/signals/index.js.map +7 -0
- package/dist/signals/index.min.js +1 -0
- package/dist/signals/index.min.js.map +1 -0
- package/dist/signals/index.mjs +71 -0
- package/dist/signals/index.mjs.map +7 -0
- package/dist/suspense/index.d.ts +6 -0
- package/dist/suspense/index.d.ts.map +1 -0
- package/dist/suspense/index.js +67 -0
- package/dist/suspense/index.js.map +7 -0
- package/dist/suspense/index.min.js +1 -0
- package/dist/suspense/index.min.js.map +1 -0
- package/dist/suspense/index.mjs +46 -0
- package/dist/suspense/index.mjs.map +7 -0
- package/dist/sw/index.min.js +1 -0
- package/dist/sw/index.min.js.map +1 -0
- package/dist/translate/index.d.ts +19 -0
- package/dist/translate/index.d.ts.map +1 -0
- package/dist/translate/index.js +150 -0
- package/dist/translate/index.js.map +7 -0
- package/dist/translate/index.min.js +1 -0
- package/dist/translate/index.min.js.map +1 -0
- package/dist/translate/index.mjs +129 -0
- package/dist/translate/index.mjs.map +7 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/deep-freeze.d.ts +3 -0
- package/dist/utils/deep-freeze.d.ts.map +1 -0
- package/dist/utils/getter-setter.d.ts +3 -0
- package/dist/utils/getter-setter.d.ts.map +1 -0
- package/dist/utils/has-changed.d.ts +2 -0
- package/dist/utils/has-changed.d.ts.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +138 -0
- package/dist/utils/index.js.map +7 -0
- package/dist/utils/index.min.js +1 -0
- package/dist/utils/index.min.js.map +1 -0
- package/dist/utils/index.mjs +115 -0
- package/dist/utils/index.mjs.map +7 -0
- package/lib/flux-store/index.ts +301 -0
- package/lib/hooks/index.ts +52 -101
- package/lib/index.ts +479 -719
- package/lib/native-store/index.ts +106 -0
- package/lib/node/index.ts +5 -3
- package/lib/node/utils/icons.ts +5 -5
- package/lib/node/utils/inline.ts +17 -17
- package/lib/node/utils/node.sw.js +152 -0
- package/lib/node/utils/session-storage.ts +117 -0
- package/lib/node/utils/sw.ts +35 -11
- package/lib/node/utils/tree-adapter.ts +99 -52
- package/lib/pulse-store/index.ts +181 -0
- package/lib/request/index.ts +86 -116
- package/lib/router/index.ts +358 -170
- package/lib/signals/index.ts +98 -0
- package/lib/suspense/index.ts +57 -0
- package/lib/translate/index.ts +156 -0
- package/lib/utils/deep-freeze.ts +54 -0
- package/lib/utils/getter-setter.ts +40 -0
- package/lib/utils/has-changed.ts +43 -0
- package/lib/utils/index.ts +3 -0
- package/package.json +38 -50
- package/tsconfig.json +1 -1
- package/dist/dataset/index.d.ts +0 -24
- package/dist/dataset/index.d.ts.map +0 -1
- package/dist/dataset/index.js +0 -178
- package/dist/dataset/index.js.map +0 -7
- package/dist/dataset/index.mjs +0 -157
- package/dist/dataset/index.mjs.map +0 -7
- package/dist/node/node.sw.tpl +0 -133
- package/dist/node/utils/node.sw.tpl +0 -133
- package/dist/proxy-signal/index.d.ts +0 -23
- package/dist/proxy-signal/index.d.ts.map +0 -1
- package/dist/proxy-signal/index.js +0 -138
- package/dist/proxy-signal/index.js.map +0 -7
- package/dist/proxy-signal/index.mjs +0 -117
- package/dist/proxy-signal/index.mjs.map +0 -7
- package/dist/signal/index.d.ts +0 -20
- package/dist/signal/index.d.ts.map +0 -1
- package/dist/signal/index.js +0 -95
- package/dist/signal/index.js.map +0 -7
- package/dist/signal/index.mjs +0 -74
- package/dist/signal/index.mjs.map +0 -7
- package/dist/store/index.d.ts +0 -16
- package/dist/store/index.d.ts.map +0 -1
- package/dist/store/index.js +0 -93
- package/dist/store/index.js.map +0 -7
- package/dist/store/index.mjs +0 -72
- package/dist/store/index.mjs.map +0 -7
- package/lib/dataset/index.ts +0 -193
- package/lib/index.d.ts +0 -0
- package/lib/interfaces.ts.bak +0 -141
- package/lib/node/utils/node.sw.tpl +0 -133
- package/lib/proxy-signal/index.ts +0 -187
- package/lib/signal/index.ts +0 -161
- package/lib/store/index.ts +0 -101
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import { debouncedUpdate } from "valyrian.js";
|
|
2
|
+
import { deepCloneUnfreeze, deepFreeze } from "valyrian.js/utils";
|
|
3
|
+
|
|
4
|
+
interface StoreOptions {
|
|
5
|
+
state?: Record<string, any> | (() => Record<string, any>);
|
|
6
|
+
// eslint-disable-next-line no-unused-vars
|
|
7
|
+
mutations?: Record<string, (state: Record<string, any>, ...args: any[]) => void>;
|
|
8
|
+
// eslint-disable-next-line no-unused-vars, no-use-before-define
|
|
9
|
+
actions?: Record<string, (store: FluxStore, ...args: any[]) => any>;
|
|
10
|
+
getters?: Record<
|
|
11
|
+
string,
|
|
12
|
+
// eslint-disable-next-line no-unused-vars
|
|
13
|
+
(state: Record<string, any>, getters: Record<string, any>, globalState?: any, globalGetters?: any) => any
|
|
14
|
+
>;
|
|
15
|
+
modules?: Record<string, StoreOptions>;
|
|
16
|
+
shouldFreeze?: boolean;
|
|
17
|
+
namespace?: string;
|
|
18
|
+
// eslint-disable-next-line no-use-before-define
|
|
19
|
+
rootStore?: FluxStore;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// This is the store entity
|
|
23
|
+
export class FluxStore {
|
|
24
|
+
public state: Record<string, any>;
|
|
25
|
+
public getters: Record<string, any>;
|
|
26
|
+
private init: {
|
|
27
|
+
frozen: boolean;
|
|
28
|
+
plugins: Function[];
|
|
29
|
+
// eslint-disable-next-line no-use-before-define
|
|
30
|
+
modules: Record<string, FluxStore>;
|
|
31
|
+
childModuleNamespaces: string[];
|
|
32
|
+
listeners: Record<string, Function[]>;
|
|
33
|
+
getters: StoreOptions["getters"];
|
|
34
|
+
mutations: StoreOptions["mutations"];
|
|
35
|
+
actions: StoreOptions["actions"];
|
|
36
|
+
};
|
|
37
|
+
// eslint-disable-next-line no-use-before-define
|
|
38
|
+
public rootStore: FluxStore | null;
|
|
39
|
+
public namespace: string | null;
|
|
40
|
+
|
|
41
|
+
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
42
|
+
constructor({
|
|
43
|
+
state = {},
|
|
44
|
+
mutations = {},
|
|
45
|
+
actions = {},
|
|
46
|
+
getters = {},
|
|
47
|
+
modules = {},
|
|
48
|
+
shouldFreeze = true,
|
|
49
|
+
namespace,
|
|
50
|
+
rootStore
|
|
51
|
+
}: StoreOptions = {}) {
|
|
52
|
+
// Initialize the localState for this store
|
|
53
|
+
const localState = typeof state === "function" ? state() : state;
|
|
54
|
+
|
|
55
|
+
// We create a proxy for the state
|
|
56
|
+
this.state = new Proxy(localState || {}, {
|
|
57
|
+
// Every time we try to access a property from the state we try to deep freeze the property
|
|
58
|
+
// to prevent direct modifications to the state
|
|
59
|
+
get: (state, prop: string) => {
|
|
60
|
+
if ((this.rootStore || this).init.modules[prop]) {
|
|
61
|
+
return state[prop];
|
|
62
|
+
}
|
|
63
|
+
if (shouldFreeze) {
|
|
64
|
+
// We are accessing a property from outside the store
|
|
65
|
+
if (this.init.frozen) {
|
|
66
|
+
return deepFreeze(state[prop]);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// We are accessing a property from inside the store
|
|
70
|
+
// So we need to unfreeze the state
|
|
71
|
+
const newState = deepCloneUnfreeze(state);
|
|
72
|
+
for (const key of Reflect.ownKeys(newState)) {
|
|
73
|
+
localState[key] = newState[key];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return state[prop];
|
|
77
|
+
},
|
|
78
|
+
// If the user tries to set directly it will throw an error, only if we have unfrozen the state via commit
|
|
79
|
+
// this will proceed to set the value
|
|
80
|
+
set: (state, prop: string, value: any) => {
|
|
81
|
+
this.isUnfrozen();
|
|
82
|
+
const old = state[prop];
|
|
83
|
+
state[prop] = value;
|
|
84
|
+
if (this.namespace) {
|
|
85
|
+
prop = `${this.namespace}.${prop}`;
|
|
86
|
+
}
|
|
87
|
+
(this.rootStore || this).trigger("set", prop, value, old);
|
|
88
|
+
return true;
|
|
89
|
+
},
|
|
90
|
+
// If the user tries to delete directly it will throw an error, only if we have unfrozen the state via commit
|
|
91
|
+
// this will proceed to delete the property
|
|
92
|
+
deleteProperty: (state, prop: string) => {
|
|
93
|
+
this.isUnfrozen();
|
|
94
|
+
const old = state[prop];
|
|
95
|
+
Reflect.deleteProperty(state, prop);
|
|
96
|
+
if (this.namespace) {
|
|
97
|
+
prop = `${this.namespace}.${prop}`;
|
|
98
|
+
}
|
|
99
|
+
(this.rootStore || this).trigger("delete", prop, old);
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// If this is a store been attached to another store
|
|
105
|
+
// this will have the rootStore for future reference
|
|
106
|
+
this.rootStore = rootStore || null;
|
|
107
|
+
|
|
108
|
+
// If this is a store been attached to another store
|
|
109
|
+
// this will have the namespace attached
|
|
110
|
+
this.namespace = namespace || null;
|
|
111
|
+
|
|
112
|
+
// We initialize the store with the initial values
|
|
113
|
+
this.init = {
|
|
114
|
+
frozen: true,
|
|
115
|
+
plugins: [],
|
|
116
|
+
modules: {},
|
|
117
|
+
childModuleNamespaces: Object.keys(modules || {}),
|
|
118
|
+
listeners: {
|
|
119
|
+
set: [],
|
|
120
|
+
delete: [],
|
|
121
|
+
beforecommit: [],
|
|
122
|
+
commit: [],
|
|
123
|
+
beforedispatch: [],
|
|
124
|
+
dispatch: [],
|
|
125
|
+
getter: [],
|
|
126
|
+
addlistener: [],
|
|
127
|
+
removelistener: [],
|
|
128
|
+
plugin: [],
|
|
129
|
+
registerModule: [],
|
|
130
|
+
unregisterModule: []
|
|
131
|
+
},
|
|
132
|
+
getters: getters || {},
|
|
133
|
+
mutations: mutations || {},
|
|
134
|
+
actions: actions || {}
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
// We create a proxy for the getters
|
|
138
|
+
this.getters = new Proxy(getters || {}, {
|
|
139
|
+
// When we try to get a property of the getter we will call the original
|
|
140
|
+
// getter method passing the state as first argument and the other getters as second
|
|
141
|
+
// if we try to get a non existent getter it will fail silently as if
|
|
142
|
+
// we were trying to get an undefined property
|
|
143
|
+
get: (getters, getter: string) => {
|
|
144
|
+
try {
|
|
145
|
+
const { store, key } = this.getStore(this, getter);
|
|
146
|
+
if (store instanceof FluxStore && store.init.getters![key]) {
|
|
147
|
+
const value = store.init.getters;
|
|
148
|
+
if (this.namespace) {
|
|
149
|
+
getter = `${this.namespace}.${getter}`;
|
|
150
|
+
}
|
|
151
|
+
(this.rootStore || this).trigger("getter", getter, value);
|
|
152
|
+
return value;
|
|
153
|
+
}
|
|
154
|
+
} catch (error) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// Finally we attach the initial modules
|
|
161
|
+
if (modules) {
|
|
162
|
+
Object.keys(modules).forEach((namespace) => {
|
|
163
|
+
const n = this.namespace ? `${this.namespace}.${namespace}` : namespace;
|
|
164
|
+
(this.rootStore || this).registerModule(n, modules[namespace]);
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
private keyExists(objectname: string, object: Record<string, any>, key: string) {
|
|
170
|
+
if (!object[key]) {
|
|
171
|
+
throw new Error(`The ${objectname} "${key}" does not exists.`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
private isFunction(type: string, callback: Function) {
|
|
176
|
+
if (typeof callback !== "function") {
|
|
177
|
+
throw new Error(`You need to provide a valid function as ${type}.`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Giving a dot based namespace this method will be used to find the module to be called
|
|
182
|
+
private getStore(store: FluxStore, namespace: string) {
|
|
183
|
+
let key = namespace;
|
|
184
|
+
if (key.indexOf(".") > -1) {
|
|
185
|
+
const parts = key.split(".");
|
|
186
|
+
key = parts.pop()!;
|
|
187
|
+
const moduleName = parts.join(".");
|
|
188
|
+
this.keyExists("module", store.init.modules, moduleName);
|
|
189
|
+
store = store.init.modules[moduleName];
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
store,
|
|
193
|
+
key
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
private isUnfrozen() {
|
|
198
|
+
if (this.init.frozen) {
|
|
199
|
+
throw new Error("You need to commit a mutation to change the state");
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// This method unfroze the state and process a mutation
|
|
204
|
+
public commit(mutation: string, ...args: any[]) {
|
|
205
|
+
const { store, key } = this.getStore(this, mutation);
|
|
206
|
+
this.keyExists("mutation", store.init.mutations!, key);
|
|
207
|
+
store.init.frozen = false;
|
|
208
|
+
this.trigger("beforecommit", mutation, ...args);
|
|
209
|
+
store.init.mutations;
|
|
210
|
+
this.trigger("commit", mutation, ...args);
|
|
211
|
+
store.init.frozen = true;
|
|
212
|
+
|
|
213
|
+
// We call the debounced update to notify the changes
|
|
214
|
+
debouncedUpdate();
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// This method will dispatch an action
|
|
218
|
+
public async dispatch(action: string, ...args: any[]): Promise<any> {
|
|
219
|
+
const { store, key } = this.getStore(this, action);
|
|
220
|
+
this.keyExists("action", store.init.actions!, key);
|
|
221
|
+
this.trigger("beforedispatch", action, ...args);
|
|
222
|
+
try {
|
|
223
|
+
const result = await store.init.actions;
|
|
224
|
+
this.trigger("dispatch", action, ...args);
|
|
225
|
+
return result;
|
|
226
|
+
} finally {
|
|
227
|
+
debouncedUpdate();
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// This method will trigger an event
|
|
232
|
+
public trigger(event: string, ...args: any[]) {
|
|
233
|
+
this.init.listeners[event].forEach((callback) => callback(this, ...args));
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// This method will add a listener to the store
|
|
237
|
+
public on(event: string, listener: Function) {
|
|
238
|
+
this.isFunction("listener", listener);
|
|
239
|
+
this.keyExists("event", this.init.listeners, event);
|
|
240
|
+
if (this.init.listeners[event].indexOf(listener) === -1) {
|
|
241
|
+
this.init.listeners[event].push(listener);
|
|
242
|
+
this.trigger("addlistener", event, listener);
|
|
243
|
+
}
|
|
244
|
+
return () => this.off(event, listener);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Remove a listener from the store
|
|
248
|
+
public off(event: string, listener: Function) {
|
|
249
|
+
this.isFunction("listener", listener);
|
|
250
|
+
this.keyExists("event", this.init.listeners, event);
|
|
251
|
+
const index = this.init.listeners[event].indexOf(listener);
|
|
252
|
+
if (index > -1) {
|
|
253
|
+
this.init.listeners[event].splice(index, 1);
|
|
254
|
+
this.trigger("removelistener", event, listener);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// This method will add a plugin to the store
|
|
259
|
+
public use(plugin: Function, ...options: any[]) {
|
|
260
|
+
this.isFunction("plugin", plugin);
|
|
261
|
+
if (this.init.plugins.indexOf(plugin) === -1) {
|
|
262
|
+
plugin(this, ...options);
|
|
263
|
+
this.init.plugins.push(plugin);
|
|
264
|
+
this.trigger("plugin", plugin, ...options);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// This method will register a module to the store
|
|
269
|
+
public registerModule(namespace: string, module: StoreOptions) {
|
|
270
|
+
const rootStore = this;
|
|
271
|
+
if (rootStore.init.modules[namespace]) {
|
|
272
|
+
throw new Error(`A module with the namespace "${namespace}" is already registered.`);
|
|
273
|
+
}
|
|
274
|
+
const newStore = new FluxStore({ ...module, rootStore, namespace });
|
|
275
|
+
rootStore.init.frozen = false;
|
|
276
|
+
rootStore.init.modules[namespace] = newStore;
|
|
277
|
+
rootStore.state[namespace] = newStore.state;
|
|
278
|
+
rootStore.init.frozen = true;
|
|
279
|
+
rootStore.trigger("registerModule", namespace, module, newStore);
|
|
280
|
+
|
|
281
|
+
// We call the debounced update to notify the changes
|
|
282
|
+
debouncedUpdate();
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// This method will unregister a module from the store
|
|
286
|
+
public unregisterModule(namespace: string) {
|
|
287
|
+
const rootStore = this;
|
|
288
|
+
const store = rootStore.init.modules[namespace];
|
|
289
|
+
if (store) {
|
|
290
|
+
store.init.childModuleNamespaces.forEach((n) => rootStore.unregisterModule(`${namespace}.${n}`));
|
|
291
|
+
rootStore.init.frozen = false;
|
|
292
|
+
Reflect.deleteProperty(rootStore.init.modules, namespace);
|
|
293
|
+
Reflect.deleteProperty(rootStore.state, namespace);
|
|
294
|
+
rootStore.init.frozen = true;
|
|
295
|
+
rootStore.trigger("unregisterModule", namespace, store);
|
|
296
|
+
|
|
297
|
+
// We call the debounced update to notify the changes
|
|
298
|
+
debouncedUpdate();
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
package/lib/hooks/index.ts
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
import { Component, POJOComponent,
|
|
2
|
-
|
|
3
|
-
interface CurrentOnPatch {
|
|
4
|
-
component: Component | POJOComponent;
|
|
5
|
-
vnode: VnodeWithDom;
|
|
6
|
-
oldVnode: VnodeWithDom;
|
|
7
|
-
}
|
|
1
|
+
import { Component, POJOComponent, current, directive, onCleanup, onUnmount, debouncedUpdate } from "valyrian.js";
|
|
2
|
+
import { hasChanged } from "valyrian.js/utils";
|
|
8
3
|
|
|
9
4
|
export type Hook = any;
|
|
10
5
|
|
|
@@ -26,6 +21,13 @@ export interface CreateHook {
|
|
|
26
21
|
(HookDefinition: HookDefinition): (...args: any[]) => any;
|
|
27
22
|
}
|
|
28
23
|
|
|
24
|
+
type HookCalls = {
|
|
25
|
+
hooks: Hook[];
|
|
26
|
+
hook_calls: number;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const componentToHooksWeakMap = new WeakMap<Component | POJOComponent, HookCalls>();
|
|
30
|
+
|
|
29
31
|
export const createHook = function createHook({
|
|
30
32
|
onCreate,
|
|
31
33
|
onUpdate: onUpdateHook,
|
|
@@ -34,91 +36,49 @@ export const createHook = function createHook({
|
|
|
34
36
|
returnValue
|
|
35
37
|
}: HookDefinition): Hook {
|
|
36
38
|
return (...args: any[]) => {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
let hook: any = null;
|
|
40
|
-
|
|
41
|
-
if (vnode) {
|
|
42
|
-
// Init the components array for the current vnode
|
|
43
|
-
if (!vnode.components) {
|
|
44
|
-
vnode.components = [];
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (vnode.components.indexOf(component) === -1) {
|
|
48
|
-
vnode.hook_calls = -1;
|
|
49
|
-
vnode.components.push(component);
|
|
50
|
-
if (!component.hooks) {
|
|
51
|
-
component.hooks = [];
|
|
52
|
-
onUnmount(() => Reflect.deleteProperty(component, "hooks"));
|
|
53
|
-
}
|
|
54
|
-
}
|
|
39
|
+
const component = current.component as Component | POJOComponent;
|
|
40
|
+
let HookCalls = componentToHooksWeakMap.get(component);
|
|
55
41
|
|
|
56
|
-
|
|
42
|
+
if (!HookCalls) {
|
|
43
|
+
HookCalls = { hooks: [], hook_calls: -1 };
|
|
44
|
+
componentToHooksWeakMap.set(component, HookCalls);
|
|
45
|
+
onUnmount(() => componentToHooksWeakMap.delete(component));
|
|
57
46
|
}
|
|
58
47
|
|
|
59
|
-
|
|
60
|
-
if (!hook) {
|
|
61
|
-
// create a new hook
|
|
62
|
-
hook = onCreate(...args);
|
|
63
|
-
|
|
64
|
-
if (vnode) {
|
|
65
|
-
// Add the hook to the component
|
|
66
|
-
component.hooks.push(hook);
|
|
67
|
-
}
|
|
48
|
+
onCleanup(() => ((HookCalls as HookCalls).hook_calls = -1));
|
|
68
49
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
onUnmount(() => onRemove(hook));
|
|
73
|
-
}
|
|
50
|
+
let hook = HookCalls.hooks[++HookCalls.hook_calls];
|
|
51
|
+
if (hook) {
|
|
52
|
+
onUpdateHook?.(hook, ...args);
|
|
74
53
|
} else {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// If we have an onCleanup function, add it to the cleanup set
|
|
81
|
-
if (onCleanupHook) {
|
|
82
|
-
// Add the hook to the onCleanup set
|
|
83
|
-
onCleanup(() => onCleanupHook(hook));
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// If we have a returnValue function, call it and return the result instead of the hook
|
|
87
|
-
if (returnValue) {
|
|
88
|
-
return returnValue(hook);
|
|
54
|
+
hook = onCreate(...args);
|
|
55
|
+
HookCalls.hooks.push(hook);
|
|
56
|
+
onRemove && onUnmount(() => onRemove(hook));
|
|
89
57
|
}
|
|
90
58
|
|
|
91
|
-
|
|
92
|
-
return hook;
|
|
59
|
+
onCleanupHook && onCleanup(() => onCleanupHook(hook));
|
|
60
|
+
return returnValue ? returnValue(hook) : hook;
|
|
93
61
|
};
|
|
94
62
|
} as unknown as CreateHook;
|
|
95
63
|
|
|
96
|
-
let updateTimeout: any;
|
|
97
|
-
function delayedUpdate() {
|
|
98
|
-
clearTimeout(updateTimeout);
|
|
99
|
-
updateTimeout = setTimeout(update);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
64
|
// Use state hook
|
|
103
65
|
export const useState = createHook({
|
|
104
66
|
onCreate: (value) => {
|
|
67
|
+
let state = value;
|
|
105
68
|
function get() {
|
|
106
|
-
return
|
|
69
|
+
return state;
|
|
107
70
|
}
|
|
108
|
-
get.value = value;
|
|
109
|
-
get.toJSON = get.valueOf = get;
|
|
110
|
-
get.toString = () => `${value}`;
|
|
111
71
|
|
|
112
72
|
function set(newValue: any) {
|
|
113
|
-
|
|
114
|
-
if (current.event) {
|
|
73
|
+
if (current.event && !current.event.defaultPrevented) {
|
|
115
74
|
current.event.preventDefault();
|
|
116
75
|
}
|
|
117
76
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
77
|
+
const resolvedValue = typeof newValue === "function" ? newValue(state) : newValue;
|
|
78
|
+
|
|
79
|
+
if (hasChanged(state, resolvedValue)) {
|
|
80
|
+
state = resolvedValue;
|
|
81
|
+
debouncedUpdate();
|
|
122
82
|
}
|
|
123
83
|
}
|
|
124
84
|
|
|
@@ -126,10 +86,9 @@ export const useState = createHook({
|
|
|
126
86
|
}
|
|
127
87
|
});
|
|
128
88
|
|
|
129
|
-
// Effect hook
|
|
130
89
|
export const useEffect = createHook({
|
|
131
90
|
onCreate: (effect: Function, changes: any[]) => {
|
|
132
|
-
|
|
91
|
+
const hook: {
|
|
133
92
|
effect: Function;
|
|
134
93
|
prev: any[];
|
|
135
94
|
onRemove?: Function;
|
|
@@ -157,18 +116,18 @@ export const useEffect = createHook({
|
|
|
157
116
|
return;
|
|
158
117
|
}
|
|
159
118
|
|
|
119
|
+
if (Array.isArray(changes) && changes.length === 0) {
|
|
120
|
+
// Si las dependencias son un array vacío, no se debe volver a ejecutar.
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
160
124
|
// on update if there are changes
|
|
161
|
-
if (Array.isArray(changes)) {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (typeof hook.onCleanup === "function") {
|
|
166
|
-
hook.onCleanup();
|
|
167
|
-
}
|
|
168
|
-
hook.onCleanup = hook.effect();
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
125
|
+
if (Array.isArray(changes) && hasChanged(hook.prev, changes)) {
|
|
126
|
+
hook.prev = changes;
|
|
127
|
+
if (typeof hook.onCleanup === "function") {
|
|
128
|
+
hook.onCleanup();
|
|
171
129
|
}
|
|
130
|
+
hook.onCleanup = hook.effect();
|
|
172
131
|
}
|
|
173
132
|
},
|
|
174
133
|
onRemove: (hook) => {
|
|
@@ -192,18 +151,15 @@ export const useRef = createHook({
|
|
|
192
151
|
|
|
193
152
|
export const useCallback = createHook({
|
|
194
153
|
onCreate: (callback, changes) => {
|
|
195
|
-
callback();
|
|
196
154
|
return { callback, changes };
|
|
197
155
|
},
|
|
198
156
|
onUpdate: (hook, callback, changes) => {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
hook.callback();
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
157
|
+
if (hasChanged(hook.changes, changes)) {
|
|
158
|
+
hook.changes = changes;
|
|
159
|
+
hook.callback = callback;
|
|
205
160
|
}
|
|
206
|
-
}
|
|
161
|
+
},
|
|
162
|
+
returnValue: (hook) => hook.callback
|
|
207
163
|
});
|
|
208
164
|
|
|
209
165
|
export const useMemo = createHook({
|
|
@@ -211,15 +167,10 @@ export const useMemo = createHook({
|
|
|
211
167
|
return { callback, changes, value: callback() };
|
|
212
168
|
},
|
|
213
169
|
onUpdate: (hook, callback, changes) => {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
hook.value = callback();
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
170
|
+
if (hasChanged(hook.changes, changes)) {
|
|
171
|
+
hook.changes = changes;
|
|
172
|
+
hook.value = callback();
|
|
220
173
|
}
|
|
221
174
|
},
|
|
222
|
-
returnValue: (hook) =>
|
|
223
|
-
return hook.value;
|
|
224
|
-
}
|
|
175
|
+
returnValue: (hook) => hook.value
|
|
225
176
|
});
|