phase 0.4.2 → 0.5.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.
- package/README.md +3 -2
- package/dist/{debounce-BkVwTxwI.js → debounce-CJYqsSXm.js} +135 -119
- package/dist/debounce-CJYqsSXm.js.map +1 -0
- package/dist/{index-DE0O-FZ4.d.ts → index-Cx0KeF0f.d.ts} +9 -4
- package/dist/index-Cx0KeF0f.d.ts.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/react.d.ts +3 -1
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +3 -1
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
- package/dist/debounce-BkVwTxwI.js.map +0 -1
- package/dist/index-DE0O-FZ4.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -36,9 +36,10 @@ function Orbit({ radius }) {
|
|
|
36
36
|
|
|
37
37
|
- **Pauses when unseen.** Off-screen or in a background tab, work stops and CPU drops to zero.
|
|
38
38
|
- **Respects reduced motion by default.** Accessibility is built in, not an opt-in.
|
|
39
|
-
- **
|
|
39
|
+
- **Batches layout reads.** Element-relative pointer tracking reads one rect per dirty frame; scroll geometry is read on attachment or explicit measurement and coalesced after resize signals; other dimensions and visibility come from observers.
|
|
40
40
|
- **Zero re-renders from the frame loop.** Per-frame work writes to refs and the DOM, never React state.
|
|
41
|
-
- **Frame-locked shared clock.**
|
|
41
|
+
- **Frame-locked shared clock.** Tickers using the same clock protocol read one timestamp, so they do not drift out of sync.
|
|
42
|
+
- **Input before frame loops.** Within one clock protocol, pointer, scroll, mutation, and throttle work queued before a frame flushes before its animation callbacks.
|
|
42
43
|
- **Renders only what matters.** Skip painting off-screen content, mount non-critical UI when idle.
|
|
43
44
|
|
|
44
45
|
Read the [full documentation](https://github.com/vercel-labs/phase#readme), install the [phase agent skill](https://github.com/vercel-labs/phase/tree/main/skills/phase), review the [changelog](https://github.com/vercel-labs/phase/blob/main/CHANGELOG.md), or see the [MIT license](https://github.com/vercel-labs/phase/blob/main/packages/phase/LICENSE).
|
|
@@ -22,6 +22,93 @@ function linkAbortSignal(signal, stop) {
|
|
|
22
22
|
/** Shared empty unlink for the no-signal and already-aborted paths. */
|
|
23
23
|
function unlinkNoop() {}
|
|
24
24
|
//#endregion
|
|
25
|
+
//#region src/core/_internal/clock/index.ts
|
|
26
|
+
const EXECUTING = -1;
|
|
27
|
+
const RESCHEDULED = -2;
|
|
28
|
+
let sharedClock;
|
|
29
|
+
let inputError;
|
|
30
|
+
let inputFailed = false;
|
|
31
|
+
function getSharedClock() {
|
|
32
|
+
const registry = globalThis;
|
|
33
|
+
return registry[Symbol.for("phase.clock@2")] ??= {
|
|
34
|
+
rafId: null,
|
|
35
|
+
frame: 0,
|
|
36
|
+
time: 0,
|
|
37
|
+
ticks: /* @__PURE__ */ new Map(),
|
|
38
|
+
input: /* @__PURE__ */ new Map()
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function stopIfEmpty() {
|
|
42
|
+
if (sharedClock.ticks.size === 0 && sharedClock.input.size === 0 && sharedClock.rafId !== null) {
|
|
43
|
+
cancelAnimationFrame(sharedClock.rafId);
|
|
44
|
+
sharedClock.rafId = null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function dispatchInput(joinedFrame, callback) {
|
|
48
|
+
if (joinedFrame < sharedClock.frame) {
|
|
49
|
+
sharedClock.input.set(callback, EXECUTING);
|
|
50
|
+
let keep = false;
|
|
51
|
+
try {
|
|
52
|
+
keep = callback(sharedClock.time) === true;
|
|
53
|
+
} catch (error) {
|
|
54
|
+
if (!inputFailed) inputError = error;
|
|
55
|
+
inputFailed = true;
|
|
56
|
+
}
|
|
57
|
+
const state = sharedClock.input.get(callback);
|
|
58
|
+
if (state !== void 0 && (keep || state !== EXECUTING)) {
|
|
59
|
+
sharedClock.input.set(callback, sharedClock.frame);
|
|
60
|
+
scheduleFrame();
|
|
61
|
+
} else sharedClock.input.delete(callback);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function dispatchTick(joinedFrame, callback) {
|
|
65
|
+
if (joinedFrame < sharedClock.frame) callback(sharedClock.time);
|
|
66
|
+
}
|
|
67
|
+
function tick(time) {
|
|
68
|
+
sharedClock.time = time;
|
|
69
|
+
sharedClock.frame++;
|
|
70
|
+
inputFailed = false;
|
|
71
|
+
sharedClock.rafId = sharedClock.ticks.size === 0 ? null : requestAnimationFrame(tick);
|
|
72
|
+
sharedClock.input.forEach(dispatchInput);
|
|
73
|
+
const failed = inputFailed;
|
|
74
|
+
const error = inputError;
|
|
75
|
+
inputFailed = false;
|
|
76
|
+
inputError = void 0;
|
|
77
|
+
sharedClock.ticks.forEach(dispatchTick);
|
|
78
|
+
stopIfEmpty();
|
|
79
|
+
if (failed) throw error;
|
|
80
|
+
}
|
|
81
|
+
function scheduleFrame() {
|
|
82
|
+
if (sharedClock.rafId === null) sharedClock.rafId = requestAnimationFrame(tick);
|
|
83
|
+
}
|
|
84
|
+
function joinTick(callback) {
|
|
85
|
+
sharedClock ??= getSharedClock();
|
|
86
|
+
sharedClock.ticks.set(callback, sharedClock.frame);
|
|
87
|
+
scheduleFrame();
|
|
88
|
+
}
|
|
89
|
+
function leaveTick(callback) {
|
|
90
|
+
if (!sharedClock) return;
|
|
91
|
+
sharedClock.ticks.delete(callback);
|
|
92
|
+
stopIfEmpty();
|
|
93
|
+
}
|
|
94
|
+
function scheduleInput(callback) {
|
|
95
|
+
sharedClock ??= getSharedClock();
|
|
96
|
+
const state = sharedClock.input.get(callback);
|
|
97
|
+
if (state === EXECUTING) {
|
|
98
|
+
sharedClock.input.set(callback, RESCHEDULED);
|
|
99
|
+
scheduleFrame();
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (state !== void 0) return;
|
|
103
|
+
sharedClock.input.set(callback, sharedClock.frame);
|
|
104
|
+
scheduleFrame();
|
|
105
|
+
}
|
|
106
|
+
function cancelInput(callback) {
|
|
107
|
+
if (!sharedClock) return;
|
|
108
|
+
sharedClock.input.delete(callback);
|
|
109
|
+
stopIfEmpty();
|
|
110
|
+
}
|
|
111
|
+
//#endregion
|
|
25
112
|
//#region src/core/_internal/errors/index.ts
|
|
26
113
|
/** Lightweight structured error for phase. */
|
|
27
114
|
var PhaseError = class extends Error {
|
|
@@ -93,42 +180,10 @@ function missingContextError(child, parent) {
|
|
|
93
180
|
}
|
|
94
181
|
//#endregion
|
|
95
182
|
//#region src/core/tick/index.ts
|
|
96
|
-
/**
|
|
183
|
+
/** Maximum amount delta may exceed the active FPS interval. */
|
|
97
184
|
const MAX_DELTA_MS = 40;
|
|
98
185
|
/** Default first-frame delta when no previous tick exists. */
|
|
99
186
|
const DEFAULT_FIRST_DELTA_MS = 16.67;
|
|
100
|
-
let sharedClock;
|
|
101
|
-
function getSharedClock() {
|
|
102
|
-
const registry = globalThis;
|
|
103
|
-
return registry[Symbol.for("phase.clock@1")] ??= {
|
|
104
|
-
rafId: null,
|
|
105
|
-
frame: 0,
|
|
106
|
-
time: 0,
|
|
107
|
-
subscribers: /* @__PURE__ */ new Set()
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
function dispatchSharedSubscription(subscription) {
|
|
111
|
-
if (subscription.joinedFrame < sharedClock.frame) subscription.callback(sharedClock.time);
|
|
112
|
-
}
|
|
113
|
-
function sharedTick(time) {
|
|
114
|
-
sharedClock.time = time;
|
|
115
|
-
sharedClock.frame++;
|
|
116
|
-
sharedClock.rafId = requestAnimationFrame(sharedTick);
|
|
117
|
-
sharedClock.subscribers.forEach(dispatchSharedSubscription);
|
|
118
|
-
}
|
|
119
|
-
function joinSharedClock(subscription) {
|
|
120
|
-
const wasEmpty = sharedClock.subscribers.size === 0;
|
|
121
|
-
subscription.joinedFrame = sharedClock.frame;
|
|
122
|
-
sharedClock.subscribers.add(subscription);
|
|
123
|
-
if (wasEmpty) sharedClock.rafId = requestAnimationFrame(sharedTick);
|
|
124
|
-
}
|
|
125
|
-
function leaveSharedClock(subscription) {
|
|
126
|
-
sharedClock.subscribers.delete(subscription);
|
|
127
|
-
if (sharedClock.subscribers.size === 0 && sharedClock.rafId !== null) {
|
|
128
|
-
cancelAnimationFrame(sharedClock.rafId);
|
|
129
|
-
sharedClock.rafId = null;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
187
|
function resetFrameState(state) {
|
|
133
188
|
state.time = 0;
|
|
134
189
|
state.delta = 0;
|
|
@@ -153,23 +208,27 @@ function advanceDeadline(deadline, now, interval) {
|
|
|
153
208
|
return next + Math.floor(behind / interval) * interval;
|
|
154
209
|
}
|
|
155
210
|
/**
|
|
156
|
-
*
|
|
211
|
+
* Low-level requestAnimationFrame loop with an optional FPS limit and pause controls.
|
|
157
212
|
*
|
|
158
213
|
* @remarks
|
|
214
|
+
* Event-derived callbacks sharing this clock protocol run before `onTick` when
|
|
215
|
+
* queued before frame dispatch. A callback first queued during dispatch runs
|
|
216
|
+
* in the next frame; additional work can coalesce into an eligible callback
|
|
217
|
+
* that has not run yet.
|
|
218
|
+
*
|
|
159
219
|
* `FrameState` is reused across frames. Do not store a reference to it.
|
|
160
220
|
* Read values immediately in your `onTick` callback.
|
|
161
221
|
*/
|
|
162
222
|
function createTicker(options) {
|
|
163
223
|
if (typeof requestAnimationFrame === "undefined") serverContextError("createTicker");
|
|
164
|
-
sharedClock ??= getSharedClock();
|
|
165
224
|
const { onTick, signal } = options;
|
|
166
225
|
let minFrameTime = resolveMinFrameTime("createTicker", options.fps);
|
|
226
|
+
let maxDeltaTime = minFrameTime + MAX_DELTA_MS;
|
|
167
227
|
let _phase = "idle";
|
|
168
228
|
let _reason = "initial";
|
|
169
|
-
let lastTickTime =
|
|
170
|
-
let
|
|
171
|
-
let
|
|
172
|
-
let startTime = 0;
|
|
229
|
+
let lastTickTime = -1;
|
|
230
|
+
let elapsedTime = 0;
|
|
231
|
+
let frameCount = 0;
|
|
173
232
|
let nextDueTime = 0;
|
|
174
233
|
const frame = {
|
|
175
234
|
time: 0,
|
|
@@ -179,20 +238,18 @@ function createTicker(options) {
|
|
|
179
238
|
};
|
|
180
239
|
function tick(now) {
|
|
181
240
|
if (now < nextDueTime) return;
|
|
182
|
-
const isFirstDelivery = lastTickTime
|
|
183
|
-
const rawDelta = isFirstDelivery ? DEFAULT_FIRST_DELTA_MS : now - lastTickTime;
|
|
241
|
+
const isFirstDelivery = lastTickTime < 0;
|
|
242
|
+
const rawDelta = isFirstDelivery ? minFrameTime || DEFAULT_FIRST_DELTA_MS : now - lastTickTime;
|
|
184
243
|
lastTickTime = now;
|
|
185
244
|
if (minFrameTime > 0) nextDueTime = isFirstDelivery ? now + minFrameTime : advanceDeadline(nextDueTime, now, minFrameTime);
|
|
186
245
|
frame.time = now;
|
|
187
|
-
frame.delta = rawDelta >
|
|
188
|
-
frame.
|
|
189
|
-
frame.
|
|
246
|
+
frame.delta = rawDelta > maxDeltaTime ? maxDeltaTime : rawDelta;
|
|
247
|
+
elapsedTime += frame.delta;
|
|
248
|
+
frame.elapsed = elapsedTime;
|
|
249
|
+
frameCount++;
|
|
250
|
+
frame.frame = frameCount;
|
|
190
251
|
onTick(frame);
|
|
191
252
|
}
|
|
192
|
-
const subscription = {
|
|
193
|
-
callback: tick,
|
|
194
|
-
joinedFrame: 0
|
|
195
|
-
};
|
|
196
253
|
function start() {
|
|
197
254
|
if (_phase === "running") return;
|
|
198
255
|
if (_phase === "stopped") tickerStoppedError();
|
|
@@ -202,41 +259,41 @@ function createTicker(options) {
|
|
|
202
259
|
}
|
|
203
260
|
_phase = "running";
|
|
204
261
|
_reason = "started";
|
|
205
|
-
|
|
206
|
-
lastTickTime = 0;
|
|
262
|
+
lastTickTime = -1;
|
|
207
263
|
nextDueTime = 0;
|
|
208
|
-
|
|
264
|
+
elapsedTime = 0;
|
|
265
|
+
frameCount = 0;
|
|
209
266
|
resetFrameState(frame);
|
|
210
|
-
|
|
267
|
+
joinTick(tick);
|
|
211
268
|
}
|
|
212
269
|
function pause() {
|
|
213
270
|
if (_phase !== "running") return;
|
|
214
271
|
_phase = "paused";
|
|
215
272
|
_reason = "manual";
|
|
216
|
-
|
|
217
|
-
leaveSharedClock(subscription);
|
|
273
|
+
leaveTick(tick);
|
|
218
274
|
}
|
|
219
275
|
function resume() {
|
|
220
276
|
if (_phase === "stopped") tickerStoppedError();
|
|
221
277
|
if (_phase !== "paused") return;
|
|
222
|
-
|
|
223
|
-
lastTickTime = 0;
|
|
278
|
+
lastTickTime = -1;
|
|
224
279
|
nextDueTime = 0;
|
|
225
280
|
_phase = "running";
|
|
226
281
|
_reason = "resumed";
|
|
227
|
-
|
|
282
|
+
joinTick(tick);
|
|
228
283
|
}
|
|
229
284
|
function setFps(fps) {
|
|
230
285
|
if (_phase === "stopped") tickerStoppedError();
|
|
231
|
-
|
|
232
|
-
|
|
286
|
+
const nextMinFrameTime = resolveMinFrameTime("setFps", fps);
|
|
287
|
+
minFrameTime = nextMinFrameTime;
|
|
288
|
+
maxDeltaTime = nextMinFrameTime + MAX_DELTA_MS;
|
|
289
|
+
nextDueTime = lastTickTime < 0 ? 0 : lastTickTime + minFrameTime;
|
|
233
290
|
}
|
|
234
291
|
function stop() {
|
|
235
292
|
if (_phase === "stopped") return;
|
|
236
293
|
_phase = "stopped";
|
|
237
294
|
_reason = _reason === "initial" ? "disposed" : "manual";
|
|
238
295
|
unlinkAbort?.();
|
|
239
|
-
|
|
296
|
+
leaveTick(tick);
|
|
240
297
|
}
|
|
241
298
|
let unlinkAbort;
|
|
242
299
|
unlinkAbort = linkAbortSignal(signal, stop);
|
|
@@ -1057,7 +1114,6 @@ function createMutation(options) {
|
|
|
1057
1114
|
let _reason = "initial";
|
|
1058
1115
|
let stopped = false;
|
|
1059
1116
|
let pendingRecords = [];
|
|
1060
|
-
let rafId = 0;
|
|
1061
1117
|
function setPhase(phase, reason) {
|
|
1062
1118
|
const prev = _phase;
|
|
1063
1119
|
_phase = phase;
|
|
@@ -1065,20 +1121,15 @@ function createMutation(options) {
|
|
|
1065
1121
|
if (prev !== phase) onPhaseChange?.(phase, reason);
|
|
1066
1122
|
}
|
|
1067
1123
|
function flushRecords() {
|
|
1068
|
-
rafId = 0;
|
|
1069
1124
|
if (stopped || pendingRecords.length === 0) return;
|
|
1070
1125
|
const batch = pendingRecords;
|
|
1071
1126
|
pendingRecords = [];
|
|
1072
1127
|
onMutations(batch);
|
|
1073
1128
|
}
|
|
1074
|
-
function scheduleFlush() {
|
|
1075
|
-
if (rafId !== 0) return;
|
|
1076
|
-
rafId = requestAnimationFrame(flushRecords);
|
|
1077
|
-
}
|
|
1078
1129
|
const mo = new MutationObserver((records) => {
|
|
1079
1130
|
if (stopped || _phase !== "observing") return;
|
|
1080
1131
|
for (let i = 0, len = records.length; i < len; i++) pendingRecords[pendingRecords.length] = records[i];
|
|
1081
|
-
|
|
1132
|
+
scheduleInput(flushRecords);
|
|
1082
1133
|
});
|
|
1083
1134
|
function startObserving() {
|
|
1084
1135
|
if (stopped || _phase === "observing") return;
|
|
@@ -1089,10 +1140,7 @@ function createMutation(options) {
|
|
|
1089
1140
|
if (stopped || _phase === "paused") return;
|
|
1090
1141
|
setPhase("paused", reason);
|
|
1091
1142
|
mo.disconnect();
|
|
1092
|
-
|
|
1093
|
-
cancelAnimationFrame(rafId);
|
|
1094
|
-
rafId = 0;
|
|
1095
|
-
}
|
|
1143
|
+
cancelInput(flushRecords);
|
|
1096
1144
|
pendingRecords = [];
|
|
1097
1145
|
}
|
|
1098
1146
|
let cleanupVisibility;
|
|
@@ -1136,10 +1184,7 @@ function createMutation(options) {
|
|
|
1136
1184
|
unlinkAbort?.();
|
|
1137
1185
|
cleanupVisibility?.();
|
|
1138
1186
|
mo.disconnect();
|
|
1139
|
-
|
|
1140
|
-
cancelAnimationFrame(rafId);
|
|
1141
|
-
rafId = 0;
|
|
1142
|
-
}
|
|
1187
|
+
cancelInput(flushRecords);
|
|
1143
1188
|
pendingRecords = [];
|
|
1144
1189
|
setPhase("stopped", "disposed");
|
|
1145
1190
|
}
|
|
@@ -1178,7 +1223,6 @@ function createPointer(options) {
|
|
|
1178
1223
|
y: 0,
|
|
1179
1224
|
active: false
|
|
1180
1225
|
};
|
|
1181
|
-
let rafId = 0;
|
|
1182
1226
|
let lastClientX = 0;
|
|
1183
1227
|
let lastClientY = 0;
|
|
1184
1228
|
let dirty = false;
|
|
@@ -1189,7 +1233,6 @@ function createPointer(options) {
|
|
|
1189
1233
|
if (prev !== phase) onPhaseChange?.(phase, reason);
|
|
1190
1234
|
}
|
|
1191
1235
|
function flush() {
|
|
1192
|
-
rafId = 0;
|
|
1193
1236
|
if (!dirty || stopped) return;
|
|
1194
1237
|
dirty = false;
|
|
1195
1238
|
const rect = element.getBoundingClientRect();
|
|
@@ -1197,15 +1240,8 @@ function createPointer(options) {
|
|
|
1197
1240
|
_state.y = lastClientY - rect.top;
|
|
1198
1241
|
onPointer(_state);
|
|
1199
1242
|
}
|
|
1200
|
-
function scheduleFlush() {
|
|
1201
|
-
if (rafId !== 0) return;
|
|
1202
|
-
rafId = requestAnimationFrame(flush);
|
|
1203
|
-
}
|
|
1204
1243
|
function cancelFlush() {
|
|
1205
|
-
|
|
1206
|
-
cancelAnimationFrame(rafId);
|
|
1207
|
-
rafId = 0;
|
|
1208
|
-
}
|
|
1244
|
+
cancelInput(flush);
|
|
1209
1245
|
dirty = false;
|
|
1210
1246
|
}
|
|
1211
1247
|
function onPointerMove(e) {
|
|
@@ -1214,7 +1250,7 @@ function createPointer(options) {
|
|
|
1214
1250
|
lastClientX = pe.clientX;
|
|
1215
1251
|
lastClientY = pe.clientY;
|
|
1216
1252
|
dirty = true;
|
|
1217
|
-
|
|
1253
|
+
scheduleInput(flush);
|
|
1218
1254
|
}
|
|
1219
1255
|
function onPointerEnter() {
|
|
1220
1256
|
if (stopped) return;
|
|
@@ -1399,7 +1435,6 @@ function createScroll(options) {
|
|
|
1399
1435
|
visibleX: 1,
|
|
1400
1436
|
visibleY: 1
|
|
1401
1437
|
};
|
|
1402
|
-
let rafId = 0;
|
|
1403
1438
|
let dirty = false;
|
|
1404
1439
|
let geometryDirty = false;
|
|
1405
1440
|
let listenersAttached = false;
|
|
@@ -1439,7 +1474,6 @@ function createScroll(options) {
|
|
|
1439
1474
|
onScroll(_state);
|
|
1440
1475
|
}
|
|
1441
1476
|
function flush() {
|
|
1442
|
-
rafId = 0;
|
|
1443
1477
|
if (stopped || !dirty && !geometryDirty) return;
|
|
1444
1478
|
if (geometryDirty) {
|
|
1445
1479
|
geometryDirty = false;
|
|
@@ -1449,27 +1483,20 @@ function createScroll(options) {
|
|
|
1449
1483
|
computePosition();
|
|
1450
1484
|
onScroll(_state);
|
|
1451
1485
|
}
|
|
1452
|
-
function scheduleFlush() {
|
|
1453
|
-
if (rafId !== 0) return;
|
|
1454
|
-
rafId = requestAnimationFrame(flush);
|
|
1455
|
-
}
|
|
1456
1486
|
function cancelFlush() {
|
|
1457
|
-
|
|
1458
|
-
cancelAnimationFrame(rafId);
|
|
1459
|
-
rafId = 0;
|
|
1460
|
-
}
|
|
1487
|
+
cancelInput(flush);
|
|
1461
1488
|
dirty = false;
|
|
1462
1489
|
geometryDirty = false;
|
|
1463
1490
|
}
|
|
1464
1491
|
function onScrollEvent() {
|
|
1465
1492
|
if (stopped) return;
|
|
1466
1493
|
dirty = true;
|
|
1467
|
-
|
|
1494
|
+
scheduleInput(flush);
|
|
1468
1495
|
}
|
|
1469
1496
|
function onROResize() {
|
|
1470
1497
|
if (stopped || !listenersAttached) return;
|
|
1471
1498
|
geometryDirty = true;
|
|
1472
|
-
|
|
1499
|
+
scheduleInput(flush);
|
|
1473
1500
|
}
|
|
1474
1501
|
function attachListeners() {
|
|
1475
1502
|
if (listenersAttached) return;
|
|
@@ -1584,7 +1611,6 @@ function createThrottle(options) {
|
|
|
1584
1611
|
let stopped = false;
|
|
1585
1612
|
let pending = false;
|
|
1586
1613
|
let lastFire = 0;
|
|
1587
|
-
let rafId = 0;
|
|
1588
1614
|
let documentVisible = !document.hidden;
|
|
1589
1615
|
let latest = void 0;
|
|
1590
1616
|
function fire(now) {
|
|
@@ -1592,21 +1618,11 @@ function createThrottle(options) {
|
|
|
1592
1618
|
pending = false;
|
|
1593
1619
|
callback(latest);
|
|
1594
1620
|
}
|
|
1595
|
-
function
|
|
1596
|
-
if (rafId !== 0) {
|
|
1597
|
-
cancelAnimationFrame(rafId);
|
|
1598
|
-
rafId = 0;
|
|
1599
|
-
}
|
|
1600
|
-
}
|
|
1601
|
-
function tick() {
|
|
1602
|
-
rafId = 0;
|
|
1621
|
+
function flushWhenDue() {
|
|
1603
1622
|
if (stopped || !pending) return;
|
|
1604
1623
|
const now = performance.now();
|
|
1605
1624
|
if (now - lastFire >= interval) fire(now);
|
|
1606
|
-
else
|
|
1607
|
-
}
|
|
1608
|
-
function scheduleRaf() {
|
|
1609
|
-
if (rafId === 0) rafId = requestAnimationFrame(tick);
|
|
1625
|
+
else return true;
|
|
1610
1626
|
}
|
|
1611
1627
|
function call(value) {
|
|
1612
1628
|
if (stopped) return;
|
|
@@ -1625,17 +1641,17 @@ function createThrottle(options) {
|
|
|
1625
1641
|
}
|
|
1626
1642
|
if (trailing) {
|
|
1627
1643
|
pending = true;
|
|
1628
|
-
|
|
1644
|
+
scheduleInput(flushWhenDue);
|
|
1629
1645
|
}
|
|
1630
1646
|
}
|
|
1631
1647
|
function flush() {
|
|
1632
1648
|
if (stopped || !pending) return;
|
|
1633
|
-
|
|
1649
|
+
cancelInput(flushWhenDue);
|
|
1634
1650
|
fire(performance.now());
|
|
1635
1651
|
}
|
|
1636
1652
|
function cancel() {
|
|
1637
1653
|
if (stopped) return;
|
|
1638
|
-
|
|
1654
|
+
cancelInput(flushWhenDue);
|
|
1639
1655
|
pending = false;
|
|
1640
1656
|
lastFire = 0;
|
|
1641
1657
|
}
|
|
@@ -1643,15 +1659,15 @@ function createThrottle(options) {
|
|
|
1643
1659
|
documentVisible = !document.hidden;
|
|
1644
1660
|
if (stopped) return;
|
|
1645
1661
|
if (!documentVisible) {
|
|
1646
|
-
|
|
1662
|
+
cancelInput(flushWhenDue);
|
|
1647
1663
|
if (pending) if (hidden === "flush") fire(performance.now());
|
|
1648
1664
|
else pending = false;
|
|
1649
|
-
} else if (pending)
|
|
1665
|
+
} else if (pending) scheduleInput(flushWhenDue);
|
|
1650
1666
|
}
|
|
1651
1667
|
function onPageShow(event) {
|
|
1652
1668
|
if (!event.persisted) return;
|
|
1653
1669
|
documentVisible = true;
|
|
1654
|
-
if (!stopped && pending)
|
|
1670
|
+
if (!stopped && pending) scheduleInput(flushWhenDue);
|
|
1655
1671
|
}
|
|
1656
1672
|
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
1657
1673
|
window.addEventListener("pageshow", onPageShow);
|
|
@@ -1662,7 +1678,7 @@ function createThrottle(options) {
|
|
|
1662
1678
|
unlinkAbort?.();
|
|
1663
1679
|
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
1664
1680
|
window.removeEventListener("pageshow", onPageShow);
|
|
1665
|
-
|
|
1681
|
+
cancelInput(flushWhenDue);
|
|
1666
1682
|
pending = false;
|
|
1667
1683
|
}
|
|
1668
1684
|
unlinkAbort = linkAbortSignal(signal, stop);
|
|
@@ -1768,4 +1784,4 @@ function createDebounce(options) {
|
|
|
1768
1784
|
//#endregion
|
|
1769
1785
|
export { isPhaseError as C, linkAbortSignal as E, invalidDurationError as S, serverContextError as T, subscribeMediaQuery as _, createPointer as a, PhaseError as b, prefersReducedMotion as c, subscribeDpr as d, createRenderState as f, readMediaQuery as g, createLifecycle as h, observeResize as i, whenIdle as l, createLoop as m, createThrottle as n, createMutation as o, createScrollProgress as p, createScroll as r, REDUCED_MOTION_QUERY as s, createDebounce as t, readDpr as u, createSight as v, missingContextError as w, conflictingTargetError as x, createTicker as y };
|
|
1770
1786
|
|
|
1771
|
-
//# sourceMappingURL=debounce-
|
|
1787
|
+
//# sourceMappingURL=debounce-CJYqsSXm.js.map
|