@multiplatform.one/core 7.1.0 → 7.2.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.
@@ -0,0 +1,429 @@
1
+ import { EventClient } from "@tanstack/devtools-event-client";
2
+ import { useEffect } from "react";
3
+
4
+ // ---------------------------------------------------------------------------
5
+ // Keyboard trigger
6
+ // ---------------------------------------------------------------------------
7
+
8
+ /**
9
+ * Keyboard shortcut that opens the devtools shell: Cmd+Shift+` on Mac,
10
+ * Ctrl+Shift+` elsewhere.
11
+ *
12
+ * Why this combo, and why `~`: unshifted Ctrl/Cmd+` is macOS "cycle
13
+ * windows" and never reaches the page. Shift+Backquote is the physical
14
+ * key the ticket names. `@tanstack/react-devtools` matches an exact
15
+ * `e.key` sequence via `@solid-primitives/keyboard`, and Shift+Backquote
16
+ * produces `e.key === "~"` on US layouts — so the TanStack config must
17
+ * be Shift + "~", not unshifted "`". The capture-phase listener in
18
+ * `useDevtoolsKeyboardTrigger` matches `e.code === "Backquote"` so
19
+ * non-US layouts (where Shift+Backquote is ¬ or `) still fire.
20
+ *
21
+ * Exported so tests pin the binding.
22
+ */
23
+ export const devtoolsOpenHotkey = ["CtrlOrMeta", "Shift", "~"] as const;
24
+
25
+ /**
26
+ * True when the event is the documented debugger shortcut. Prefers the
27
+ * physical Backquote key so it does not depend on keyboard layout;
28
+ * `e.key` of "`" or "~" is accepted as a fallback when `code` is absent
29
+ * (jsdom / synthetic events).
30
+ */
31
+ export function isDevtoolsOpenHotkeyEvent(event: KeyboardEvent): boolean {
32
+ if (!(event.metaKey || event.ctrlKey) || !event.shiftKey || event.altKey) {
33
+ return false;
34
+ }
35
+ if (event.code === "Backquote") return true;
36
+ return event.key === "`" || event.key === "~";
37
+ }
38
+
39
+ /**
40
+ * Capture-phase window listener that opens the shell on the documented
41
+ * shortcut. Capture runs before app-level keydown handlers, so a page
42
+ * that stopPropagation's cannot swallow it. preventDefault +
43
+ * stopImmediatePropagation keep TanStack's own createShortcut from
44
+ * also firing (which would toggle the panel shut again).
45
+ */
46
+ export function useDevtoolsKeyboardTrigger(enabled: boolean) {
47
+ useEffect(() => {
48
+ if (!enabled || typeof window === "undefined") return;
49
+ const onKeyDown = (event: KeyboardEvent) => {
50
+ if (!isDevtoolsOpenHotkeyEvent(event)) return;
51
+ event.preventDefault();
52
+ event.stopImmediatePropagation();
53
+ openDevtoolsShell();
54
+ };
55
+ window.addEventListener("keydown", onKeyDown, { capture: true });
56
+ return () => window.removeEventListener("keydown", onKeyDown, { capture: true });
57
+ }, [enabled]);
58
+ }
59
+
60
+ // ---------------------------------------------------------------------------
61
+ // Programmatic open — the same event the devtools shell's own trigger emits
62
+ // ---------------------------------------------------------------------------
63
+
64
+ /**
65
+ * Plugin id of the TanStack Devtools shell's internal event client
66
+ * (`devtoolsEventClient` in `@tanstack/devtools-client`). The shell
67
+ * subscribes to `<pluginId>:trigger-toggled` and opens/closes on the
68
+ * payload's `isOpen`. The spec asserts both strings
69
+ * against the installed packages so an upstream rename fails the build
70
+ * instead of silently breaking shake-to-open.
71
+ */
72
+ export const devtoolsShellPluginId = "tanstack-devtools-core";
73
+
74
+ /** Event suffix the shell listens on for open/close state changes. */
75
+ export const devtoolsTriggerToggledEvent = "trigger-toggled";
76
+
77
+ interface DevtoolsShellEventMap {
78
+ "trigger-toggled": { isOpen: boolean };
79
+ }
80
+
81
+ let shellEventClient: EventClient<DevtoolsShellEventMap> | undefined;
82
+
83
+ /**
84
+ * Open the TanStack Devtools shell programmatically by emitting the same
85
+ * bus event the shell's own (hidden) trigger button uses. Open-only by
86
+ * design: a continued shake must not immediately re-close the panel —
87
+ * closing stays on the close button / Escape / the keyboard shortcut.
88
+ * The event client queues emits until the bus connects, so an early shake
89
+ * racing the shell mount is still delivered.
90
+ */
91
+ export function openDevtoolsShell() {
92
+ shellEventClient ??= new EventClient<DevtoolsShellEventMap>({
93
+ pluginId: devtoolsShellPluginId,
94
+ });
95
+ shellEventClient.emit(devtoolsTriggerToggledEvent, { isOpen: true });
96
+ }
97
+
98
+ // ---------------------------------------------------------------------------
99
+ // Shake detection — pure state machine over devicemotion samples
100
+ // ---------------------------------------------------------------------------
101
+
102
+ const gravityMs2 = 9.81;
103
+
104
+ /** Defaults: deliberate shakes peak 15–25 m/s²; walking/bumps stay under ~8. */
105
+ export const shakeDefaults = {
106
+ /** m/s² a sample must exceed to count as a shake peak. */
107
+ threshold: 12,
108
+ /** Minimum ms between counted peaks (one swing = one peak, not many samples). */
109
+ minPeakGapMs: 80,
110
+ /** Peaks required inside the rolling window to fire. */
111
+ peakCount: 3,
112
+ /** Rolling window (ms) the peaks must land in. */
113
+ windowMs: 1000,
114
+ /** Dead time (ms) after firing before the detector re-arms. */
115
+ cooldownMs: 2000,
116
+ } as const;
117
+
118
+ interface MotionAxes {
119
+ x?: number | null;
120
+ y?: number | null;
121
+ z?: number | null;
122
+ }
123
+
124
+ /** Structural subset of DeviceMotionEvent the detector needs (testable in node). */
125
+ export interface MotionEventLike {
126
+ acceleration?: MotionAxes | null;
127
+ accelerationIncludingGravity?: MotionAxes | null;
128
+ }
129
+
130
+ /**
131
+ * Acceleration magnitude (m/s²) of a devicemotion sample. Prefers the
132
+ * gravity-excluded reading; falls back to the including-gravity reading
133
+ * minus standard gravity. Returns null when the event carries no data
134
+ * (some desktop browsers fire devicemotion with all-null axes).
135
+ */
136
+ export function motionMagnitude(event: MotionEventLike): number | null {
137
+ const a = event.acceleration;
138
+ if (a && (a.x != null || a.y != null || a.z != null)) {
139
+ return Math.hypot(a.x ?? 0, a.y ?? 0, a.z ?? 0);
140
+ }
141
+ const g = event.accelerationIncludingGravity;
142
+ if (g && (g.x != null || g.y != null || g.z != null)) {
143
+ return Math.abs(Math.hypot(g.x ?? 0, g.y ?? 0, g.z ?? 0) - gravityMs2);
144
+ }
145
+ return null;
146
+ }
147
+
148
+ export interface ShakeDetectorOptions {
149
+ onShake: () => void;
150
+ threshold?: number;
151
+ minPeakGapMs?: number;
152
+ peakCount?: number;
153
+ windowMs?: number;
154
+ cooldownMs?: number;
155
+ }
156
+
157
+ export interface ShakeDetector {
158
+ /** Feed a devicemotion sample. `now` is injectable for tests. */
159
+ handleMotion: (event: MotionEventLike, now?: number) => void;
160
+ /** Drop all peaks and cooldown state. */
161
+ reset: () => void;
162
+ }
163
+
164
+ /**
165
+ * Debounced shake detector: fires `onShake` when `peakCount` peaks above
166
+ * `threshold` (each at least `minPeakGapMs` apart) land inside a rolling
167
+ * `windowMs`, then goes dead for `cooldownMs` before re-arming.
168
+ */
169
+ export function createShakeDetector({
170
+ onShake,
171
+ threshold = shakeDefaults.threshold,
172
+ minPeakGapMs = shakeDefaults.minPeakGapMs,
173
+ peakCount = shakeDefaults.peakCount,
174
+ windowMs = shakeDefaults.windowMs,
175
+ cooldownMs = shakeDefaults.cooldownMs,
176
+ }: ShakeDetectorOptions): ShakeDetector {
177
+ let peaks: number[] = [];
178
+ let lastPeakAt = Number.NEGATIVE_INFINITY;
179
+ let cooldownUntil = Number.NEGATIVE_INFINITY;
180
+
181
+ function reset() {
182
+ peaks = [];
183
+ lastPeakAt = Number.NEGATIVE_INFINITY;
184
+ cooldownUntil = Number.NEGATIVE_INFINITY;
185
+ }
186
+
187
+ function handleMotion(event: MotionEventLike, now: number = Date.now()) {
188
+ if (now < cooldownUntil) return;
189
+ const magnitude = motionMagnitude(event);
190
+ if (magnitude == null || magnitude <= threshold) return;
191
+ if (now - lastPeakAt < minPeakGapMs) return;
192
+ lastPeakAt = now;
193
+ peaks = peaks.filter((at) => now - at <= windowMs);
194
+ peaks.push(now);
195
+ if (peaks.length < peakCount) return;
196
+ peaks = [];
197
+ lastPeakAt = Number.NEGATIVE_INFINITY;
198
+ cooldownUntil = now + cooldownMs;
199
+ onShake();
200
+ }
201
+
202
+ return { handleMotion, reset };
203
+ }
204
+
205
+ // ---------------------------------------------------------------------------
206
+ // Motion permission — iOS 13+ WebKit gesture-gated grant flow
207
+ // ---------------------------------------------------------------------------
208
+
209
+ export type MotionPermissionState = "granted" | "awaiting-gesture" | "requesting" | "denied";
210
+
211
+ export interface MotionPermissionFlow {
212
+ readonly state: MotionPermissionState;
213
+ /**
214
+ * Call from a user gesture (pointerup/click). Resolves once the
215
+ * permission settles; no-ops unless state is "awaiting-gesture".
216
+ */
217
+ handleGesture: () => Promise<void>;
218
+ }
219
+
220
+ /**
221
+ * Permission state machine. Platforms without
222
+ * `DeviceMotionEvent.requestPermission` (Android, desktop) grant
223
+ * immediately; iOS WebKit waits for a user gesture, asks once, and lands
224
+ * on granted or denied. A denial is terminal for this page load — Safari
225
+ * remembers the answer per site, so later loads resolve silently.
226
+ */
227
+ export function createMotionPermissionFlow({
228
+ requestPermission,
229
+ onGranted,
230
+ onDenied,
231
+ }: {
232
+ requestPermission?: () => Promise<string>;
233
+ onGranted: () => void;
234
+ onDenied?: () => void;
235
+ }): MotionPermissionFlow {
236
+ let state: MotionPermissionState = requestPermission ? "awaiting-gesture" : "granted";
237
+ if (state === "granted") onGranted();
238
+
239
+ async function handleGesture() {
240
+ if (state !== "awaiting-gesture" || !requestPermission) return;
241
+ state = "requesting";
242
+ let result: string;
243
+ try {
244
+ result = await requestPermission();
245
+ } catch {
246
+ // requestPermission rejects when called outside a user gesture or in
247
+ // an insecure context — treat as denied for this load.
248
+ result = "denied";
249
+ }
250
+ if (result === "granted") {
251
+ state = "granted";
252
+ onGranted();
253
+ } else {
254
+ state = "denied";
255
+ onDenied?.();
256
+ }
257
+ }
258
+
259
+ return {
260
+ get state() {
261
+ return state;
262
+ },
263
+ handleGesture,
264
+ };
265
+ }
266
+
267
+ // ---------------------------------------------------------------------------
268
+ // Motion arming — a DELIBERATE, app-driven grant (no arbitrary tap grab)
269
+ // ---------------------------------------------------------------------------
270
+
271
+ interface DeviceMotionEventConstructorLike {
272
+ requestPermission?: () => Promise<string>;
273
+ }
274
+
275
+ function motionEventCtor(): DeviceMotionEventConstructorLike | undefined {
276
+ return (globalThis as { DeviceMotionEvent?: DeviceMotionEventConstructorLike }).DeviceMotionEvent;
277
+ }
278
+
279
+ /**
280
+ * True only on the platform that gates devicemotion behind a user-gesture
281
+ * grant: iOS 13+ WebKit exposes `DeviceMotionEvent.requestPermission`.
282
+ * Android and desktop return false — they deliver motion events without a
283
+ * prompt, so shake-to-open arms itself there and no trigger UI is needed.
284
+ */
285
+ export function isMotionPermissionRequired(): boolean {
286
+ return typeof motionEventCtor()?.requestPermission === "function";
287
+ }
288
+
289
+ /**
290
+ * The window event an app dispatches from a DELIBERATE user gesture to arm
291
+ * shake-to-open on iOS (e.g. the SHC console's triple-tap on the build
292
+ * number in Settings › Estate). It is a window CustomEvent rather than an
293
+ * imported function on purpose: the trigger lives in a feature package that
294
+ * does not — and must not — depend on this core build. `dispatchEvent` is
295
+ * synchronous, so the `requestPermission()` this fires runs INSIDE the
296
+ * originating gesture's call stack, which is the whole reason iOS accepts
297
+ * it. `armDevtoolsMotion()` dispatches it for callers that CAN import core.
298
+ */
299
+ export const devtoolsArmMotionEvent = "mpo:devtools-arm-motion";
300
+
301
+ /**
302
+ * The window event core dispatches back once an arm attempt settles, so a
303
+ * trigger UI can report the honest outcome. `detail.granted` is true only
304
+ * when motion is now live.
305
+ */
306
+ export const devtoolsMotionArmedEvent = "mpo:devtools-motion-armed";
307
+
308
+ // The grant is a one-shot module latch plus a set of attachers (one per
309
+ // mounted `useShakeToOpen`). Once granted, a shell that mounts LATER — a
310
+ // colour-scheme change remounts it under a new key — attaches immediately
311
+ // instead of waiting for a second arm gesture.
312
+ let motionGranted = false;
313
+ const motionAttachers = new Set<() => void>();
314
+
315
+ function registerMotionAttacher(attach: () => void): () => void {
316
+ if (motionGranted) {
317
+ attach();
318
+ return () => {};
319
+ }
320
+ motionAttachers.add(attach);
321
+ return () => {
322
+ motionAttachers.delete(attach);
323
+ };
324
+ }
325
+
326
+ function grantAndAttachAll() {
327
+ motionGranted = true;
328
+ // Safe to iterate directly: `attach` adds a devicemotion listener and
329
+ // never mutates the set, and a shell mounting mid-grant sees
330
+ // motionGranted === true and attaches without registering.
331
+ for (const attach of motionAttachers) attach();
332
+ }
333
+
334
+ /** Test seam: forget the grant and drop attachers between cases. */
335
+ export function __resetMotionArming() {
336
+ motionGranted = false;
337
+ motionAttachers.clear();
338
+ }
339
+
340
+ /**
341
+ * Request motion permission from within a user gesture and, on grant,
342
+ * attach every waiting shake listener. Idempotent once granted. Resolves
343
+ * to the settled permission state; a denial is terminal for this page load
344
+ * (Safari remembers it per site). Broadcast the outcome on
345
+ * `devtoolsMotionArmedEvent` so a trigger UI can report it.
346
+ */
347
+ export async function requestMotionPermissionFromGesture(): Promise<MotionPermissionState> {
348
+ if (motionGranted) return "granted";
349
+ const ctor = motionEventCtor();
350
+ const flow = createMotionPermissionFlow({
351
+ // Invoke as a static method on the constructor — a detached reference
352
+ // throws in WebKit.
353
+ requestPermission:
354
+ typeof ctor?.requestPermission === "function" ? () => ctor.requestPermission!() : undefined,
355
+ onGranted: grantAndAttachAll,
356
+ });
357
+ // Non-iOS: the flow granted (and attached) synchronously in its
358
+ // constructor — nothing to await.
359
+ if (flow.state !== "granted") await flow.handleGesture();
360
+ if (typeof window !== "undefined") {
361
+ window.dispatchEvent(
362
+ new CustomEvent(devtoolsMotionArmedEvent, {
363
+ detail: { granted: flow.state === "granted" },
364
+ }),
365
+ );
366
+ }
367
+ return flow.state;
368
+ }
369
+
370
+ /**
371
+ * Arm shake-to-open programmatically. For callers that CAN import core
372
+ * (the app layer); a feature package instead dispatches
373
+ * `devtoolsArmMotionEvent` directly. Must be called from a user gesture on
374
+ * iOS. No-op on the server.
375
+ */
376
+ export function armDevtoolsMotion(): void {
377
+ if (typeof window === "undefined") return;
378
+ window.dispatchEvent(new Event(devtoolsArmMotionEvent));
379
+ }
380
+
381
+ // ---------------------------------------------------------------------------
382
+ // React wiring
383
+ // ---------------------------------------------------------------------------
384
+
385
+ /**
386
+ * Shake-to-open for the devtools shell. Attaches a `devicemotion` listener
387
+ * and opens the shell on a detected shake. Desktop browsers deliver no
388
+ * devicemotion events, so the listener is inert there — the keyboard
389
+ * shortcut is the desktop path.
390
+ *
391
+ * iOS 13+ gates devicemotion behind a permission prompt that can ONLY be
392
+ * requested from a user gesture, and the first shake cannot self-grant. So
393
+ * on iOS the listener attaches only after the app arms it — by dispatching
394
+ * `devtoolsArmMotionEvent` from a deliberate gesture (the console wires the
395
+ * build-number triple-tap). Android/desktop attach immediately. SSR-safe;
396
+ * every listener is torn down on unmount.
397
+ */
398
+ export function useShakeToOpen(enabled: boolean, onShake: () => void = openDevtoolsShell) {
399
+ useEffect(() => {
400
+ if (!enabled || typeof window === "undefined") return;
401
+
402
+ const detector = createShakeDetector({ onShake });
403
+ const motionListener = (event: Event) =>
404
+ detector.handleMotion(event as unknown as MotionEventLike);
405
+ const attach = () => window.addEventListener("devicemotion", motionListener, { passive: true });
406
+ const detach = () => window.removeEventListener("devicemotion", motionListener);
407
+
408
+ if (!isMotionPermissionRequired()) {
409
+ // Android / desktop: no grant needed — listen right away.
410
+ attach();
411
+ return detach;
412
+ }
413
+
414
+ // iOS: attach now if a prior deliberate arm already granted; otherwise
415
+ // wait for the app's arm event (dispatched from a user gesture, so the
416
+ // permission request it fires stays inside that gesture's stack).
417
+ const removeAttacher = registerMotionAttacher(attach);
418
+ const armListener = () => {
419
+ void requestMotionPermissionFromGesture();
420
+ };
421
+ window.addEventListener(devtoolsArmMotionEvent, armListener);
422
+
423
+ return () => {
424
+ detach();
425
+ removeAttacher();
426
+ window.removeEventListener(devtoolsArmMotionEvent, armListener);
427
+ };
428
+ }, [enabled, onShake]);
429
+ }
@@ -15,6 +15,15 @@ export declare function followPageOriginForLoopback(configured: string): string;
15
15
  export interface TanstackConfig {
16
16
  /** Show React Query devtools (web only, ignored on native and in Storybook). */
17
17
  debug?: boolean;
18
+ /**
19
+ * Shake the device to open the devtools shell (web only; requires
20
+ * `debug`). Defaults to true whenever the devtools mount. On iOS 13+
21
+ * WebKit the motion permission is requested once from the user's first
22
+ * tap; Android and desktop need no permission (desktop simply never
23
+ * fires devicemotion — use Cmd/Ctrl+Shift+` there). Set false to
24
+ * keep the keyboard shortcut as the only trigger.
25
+ */
26
+ shakeToOpen?: boolean;
18
27
  /** Options forwarded to the QueryClient constructor. */
19
28
  queryClientOptions?: Record<string, unknown>;
20
29
  /**
@@ -33,6 +42,22 @@ export interface TanstackConfig {
33
42
  * Passed automatically by `createApp()` from the theme config.
34
43
  */
35
44
  tamaguiConfig?: unknown;
45
+ /**
46
+ * Theme COLOR names the devtools panel offers in its accent dropdown
47
+ * (e.g. `["", "blue", "green", "purple"]`; `""` is the base theme).
48
+ * The panel renders the dropdown only when this AND `onThemeColorChange`
49
+ * are both set, and only then does the panel's Randomize action touch the
50
+ * accent — otherwise the picker is inert.
51
+ */
52
+ themeColors?: string[];
53
+ /** The theme color the app currently has applied (`""` for the base). */
54
+ currentThemeColor?: string;
55
+ /**
56
+ * Apply a theme color the user picked. The app owns this because a theme
57
+ * color is app state, not devtools state: the panel changes nothing on its
58
+ * own, it hands the choice back.
59
+ */
60
+ onThemeColorChange?: (color: string) => void;
36
61
  }
