react-native-tapline 0.0.0-stage → 1.1.0
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/LICENSE +21 -0
- package/README.md +86 -2
- package/TaplineNative.podspec +14 -0
- package/dist/actions.d.ts +203 -0
- package/dist/actions.js +1991 -0
- package/dist/actions.js.map +1 -0
- package/dist/agent.d.ts +117 -0
- package/dist/agent.js +352 -0
- package/dist/agent.js.map +1 -0
- package/dist/alerts.d.ts +35 -0
- package/dist/alerts.js +437 -0
- package/dist/alerts.js.map +1 -0
- package/dist/awake.d.ts +2 -0
- package/dist/awake.js +53 -0
- package/dist/awake.js.map +1 -0
- package/dist/checks.d.ts +35 -0
- package/dist/checks.js +501 -0
- package/dist/checks.js.map +1 -0
- package/dist/client.d.ts +111 -0
- package/dist/client.js +446 -0
- package/dist/client.js.map +1 -0
- package/dist/commands.d.ts +24 -0
- package/dist/commands.js +111 -0
- package/dist/commands.js.map +1 -0
- package/dist/events.d.ts +5 -0
- package/dist/events.js +22 -0
- package/dist/events.js.map +1 -0
- package/dist/feed.d.ts +117 -0
- package/dist/feed.js +440 -0
- package/dist/feed.js.map +1 -0
- package/dist/fiber.d.ts +43 -0
- package/dist/fiber.js +100 -0
- package/dist/fiber.js.map +1 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.js +181 -0
- package/dist/index.js.map +1 -0
- package/dist/inspect.d.ts +249 -0
- package/dist/inspect.js +1354 -0
- package/dist/inspect.js.map +1 -0
- package/dist/keyboard.d.ts +10 -0
- package/dist/keyboard.js +63 -0
- package/dist/keyboard.js.map +1 -0
- package/dist/link.d.ts +21 -0
- package/dist/link.js +63 -0
- package/dist/link.js.map +1 -0
- package/dist/live.d.ts +30 -0
- package/dist/live.js +279 -0
- package/dist/live.js.map +1 -0
- package/dist/logs.d.ts +16 -0
- package/dist/logs.js +171 -0
- package/dist/logs.js.map +1 -0
- package/dist/methods.d.ts +3 -0
- package/dist/methods.js +49 -0
- package/dist/methods.js.map +1 -0
- package/dist/native.d.ts +34 -0
- package/dist/native.js +63 -0
- package/dist/native.js.map +1 -0
- package/dist/network.d.ts +27 -0
- package/dist/network.js +238 -0
- package/dist/network.js.map +1 -0
- package/dist/register.d.ts +24 -0
- package/dist/register.js +180 -0
- package/dist/register.js.map +1 -0
- package/dist/settle.d.ts +27 -0
- package/dist/settle.js +70 -0
- package/dist/settle.js.map +1 -0
- package/dist/source.d.ts +60 -0
- package/dist/source.js +214 -0
- package/dist/source.js.map +1 -0
- package/dist/storage.d.ts +10 -0
- package/dist/storage.js +45 -0
- package/dist/storage.js.map +1 -0
- package/dist/touches.d.ts +15 -0
- package/dist/touches.js +89 -0
- package/dist/touches.js.map +1 -0
- package/dist/types.d.ts +168 -0
- package/dist/types.js +32 -0
- package/dist/types.js.map +1 -0
- package/dist/wait.d.ts +8 -0
- package/dist/wait.js +99 -0
- package/dist/wait.js.map +1 -0
- package/expo-module.config.json +7 -0
- package/ios/TaplineNativeModule.swift +79 -0
- package/metro.d.ts +26 -0
- package/metro.js +146 -0
- package/package.json +100 -4
- package/register.d.ts +1 -0
- package/register.js +3 -0
package/dist/feed.d.ts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The in-app side of the live viewer: captures the app's own screen when the UI
|
|
3
|
+
* changes (not at a fixed rate), plus a slow heartbeat, and hands each frame to a
|
|
4
|
+
* sender. After an action (`requestFrame`) it waits for the action's commit, captures
|
|
5
|
+
* right after it, and keeps capturing at a shorter gap for a burst so a transition
|
|
6
|
+
* shows. Capturing can make the app stutter, so it also measures animation-frame
|
|
7
|
+
* jank while the feed runs. Everything the feed needs from the outside is injected
|
|
8
|
+
* (`FeedDeps`), so it runs against a fake clock in tests.
|
|
9
|
+
*
|
|
10
|
+
* This file must not import react or react-native.
|
|
11
|
+
*/
|
|
12
|
+
export type QualityPreset = 'sharp' | 'balanced' | 'light';
|
|
13
|
+
interface CaptureParams {
|
|
14
|
+
format: 'jpg';
|
|
15
|
+
quality: number;
|
|
16
|
+
maxWidth: number;
|
|
17
|
+
}
|
|
18
|
+
export interface FeedFrame {
|
|
19
|
+
/** 1, 2, 3, ... in the order frames are sent. */
|
|
20
|
+
seq: number;
|
|
21
|
+
/** The commit revision when the capture started. */
|
|
22
|
+
rev: number;
|
|
23
|
+
/** now() when the capture started. */
|
|
24
|
+
capturedAt: number;
|
|
25
|
+
/** How long the capture took, in ms. */
|
|
26
|
+
captureMs: number;
|
|
27
|
+
mime: string;
|
|
28
|
+
/** Base64 image data. */
|
|
29
|
+
data: string;
|
|
30
|
+
width?: number;
|
|
31
|
+
height?: number;
|
|
32
|
+
}
|
|
33
|
+
export interface FeedStats {
|
|
34
|
+
/** Frames sent. */
|
|
35
|
+
frames: number;
|
|
36
|
+
avgCaptureMs: number;
|
|
37
|
+
maxCaptureMs: number;
|
|
38
|
+
/** Animation frames seen while the feed ran. */
|
|
39
|
+
observedFrames: number;
|
|
40
|
+
/** Animation frames that came more than 50 ms after the previous one. */
|
|
41
|
+
janky: number;
|
|
42
|
+
/** Of those, how many happened while a capture was in flight. */
|
|
43
|
+
jankyWhileCapturing: number;
|
|
44
|
+
/** Captures that failed, and the last failure's message. */
|
|
45
|
+
failures: number;
|
|
46
|
+
lastFailure?: string;
|
|
47
|
+
/** Captures the heartbeat started (nothing else asked for one within heartbeatMs). */
|
|
48
|
+
heartbeats: number;
|
|
49
|
+
/** Times a slow frame near a capture widened the gap between captures. */
|
|
50
|
+
backoffs: number;
|
|
51
|
+
}
|
|
52
|
+
export interface FeedDeps {
|
|
53
|
+
capture: (params: CaptureParams) => Promise<{
|
|
54
|
+
mime: string;
|
|
55
|
+
data: string;
|
|
56
|
+
width?: number;
|
|
57
|
+
height?: number;
|
|
58
|
+
}>;
|
|
59
|
+
send: (frame: FeedFrame) => void;
|
|
60
|
+
onCommit: (listener: (revision: number) => void) => () => void;
|
|
61
|
+
commitRevision: () => number;
|
|
62
|
+
now: () => number;
|
|
63
|
+
setTimer: (fn: () => void, ms: number) => unknown;
|
|
64
|
+
clearTimer: (handle: unknown) => void;
|
|
65
|
+
requestAnimationFrame?: (fn: (t: number) => void) => unknown;
|
|
66
|
+
cancelAnimationFrame?: (handle: unknown) => void;
|
|
67
|
+
/**
|
|
68
|
+
* Whether the link can take another frame now (flow control): false while earlier frames are
|
|
69
|
+
* still on their way to the host. A capture that is due then waits and is tried again shortly.
|
|
70
|
+
*/
|
|
71
|
+
canSend?: () => boolean;
|
|
72
|
+
}
|
|
73
|
+
export interface FeedOptions {
|
|
74
|
+
quality?: QualityPreset;
|
|
75
|
+
/** Quiet time to wait after the last commit before capturing (default 250). */
|
|
76
|
+
settleMs?: number;
|
|
77
|
+
/** The least time between the starts of two captures (default 350). */
|
|
78
|
+
minIntervalMs?: number;
|
|
79
|
+
/** Capture a frame if none was sent for this long (default 1000). */
|
|
80
|
+
heartbeatMs?: number;
|
|
81
|
+
/** After requestFrame, keep capturing (every burstIntervalMs) for this long, so a transition shows (default 1200). */
|
|
82
|
+
burstMs?: number;
|
|
83
|
+
/** During a burst, the least time between the starts of two captures (default 150). */
|
|
84
|
+
burstIntervalMs?: number;
|
|
85
|
+
/** After the commit that shows an action's result, wait this long before capturing (default 16). */
|
|
86
|
+
commitDelayMs?: number;
|
|
87
|
+
/** After requestFrame, capture anyway if no commit arrived within this time (default 120). */
|
|
88
|
+
actionWaitMs?: number;
|
|
89
|
+
/** Outside a burst, capture at the latest this long after the first unseen commit, even if commits keep coming (default 400). */
|
|
90
|
+
maxWaitMs?: number;
|
|
91
|
+
/**
|
|
92
|
+
* The largest share of the time captures may take: the gap between capture starts is at least the
|
|
93
|
+
* recent capture time divided by this (0.33: a 30 ms capture allows one every 90 ms). Off when unset.
|
|
94
|
+
*/
|
|
95
|
+
dutyCycle?: number;
|
|
96
|
+
/**
|
|
97
|
+
* Back off when capturing makes the app stutter: from the second animation frame slower than 50 ms
|
|
98
|
+
* during or right after a capture (within 20 clean captures), each one doubles the gap (up to this
|
|
99
|
+
* many ms); each clean capture shrinks it again. Off when unset.
|
|
100
|
+
*/
|
|
101
|
+
backoffMaxMs?: number;
|
|
102
|
+
/**
|
|
103
|
+
* With backoffMaxMs: the gap the first few slow frames give (the second to the fourth within 20
|
|
104
|
+
* clean captures); only from the fifth does the gap double. Unset: it doubles from the second.
|
|
105
|
+
*/
|
|
106
|
+
backoffSoftMs?: number;
|
|
107
|
+
}
|
|
108
|
+
export interface FrameFeed {
|
|
109
|
+
/** Stop everything; nothing fires afterwards. Safe to call twice. */
|
|
110
|
+
stop(): void;
|
|
111
|
+
/** Call right after an action: captures once its result is rendered (or after actionWaitMs), then keeps capturing for a burst. */
|
|
112
|
+
requestFrame(): void;
|
|
113
|
+
setQuality(preset: QualityPreset): void;
|
|
114
|
+
stats(): FeedStats;
|
|
115
|
+
}
|
|
116
|
+
export declare function startFrameFeed(options: FeedOptions, deps: FeedDeps): FrameFeed;
|
|
117
|
+
export {};
|
package/dist/feed.js
ADDED
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The in-app side of the live viewer: captures the app's own screen when the UI
|
|
4
|
+
* changes (not at a fixed rate), plus a slow heartbeat, and hands each frame to a
|
|
5
|
+
* sender. After an action (`requestFrame`) it waits for the action's commit, captures
|
|
6
|
+
* right after it, and keeps capturing at a shorter gap for a burst so a transition
|
|
7
|
+
* shows. Capturing can make the app stutter, so it also measures animation-frame
|
|
8
|
+
* jank while the feed runs. Everything the feed needs from the outside is injected
|
|
9
|
+
* (`FeedDeps`), so it runs against a fake clock in tests.
|
|
10
|
+
*
|
|
11
|
+
* This file must not import react or react-native.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.startFrameFeed = startFrameFeed;
|
|
15
|
+
// QUALITY-BAR V5: sharp ≥ 2.0, balanced ≥ 1.5, light ≥ 0.75 px per point, met on the widest iPhone
|
|
16
|
+
// (440 pt); narrower phones get a little more.
|
|
17
|
+
const PRESETS = {
|
|
18
|
+
sharp: { format: 'jpg', quality: 0.75, maxWidth: 880 },
|
|
19
|
+
balanced: { format: 'jpg', quality: 0.6, maxWidth: 660 },
|
|
20
|
+
light: { format: 'jpg', quality: 0.5, maxWidth: 330 },
|
|
21
|
+
};
|
|
22
|
+
/** How soon a capture held back by `canSend` is tried again. */
|
|
23
|
+
const FLOW_RETRY_MS = 10;
|
|
24
|
+
const DEFAULT_SETTLE_MS = 250;
|
|
25
|
+
const DEFAULT_MIN_INTERVAL_MS = 350;
|
|
26
|
+
const DEFAULT_HEARTBEAT_MS = 1000;
|
|
27
|
+
const DEFAULT_BURST_MS = 1200;
|
|
28
|
+
const DEFAULT_BURST_INTERVAL_MS = 150;
|
|
29
|
+
const DEFAULT_COMMIT_DELAY_MS = 16;
|
|
30
|
+
const DEFAULT_ACTION_WAIT_MS = 120;
|
|
31
|
+
const DEFAULT_MAX_WAIT_MS = 400;
|
|
32
|
+
/** After this many failed captures in a row, only the heartbeat tries again. */
|
|
33
|
+
const MAX_FAILURES_IN_A_ROW = 3;
|
|
34
|
+
/** An animation frame longer than this counts as a stutter. */
|
|
35
|
+
const JANK_MS = 50;
|
|
36
|
+
/** Weight of the newest capture in the recent capture time. */
|
|
37
|
+
const CAPTURE_TIME_WEIGHT = 0.3;
|
|
38
|
+
/** Each clean capture shrinks the backoff to this share; below the plain gap it ends. */
|
|
39
|
+
const BACKOFF_DECAY = 0.85;
|
|
40
|
+
/** The backoff starts at the second slow frame near a capture... */
|
|
41
|
+
const BACKOFF_STRIKES = 2;
|
|
42
|
+
/** ...counted since this many clean captures in a row. */
|
|
43
|
+
const BACKOFF_FORGET_AFTER = 20;
|
|
44
|
+
/** With backoffSoftMs, the gap only doubles from this many slow frames near captures. */
|
|
45
|
+
const BACKOFF_HARD_STRIKES = 5;
|
|
46
|
+
function safely(fn) {
|
|
47
|
+
try {
|
|
48
|
+
fn();
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// never break the app because of the feed
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function startFrameFeed(options, deps) {
|
|
55
|
+
const settleMs = options.settleMs ?? DEFAULT_SETTLE_MS;
|
|
56
|
+
const minIntervalMs = options.minIntervalMs ?? DEFAULT_MIN_INTERVAL_MS;
|
|
57
|
+
const heartbeatMs = options.heartbeatMs ?? DEFAULT_HEARTBEAT_MS;
|
|
58
|
+
const burstMs = options.burstMs ?? DEFAULT_BURST_MS;
|
|
59
|
+
const burstIntervalMs = options.burstIntervalMs ?? DEFAULT_BURST_INTERVAL_MS;
|
|
60
|
+
const commitDelayMs = options.commitDelayMs ?? DEFAULT_COMMIT_DELAY_MS;
|
|
61
|
+
const actionWaitMs = options.actionWaitMs ?? DEFAULT_ACTION_WAIT_MS;
|
|
62
|
+
const maxWaitMs = options.maxWaitMs ?? DEFAULT_MAX_WAIT_MS;
|
|
63
|
+
const dutyCycle = options.dutyCycle !== undefined && options.dutyCycle > 0 ? options.dutyCycle : undefined;
|
|
64
|
+
const backoffMaxMs = options.backoffMaxMs;
|
|
65
|
+
const backoffSoftMs = options.backoffSoftMs;
|
|
66
|
+
let backoffs = 0;
|
|
67
|
+
let preset = options.quality ?? 'balanced';
|
|
68
|
+
/** Recent capture time in ms (a moving average), or null before the first frame. */
|
|
69
|
+
let recentCaptureMs = null;
|
|
70
|
+
/** The stutter backoff: the gap between capture starts is at least this (0: none). */
|
|
71
|
+
let backoffMs = 0;
|
|
72
|
+
/** A slow animation frame was seen during (or right after) the current capture. */
|
|
73
|
+
let jankThisCapture = false;
|
|
74
|
+
/** Slow frames near a capture since the last BACKOFF_FORGET_AFTER clean captures in a row. */
|
|
75
|
+
let jankStrikes = 0;
|
|
76
|
+
let cleanInARow = 0;
|
|
77
|
+
let lastFinishAt = Number.NEGATIVE_INFINITY;
|
|
78
|
+
/** The first commit since the last capture started (null: none yet). */
|
|
79
|
+
let pendingSince = null;
|
|
80
|
+
/** Until when requestFrame's burst keeps capturing. */
|
|
81
|
+
let burstUntil = Number.NEGATIVE_INFINITY;
|
|
82
|
+
let stopped = false;
|
|
83
|
+
let capturing = false;
|
|
84
|
+
/** A change (or request) arrived since the last capture started. */
|
|
85
|
+
let pending = false;
|
|
86
|
+
/** The pending capture follows a burst capture: no settle wait, only the burst gap. */
|
|
87
|
+
let wantNow = false;
|
|
88
|
+
/** requestFrame was called and the action's result has not been captured yet. */
|
|
89
|
+
let waitingForAction = false;
|
|
90
|
+
/** A commit arrived since requestFrame (it already set actionDueAt). */
|
|
91
|
+
let actionCommitSeen = false;
|
|
92
|
+
/** When the action's capture is due: the fallback, or the first commit plus commitDelayMs. */
|
|
93
|
+
let actionDueAt = Number.POSITIVE_INFINITY;
|
|
94
|
+
/** requestFrame armed the once-per-action skip: the first commit after it is the action's result. */
|
|
95
|
+
let resultSkipArmed = false;
|
|
96
|
+
/** When the capture for the action's result commit is due (ignores the burst gap), or null. */
|
|
97
|
+
let resultDueAt = null;
|
|
98
|
+
let lastCommitAt = Number.NEGATIVE_INFINITY;
|
|
99
|
+
let lastStartAt = Number.NEGATIVE_INFINITY;
|
|
100
|
+
let failuresInARow = 0;
|
|
101
|
+
let seq = 0;
|
|
102
|
+
let captureTimer = null;
|
|
103
|
+
let hasCaptureTimer = false;
|
|
104
|
+
let heartbeatTimer = null;
|
|
105
|
+
let hasHeartbeatTimer = false;
|
|
106
|
+
let unsubscribe = null;
|
|
107
|
+
let rafHandle = null;
|
|
108
|
+
let hasRafHandle = false;
|
|
109
|
+
let lastFrameTime = null;
|
|
110
|
+
let frames = 0;
|
|
111
|
+
let totalCaptureMs = 0;
|
|
112
|
+
let maxCaptureMs = 0;
|
|
113
|
+
let observedFrames = 0;
|
|
114
|
+
let janky = 0;
|
|
115
|
+
let jankyWhileCapturing = 0;
|
|
116
|
+
let failures = 0;
|
|
117
|
+
let lastFailure;
|
|
118
|
+
let heartbeats = 0;
|
|
119
|
+
function clearCaptureTimer() {
|
|
120
|
+
if (!hasCaptureTimer)
|
|
121
|
+
return;
|
|
122
|
+
const handle = captureTimer;
|
|
123
|
+
captureTimer = null;
|
|
124
|
+
hasCaptureTimer = false;
|
|
125
|
+
safely(() => deps.clearTimer(handle));
|
|
126
|
+
}
|
|
127
|
+
function clearHeartbeatTimer() {
|
|
128
|
+
if (!hasHeartbeatTimer)
|
|
129
|
+
return;
|
|
130
|
+
const handle = heartbeatTimer;
|
|
131
|
+
heartbeatTimer = null;
|
|
132
|
+
hasHeartbeatTimer = false;
|
|
133
|
+
safely(() => deps.clearTimer(handle));
|
|
134
|
+
}
|
|
135
|
+
function armHeartbeat() {
|
|
136
|
+
clearHeartbeatTimer();
|
|
137
|
+
if (stopped)
|
|
138
|
+
return;
|
|
139
|
+
safely(() => {
|
|
140
|
+
heartbeatTimer = deps.setTimer(onHeartbeat, heartbeatMs);
|
|
141
|
+
hasHeartbeatTimer = true;
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
function onHeartbeat() {
|
|
145
|
+
heartbeatTimer = null;
|
|
146
|
+
hasHeartbeatTimer = false;
|
|
147
|
+
if (stopped)
|
|
148
|
+
return;
|
|
149
|
+
// An action's capture is on its way (within actionWaitMs); it will do. The bound
|
|
150
|
+
// keeps a stuck waiting state from blocking the heartbeat for good.
|
|
151
|
+
if (capturing || (waitingForAction && deps.now() <= actionDueAt + heartbeatMs)) {
|
|
152
|
+
armHeartbeat();
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
heartbeats += 1;
|
|
156
|
+
startCapture();
|
|
157
|
+
}
|
|
158
|
+
/** The gap between capture starts: the plain gap, widened by the capture-time budget and the backoff. */
|
|
159
|
+
function paced(base) {
|
|
160
|
+
let gap = base;
|
|
161
|
+
if (dutyCycle !== undefined && recentCaptureMs !== null)
|
|
162
|
+
gap = Math.max(gap, recentCaptureMs / dutyCycle);
|
|
163
|
+
return Math.max(gap, backoffMs);
|
|
164
|
+
}
|
|
165
|
+
function onCaptureJank() {
|
|
166
|
+
jankThisCapture = true;
|
|
167
|
+
cleanInARow = 0;
|
|
168
|
+
jankStrikes += 1;
|
|
169
|
+
// One slow frame can be anything (a GC, the app's own work); stutter that captures cause comes back.
|
|
170
|
+
if (backoffMaxMs === undefined || jankStrikes < BACKOFF_STRIKES)
|
|
171
|
+
return;
|
|
172
|
+
backoffs += 1;
|
|
173
|
+
// The first few slow frames only widen the gap a little: they are rare and usually not the
|
|
174
|
+
// capture's doing, and doubling the gap at once made the picture stall (V3) for nothing.
|
|
175
|
+
if (backoffSoftMs !== undefined && jankStrikes < BACKOFF_HARD_STRIKES) {
|
|
176
|
+
backoffMs = Math.max(backoffMs, Math.min(backoffMaxMs, backoffSoftMs));
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
backoffMs = Math.min(backoffMaxMs, Math.max(backoffMs * 2, minIntervalMs * 2));
|
|
180
|
+
}
|
|
181
|
+
/** (Re)schedule the capture a pending change is waiting for. */
|
|
182
|
+
function reschedule() {
|
|
183
|
+
if (stopped || capturing || !pending || failuresInARow >= MAX_FAILURES_IN_A_ROW)
|
|
184
|
+
return;
|
|
185
|
+
clearCaptureTimer();
|
|
186
|
+
safely(() => {
|
|
187
|
+
const now = deps.now();
|
|
188
|
+
const inBurst = now < burstUntil;
|
|
189
|
+
const gap = paced(inBurst ? burstIntervalMs : minIntervalMs);
|
|
190
|
+
// A result capture that no capture covered (a heartbeat started first) goes stale once the burst ends.
|
|
191
|
+
if (!inBurst)
|
|
192
|
+
resultDueAt = null;
|
|
193
|
+
if (resultDueAt !== null) {
|
|
194
|
+
// The action's result commit: no burst gap, only the commit delay (and the capture in flight, handled by `capturing`).
|
|
195
|
+
captureTimer = deps.setTimer(onCaptureTimer, Math.max(0, resultDueAt - now));
|
|
196
|
+
hasCaptureTimer = true;
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
// The commit delay counts from the first commit not yet captured: on a 120 Hz screen commits
|
|
200
|
+
// come every 8 ms, so counting from the latest would push the capture back for as long as
|
|
201
|
+
// the screen keeps changing.
|
|
202
|
+
const firstUnseen = pendingSince ?? lastCommitAt;
|
|
203
|
+
let readyAt;
|
|
204
|
+
if (waitingForAction)
|
|
205
|
+
readyAt = actionDueAt;
|
|
206
|
+
else if (wantNow)
|
|
207
|
+
readyAt = lastCommitAt > lastStartAt ? firstUnseen + commitDelayMs : Number.NEGATIVE_INFINITY;
|
|
208
|
+
else if (inBurst)
|
|
209
|
+
readyAt = firstUnseen + commitDelayMs;
|
|
210
|
+
// Debounce with a maximum wait: continuous commits still get a capture every maxWaitMs.
|
|
211
|
+
else
|
|
212
|
+
readyAt = Math.min(lastCommitAt + settleMs, (pendingSince ?? lastCommitAt) + maxWaitMs);
|
|
213
|
+
const due = Math.max(readyAt, lastStartAt + gap);
|
|
214
|
+
captureTimer = deps.setTimer(onCaptureTimer, Math.max(0, due - now));
|
|
215
|
+
hasCaptureTimer = true;
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
function onCaptureTimer() {
|
|
219
|
+
captureTimer = null;
|
|
220
|
+
hasCaptureTimer = false;
|
|
221
|
+
startCapture();
|
|
222
|
+
}
|
|
223
|
+
function startCapture() {
|
|
224
|
+
if (stopped || capturing)
|
|
225
|
+
return;
|
|
226
|
+
clearCaptureTimer();
|
|
227
|
+
// Frames still on their way: a new one would only queue behind them and arrive in a bunch.
|
|
228
|
+
let linkBusy = false;
|
|
229
|
+
safely(() => {
|
|
230
|
+
linkBusy = deps.canSend !== undefined && !deps.canSend();
|
|
231
|
+
});
|
|
232
|
+
if (linkBusy) {
|
|
233
|
+
captureTimer = deps.setTimer(onCaptureTimer, FLOW_RETRY_MS);
|
|
234
|
+
hasCaptureTimer = true;
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
pending = false;
|
|
238
|
+
wantNow = false;
|
|
239
|
+
pendingSince = null;
|
|
240
|
+
waitingForAction = false;
|
|
241
|
+
actionCommitSeen = false;
|
|
242
|
+
capturing = true;
|
|
243
|
+
jankThisCapture = false;
|
|
244
|
+
let startedAt = 0;
|
|
245
|
+
let rev = 0;
|
|
246
|
+
let request;
|
|
247
|
+
try {
|
|
248
|
+
startedAt = deps.now();
|
|
249
|
+
lastStartAt = startedAt;
|
|
250
|
+
// This capture shows the result commit when it starts after the commit delay.
|
|
251
|
+
if (resultDueAt !== null && startedAt >= resultDueAt)
|
|
252
|
+
resultDueAt = null;
|
|
253
|
+
rev = deps.commitRevision();
|
|
254
|
+
request = deps.capture({ ...PRESETS[preset] });
|
|
255
|
+
}
|
|
256
|
+
catch (error) {
|
|
257
|
+
request = Promise.reject(error);
|
|
258
|
+
}
|
|
259
|
+
request.then((result) => finishCapture(startedAt, rev, result), (error) => {
|
|
260
|
+
failures += 1;
|
|
261
|
+
safely(() => {
|
|
262
|
+
lastFailure = (error instanceof Error ? error.message : String(error)).slice(0, 160);
|
|
263
|
+
});
|
|
264
|
+
finishCapture(startedAt, rev, null);
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
function finishCapture(startedAt, rev, result) {
|
|
268
|
+
capturing = false;
|
|
269
|
+
if (stopped)
|
|
270
|
+
return;
|
|
271
|
+
safely(() => {
|
|
272
|
+
lastFinishAt = deps.now();
|
|
273
|
+
});
|
|
274
|
+
if (result === null) {
|
|
275
|
+
failuresInARow += 1;
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
failuresInARow = 0;
|
|
279
|
+
if (!jankThisCapture) {
|
|
280
|
+
cleanInARow += 1;
|
|
281
|
+
if (cleanInARow >= BACKOFF_FORGET_AFTER)
|
|
282
|
+
jankStrikes = 0;
|
|
283
|
+
if (backoffMs > 0) {
|
|
284
|
+
backoffMs *= BACKOFF_DECAY;
|
|
285
|
+
if (backoffMs < minIntervalMs)
|
|
286
|
+
backoffMs = 0;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
safely(() => {
|
|
290
|
+
const captureMs = Math.max(0, deps.now() - startedAt);
|
|
291
|
+
recentCaptureMs =
|
|
292
|
+
recentCaptureMs === null ? captureMs : recentCaptureMs * (1 - CAPTURE_TIME_WEIGHT) + captureMs * CAPTURE_TIME_WEIGHT;
|
|
293
|
+
seq += 1;
|
|
294
|
+
frames += 1;
|
|
295
|
+
totalCaptureMs += captureMs;
|
|
296
|
+
maxCaptureMs = Math.max(maxCaptureMs, captureMs);
|
|
297
|
+
const frame = { seq, rev, capturedAt: startedAt, captureMs, mime: result.mime, data: result.data };
|
|
298
|
+
if (result.width !== undefined)
|
|
299
|
+
frame.width = result.width;
|
|
300
|
+
if (result.height !== undefined)
|
|
301
|
+
frame.height = result.height;
|
|
302
|
+
deps.send(frame);
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
// A frame was sent, or we gave up for now: either way the heartbeat wait starts over.
|
|
306
|
+
armHeartbeat();
|
|
307
|
+
if (failuresInARow >= MAX_FAILURES_IN_A_ROW) {
|
|
308
|
+
waitingForAction = false;
|
|
309
|
+
resultDueAt = null;
|
|
310
|
+
}
|
|
311
|
+
// During a burst, the next capture follows if it can start before the burst ends.
|
|
312
|
+
safely(() => {
|
|
313
|
+
if (failuresInARow === 0 && burstUntil > Math.max(deps.now(), lastStartAt + burstIntervalMs)) {
|
|
314
|
+
pending = true;
|
|
315
|
+
wantNow = true;
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
reschedule();
|
|
319
|
+
}
|
|
320
|
+
function onCommitted() {
|
|
321
|
+
if (stopped)
|
|
322
|
+
return;
|
|
323
|
+
lastCommitAt = deps.now();
|
|
324
|
+
if (failuresInARow >= MAX_FAILURES_IN_A_ROW)
|
|
325
|
+
return;
|
|
326
|
+
pending = true;
|
|
327
|
+
if (pendingSince === null)
|
|
328
|
+
pendingSince = lastCommitAt;
|
|
329
|
+
if (resultSkipArmed) {
|
|
330
|
+
// The first commit after a request is the action's result; after the burst the skip is dropped.
|
|
331
|
+
resultSkipArmed = false;
|
|
332
|
+
if (lastCommitAt < burstUntil)
|
|
333
|
+
resultDueAt = lastCommitAt + commitDelayMs;
|
|
334
|
+
}
|
|
335
|
+
if (waitingForAction && !actionCommitSeen) {
|
|
336
|
+
actionCommitSeen = true;
|
|
337
|
+
actionDueAt = Math.min(actionDueAt, lastCommitAt + commitDelayMs);
|
|
338
|
+
}
|
|
339
|
+
reschedule();
|
|
340
|
+
}
|
|
341
|
+
function watchAnimationFrames() {
|
|
342
|
+
const request = deps.requestAnimationFrame;
|
|
343
|
+
if (!request)
|
|
344
|
+
return;
|
|
345
|
+
const tick = (t) => {
|
|
346
|
+
if (stopped)
|
|
347
|
+
return;
|
|
348
|
+
observedFrames += 1;
|
|
349
|
+
if (lastFrameTime !== null && t - lastFrameTime > JANK_MS) {
|
|
350
|
+
janky += 1;
|
|
351
|
+
if (capturing)
|
|
352
|
+
jankyWhileCapturing += 1;
|
|
353
|
+
// A frame held up by a capture can arrive just after it ends.
|
|
354
|
+
let nearCapture = capturing;
|
|
355
|
+
safely(() => {
|
|
356
|
+
if (deps.now() - lastFinishAt <= JANK_MS)
|
|
357
|
+
nearCapture = true;
|
|
358
|
+
});
|
|
359
|
+
if (nearCapture)
|
|
360
|
+
onCaptureJank();
|
|
361
|
+
}
|
|
362
|
+
lastFrameTime = t;
|
|
363
|
+
next();
|
|
364
|
+
};
|
|
365
|
+
const next = () => {
|
|
366
|
+
safely(() => {
|
|
367
|
+
rafHandle = request(tick);
|
|
368
|
+
hasRafHandle = true;
|
|
369
|
+
});
|
|
370
|
+
};
|
|
371
|
+
next();
|
|
372
|
+
}
|
|
373
|
+
safely(() => {
|
|
374
|
+
unsubscribe = deps.onCommit(onCommitted);
|
|
375
|
+
});
|
|
376
|
+
watchAnimationFrames();
|
|
377
|
+
armHeartbeat();
|
|
378
|
+
startCapture();
|
|
379
|
+
return {
|
|
380
|
+
stop() {
|
|
381
|
+
if (stopped)
|
|
382
|
+
return;
|
|
383
|
+
stopped = true;
|
|
384
|
+
pending = false;
|
|
385
|
+
waitingForAction = false;
|
|
386
|
+
resultSkipArmed = false;
|
|
387
|
+
resultDueAt = null;
|
|
388
|
+
clearCaptureTimer();
|
|
389
|
+
clearHeartbeatTimer();
|
|
390
|
+
const unsub = unsubscribe;
|
|
391
|
+
unsubscribe = null;
|
|
392
|
+
if (unsub)
|
|
393
|
+
safely(unsub);
|
|
394
|
+
if (hasRafHandle) {
|
|
395
|
+
const handle = rafHandle;
|
|
396
|
+
rafHandle = null;
|
|
397
|
+
hasRafHandle = false;
|
|
398
|
+
const cancel = deps.cancelAnimationFrame;
|
|
399
|
+
if (cancel)
|
|
400
|
+
safely(() => cancel(handle));
|
|
401
|
+
}
|
|
402
|
+
},
|
|
403
|
+
requestFrame() {
|
|
404
|
+
if (stopped || failuresInARow >= MAX_FAILURES_IN_A_ROW)
|
|
405
|
+
return;
|
|
406
|
+
pending = true;
|
|
407
|
+
safely(() => {
|
|
408
|
+
const now = deps.now();
|
|
409
|
+
burstUntil = Math.max(burstUntil, now + burstMs);
|
|
410
|
+
resultSkipArmed = true;
|
|
411
|
+
// The first request fixes the fallback deadline; later ones do not push it back.
|
|
412
|
+
if (!waitingForAction) {
|
|
413
|
+
waitingForAction = true;
|
|
414
|
+
actionCommitSeen = false;
|
|
415
|
+
actionDueAt = now + actionWaitMs;
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
reschedule();
|
|
419
|
+
},
|
|
420
|
+
setQuality(next) {
|
|
421
|
+
if (next in PRESETS)
|
|
422
|
+
preset = next;
|
|
423
|
+
},
|
|
424
|
+
stats() {
|
|
425
|
+
return {
|
|
426
|
+
frames,
|
|
427
|
+
avgCaptureMs: frames === 0 ? 0 : totalCaptureMs / frames,
|
|
428
|
+
maxCaptureMs,
|
|
429
|
+
observedFrames,
|
|
430
|
+
janky,
|
|
431
|
+
jankyWhileCapturing,
|
|
432
|
+
failures,
|
|
433
|
+
...(lastFailure !== undefined ? { lastFailure } : {}),
|
|
434
|
+
heartbeats,
|
|
435
|
+
backoffs,
|
|
436
|
+
};
|
|
437
|
+
},
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
//# sourceMappingURL=feed.js.map
|
package/dist/feed.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feed.js","sourceRoot":"","sources":["../src/feed.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;AAsJH,wCA0XC;AAtgBD,mGAAmG;AACnG,+CAA+C;AAC/C,MAAM,OAAO,GAAyC;IACpD,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE;IACtD,QAAQ,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE;IACxD,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE;CACtD,CAAC;AAuDF,gEAAgE;AAChE,MAAM,aAAa,GAAG,EAAE,CAAC;AA+CzB,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAC9B,MAAM,uBAAuB,GAAG,GAAG,CAAC;AACpC,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAClC,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAC9B,MAAM,yBAAyB,GAAG,GAAG,CAAC;AACtC,MAAM,uBAAuB,GAAG,EAAE,CAAC;AACnC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AACnC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAChC,gFAAgF;AAChF,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAChC,+DAA+D;AAC/D,MAAM,OAAO,GAAG,EAAE,CAAC;AACnB,+DAA+D;AAC/D,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAChC,yFAAyF;AACzF,MAAM,aAAa,GAAG,IAAI,CAAC;AAC3B,oEAAoE;AACpE,MAAM,eAAe,GAAG,CAAC,CAAC;AAC1B,0DAA0D;AAC1D,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAChC,yFAAyF;AACzF,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAE/B,SAAS,MAAM,CAAC,EAAc;IAC5B,IAAI,CAAC;QACH,EAAE,EAAE,CAAC;IACP,CAAC;IAAC,MAAM,CAAC;QACP,0CAA0C;IAC5C,CAAC;AACH,CAAC;AAED,SAAgB,cAAc,CAAC,OAAoB,EAAE,IAAc;IACjE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,iBAAiB,CAAC;IACvD,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,uBAAuB,CAAC;IACvE,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,oBAAoB,CAAC;IAChE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,gBAAgB,CAAC;IACpD,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,yBAAyB,CAAC;IAC7E,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,uBAAuB,CAAC;IACvE,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,sBAAsB,CAAC;IACpE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,mBAAmB,CAAC;IAC3D,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,KAAK,SAAS,IAAI,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3G,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAC1C,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IAC5C,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,MAAM,GAAkB,OAAO,CAAC,OAAO,IAAI,UAAU,CAAC;IAC1D,oFAAoF;IACpF,IAAI,eAAe,GAAkB,IAAI,CAAC;IAC1C,sFAAsF;IACtF,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,mFAAmF;IACnF,IAAI,eAAe,GAAG,KAAK,CAAC;IAC5B,8FAA8F;IAC9F,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,YAAY,GAAG,MAAM,CAAC,iBAAiB,CAAC;IAC5C,wEAAwE;IACxE,IAAI,YAAY,GAAkB,IAAI,CAAC;IACvC,uDAAuD;IACvD,IAAI,UAAU,GAAG,MAAM,CAAC,iBAAiB,CAAC;IAE1C,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,oEAAoE;IACpE,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,uFAAuF;IACvF,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,iFAAiF;IACjF,IAAI,gBAAgB,GAAG,KAAK,CAAC;IAC7B,wEAAwE;IACxE,IAAI,gBAAgB,GAAG,KAAK,CAAC;IAC7B,8FAA8F;IAC9F,IAAI,WAAW,GAAG,MAAM,CAAC,iBAAiB,CAAC;IAC3C,qGAAqG;IACrG,IAAI,eAAe,GAAG,KAAK,CAAC;IAC5B,+FAA+F;IAC/F,IAAI,WAAW,GAAkB,IAAI,CAAC;IACtC,IAAI,YAAY,GAAG,MAAM,CAAC,iBAAiB,CAAC;IAC5C,IAAI,WAAW,GAAG,MAAM,CAAC,iBAAiB,CAAC;IAC3C,IAAI,cAAc,GAAG,CAAC,CAAC;IACvB,IAAI,GAAG,GAAG,CAAC,CAAC;IAEZ,IAAI,YAAY,GAAY,IAAI,CAAC;IACjC,IAAI,eAAe,GAAG,KAAK,CAAC;IAC5B,IAAI,cAAc,GAAY,IAAI,CAAC;IACnC,IAAI,iBAAiB,GAAG,KAAK,CAAC;IAC9B,IAAI,WAAW,GAAwB,IAAI,CAAC;IAC5C,IAAI,SAAS,GAAY,IAAI,CAAC;IAC9B,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,IAAI,aAAa,GAAkB,IAAI,CAAC;IAExC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,cAAc,GAAG,CAAC,CAAC;IACvB,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,cAAc,GAAG,CAAC,CAAC;IACvB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,mBAAmB,GAAG,CAAC,CAAC;IAC5B,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,WAA+B,CAAC;IACpC,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,SAAS,iBAAiB;QACxB,IAAI,CAAC,eAAe;YAAE,OAAO;QAC7B,MAAM,MAAM,GAAG,YAAY,CAAC;QAC5B,YAAY,GAAG,IAAI,CAAC;QACpB,eAAe,GAAG,KAAK,CAAC;QACxB,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IACxC,CAAC;IAED,SAAS,mBAAmB;QAC1B,IAAI,CAAC,iBAAiB;YAAE,OAAO;QAC/B,MAAM,MAAM,GAAG,cAAc,CAAC;QAC9B,cAAc,GAAG,IAAI,CAAC;QACtB,iBAAiB,GAAG,KAAK,CAAC;QAC1B,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IACxC,CAAC;IAED,SAAS,YAAY;QACnB,mBAAmB,EAAE,CAAC;QACtB,IAAI,OAAO;YAAE,OAAO;QACpB,MAAM,CAAC,GAAG,EAAE;YACV,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;YACzD,iBAAiB,GAAG,IAAI,CAAC;QAC3B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,SAAS,WAAW;QAClB,cAAc,GAAG,IAAI,CAAC;QACtB,iBAAiB,GAAG,KAAK,CAAC;QAC1B,IAAI,OAAO;YAAE,OAAO;QACpB,iFAAiF;QACjF,oEAAoE;QACpE,IAAI,SAAS,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,WAAW,GAAG,WAAW,CAAC,EAAE,CAAC;YAC/E,YAAY,EAAE,CAAC;YACf,OAAO;QACT,CAAC;QACD,UAAU,IAAI,CAAC,CAAC;QAChB,YAAY,EAAE,CAAC;IACjB,CAAC;IAED,yGAAyG;IACzG,SAAS,KAAK,CAAC,IAAY;QACzB,IAAI,GAAG,GAAG,IAAI,CAAC;QACf,IAAI,SAAS,KAAK,SAAS,IAAI,eAAe,KAAK,IAAI;YAAE,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,GAAG,SAAS,CAAC,CAAC;QAC1G,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAClC,CAAC;IAED,SAAS,aAAa;QACpB,eAAe,GAAG,IAAI,CAAC;QACvB,WAAW,GAAG,CAAC,CAAC;QAChB,WAAW,IAAI,CAAC,CAAC;QACjB,qGAAqG;QACrG,IAAI,YAAY,KAAK,SAAS,IAAI,WAAW,GAAG,eAAe;YAAE,OAAO;QACxE,QAAQ,IAAI,CAAC,CAAC;QACd,2FAA2F;QAC3F,yFAAyF;QACzF,IAAI,aAAa,KAAK,SAAS,IAAI,WAAW,GAAG,oBAAoB,EAAE,CAAC;YACtE,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC,CAAC;YACvE,OAAO;QACT,CAAC;QACD,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,CAAC,EAAE,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC;IACjF,CAAC;IAED,gEAAgE;IAChE,SAAS,UAAU;QACjB,IAAI,OAAO,IAAI,SAAS,IAAI,CAAC,OAAO,IAAI,cAAc,IAAI,qBAAqB;YAAE,OAAO;QACxF,iBAAiB,EAAE,CAAC;QACpB,MAAM,CAAC,GAAG,EAAE;YACV,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,MAAM,OAAO,GAAG,GAAG,GAAG,UAAU,CAAC;YACjC,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;YAC7D,uGAAuG;YACvG,IAAI,CAAC,OAAO;gBAAE,WAAW,GAAG,IAAI,CAAC;YACjC,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;gBACzB,uHAAuH;gBACvH,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,GAAG,GAAG,CAAC,CAAC,CAAC;gBAC7E,eAAe,GAAG,IAAI,CAAC;gBACvB,OAAO;YACT,CAAC;YACD,6FAA6F;YAC7F,0FAA0F;YAC1F,6BAA6B;YAC7B,MAAM,WAAW,GAAG,YAAY,IAAI,YAAY,CAAC;YACjD,IAAI,OAAe,CAAC;YACpB,IAAI,gBAAgB;gBAAE,OAAO,GAAG,WAAW,CAAC;iBACvC,IAAI,OAAO;gBAAE,OAAO,GAAG,YAAY,GAAG,WAAW,CAAC,CAAC,CAAC,WAAW,GAAG,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC;iBAC3G,IAAI,OAAO;gBAAE,OAAO,GAAG,WAAW,GAAG,aAAa,CAAC;YACxD,wFAAwF;;gBACnF,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,GAAG,QAAQ,EAAE,CAAC,YAAY,IAAI,YAAY,CAAC,GAAG,SAAS,CAAC,CAAC;YAC7F,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,GAAG,CAAC,CAAC;YACjD,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC;YACrE,eAAe,GAAG,IAAI,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,SAAS,cAAc;QACrB,YAAY,GAAG,IAAI,CAAC;QACpB,eAAe,GAAG,KAAK,CAAC;QACxB,YAAY,EAAE,CAAC;IACjB,CAAC;IAED,SAAS,YAAY;QACnB,IAAI,OAAO,IAAI,SAAS;YAAE,OAAO;QACjC,iBAAiB,EAAE,CAAC;QACpB,2FAA2F;QAC3F,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,MAAM,CAAC,GAAG,EAAE;YACV,QAAQ,GAAG,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAC3D,CAAC,CAAC,CAAC;QACH,IAAI,QAAQ,EAAE,CAAC;YACb,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,aAAa,CAAC,CAAC;YAC5D,eAAe,GAAG,IAAI,CAAC;YACvB,OAAO;QACT,CAAC;QACD,OAAO,GAAG,KAAK,CAAC;QAChB,OAAO,GAAG,KAAK,CAAC;QAChB,YAAY,GAAG,IAAI,CAAC;QACpB,gBAAgB,GAAG,KAAK,CAAC;QACzB,gBAAgB,GAAG,KAAK,CAAC;QACzB,SAAS,GAAG,IAAI,CAAC;QACjB,eAAe,GAAG,KAAK,CAAC;QAExB,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,IAAI,OAAiF,CAAC;QACtF,IAAI,CAAC;YACH,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,WAAW,GAAG,SAAS,CAAC;YACxB,8EAA8E;YAC9E,IAAI,WAAW,KAAK,IAAI,IAAI,SAAS,IAAI,WAAW;gBAAE,WAAW,GAAG,IAAI,CAAC;YACzE,GAAG,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YAC5B,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,CAAC,IAAI,CACV,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,GAAG,EAAE,MAAM,CAAC,EACjD,CAAC,KAAc,EAAE,EAAE;YACjB,QAAQ,IAAI,CAAC,CAAC;YACd,MAAM,CAAC,GAAG,EAAE;gBACV,WAAW,GAAG,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YACvF,CAAC,CAAC,CAAC;YACH,aAAa,CAAC,SAAS,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACtC,CAAC,CACF,CAAC;IACJ,CAAC;IAED,SAAS,aAAa,CACpB,SAAiB,EACjB,GAAW,EACX,MAA8E;QAE9E,SAAS,GAAG,KAAK,CAAC;QAClB,IAAI,OAAO;YAAE,OAAO;QACpB,MAAM,CAAC,GAAG,EAAE;YACV,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QACH,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,cAAc,IAAI,CAAC,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,cAAc,GAAG,CAAC,CAAC;YACnB,IAAI,CAAC,eAAe,EAAE,CAAC;gBACrB,WAAW,IAAI,CAAC,CAAC;gBACjB,IAAI,WAAW,IAAI,oBAAoB;oBAAE,WAAW,GAAG,CAAC,CAAC;gBACzD,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;oBAClB,SAAS,IAAI,aAAa,CAAC;oBAC3B,IAAI,SAAS,GAAG,aAAa;wBAAE,SAAS,GAAG,CAAC,CAAC;gBAC/C,CAAC;YACH,CAAC;YACD,MAAM,CAAC,GAAG,EAAE;gBACV,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;gBACtD,eAAe;oBACb,eAAe,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,GAAG,CAAC,CAAC,GAAG,mBAAmB,CAAC,GAAG,SAAS,GAAG,mBAAmB,CAAC;gBACvH,GAAG,IAAI,CAAC,CAAC;gBACT,MAAM,IAAI,CAAC,CAAC;gBACZ,cAAc,IAAI,SAAS,CAAC;gBAC5B,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;gBACjD,MAAM,KAAK,GAAc,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;gBAC9G,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS;oBAAE,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;gBAC3D,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;oBAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;gBAC9D,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnB,CAAC,CAAC,CAAC;QACL,CAAC;QACD,sFAAsF;QACtF,YAAY,EAAE,CAAC;QACf,IAAI,cAAc,IAAI,qBAAqB,EAAE,CAAC;YAC5C,gBAAgB,GAAG,KAAK,CAAC;YACzB,WAAW,GAAG,IAAI,CAAC;QACrB,CAAC;QACD,kFAAkF;QAClF,MAAM,CAAC,GAAG,EAAE;YACV,IAAI,cAAc,KAAK,CAAC,IAAI,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,WAAW,GAAG,eAAe,CAAC,EAAE,CAAC;gBAC7F,OAAO,GAAG,IAAI,CAAC;gBACf,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC,CAAC,CAAC;QACH,UAAU,EAAE,CAAC;IACf,CAAC;IAED,SAAS,WAAW;QAClB,IAAI,OAAO;YAAE,OAAO;QACpB,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC1B,IAAI,cAAc,IAAI,qBAAqB;YAAE,OAAO;QACpD,OAAO,GAAG,IAAI,CAAC;QACf,IAAI,YAAY,KAAK,IAAI;YAAE,YAAY,GAAG,YAAY,CAAC;QACvD,IAAI,eAAe,EAAE,CAAC;YACpB,gGAAgG;YAChG,eAAe,GAAG,KAAK,CAAC;YACxB,IAAI,YAAY,GAAG,UAAU;gBAAE,WAAW,GAAG,YAAY,GAAG,aAAa,CAAC;QAC5E,CAAC;QACD,IAAI,gBAAgB,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1C,gBAAgB,GAAG,IAAI,CAAC;YACxB,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,YAAY,GAAG,aAAa,CAAC,CAAC;QACpE,CAAC;QACD,UAAU,EAAE,CAAC;IACf,CAAC;IAED,SAAS,oBAAoB;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,qBAAqB,CAAC;QAC3C,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,MAAM,IAAI,GAAG,CAAC,CAAS,EAAQ,EAAE;YAC/B,IAAI,OAAO;gBAAE,OAAO;YACpB,cAAc,IAAI,CAAC,CAAC;YACpB,IAAI,aAAa,KAAK,IAAI,IAAI,CAAC,GAAG,aAAa,GAAG,OAAO,EAAE,CAAC;gBAC1D,KAAK,IAAI,CAAC,CAAC;gBACX,IAAI,SAAS;oBAAE,mBAAmB,IAAI,CAAC,CAAC;gBACxC,8DAA8D;gBAC9D,IAAI,WAAW,GAAG,SAAS,CAAC;gBAC5B,MAAM,CAAC,GAAG,EAAE;oBACV,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,YAAY,IAAI,OAAO;wBAAE,WAAW,GAAG,IAAI,CAAC;gBAC/D,CAAC,CAAC,CAAC;gBACH,IAAI,WAAW;oBAAE,aAAa,EAAE,CAAC;YACnC,CAAC;YACD,aAAa,GAAG,CAAC,CAAC;YAClB,IAAI,EAAE,CAAC;QACT,CAAC,CAAC;QACF,MAAM,IAAI,GAAG,GAAS,EAAE;YACtB,MAAM,CAAC,GAAG,EAAE;gBACV,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;gBAC1B,YAAY,GAAG,IAAI,CAAC;YACtB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QACF,IAAI,EAAE,CAAC;IACT,CAAC;IAED,MAAM,CAAC,GAAG,EAAE;QACV,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IACH,oBAAoB,EAAE,CAAC;IACvB,YAAY,EAAE,CAAC;IACf,YAAY,EAAE,CAAC;IAEf,OAAO;QACL,IAAI;YACF,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,OAAO,GAAG,KAAK,CAAC;YAChB,gBAAgB,GAAG,KAAK,CAAC;YACzB,eAAe,GAAG,KAAK,CAAC;YACxB,WAAW,GAAG,IAAI,CAAC;YACnB,iBAAiB,EAAE,CAAC;YACpB,mBAAmB,EAAE,CAAC;YACtB,MAAM,KAAK,GAAG,WAAW,CAAC;YAC1B,WAAW,GAAG,IAAI,CAAC;YACnB,IAAI,KAAK;gBAAE,MAAM,CAAC,KAAK,CAAC,CAAC;YACzB,IAAI,YAAY,EAAE,CAAC;gBACjB,MAAM,MAAM,GAAG,SAAS,CAAC;gBACzB,SAAS,GAAG,IAAI,CAAC;gBACjB,YAAY,GAAG,KAAK,CAAC;gBACrB,MAAM,MAAM,GAAG,IAAI,CAAC,oBAAoB,CAAC;gBACzC,IAAI,MAAM;oBAAE,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;QAED,YAAY;YACV,IAAI,OAAO,IAAI,cAAc,IAAI,qBAAqB;gBAAE,OAAO;YAC/D,OAAO,GAAG,IAAI,CAAC;YACf,MAAM,CAAC,GAAG,EAAE;gBACV,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBACvB,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,GAAG,OAAO,CAAC,CAAC;gBACjD,eAAe,GAAG,IAAI,CAAC;gBACvB,iFAAiF;gBACjF,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACtB,gBAAgB,GAAG,IAAI,CAAC;oBACxB,gBAAgB,GAAG,KAAK,CAAC;oBACzB,WAAW,GAAG,GAAG,GAAG,YAAY,CAAC;gBACnC,CAAC;YACH,CAAC,CAAC,CAAC;YACH,UAAU,EAAE,CAAC;QACf,CAAC;QAED,UAAU,CAAC,IAAmB;YAC5B,IAAI,IAAI,IAAI,OAAO;gBAAE,MAAM,GAAG,IAAI,CAAC;QACrC,CAAC;QAED,KAAK;YACH,OAAO;gBACL,MAAM;gBACN,YAAY,EAAE,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,GAAG,MAAM;gBACxD,YAAY;gBACZ,cAAc;gBACd,KAAK;gBACL,mBAAmB;gBACnB,QAAQ;gBACR,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrD,UAAU;gBACV,QAAQ;aACT,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/fiber.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type UnknownRecord } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Minimal structural view of a React fiber. Only the fields Tapline reads are
|
|
4
|
+
* declared; everything else about fibers is private to React.
|
|
5
|
+
*/
|
|
6
|
+
export interface Fiber {
|
|
7
|
+
tag: number;
|
|
8
|
+
type: unknown;
|
|
9
|
+
elementType: unknown;
|
|
10
|
+
memoizedProps: unknown;
|
|
11
|
+
stateNode: unknown;
|
|
12
|
+
child: Fiber | null;
|
|
13
|
+
sibling: Fiber | null;
|
|
14
|
+
return: Fiber | null;
|
|
15
|
+
alternate?: Fiber | null;
|
|
16
|
+
}
|
|
17
|
+
/** Minimal view of a FiberRoot as handed to `onCommitFiberRoot`. */
|
|
18
|
+
export interface FiberRootLike {
|
|
19
|
+
current: Fiber;
|
|
20
|
+
}
|
|
21
|
+
export declare const FunctionComponent = 0;
|
|
22
|
+
export declare const ClassComponent = 1;
|
|
23
|
+
export declare const IndeterminateComponent = 2;
|
|
24
|
+
export declare const HostRoot = 3;
|
|
25
|
+
export declare const HostComponent = 5;
|
|
26
|
+
export declare const HostText = 6;
|
|
27
|
+
export declare const ForwardRef = 11;
|
|
28
|
+
export declare const MemoComponent = 14;
|
|
29
|
+
export declare const SimpleMemoComponent = 15;
|
|
30
|
+
export declare function isFiber(value: unknown): value is Fiber;
|
|
31
|
+
export declare function isFiberRoot(value: unknown): value is FiberRootLike;
|
|
32
|
+
export declare function isCompositeTag(tag: number): boolean;
|
|
33
|
+
/** Props of a fiber as a plain record ({} when absent or a text string). */
|
|
34
|
+
export declare function propsOf(fiber: Fiber): UnknownRecord;
|
|
35
|
+
/** The first host fiber below `fiber` in tree order (a scroll view's content container); null when none. */
|
|
36
|
+
export declare function firstHostChild(fiber: Fiber): Fiber | null;
|
|
37
|
+
/** The host fibers directly below `fiber`, looking through non-host wrappers but not into hosts. */
|
|
38
|
+
export declare function hostChildren(fiber: Fiber): Fiber[];
|
|
39
|
+
/** Best-effort display name of a component type; null when anonymous. */
|
|
40
|
+
export declare function componentName(type: unknown, depth?: number): string | null;
|
|
41
|
+
export declare function fiberName(fiber: Fiber): string | null;
|
|
42
|
+
/** Whether `fiber` is `other` or its alternate (the same logical fiber). */
|
|
43
|
+
export declare function sameFiber(fiber: Fiber, other: Fiber): boolean;
|