isomorfeus-preact 10.7.3 → 10.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/lib/preact/version.rb +1 -1
  3. data/node_modules/.package-lock.json +5 -7
  4. data/node_modules/preact/compat/LICENSE +21 -0
  5. data/node_modules/preact/compat/client.js +11 -5
  6. data/node_modules/preact/compat/client.mjs +7 -3
  7. data/node_modules/preact/compat/dist/compat.js +2 -2
  8. data/node_modules/preact/compat/dist/compat.js.map +1 -1
  9. data/node_modules/preact/compat/dist/compat.mjs +2 -2
  10. data/node_modules/preact/compat/dist/compat.module.js +2 -2
  11. data/node_modules/preact/compat/dist/compat.module.js.map +1 -1
  12. data/node_modules/preact/compat/dist/compat.umd.js +2 -2
  13. data/node_modules/preact/compat/dist/compat.umd.js.map +1 -1
  14. data/node_modules/preact/compat/package.json +47 -17
  15. data/node_modules/preact/compat/src/render.js +238 -229
  16. data/node_modules/preact/debug/LICENSE +21 -0
  17. data/node_modules/preact/debug/dist/debug.js +2 -2
  18. data/node_modules/preact/debug/dist/debug.js.map +1 -1
  19. data/node_modules/preact/debug/dist/debug.mjs +2 -2
  20. data/node_modules/preact/debug/dist/debug.module.js +2 -2
  21. data/node_modules/preact/debug/dist/debug.module.js.map +1 -1
  22. data/node_modules/preact/debug/dist/debug.umd.js +2 -2
  23. data/node_modules/preact/debug/dist/debug.umd.js.map +1 -1
  24. data/node_modules/preact/debug/package.json +24 -16
  25. data/node_modules/preact/debug/src/debug.js +437 -444
  26. data/node_modules/preact/devtools/LICENSE +21 -0
  27. data/node_modules/preact/devtools/dist/devtools.js +2 -2
  28. data/node_modules/preact/devtools/dist/devtools.js.map +1 -1
  29. data/node_modules/preact/devtools/dist/devtools.mjs +2 -2
  30. data/node_modules/preact/devtools/dist/devtools.module.js +2 -2
  31. data/node_modules/preact/devtools/dist/devtools.module.js.map +1 -1
  32. data/node_modules/preact/devtools/dist/devtools.umd.js +2 -2
  33. data/node_modules/preact/devtools/dist/devtools.umd.js.map +1 -1
  34. data/node_modules/preact/devtools/package.json +9 -0
  35. data/node_modules/preact/devtools/src/devtools.js +10 -10
  36. data/node_modules/preact/dist/preact.js +1 -1
  37. data/node_modules/preact/dist/preact.js.map +1 -1
  38. data/node_modules/preact/dist/preact.min.js +1 -1
  39. data/node_modules/preact/dist/preact.min.js.map +1 -1
  40. data/node_modules/preact/dist/preact.mjs +1 -1
  41. data/node_modules/preact/dist/preact.module.js +1 -1
  42. data/node_modules/preact/dist/preact.module.js.map +1 -1
  43. data/node_modules/preact/dist/preact.umd.js +1 -1
  44. data/node_modules/preact/dist/preact.umd.js.map +1 -1
  45. data/node_modules/preact/hooks/LICENSE +21 -0
  46. data/node_modules/preact/hooks/dist/hooks.js +2 -2
  47. data/node_modules/preact/hooks/dist/hooks.js.map +1 -1
  48. data/node_modules/preact/hooks/dist/hooks.mjs +2 -2
  49. data/node_modules/preact/hooks/dist/hooks.module.js +2 -2
  50. data/node_modules/preact/hooks/dist/hooks.module.js.map +1 -1
  51. data/node_modules/preact/hooks/dist/hooks.umd.js +2 -2
  52. data/node_modules/preact/hooks/dist/hooks.umd.js.map +1 -1
  53. data/node_modules/preact/hooks/package.json +33 -24
  54. data/node_modules/preact/hooks/src/index.js +417 -391
  55. data/node_modules/preact/hooks/src/internal.d.ts +3 -0
  56. data/node_modules/preact/jsx-runtime/LICENSE +21 -0
  57. data/node_modules/preact/jsx-runtime/package.json +9 -0
  58. data/node_modules/preact/package.json +304 -304
  59. data/node_modules/preact/src/diff/index.js +20 -6
  60. data/node_modules/preact/test-utils/package.json +26 -17
  61. data/package.json +1 -1
  62. metadata +9 -11
  63. data/node_modules/preact/compat/dist/compat.mjs.map +0 -1
  64. data/node_modules/preact/debug/dist/debug.mjs.map +0 -1
  65. data/node_modules/preact/devtools/dist/devtools.mjs.map +0 -1
  66. data/node_modules/preact/dist/preact.mjs.map +0 -1
  67. data/node_modules/preact/hooks/dist/hooks.mjs.map +0 -1
  68. data/node_modules/preact/jsx-runtime/dist/jsxRuntime.mjs.map +0 -1
  69. data/node_modules/preact/test-utils/dist/testUtils.mjs.map +0 -1