37
62
  export interface KeycloakConfig {
38
63
  /** Force-enable or disable. When omitted, reads KEYCLOAK_ENABLED from env config. */
@@ -1 +1 @@
1
- {"version":3,"file":"CreateApp.d.ts","sourceRoot":"","sources":["../../src/app/CreateApp.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CreateApp.d.ts","sourceRoot":"","sources":["../../src/app/CreateApp.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"TanstackDevtools.d.ts","sourceRoot":"","sources":["../../src/app/TanstackDevtools.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAsBlD,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,OAAO,GAAG,MAAM,CAAC;IACjC,cAAc,EAAE,cAAc,CAAC;CAChC;AAkED,MAAM,CAAC,OAAO,UAAU,uBAAuB,CAAC,EAC9C,cAAc,EACd,cAAc,GACf,EAAE,qBAAqB,2CA0CvB"}
1
+ {"version":3,"file":"TanstackDevtools.d.ts","sourceRoot":"","sources":["../../src/app/TanstackDevtools.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAoClD,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,OAAO,GAAG,MAAM,CAAC;IACjC,cAAc,EAAE,cAAc,CAAC;CAChC;AAkED,MAAM,CAAC,OAAO,UAAU,uBAAuB,CAAC,EAC9C,cAAc,EACd,cAAc,GACf,EAAE,qBAAqB,2CAoEvB"}
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Keyboard shortcut that opens the devtools shell: Cmd+Shift+` on Mac,
3
+ * Ctrl+Shift+` elsewhere.
4
+ *
5
+ * Why this combo, and why `~`: unshifted Ctrl/Cmd+` is macOS "cycle
6
+ * windows" and never reaches the page. Shift+Backquote is the physical
7
+ * key the ticket names. `@tanstack/react-devtools` matches an exact
8
+ * `e.key` sequence via `@solid-primitives/keyboard`, and Shift+Backquote
9
+ * produces `e.key === "~"` on US layouts — so the TanStack config must
10
+ * be Shift + "~", not unshifted "`". The capture-phase listener in
11
+ * `useDevtoolsKeyboardTrigger` matches `e.code === "Backquote"` so
12
+ * non-US layouts (where Shift+Backquote is ¬ or `) still fire.
13
+ *
14
+ * Exported so tests pin the binding.
15
+ */
16
+ export declare const devtoolsOpenHotkey: readonly ["CtrlOrMeta", "Shift", "~"];
17
+ /**
18
+ * True when the event is the documented debugger shortcut. Prefers the
19
+ * physical Backquote key so it does not depend on keyboard layout;
20
+ * `e.key` of "`" or "~" is accepted as a fallback when `code` is absent
21
+ * (jsdom / synthetic events).
22
+ */
23
+ export declare function isDevtoolsOpenHotkeyEvent(event: KeyboardEvent): boolean;
24
+ /**
25
+ * Capture-phase window listener that opens the shell on the documented
26
+ * shortcut. Capture runs before app-level keydown handlers, so a page
27
+ * that stopPropagation's cannot swallow it. preventDefault +
28
+ * stopImmediatePropagation keep TanStack's own createShortcut from
29
+ * also firing (which would toggle the panel shut again).
30
+ */
31
+ export declare function useDevtoolsKeyboardTrigger(enabled: boolean): void;
32
+ /**
33
+ * Plugin id of the TanStack Devtools shell's internal event client
34
+ * (`devtoolsEventClient` in `@tanstack/devtools-client`). The shell
35
+ * subscribes to `<pluginId>:trigger-toggled` and opens/closes on the
36
+ * payload's `isOpen`. The spec asserts both strings
37
+ * against the installed packages so an upstream rename fails the build
38
+ * instead of silently breaking shake-to-open.
39
+ */
40
+ export declare const devtoolsShellPluginId = "tanstack-devtools-core";
41
+ /** Event suffix the shell listens on for open/close state changes. */
42
+ export declare const devtoolsTriggerToggledEvent = "trigger-toggled";
43
+ /**
44
+ * Open the TanStack Devtools shell programmatically by emitting the same
45
+ * bus event the shell's own (hidden) trigger button uses. Open-only by
46
+ * design: a continued shake must not immediately re-close the panel —
47
+ * closing stays on the close button / Escape / the keyboard shortcut.
48
+ * The event client queues emits until the bus connects, so an early shake
49
+ * racing the shell mount is still delivered.
50
+ */
51
+ export declare function openDevtoolsShell(): void;
52
+ /** Defaults: deliberate shakes peak 15–25 m/s²; walking/bumps stay under ~8. */
53
+ export declare const shakeDefaults: {
54
+ /** m/s² a sample must exceed to count as a shake peak. */
55
+ readonly threshold: 12;
56
+ /** Minimum ms between counted peaks (one swing = one peak, not many samples). */
57
+ readonly minPeakGapMs: 80;
58
+ /** Peaks required inside the rolling window to fire. */
59
+ readonly peakCount: 3;
60
+ /** Rolling window (ms) the peaks must land in. */
61
+ readonly windowMs: 1000;
62
+ /** Dead time (ms) after firing before the detector re-arms. */
63
+ readonly cooldownMs: 2000;
64
+ };
65
+ interface MotionAxes {
66
+ x?: number | null;
67
+ y?: number | null;
68
+ z?: number | null;
69
+ }
70
+ /** Structural subset of DeviceMotionEvent the detector needs (testable in node). */
71
+ export interface MotionEventLike {
72
+ acceleration?: MotionAxes | null;
73
+ accelerationIncludingGravity?: MotionAxes | null;
74
+ }
75
+ /**
76
+ * Acceleration magnitude (m/s²) of a devicemotion sample. Prefers the
77
+ * gravity-excluded reading; falls back to the including-gravity reading
78
+ * minus standard gravity. Returns null when the event carries no data
79
+ * (some desktop browsers fire devicemotion with all-null axes).
80
+ */
81
+ export declare function motionMagnitude(event: MotionEventLike): number | null;
82
+ export interface ShakeDetectorOptions {
83
+ onShake: () => void;
84
+ threshold?: number;
85
+ minPeakGapMs?: number;
86
+ peakCount?: number;
87
+ windowMs?: number;
88
+ cooldownMs?: number;
89
+ }
90
+ export interface ShakeDetector {
91
+ /** Feed a devicemotion sample. `now` is injectable for tests. */
92
+ handleMotion: (event: MotionEventLike, now?: number) => void;
93
+ /** Drop all peaks and cooldown state. */
94
+ reset: () => void;
95
+ }
96
+ /**
97
+ * Debounced shake detector: fires `onShake` when `peakCount` peaks above
98
+ * `threshold` (each at least `minPeakGapMs` apart) land inside a rolling
99
+ * `windowMs`, then goes dead for `cooldownMs` before re-arming.
100
+ */
101
+ export declare function createShakeDetector({ onShake, threshold, minPeakGapMs, peakCount, windowMs, cooldownMs, }: ShakeDetectorOptions): ShakeDetector;
102
+ export type MotionPermissionState = "granted" | "awaiting-gesture" | "requesting" | "denied";
103
+ export interface MotionPermissionFlow {
104
+ readonly state: MotionPermissionState;
105
+ /**
106
+ * Call from a user gesture (pointerup/click). Resolves once the
107
+ * permission settles; no-ops unless state is "awaiting-gesture".
108
+ */
109
+ handleGesture: () => Promise<void>;
110
+ }
111
+ /**
112
+ * Permission state machine. Platforms without
113
+ * `DeviceMotionEvent.requestPermission` (Android, desktop) grant
114
+ * immediately; iOS WebKit waits for a user gesture, asks once, and lands
115
+ * on granted or denied. A denial is terminal for this page load — Safari
116
+ * remembers the answer per site, so later loads resolve silently.
117
+ */
118
+ export declare function createMotionPermissionFlow({ requestPermission, onGranted, onDenied, }: {
119
+ requestPermission?: () => Promise<string>;
120
+ onGranted: () => void;
121
+ onDenied?: () => void;
122
+ }): MotionPermissionFlow;
123
+ /**
124
+ * True only on the platform that gates devicemotion behind a user-gesture
125
+ * grant: iOS 13+ WebKit exposes `DeviceMotionEvent.requestPermission`.
126
+ * Android and desktop return false — they deliver motion events without a
127
+ * prompt, so shake-to-open arms itself there and no trigger UI is needed.
128
+ */
129
+ export declare function isMotionPermissionRequired(): boolean;
130
+ /**
131
+ * The window event an app dispatches from a DELIBERATE user gesture to arm
132
+ * shake-to-open on iOS (e.g. the SHC console's triple-tap on the build
133
+ * number in Settings › Estate). It is a window CustomEvent rather than an
134
+ * imported function on purpose: the trigger lives in a feature package that
135
+ * does not — and must not — depend on this core build. `dispatchEvent` is
136
+ * synchronous, so the `requestPermission()` this fires runs INSIDE the
137
+ * originating gesture's call stack, which is the whole reason iOS accepts
138
+ * it. `armDevtoolsMotion()` dispatches it for callers that CAN import core.
139
+ */
140
+ export declare const devtoolsArmMotionEvent = "mpo:devtools-arm-motion";
141
+ /**
142
+ * The window event core dispatches back once an arm attempt settles, so a
143
+ * trigger UI can report the honest outcome. `detail.granted` is true only
144
+ * when motion is now live.
145
+ */
146
+ export declare const devtoolsMotionArmedEvent = "mpo:devtools-motion-armed";
147
+ /** Test seam: forget the grant and drop attachers between cases. */
148
+ export declare function __resetMotionArming(): void;
149
+ /**
150
+ * Request motion permission from within a user gesture and, on grant,
151
+ * attach every waiting shake listener. Idempotent once granted. Resolves
152
+ * to the settled permission state; a denial is terminal for this page load
153
+ * (Safari remembers it per site). Broadcast the outcome on
154
+ * `devtoolsMotionArmedEvent` so a trigger UI can report it.
155
+ */
156
+ export declare function requestMotionPermissionFromGesture(): Promise<MotionPermissionState>;
157
+ /**
158
+ * Arm shake-to-open programmatically. For callers that CAN import core
159
+ * (the app layer); a feature package instead dispatches
160
+ * `devtoolsArmMotionEvent` directly. Must be called from a user gesture on
161
+ * iOS. No-op on the server.
162
+ */
163
+ export declare function armDevtoolsMotion(): void;
164
+ /**
165
+ * Shake-to-open for the devtools shell. Attaches a `devicemotion` listener
166
+ * and opens the shell on a detected shake. Desktop browsers deliver no
167
+ * devicemotion events, so the listener is inert there — the keyboard
168
+ * shortcut is the desktop path.
169
+ *
170
+ * iOS 13+ gates devicemotion behind a permission prompt that can ONLY be
171
+ * requested from a user gesture, and the first shake cannot self-grant. So
172
+ * on iOS the listener attaches only after the app arms it — by dispatching
173
+ * `devtoolsArmMotionEvent` from a deliberate gesture (the console wires the
174
+ * build-number triple-tap). Android/desktop attach immediately. SSR-safe;
175
+ * every listener is torn down on unmount.
176
+ */
177
+ export declare function useShakeToOpen(enabled: boolean, onShake?: () => void): void;
178
+ export {};
179
+ //# sourceMappingURL=devtoolsTrigger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devtoolsTrigger.d.ts","sourceRoot":"","sources":["../../src/app/devtoolsTrigger.ts"],"names":[],"mappings":"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"}