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