valyrian.js 7.2.12 → 8.0.1

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.
Files changed (168) hide show
  1. package/README.md +6 -6
  2. package/dist/flux-store/index.d.ts +32 -0
  3. package/dist/flux-store/index.d.ts.map +1 -0
  4. package/dist/flux-store/index.js +267 -0
  5. package/dist/flux-store/index.js.map +7 -0
  6. package/dist/flux-store/index.min.js +1 -0
  7. package/dist/flux-store/index.min.js.map +1 -0
  8. package/dist/flux-store/index.mjs +246 -0
  9. package/dist/flux-store/index.mjs.map +7 -0
  10. package/dist/hooks/index.d.ts.map +1 -1
  11. package/dist/hooks/index.js +35 -51
  12. package/dist/hooks/index.js.map +3 -3
  13. package/dist/hooks/index.min.js +1 -0
  14. package/dist/hooks/index.min.js.map +1 -0
  15. package/dist/hooks/index.mjs +36 -52
  16. package/dist/hooks/index.mjs.map +3 -3
  17. package/dist/index.d.ts +18 -14
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +107 -88
  20. package/dist/index.js.map +3 -3
  21. package/dist/index.min.js +1 -1
  22. package/dist/index.min.js.map +1 -1
  23. package/dist/index.mjs +107 -88
  24. package/dist/index.mjs.map +3 -3
  25. package/dist/native-store/index.d.ts +14 -0
  26. package/dist/native-store/index.d.ts.map +1 -0
  27. package/dist/native-store/index.js +103 -0
  28. package/dist/native-store/index.js.map +7 -0
  29. package/dist/native-store/index.min.js +1 -0
  30. package/dist/native-store/index.min.js.map +1 -0
  31. package/dist/native-store/index.mjs +82 -0
  32. package/dist/native-store/index.mjs.map +7 -0
  33. package/dist/node/index.d.ts +1 -1
  34. package/dist/node/index.d.ts.map +1 -1
  35. package/dist/node/index.js +125 -10
  36. package/dist/node/index.js.map +4 -4
  37. package/dist/node/index.mjs +125 -10
  38. package/dist/node/index.mjs.map +4 -4
  39. package/dist/node/node.sw.js +152 -0
  40. package/dist/node/utils/icons.d.ts +4 -5
  41. package/dist/node/utils/icons.d.ts.map +1 -1
  42. package/dist/node/utils/inline.d.ts +1 -1
  43. package/dist/node/utils/inline.d.ts.map +1 -1
  44. package/dist/node/utils/node.sw.js +152 -0
  45. package/dist/node/utils/session-storage.d.ts +22 -0
  46. package/dist/node/utils/session-storage.d.ts.map +1 -0
  47. package/dist/node/utils/sw.d.ts.map +1 -1
  48. package/dist/node/utils/tree-adapter.d.ts +5 -1
  49. package/dist/node/utils/tree-adapter.d.ts.map +1 -1
  50. package/dist/pulse-store/index.d.ts +16 -0
  51. package/dist/pulse-store/index.d.ts.map +1 -0
  52. package/dist/pulse-store/index.js +143 -0
  53. package/dist/pulse-store/index.js.map +7 -0
  54. package/dist/pulse-store/index.min.js +1 -0
  55. package/dist/pulse-store/index.min.js.map +1 -0
  56. package/dist/pulse-store/index.mjs +122 -0
  57. package/dist/pulse-store/index.mjs.map +7 -0
  58. package/dist/request/index.d.ts +11 -11
  59. package/dist/request/index.d.ts.map +1 -1
  60. package/dist/request/index.js +63 -84
  61. package/dist/request/index.js.map +2 -2
  62. package/dist/request/index.min.js +1 -0
  63. package/dist/request/index.min.js.map +1 -0
  64. package/dist/request/index.mjs +63 -84
  65. package/dist/request/index.mjs.map +2 -2
  66. package/dist/router/index.d.ts +36 -33
  67. package/dist/router/index.d.ts.map +1 -1
  68. package/dist/router/index.js +247 -96
  69. package/dist/router/index.js.map +3 -3
  70. package/dist/router/index.min.js +1 -0
  71. package/dist/router/index.min.js.map +1 -0
  72. package/dist/router/index.mjs +247 -96
  73. package/dist/router/index.mjs.map +3 -3
  74. package/dist/signals/index.d.ts +6 -0
  75. package/dist/signals/index.d.ts.map +1 -0
  76. package/dist/signals/index.js +92 -0
  77. package/dist/signals/index.js.map +7 -0
  78. package/dist/signals/index.min.js +1 -0
  79. package/dist/signals/index.min.js.map +1 -0
  80. package/dist/signals/index.mjs +71 -0
  81. package/dist/signals/index.mjs.map +7 -0
  82. package/dist/suspense/index.d.ts +6 -0
  83. package/dist/suspense/index.d.ts.map +1 -0
  84. package/dist/suspense/index.js +67 -0
  85. package/dist/suspense/index.js.map +7 -0
  86. package/dist/suspense/index.min.js +1 -0
  87. package/dist/suspense/index.min.js.map +1 -0
  88. package/dist/suspense/index.mjs +46 -0
  89. package/dist/suspense/index.mjs.map +7 -0
  90. package/dist/sw/index.min.js +1 -0
  91. package/dist/sw/index.min.js.map +1 -0
  92. package/dist/translate/index.d.ts +19 -0
  93. package/dist/translate/index.d.ts.map +1 -0
  94. package/dist/translate/index.js +150 -0
  95. package/dist/translate/index.js.map +7 -0
  96. package/dist/translate/index.min.js +1 -0
  97. package/dist/translate/index.min.js.map +1 -0
  98. package/dist/translate/index.mjs +129 -0
  99. package/dist/translate/index.mjs.map +7 -0
  100. package/dist/tsconfig.tsbuildinfo +1 -1
  101. package/dist/utils/deep-freeze.d.ts +3 -0
  102. package/dist/utils/deep-freeze.d.ts.map +1 -0
  103. package/dist/utils/getter-setter.d.ts +3 -0
  104. package/dist/utils/getter-setter.d.ts.map +1 -0
  105. package/dist/utils/has-changed.d.ts +2 -0
  106. package/dist/utils/has-changed.d.ts.map +1 -0
  107. package/dist/utils/index.d.ts +4 -0
  108. package/dist/utils/index.d.ts.map +1 -0
  109. package/dist/utils/index.js +138 -0
  110. package/dist/utils/index.js.map +7 -0
  111. package/dist/utils/index.min.js +1 -0
  112. package/dist/utils/index.min.js.map +1 -0
  113. package/dist/utils/index.mjs +115 -0
  114. package/dist/utils/index.mjs.map +7 -0
  115. package/lib/flux-store/index.ts +312 -0
  116. package/lib/hooks/index.ts +39 -57
  117. package/lib/index.ts +135 -118
  118. package/lib/native-store/index.ts +106 -0
  119. package/lib/node/index.ts +3 -1
  120. package/lib/node/utils/icons.ts +4 -4
  121. package/lib/node/utils/inline.ts +2 -0
  122. package/lib/node/utils/node.sw.js +152 -0
  123. package/lib/node/utils/session-storage.ts +117 -0
  124. package/lib/node/utils/sw.ts +34 -10
  125. package/lib/node/utils/tree-adapter.ts +19 -1
  126. package/lib/pulse-store/index.ts +188 -0
  127. package/lib/request/index.ts +92 -122
  128. package/lib/router/index.ts +353 -164
  129. package/lib/signals/index.ts +98 -0
  130. package/lib/suspense/index.ts +57 -0
  131. package/lib/translate/index.ts +156 -0
  132. package/lib/utils/deep-freeze.ts +54 -0
  133. package/lib/utils/getter-setter.ts +40 -0
  134. package/lib/utils/has-changed.ts +43 -0
  135. package/lib/utils/index.ts +3 -0
  136. package/package.json +40 -57
  137. package/tsconfig.json +5 -4
  138. package/dist/dataset/index.d.ts +0 -24
  139. package/dist/dataset/index.d.ts.map +0 -1
  140. package/dist/dataset/index.js +0 -178
  141. package/dist/dataset/index.js.map +0 -7
  142. package/dist/dataset/index.mjs +0 -157
  143. package/dist/dataset/index.mjs.map +0 -7
  144. package/dist/node/node.sw.tpl +0 -133
  145. package/dist/node/utils/node.sw.tpl +0 -133
  146. package/dist/proxy-signal/index.d.ts +0 -23
  147. package/dist/proxy-signal/index.d.ts.map +0 -1
  148. package/dist/proxy-signal/index.js +0 -138
  149. package/dist/proxy-signal/index.js.map +0 -7
  150. package/dist/proxy-signal/index.mjs +0 -117
  151. package/dist/proxy-signal/index.mjs.map +0 -7
  152. package/dist/signal/index.d.ts +0 -9
  153. package/dist/signal/index.d.ts.map +0 -1
  154. package/dist/signal/index.js +0 -76
  155. package/dist/signal/index.js.map +0 -7
  156. package/dist/signal/index.mjs +0 -55
  157. package/dist/signal/index.mjs.map +0 -7
  158. package/dist/store/index.d.ts +0 -16
  159. package/dist/store/index.d.ts.map +0 -1
  160. package/dist/store/index.js +0 -93
  161. package/dist/store/index.js.map +0 -7
  162. package/dist/store/index.mjs +0 -72
  163. package/dist/store/index.mjs.map +0 -7
  164. package/lib/dataset/index.ts +0 -193
  165. package/lib/node/utils/node.sw.tpl +0 -133
  166. package/lib/proxy-signal/index.ts +0 -187
  167. package/lib/signal/index.ts +0 -86
  168. package/lib/store/index.ts +0 -101
