isomorfeus-preact 10.7.3 → 10.8.2

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 (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
+ }