@@ -1,391 +1,417 @@
1
- import { options } from 'preact';
2
-
3
- /** @type {number} */
4
- let currentIndex;
5
-
6
- /** @type {import('./internal').Component} */
7
- let currentComponent;
8
-
9
- /** @type {number} */
10
- let currentHook = 0;
11
-
12
- /** @type {Array<import('./internal').Component>} */
13
- let afterPaintEffects = [];
14
-
15
- let oldBeforeDiff = options._diff;
16
- let oldBeforeRender = options._render;
17
- let oldAfterDiff = options.diffed;
18
- let oldCommit = options._commit;
19
- let oldBeforeUnmount = options.unmount;
20
-
21
- const RAF_TIMEOUT = 100;
22
- let prevRaf;
23
-
24
- options._diff = vnode => {
25
- currentComponent = null;
26
- if (oldBeforeDiff) oldBeforeDiff(vnode);
27
- };
28
-
29
- options._render = vnode => {
30
- if (oldBeforeRender) oldBeforeRender(vnode);
31
-
32
- currentComponent = vnode._component;
33
- currentIndex = 0;
34
-
35
- const hooks = currentComponent.__hooks;
36
- if (hooks) {
37
- hooks._pendingEffects.forEach(invokeCleanup);
38
- hooks._pendingEffects.forEach(invokeEffect);
39
- hooks._pendingEffects = [];
40
- }
41
- };
42
-
43
- options.diffed = vnode => {
44
- if (oldAfterDiff) oldAfterDiff(vnode);
45
-
46
- const c = vnode._component;
47
- if (c && c.__hooks && c.__hooks._pendingEffects.length) {
48
- afterPaint(afterPaintEffects.push(c));
49
- }
50
- currentComponent = null;
51
- };
52
-
53
- options._commit = (vnode, commitQueue) => {
54
- commitQueue.some(component => {
55
- try {
56
- component._renderCallbacks.forEach(invokeCleanup);
57
- component._renderCallbacks = component._renderCallbacks.filter(cb =>
58
- cb._value ? invokeEffect(cb) : true
59
- );
60
- } catch (e) {
61
- commitQueue.some(c => {
62
- if (c._renderCallbacks) c._renderCallbacks = [];
63
- });
64
- commitQueue = [];
65
- options._catchError(e, component._vnode);
66
- }
67
- });
68
-
69
- if (oldCommit) oldCommit(vnode, commitQueue);
70
- };
71
-
72
- options.unmount = vnode => {
73
- if (oldBeforeUnmount) oldBeforeUnmount(vnode);
74
-
75
- const c = vnode._component;
76
- if (c && c.__hooks) {
77
- let hasErrored;
78
- c.__hooks._list.forEach(s => {
79
- try {
80
- invokeCleanup(s);
81
- } catch (e) {
82
- hasErrored = e;
83
- }
84
- });
85
- if (hasErrored) options._catchError(hasErrored, c._vnode);
86
- }
87
- };
88
-
89
- /**
90
- * Get a hook's state from the currentComponent
91
- * @param {number} index The index of the hook to get
92
- * @param {number} type The index of the hook to get
93
- * @returns {any}
94
- */
95
- function getHookState(index, type) {
96
- if (options._hook) {
97
- options._hook(currentComponent, index, currentHook || type);
98
- }
99
- currentHook = 0;
100
-
101
- // Largely inspired by:
102
- // * https://github.com/michael-klein/funcy.js/blob/f6be73468e6ec46b0ff5aa3cc4c9baf72a29025a/src/hooks/core_hooks.mjs
103
- // * https://github.com/michael-klein/funcy.js/blob/650beaa58c43c33a74820a3c98b3c7079cf2e333/src/renderer.mjs
104
- // Other implementations to look at:
105
- // * https://codesandbox.io/s/mnox05qp8
106
- const hooks =
107
- currentComponent.__hooks ||
108
- (currentComponent.__hooks = {
109
- _list: [],
110
- _pendingEffects: []
111
- });
112
-
113
- if (index >= hooks._list.length) {
114
- hooks._list.push({});
115
- }
116
- return hooks._list[index];
117
- }
118
-
119
- /**
120
- * @param {import('./index').StateUpdater<any>} [initialState]
121
- */
122
- export function useState(initialState) {
123
- currentHook = 1;
124
- return useReducer(invokeOrReturn, initialState);
125
- }
126
-
127
- /**
128
- * @param {import('./index').Reducer<any, any>} reducer
129
- * @param {import('./index').StateUpdater<any>} initialState
130
- * @param {(initialState: any) => void} [init]
131
- * @returns {[ any, (state: any) => void ]}
132
- */
133
- export function useReducer(reducer, initialState, init) {
134
- /** @type {import('./internal').ReducerHookState} */
135
- const hookState = getHookState(currentIndex++, 2);
136
- hookState._reducer = reducer;
137
- if (!hookState._component) {
138
- hookState._value = [
139
- !init ? invokeOrReturn(undefined, initialState) : init(initialState),
140
-
141
- action => {
142
- const nextValue = hookState._reducer(hookState._value[0], action);
143
- if (hookState._value[0] !== nextValue) {
144
- hookState._value = [nextValue, hookState._value[1]];
145
- hookState._component.setState({});
146
- }
147
- }
148
- ];
149
-
150
- hookState._component = currentComponent;
151
- }
152
-
153
- return hookState._value;
154
- }
155
-
156
- /**
157
- * @param {import('./internal').Effect} callback
158
- * @param {any[]} args
159
- */
160
- export function useEffect(callback, args) {
161
- /** @type {import('./internal').EffectHookState} */
162
- const state = getHookState(currentIndex++, 3);
163
- if (!options._skipEffects && argsChanged(state._args, args)) {
164
- state._value = callback;
165
- state._args = args;
166
-
167
- currentComponent.__hooks._pendingEffects.push(state);
168
- }
169
- }
170
-
171
- /**
172
- * @param {import('./internal').Effect} callback
173
- * @param {any[]} args
174
- */
175
- export function useLayoutEffect(callback, args) {
176
- /** @type {import('./internal').EffectHookState} */
177
- const state = getHookState(currentIndex++, 4);
178
- if (!options._skipEffects && argsChanged(state._args, args)) {
179
- state._value = callback;
180
- state._args = args;
181
-
182
- currentComponent._renderCallbacks.push(state);
183
- }
184
- }
185
-
186
- export function useRef(initialValue) {
187
- currentHook = 5;
188
- return useMemo(() => ({ current: initialValue }), []);
189
- }
190
-
191
- /**
192
- * @param {object} ref
193
- * @param {() => object} createHandle
194
- * @param {any[]} args
195
- */
196
- export function useImperativeHandle(ref, createHandle, args) {
197
- currentHook = 6;
198
- useLayoutEffect(
199
- () => {
200
- if (typeof ref == 'function') {
201
- ref(createHandle());
202
- return () => ref(null);
203
- } else if (ref) {
204
- ref.current = createHandle();
205
- return () => ref.current = null;
206
- }
207
- },
208
- args == null ? args : args.concat(ref)
209
- );
210
- }
211
-
212
- /**
213
- * @param {() => any} factory
214
- * @param {any[]} args
215
- */
216
- export function useMemo(factory, args) {
217
- /** @type {import('./internal').MemoHookState} */
218
- const state = getHookState(currentIndex++, 7);
219
- if (argsChanged(state._args, args)) {
220
- state._value = factory();
221
- state._args = args;
222
- state._factory = factory;
223
- }
224
-
225
- return state._value;
226
- }
227
-
228
- /**
229
- * @param {() => void} callback
230
- * @param {any[]} args
231
- */
232
- export function useCallback(callback, args) {
233
- currentHook = 8;
234
- return useMemo(() => callback, args);
235
- }
236
-
237
- /**
238
- * @param {import('./internal').PreactContext} context
239
- */
240
- export function useContext(context) {
241
- const provider = currentComponent.context[context._id];
242
- // We could skip this call here, but than we'd not call
243
- // `options._hook`. We need to do that in order to make
244
- // the devtools aware of this hook.
245
- /** @type {import('./internal').ContextHookState} */
246
- const state = getHookState(currentIndex++, 9);
247
- // The devtools needs access to the context object to
248
- // be able to pull of the default value when no provider
249
- // is present in the tree.
250
- state._context = context;
251
- if (!provider) return context._defaultValue;
252
- // This is probably not safe to convert to "!"
253
- if (state._value == null) {
254
- state._value = true;
255
- provider.sub(currentComponent);
256
- }
257
- return provider.props.value;
258
- }
259
-
260
- /**
261
- * Display a custom label for a custom hook for the devtools panel
262
- * @type {<T>(value: T, cb?: (value: T) => string | number) => void}
263
- */
264
- export function useDebugValue(value, formatter) {
265
- if (options.useDebugValue) {
266
- options.useDebugValue(formatter ? formatter(value) : value);
267
- }
268
- }
269
-
270
- /**
271
- * @param {(error: any) => void} cb
272
- */
273
- export function useErrorBoundary(cb) {
274
- /** @type {import('./internal').ErrorBoundaryHookState} */
275
- const state = getHookState(currentIndex++, 10);
276
- const errState = useState();
277
- state._value = cb;
278
- if (!currentComponent.componentDidCatch) {
279
- currentComponent.componentDidCatch = err => {
280
- if (state._value) state._value(err);
281
- errState[1](err);
282
- };
283
- }
284
- return [
285
- errState[0],
286
- () => {
287
- errState[1](undefined);
288
- }
289
- ];
290
- }
291
-
292
- /**
293
- * After paint effects consumer.
294
- */
295
- function flushAfterPaintEffects() {
296
- let component;
297
- while ((component = afterPaintEffects.shift())) {
298
- if (!component._parentDom) continue;
299
- try {
300
- component.__hooks._pendingEffects.forEach(invokeCleanup);
301
- component.__hooks._pendingEffects.forEach(invokeEffect);
302
- component.__hooks._pendingEffects = [];
303
- } catch (e) {
304
- component.__hooks._pendingEffects = [];
305
- options._catchError(e, component._vnode);
306
- }
307
- }
308
- }
309
-
310
- let HAS_RAF = typeof requestAnimationFrame == 'function';
311
-
312
- /**
313
- * Schedule a callback to be invoked after the browser has a chance to paint a new frame.
314
- * Do this by combining requestAnimationFrame (rAF) + setTimeout to invoke a callback after
315
- * the next browser frame.
316
- *
317
- * Also, schedule a timeout in parallel to the the rAF to ensure the callback is invoked
318
- * even if RAF doesn't fire (for example if the browser tab is not visible)
319
- *
320
- * @param {() => void} callback
321
- */
322
- function afterNextFrame(callback) {
323
- const done = () => {
324
- clearTimeout(timeout);
325
- if (HAS_RAF) cancelAnimationFrame(raf);
326
- setTimeout(callback);
327
- };
328
- const timeout = setTimeout(done, RAF_TIMEOUT);
329
-
330
- let raf;
331
- if (HAS_RAF) {
332
- raf = requestAnimationFrame(done);
333
- }
334
- }
335
-
336
- // Note: if someone used options.debounceRendering = requestAnimationFrame,
337
- // then effects will ALWAYS run on the NEXT frame instead of the current one, incurring a ~16ms delay.
338
- // Perhaps this is not such a big deal.
339
- /**
340
- * Schedule afterPaintEffects flush after the browser paints
341
- * @param {number} newQueueLength
342
- */
343
- function afterPaint(newQueueLength) {
344
- if (newQueueLength === 1 || prevRaf !== options.requestAnimationFrame) {
345
- prevRaf = options.requestAnimationFrame;
346
- (prevRaf || afterNextFrame)(flushAfterPaintEffects);
347
- }
348
- }
349
-
350
- /**
351
- * @param {import('./internal').EffectHookState} hook
352
- */
353
- function invokeCleanup(hook) {
354
- // A hook cleanup can introduce a call to render which creates a new root, this will call options.vnode
355
- // and move the currentComponent away.
356
- const comp = currentComponent;
357
- let cleanup = hook._cleanup;
358
- if (typeof cleanup == 'function') {
359
- hook._cleanup = undefined;
360
- cleanup();
361
- }
362
- currentComponent = comp;
363
- }
364
-
365
- /**
366
- * Invoke a Hook's effect
367
- * @param {import('./internal').EffectHookState} hook
368
- */
369
- function invokeEffect(hook) {
370
- // A hook call can introduce a call to render which creates a new root, this will call options.vnode
371
- // and move the currentComponent away.
372
- const comp = currentComponent;
373
- hook._cleanup = hook._value();
374
- currentComponent = comp;
375
- }
376
-
377
- /**
378
- * @param {any[]} oldArgs
379
- * @param {any[]} newArgs
380
- */
381
- function argsChanged(oldArgs, newArgs) {
382
- return (
383
- !oldArgs ||
384
- oldArgs.length !== newArgs.length ||
385
- newArgs.some((arg, index) => arg !== oldArgs[index])
386
- );
387
- }
388
-
389
- function invokeOrReturn(arg, f) {
390
- return typeof f == 'function' ? f(arg) : f;
391
- }
1
+ import { options } from 'preact';
2
+
3
+ /** @type {number} */
4
+ let currentIndex;
5
+
6
+ /** @type {import('./internal').Component} */
7
+ let currentComponent;
8
+
9
+ /** @type {import('./internal').Component} */
10
+ let previousComponent;
11
+
12
+ /** @type {number} */
13
+ let currentHook = 0;
14
+
15
+ /** @type {Array<import('./internal').Component>} */
16
+ let afterPaintEffects = [];
17
+
18
+ let EMPTY = [];
19
+
20
+ let oldBeforeDiff = options._diff;
21
+ let oldBeforeRender = options._render;
22
+ let oldAfterDiff = options.diffed;
23
+ let oldCommit = options._commit;
24
+ let oldBeforeUnmount = options.unmount;
25
+
26
+ const RAF_TIMEOUT = 100;
27
+ let prevRaf;
28
+
29
+ options._diff = vnode => {
30
+ currentComponent = null;
31
+ if (oldBeforeDiff) oldBeforeDiff(vnode);
32
+ };
33
+
34
+ options._render = vnode => {
35
+ if (oldBeforeRender) oldBeforeRender(vnode);
36
+
37
+ currentComponent = vnode._component;
38
+ currentIndex = 0;
39
+
40
+ const hooks = currentComponent.__hooks;
41
+ if (hooks) {
42
+ if (previousComponent === currentComponent) {
43
+ hooks._pendingEffects = [];
44
+ currentComponent._renderCallbacks = [];
45
+ hooks._list.forEach(hookItem => {
46
+ hookItem._pendingValue = EMPTY;
47
+ hookItem._pendingArgs = undefined;
48
+ });
49
+ } else {
50
+ hooks._pendingEffects.forEach(invokeCleanup);
51
+ hooks._pendingEffects.forEach(invokeEffect);
52
+ hooks._pendingEffects = [];
53
+ }
54
+ }
55
+ previousComponent = currentComponent;
56
+ };
57
+
58
+ options.diffed = vnode => {
59
+ if (oldAfterDiff) oldAfterDiff(vnode);
60
+
61
+ const c = vnode._component;
62
+ if (c && c.__hooks) {
63
+ if (c.__hooks._pendingEffects.length) afterPaint(afterPaintEffects.push(c));
64
+ c.__hooks._list.forEach(hookItem => {
65
+ if (hookItem._pendingArgs) {
66
+ hookItem._args = hookItem._pendingArgs;
67
+ }
68
+ if (hookItem._pendingValue !== EMPTY) {
69
+ hookItem._value = hookItem._pendingValue;
70
+ }
71
+ hookItem._pendingArgs = undefined;
72
+ hookItem._pendingValue = EMPTY;
73
+ });
74
+ }
75
+ previousComponent = currentComponent = null;
76
+ };
77
+
78
+ options._commit = (vnode, commitQueue) => {
79
+ commitQueue.some(component => {
80
+ try {
81
+ component._renderCallbacks.forEach(invokeCleanup);
82
+ component._renderCallbacks = component._renderCallbacks.filter(cb =>
83
+ cb._value ? invokeEffect(cb) : true
84
+ );
85
+ } catch (e) {
86
+ commitQueue.some(c => {
87
+ if (c._renderCallbacks) c._renderCallbacks = [];
88
+ });
89
+ commitQueue = [];
90
+ options._catchError(e, component._vnode);
91
+ }
92
+ });
93
+
94
+ if (oldCommit) oldCommit(vnode, commitQueue);
95
+ };
96
+
97
+ options.unmount = vnode => {
98
+ if (oldBeforeUnmount) oldBeforeUnmount(vnode);
99
+
100
+ const c = vnode._component;
101
+ if (c && c.__hooks) {
102
+ let hasErrored;
103
+ c.__hooks._list.forEach(s => {
104
+ try {
105
+ invokeCleanup(s);
106
+ } catch (e) {
107
+ hasErrored = e;
108
+ }
109
+ });
110
+ if (hasErrored) options._catchError(hasErrored, c._vnode);
111
+ }
112
+ };
113
+
114
+ /**
115
+ * Get a hook's state from the currentComponent
116
+ * @param {number} index The index of the hook to get
117
+ * @param {number} type The index of the hook to get
118
+ * @returns {any}
119
+ */
120
+ function getHookState(index, type) {
121
+ if (options._hook) {
122
+ options._hook(currentComponent, index, currentHook || type);
123
+ }
124
+ currentHook = 0;
125
+
126
+ // Largely inspired by:
127
+ // * https://github.com/michael-klein/funcy.js/blob/f6be73468e6ec46b0ff5aa3cc4c9baf72a29025a/src/hooks/core_hooks.mjs
128
+ // * https://github.com/michael-klein/funcy.js/blob/650beaa58c43c33a74820a3c98b3c7079cf2e333/src/renderer.mjs
129
+ // Other implementations to look at:
130
+ // * https://codesandbox.io/s/mnox05qp8
131
+ const hooks =
132
+ currentComponent.__hooks ||
133
+ (currentComponent.__hooks = {
134
+ _list: [],
135
+ _pendingEffects: []
136
+ });
137
+
138
+ if (index >= hooks._list.length) {
139
+ hooks._list.push({ _pendingValue: EMPTY });
140
+ }
141
+ return hooks._list[index];
142
+ }
143
+
144
+ /**
145
+ * @param {import('./index').StateUpdater<any>} [initialState]
146
+ */
147
+ export function useState(initialState) {
148
+ currentHook = 1;
149
+ return useReducer(invokeOrReturn, initialState);
150
+ }
151
+
152
+ /**
153
+ * @param {import('./index').Reducer<any, any>} reducer
154
+ * @param {import('./index').StateUpdater<any>} initialState
155
+ * @param {(initialState: any) => void} [init]
156
+ * @returns {[ any, (state: any) => void ]}
157
+ */
158
+ export function useReducer(reducer, initialState, init) {
159
+ /** @type {import('./internal').ReducerHookState} */
160
+ const hookState = getHookState(currentIndex++, 2);
161
+ hookState._reducer = reducer;
162
+ if (!hookState._component) {
163
+ hookState._value = [
164
+ !init ? invokeOrReturn(undefined, initialState) : init(initialState),
165
+
166
+ action => {
167
+ const nextValue = hookState._reducer(hookState._value[0], action);
168
+ if (hookState._value[0] !== nextValue) {
169
+ hookState._value = [nextValue, hookState._value[1]];
170
+ hookState._component.setState({});
171
+ }
172
+ }
173
+ ];
174
+
175
+ hookState._component = currentComponent;
176
+ }
177
+
178
+ return hookState._value;
179
+ }
180
+
181
+ /**
182
+ * @param {import('./internal').Effect} callback
183
+ * @param {any[]} args
184
+ */
185
+ export function useEffect(callback, args) {
186
+ /** @type {import('./internal').EffectHookState} */
187
+ const state = getHookState(currentIndex++, 3);
188
+ if (!options._skipEffects && argsChanged(state._args, args)) {
189
+ state._value = callback;
190
+ state._pendingArgs = args;
191
+
192
+ currentComponent.__hooks._pendingEffects.push(state);
193
+ }
194
+ }
195
+
196
+ /**
197
+ * @param {import('./internal').Effect} callback
198
+ * @param {any[]} args
199
+ */
200
+ export function useLayoutEffect(callback, args) {
201
+ /** @type {import('./internal').EffectHookState} */
202
+ const state = getHookState(currentIndex++, 4);
203
+ if (!options._skipEffects && argsChanged(state._args, args)) {
204
+ state._value = callback;
205
+ state._pendingArgs = args;
206
+
207
+ currentComponent._renderCallbacks.push(state);
208
+ }
209
+ }
210
+
211
+ export function useRef(initialValue) {
212
+ currentHook = 5;
213
+ return useMemo(() => ({ current: initialValue }), []);
214
+ }
215
+
216
+ /**
217
+ * @param {object} ref
218
+ * @param {() => object} createHandle
219
+ * @param {any[]} args
220
+ */
221
+ export function useImperativeHandle(ref, createHandle, args) {
222
+ currentHook = 6;
223
+ useLayoutEffect(
224
+ () => {
225
+ if (typeof ref == 'function') {
226
+ ref(createHandle());
227
+ return () => ref(null);
228
+ } else if (ref) {
229
+ ref.current = createHandle();
230
+ return () => (ref.current = null);
231
+ }
232
+ },
233
+ args == null ? args : args.concat(ref)
234
+ );
235
+ }
236
+
237
+ /**
238
+ * @param {() => any} factory
239
+ * @param {any[]} args
240
+ */
241
+ export function useMemo(factory, args) {
242
+ /** @type {import('./internal').MemoHookState} */
243
+ const state = getHookState(currentIndex++, 7);
244
+ if (argsChanged(state._args, args)) {
245
+ state._pendingValue = factory();
246
+ state._pendingArgs = args;
247
+ state._factory = factory;
248
+ return state._pendingValue;
249
+ }
250
+
251
+ return state._value;
252
+ }
253
+
254
+ /**
255
+ * @param {() => void} callback
256
+ * @param {any[]} args
257
+ */
258
+ export function useCallback(callback, args) {
259
+ currentHook = 8;
260
+ return useMemo(() => callback, args);
261
+ }
262
+
263
+ /**
264
+ * @param {import('./internal').PreactContext} context
265
+ */
266
+ export function useContext(context) {
267
+ const provider = currentComponent.context[context._id];
268
+ // We could skip this call here, but than we'd not call
269
+ // `options._hook`. We need to do that in order to make
270
+ // the devtools aware of this hook.
271
+ /** @type {import('./internal').ContextHookState} */
272
+ const state = getHookState(currentIndex++, 9);
273
+ // The devtools needs access to the context object to
274
+ // be able to pull of the default value when no provider
275
+ // is present in the tree.
276
+ state._context = context;
277
+ if (!provider) return context._defaultValue;
278
+ // This is probably not safe to convert to "!"
279
+ if (state._value == null) {
280
+ state._value = true;
281
+ provider.sub(currentComponent);
282
+ }
283
+ return provider.props.value;
284
+ }
285
+
286
+ /**
287
+ * Display a custom label for a custom hook for the devtools panel
288
+ * @type {<T>(value: T, cb?: (value: T) => string | number) => void}
289
+ */
290
+ export function useDebugValue(value, formatter) {
291
+ if (options.useDebugValue) {
292
+ options.useDebugValue(formatter ? formatter(value) : value);
293
+ }
294
+ }
295
+
296
+ /**
297
+ * @param {(error: any) => void} cb
298
+ */
299
+ export function useErrorBoundary(cb) {
300
+ /** @type {import('./internal').ErrorBoundaryHookState} */
301
+ const state = getHookState(currentIndex++, 10);
302
+ const errState = useState();
303
+ state._value = cb;
304
+ if (!currentComponent.componentDidCatch) {
305
+ currentComponent.componentDidCatch = err => {
306
+ if (state._value) state._value(err);
307
+ errState[1](err);
308
+ };
309
+ }
310
+ return [
311
+ errState[0],
312
+ () => {
313
+ errState[1](undefined);
314
+ }
315
+ ];
316
+ }
317
+
318
+ /**
319
+ * After paint effects consumer.
320
+ */
321
+ function flushAfterPaintEffects() {
322
+ let component;
323
+ while ((component = afterPaintEffects.shift())) {
324
+ if (!component._parentDom) continue;
325
+ try {
326
+ component.__hooks._pendingEffects.forEach(invokeCleanup);
327
+ component.__hooks._pendingEffects.forEach(invokeEffect);
328
+ component.__hooks._pendingEffects = [];
329
+ } catch (e) {
330
+ component.__hooks._pendingEffects = [];
331
+ options._catchError(e, component._vnode);
332
+ }
333
+ }
334
+ }
335
+
336
+ let HAS_RAF = typeof requestAnimationFrame == 'function';
337
+
338
+ /**
339
+ * Schedule a callback to be invoked after the browser has a chance to paint a new frame.
340
+ * Do this by combining requestAnimationFrame (rAF) + setTimeout to invoke a callback after
341
+ * the next browser frame.
342
+ *
343
+ * Also, schedule a timeout in parallel to the the rAF to ensure the callback is invoked
344
+ * even if RAF doesn't fire (for example if the browser tab is not visible)
345
+ *
346
+ * @param {() => void} callback
347
+ */
348
+ function afterNextFrame(callback) {
349
+ const done = () => {
350
+ clearTimeout(timeout);
351
+ if (HAS_RAF) cancelAnimationFrame(raf);
352
+ setTimeout(callback);
353
+ };
354
+ const timeout = setTimeout(done, RAF_TIMEOUT);
355
+
356
+ let raf;
357
+ if (HAS_RAF) {
358
+ raf = requestAnimationFrame(done);
359
+ }
360
+ }
361
+
362
+ // Note: if someone used options.debounceRendering = requestAnimationFrame,
363
+ // then effects will ALWAYS run on the NEXT frame instead of the current one, incurring a ~16ms delay.
364
+ // Perhaps this is not such a big deal.
365
+ /**
366
+ * Schedule afterPaintEffects flush after the browser paints
367
+ * @param {number} newQueueLength
368
+ */
369
+ function afterPaint(newQueueLength) {
370
+ if (newQueueLength === 1 || prevRaf !== options.requestAnimationFrame) {
371
+ prevRaf = options.requestAnimationFrame;
372
+ (prevRaf || afterNextFrame)(flushAfterPaintEffects);
373
+ }
374
+ }
375
+
376
+ /**
377
+ * @param {import('./internal').EffectHookState} hook
378
+ */
379
+ function invokeCleanup(hook) {
380
+ // A hook cleanup can introduce a call to render which creates a new root, this will call options.vnode
381
+ // and move the currentComponent away.
382
+ const comp = currentComponent;
383
+ let cleanup = hook._cleanup;
384
+ if (typeof cleanup == 'function') {
385
+ hook._cleanup = undefined;
386
+ cleanup();
387
+ }
388
+ currentComponent = comp;
389
+ }
390
+
391
+ /**
392
+ * Invoke a Hook's effect
393
+ * @param {import('./internal').EffectHookState} hook
394
+ */
395
+ function invokeEffect(hook) {
396
+ // A hook call can introduce a call to render which creates a new root, this will call options.vnode
397
+ // and move the currentComponent away.
398
+ const comp = currentComponent;
399
+ hook._cleanup = hook._value();
400
+ currentComponent = comp;
401
+ }
402
+
403
+ /**
404
+ * @param {any[]} oldArgs
405
+ * @param {any[]} newArgs
406
+ */
407
+ function argsChanged(oldArgs, newArgs) {
408
+ return (
409
+ !oldArgs ||
410
+ oldArgs.length !== newArgs.length ||
411
+ newArgs.some((arg, index) => arg !== oldArgs[index])
412
+ );
413
+ }
414
+
415
+ function invokeOrReturn(arg, f) {
416
+ return typeof f == 'function' ? f(arg) : f;
417
+ }