@@ -0,0 +1,312 @@
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![key](store.state, store.getters, this.state, this.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![key](store.state, ...args);
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![key](store, ...args);
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, namespace?: string) {
238
+ this.isFunction("listener", listener);
239
+
240
+ if (namespace) {
241
+ const { store, key } = this.getStore(this, namespace);
242
+ this.keyExists("event", store.init.listeners, event);
243
+ if (store.init.listeners[event].indexOf(listener) === -1) {
244
+ store.init.listeners[event].push(listener);
245
+ this.trigger("addlistener", event, listener);
246
+ }
247
+ return () => this.off(event, listener);
248
+ }
249
+
250
+ this.keyExists("event", this.init.listeners, event);
251
+ if (this.init.listeners[event].indexOf(listener) === -1) {
252
+ this.init.listeners[event].push(listener);
253
+ this.trigger("addlistener", event, listener);
254
+ }
255
+ return () => this.off(event, listener);
256
+ }
257
+
258
+ // Remove a listener from the store
259
+ public off(event: string, listener: Function) {
260
+ this.isFunction("listener", listener);
261
+ this.keyExists("event", this.init.listeners, event);
262
+ const index = this.init.listeners[event].indexOf(listener);
263
+ if (index > -1) {
264
+ this.init.listeners[event].splice(index, 1);
265
+ this.trigger("removelistener", event, listener);
266
+ }
267
+ }
268
+
269
+ // This method will add a plugin to the store
270
+ public use(plugin: Function, ...options: any[]) {
271
+ this.isFunction("plugin", plugin);
272
+ if (this.init.plugins.indexOf(plugin) === -1) {
273
+ plugin(this, ...options);
274
+ this.init.plugins.push(plugin);
275
+ this.trigger("plugin", plugin, ...options);
276
+ }
277
+ }
278
+
279
+ // This method will register a module to the store
280
+ public registerModule(namespace: string, module: StoreOptions) {
281
+ const rootStore = this;
282
+ if (rootStore.init.modules[namespace]) {
283
+ throw new Error(`A module with the namespace "${namespace}" is already registered.`);
284
+ }
285
+ const newStore = new FluxStore({ ...module, rootStore, namespace });
286
+ rootStore.init.frozen = false;
287
+ rootStore.init.modules[namespace] = newStore;
288
+ rootStore.state[namespace] = newStore.state;
289
+ rootStore.init.frozen = true;
290
+ rootStore.trigger("registerModule", namespace, module, newStore);
291
+
292
+ // We call the debounced update to notify the changes
293
+ debouncedUpdate();
294
+ }
295
+
296
+ // This method will unregister a module from the store
297
+ public unregisterModule(namespace: string) {
298
+ const rootStore = this;
299
+ const store = rootStore.init.modules[namespace];
300
+ if (store) {
301
+ store.init.childModuleNamespaces.forEach((n) => rootStore.unregisterModule(`${namespace}.${n}`));
302
+ rootStore.init.frozen = false;
303
+ Reflect.deleteProperty(rootStore.init.modules, namespace);
304
+ Reflect.deleteProperty(rootStore.state, namespace);
305
+ rootStore.init.frozen = true;
306
+ rootStore.trigger("unregisterModule", namespace, store);
307
+
308
+ // We call the debounced update to notify the changes
309
+ debouncedUpdate();
310
+ }
311
+ }
312
+ }
@@ -1,4 +1,5 @@
1
- import { Component, POJOComponent, current, directive, onCleanup, onUnmount, update } from "valyrian.js";
1
+ import { Component, POJOComponent, current, directive, onCleanup, onUnmount, debouncedUpdate } from "valyrian.js";
2
+ import { hasChanged } from "valyrian.js/utils";
2
3
 
3
4
  export type Hook = any;
4
5
 
@@ -36,25 +37,22 @@ export const createHook = function createHook({
36
37
  }: HookDefinition): Hook {
37
38
  return (...args: any[]) => {
38
39
  const component = current.component as Component | POJOComponent;
39
- let hook: any = null;
40
+ let HookCalls = componentToHooksWeakMap.get(component);
40
41
 
41
- if (componentToHooksWeakMap.has(component) === false) {
42
- const HookCalls = { hooks: [], hook_calls: -1 };
42
+ if (!HookCalls) {
43
+ HookCalls = { hooks: [], hook_calls: -1 } as HookCalls;
43
44
  componentToHooksWeakMap.set(component, HookCalls);
44
- onUnmount(() => componentToHooksWeakMap.delete(component));
45
+ onUnmount(() => {
46
+ componentToHooksWeakMap.delete(component);
47
+ });
45
48
  }
46
49
 
47
- const HookCalls = componentToHooksWeakMap.get(component) as HookCalls;
48
- onCleanup(() => (HookCalls.hook_calls = -1));
49
-
50
- hook = HookCalls.hooks[++HookCalls.hook_calls];
50
+ onCleanup(() => ((HookCalls as HookCalls).hook_calls = -1));
51
51
 
52
+ let hook = HookCalls.hooks[++HookCalls.hook_calls];
52
53
  if (hook) {
53
- onUpdateHook && onUpdateHook(hook, ...args);
54
- }
55
-
56
- // If the hook doesn't exist, create it
57
- if (!hook) {
54
+ onUpdateHook?.(hook, ...args);
55
+ } else {
58
56
  hook = onCreate(...args);
59
57
  HookCalls.hooks.push(hook);
60
58
  onRemove && onUnmount(() => onRemove(hook));
@@ -65,31 +63,24 @@ export const createHook = function createHook({
65
63
  };
66
64
  } as unknown as CreateHook;
67
65
 
68
- let updateTimeout: any;
69
- function delayedUpdate() {
70
- clearTimeout(updateTimeout);
71
- updateTimeout = setTimeout(update);
72
- }
73
-
74
66
  // Use state hook
75
67
  export const useState = createHook({
76
68
  onCreate: (value) => {
69
+ let state = value;
77
70
  function get() {
78
- return value;
71
+ return state;
79
72
  }
80
- get.value = value;
81
- get.toJSON = get.valueOf = get;
82
- get.toString = () => `${value}`;
83
73
 
84
74
  function set(newValue: any) {
85
- if (current.event) {
75
+ if (current.event && !current.event.defaultPrevented) {
86
76
  current.event.preventDefault();
87
77
  }
88
78
 
89
- if (value !== newValue) {
90
- value = newValue;
91
- get.value = newValue;
92
- delayedUpdate();
79
+ const resolvedValue = typeof newValue === "function" ? newValue(state) : newValue;
80
+
81
+ if (hasChanged(state, resolvedValue)) {
82
+ state = resolvedValue;
83
+ debouncedUpdate();
93
84
  }
94
85
  }
95
86
 
@@ -97,7 +88,6 @@ export const useState = createHook({
97
88
  }
98
89
  });
99
90
 
100
- // Effect hook
101
91
  export const useEffect = createHook({
102
92
  onCreate: (effect: Function, changes: any[]) => {
103
93
  const hook: {
@@ -128,18 +118,18 @@ export const useEffect = createHook({
128
118
  return;
129
119
  }
130
120
 
121
+ if (Array.isArray(changes) && changes.length === 0) {
122
+ // Si las dependencias son un array vacío, no se debe volver a ejecutar.
123
+ return;
124
+ }
125
+
131
126
  // on update if there are changes
132
- if (Array.isArray(changes)) {
133
- for (let i = 0, l = changes.length; i < l; i++) {
134
- if (changes[i] !== hook.prev[i]) {
135
- hook.prev = changes;
136
- if (typeof hook.onCleanup === "function") {
137
- hook.onCleanup();
138
- }
139
- hook.onCleanup = hook.effect();
140
- return;
141
- }
127
+ if (Array.isArray(changes) && hasChanged(hook.prev, changes)) {
128
+ hook.prev = changes;
129
+ if (typeof hook.onCleanup === "function") {
130
+ hook.onCleanup();
142
131
  }
132
+ hook.onCleanup = hook.effect();
143
133
  }
144
134
  },
145
135
  onRemove: (hook) => {
@@ -163,18 +153,15 @@ export const useRef = createHook({
163
153
 
164
154
  export const useCallback = createHook({
165
155
  onCreate: (callback, changes) => {
166
- callback();
167
156
  return { callback, changes };
168
157
  },
169
158
  onUpdate: (hook, callback, changes) => {
170
- for (let i = 0, l = changes.length; i < l; i++) {
171
- if (changes[i] !== hook.changes[i]) {
172
- hook.changes = changes;
173
- hook.callback();
174
- return;
175
- }
159
+ if (hasChanged(hook.changes, changes)) {
160
+ hook.changes = changes;
161
+ hook.callback = callback;
176
162
  }
177
- }
163
+ },
164
+ returnValue: (hook) => hook.callback
178
165
  });
179
166
 
180
167
  export const useMemo = createHook({
@@ -182,15 +169,10 @@ export const useMemo = createHook({
182
169
  return { callback, changes, value: callback() };
183
170
  },
184
171
  onUpdate: (hook, callback, changes) => {
185
- for (let i = 0, l = changes.length; i < l; i++) {
186
- if (changes[i] !== hook.changes[i]) {
187
- hook.changes = changes;
188
- hook.value = callback();
189
- return;
190
- }
172
+ if (hasChanged(hook.changes, changes)) {
173
+ hook.changes = changes;
174
+ hook.value = callback();
191
175
  }
192
176
  },
193
- returnValue: (hook) => {
194
- return hook.value;
195
- }
177
+ returnValue: (hook) => hook.value
196
178
  });