@buoy-gg/tv-remote 7.0.38 → 7.0.39

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.
@@ -1 +1,56 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),Object.defineProperty(exports,"arm",{enumerable:!0,get:function(){return _tvEventStore.arm}}),Object.defineProperty(exports,"clear",{enumerable:!0,get:function(){return _tvEventStore.clear}}),Object.defineProperty(exports,"disarm",{enumerable:!0,get:function(){return _tvEventStore.disarm}}),Object.defineProperty(exports,"getEventsSince",{enumerable:!0,get:function(){return _tvEventStore.getEventsSince}}),Object.defineProperty(exports,"getState",{enumerable:!0,get:function(){return _tvEventStore.getState}}),Object.defineProperty(exports,"setMenuCapture",{enumerable:!0,get:function(){return _tvEventStore.setMenuCapture}}),Object.defineProperty(exports,"subscribe",{enumerable:!0,get:function(){return _tvEventStore.subscribe}}),Object.defineProperty(exports,"tvRemoteSyncAdapter",{enumerable:!0,get:function(){return _tvRemoteSyncAdapter.tvRemoteSyncAdapter}});var _tvRemoteSyncAdapter=require("./sync/tvRemoteSyncAdapter"),_tvEventStore=require("./store/tvEventStore");
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "arm", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _tvEventStore.arm;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "clear", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _tvEventStore.clear;
16
+ }
17
+ });
18
+ Object.defineProperty(exports, "disarm", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _tvEventStore.disarm;
22
+ }
23
+ });
24
+ Object.defineProperty(exports, "getEventsSince", {
25
+ enumerable: true,
26
+ get: function () {
27
+ return _tvEventStore.getEventsSince;
28
+ }
29
+ });
30
+ Object.defineProperty(exports, "getState", {
31
+ enumerable: true,
32
+ get: function () {
33
+ return _tvEventStore.getState;
34
+ }
35
+ });
36
+ Object.defineProperty(exports, "setMenuCapture", {
37
+ enumerable: true,
38
+ get: function () {
39
+ return _tvEventStore.setMenuCapture;
40
+ }
41
+ });
42
+ Object.defineProperty(exports, "subscribe", {
43
+ enumerable: true,
44
+ get: function () {
45
+ return _tvEventStore.subscribe;
46
+ }
47
+ });
48
+ Object.defineProperty(exports, "tvRemoteSyncAdapter", {
49
+ enumerable: true,
50
+ get: function () {
51
+ return _tvRemoteSyncAdapter.tvRemoteSyncAdapter;
52
+ }
53
+ });
54
+ var _tvRemoteSyncAdapter = require("./sync/tvRemoteSyncAdapter");
55
+ var _tvEventStore = require("./store/tvEventStore");
56
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_tvRemoteSyncAdapter","require","_tvEventStore"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAcA,IAAAA,oBAAA,GAAAC,OAAA;AAKA,IAAAC,aAAA,GAAAD,OAAA","ignoreList":[]}
@@ -1 +1,167 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.arm=arm,exports.clear=clear,exports.disarm=disarm,exports.getEventsSince=getEventsSince,exports.getState=getState,exports.setMenuCapture=setMenuCapture,exports.subscribe=subscribe;var ReactNative=_interopRequireWildcard(require("react-native"));function _interopRequireWildcard(e,t){if("function"==typeof WeakMap)var n=new WeakMap,r=new WeakMap;return(_interopRequireWildcard=function(e,t){if(!t&&e&&e.__esModule)return e;var i,s,a={__proto__:null,default:e};if(null===e||"object"!=typeof e&&"function"!=typeof e)return a;if(i=t?r:n){if(i.has(e))return i.get(e);i.set(e,a)}for(const t in e)"default"!==t&&{}.hasOwnProperty.call(e,t)&&((s=(i=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,t))&&(s.get||s.set)?i(a,t,s):a[t]=e[t]);return a})(e,t)}const MAX_EVENTS=50,IGNORED_EVENT_TYPES=new Set(["pan","swipeUp","swipeDown","swipeLeft","swipeRight"]),RN=ReactNative,isTV=!0===RN.Platform?.isTV;let events=[],seq=0,armed=!1,menuCaptureArmed=!1,subscription=null;const listeners=new Set;function emitChange(){listeners.forEach(e=>{e()})}function handleEvent(e){if(!armed)return;const t=e,n=t?.eventType;if("string"!=typeof n)return;if(IGNORED_EVENT_TYPES.has(n))return;if(0===t?.eventKeyAction)return;seq+=1;const r={seq:seq,t:Date.now(),eventType:n,eventKeyAction:t?.eventKeyAction};events=events.length>=50?[...events.slice(1),r]:[...events,r],emitChange()}function arm(){armed||(armed=!0,isTV&&RN.TVEventHandler&&!subscription&&(subscription=RN.TVEventHandler.addListener(handleEvent)),emitChange())}function disarm(){subscription&&(subscription.remove(),subscription=null),menuCaptureArmed&&setMenuCapture(!1),armed&&(armed=!1,emitChange())}function setMenuCapture(e){isTV&&"ios"===RN.Platform.OS&&RN.TVEventControl&&e!==menuCaptureArmed&&(e?RN.TVEventControl.enableTVMenuKey():RN.TVEventControl.disableTVMenuKey(),menuCaptureArmed=e,emitChange())}function clear(){0!==events.length&&(events=[],emitChange())}function getEventsSince(e){return Number.isFinite(e)?events.filter(t=>t.seq>e):events.slice()}function getState(){return{supported:isTV,platform:RN.Platform?.OS??"unknown",captureArmed:armed,listening:null!==subscription,menuCaptureArmed:menuCaptureArmed,seq:seq,recent:events.slice()}}function subscribe(e){return listeners.add(e),()=>{listeners.delete(e)}}
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.arm = arm;
7
+ exports.clear = clear;
8
+ exports.disarm = disarm;
9
+ exports.getEventsSince = getEventsSince;
10
+ exports.getState = getState;
11
+ exports.setMenuCapture = setMenuCapture;
12
+ exports.subscribe = subscribe;
13
+ var ReactNative = _interopRequireWildcard(require("react-native"));
14
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
15
+ /**
16
+ * tvEventStore — the whole device-side half of the TV remote tool.
17
+ *
18
+ * CONTRACT: this store only ever OBSERVES. It never injects, synthesizes, or
19
+ * fakes a remote press. Presses come from the host (Buoy Desktop shells out to
20
+ * `adb shell input keyevent` / `idb ui key`), because those go through the real
21
+ * platform focus engine; anything we could fake in-process would move focus
22
+ * without firing events, or fire events without moving focus. See
23
+ * TV_REMOTE_DRIVER_PLAN.md §2.
24
+ *
25
+ * It is also deliberately UI-less. On Android TV any focusable view we rendered
26
+ * would become a D-pad stop in the host app's focus order, so the tool would
27
+ * alter the navigation it is supposed to be replaying.
28
+ *
29
+ * Safe to ship in non-TV apps: the native event emitter is never touched unless
30
+ * `Platform.isTV` is true, so the cost on a phone is one boolean.
31
+ */
32
+
33
+ /** One captured remote event, as it goes over the wire to the dashboard. */
34
+
35
+ /**
36
+ * Ring buffer depth. Replay polls `getEventsSince` every few dozen ms with a
37
+ * ~2s budget per step, so 50 is many times more than any echo needs; it exists
38
+ * so a human scrubbing the echo strip has some scrollback.
39
+ */
40
+ const MAX_EVENTS = 50;
41
+
42
+ /**
43
+ * Continuous gestures are not presses and are never recorded — the macro format
44
+ * is discrete keys. Dropping them here keeps them out of the ring buffer so
45
+ * they can't push real presses out of it during a replay.
46
+ */
47
+ const IGNORED_EVENT_TYPES = new Set(["pan", "swipeUp", "swipeDown", "swipeLeft", "swipeRight"]);
48
+ /**
49
+ * `TVEventHandler` / `TVEventControl` only exist on the react-native-tvos fork.
50
+ * A namespace read (rather than a named import) keeps this module importable on
51
+ * stock react-native, where those exports are absent.
52
+ */
53
+ const RN = ReactNative;
54
+ const isTV = RN.Platform?.isTV === true;
55
+ let events = [];
56
+ let seq = 0;
57
+ let armed = false;
58
+ let menuCaptureArmed = false;
59
+ let subscription = null;
60
+ const listeners = new Set();
61
+ function emitChange() {
62
+ listeners.forEach(listener => {
63
+ listener();
64
+ });
65
+ }
66
+ function handleEvent(raw) {
67
+ // Disarming removes the subscription, but don't take that on trust: a native
68
+ // emitter that delivered one more event after `remove()` would land a stray
69
+ // press in the buffer, and a stray press is exactly what a replay would
70
+ // mistake for a step's echo.
71
+ if (!armed) return;
72
+ const event = raw;
73
+ const eventType = event?.eventType;
74
+ if (typeof eventType !== "string") return;
75
+ if (IGNORED_EVENT_TYPES.has(eventType)) return;
76
+
77
+ /**
78
+ * Dedupe by ignoring key DOWN, never key UP. tvOS emits keyAction 1 (up)
79
+ * ONLY — taps reach the gesture recognizer at StateEnded — so filtering to
80
+ * "down" would swallow every tvOS event. Android's down-emit is
81
+ * feature-flagged off by default, but dropping it here is the correct
82
+ * invariant either way: one press must produce exactly one echo.
83
+ */
84
+ if (event?.eventKeyAction === 0) return;
85
+ seq += 1;
86
+ const next = {
87
+ seq,
88
+ t: Date.now(),
89
+ eventType,
90
+ eventKeyAction: event?.eventKeyAction
91
+ };
92
+ events = events.length >= MAX_EVENTS ? [...events.slice(1), next] : [...events, next];
93
+ emitChange();
94
+ }
95
+
96
+ /** Start pushing remote events into the buffer. Idempotent. */
97
+ function arm() {
98
+ if (armed) return;
99
+ armed = true;
100
+ if (isTV && RN.TVEventHandler && !subscription) {
101
+ subscription = RN.TVEventHandler.addListener(handleEvent);
102
+ }
103
+ emitChange();
104
+ }
105
+
106
+ /**
107
+ * Stop capturing and hand the Menu key back to the platform. Every teardown
108
+ * path funnels through here — leaving menu capture on would leave the app
109
+ * unable to navigate back, which is an App Store behavior change.
110
+ */
111
+ function disarm() {
112
+ if (subscription) {
113
+ subscription.remove();
114
+ subscription = null;
115
+ }
116
+ if (menuCaptureArmed) setMenuCapture(false);
117
+ if (!armed) return;
118
+ armed = false;
119
+ emitChange();
120
+ }
121
+
122
+ /**
123
+ * tvOS: route the Menu key to JS so it can be recorded, instead of letting it
124
+ * pop the navigation stack (and background the app at the root). This changes
125
+ * how the app under test behaves, so it is opt-in per recording session and is
126
+ * always undone on disarm.
127
+ */
128
+ function setMenuCapture(on) {
129
+ if (!isTV || RN.Platform.OS !== "ios" || !RN.TVEventControl) return;
130
+ if (on === menuCaptureArmed) return;
131
+ if (on) {
132
+ RN.TVEventControl.enableTVMenuKey();
133
+ } else {
134
+ RN.TVEventControl.disableTVMenuKey();
135
+ }
136
+ menuCaptureArmed = on;
137
+ emitChange();
138
+ }
139
+ function clear() {
140
+ if (events.length === 0) return;
141
+ events = [];
142
+ emitChange();
143
+ }
144
+
145
+ /** Events strictly newer than `sinceSeq` — the replay echo cursor. */
146
+ function getEventsSince(sinceSeq) {
147
+ if (!Number.isFinite(sinceSeq)) return events.slice();
148
+ return events.filter(event => event.seq > sinceSeq);
149
+ }
150
+ function getState() {
151
+ return {
152
+ supported: isTV,
153
+ platform: RN.Platform?.OS ?? "unknown",
154
+ captureArmed: armed,
155
+ listening: subscription !== null,
156
+ menuCaptureArmed,
157
+ seq,
158
+ recent: events.slice()
159
+ };
160
+ }
161
+ function subscribe(listener) {
162
+ listeners.add(listener);
163
+ return () => {
164
+ listeners.delete(listener);
165
+ };
166
+ }
167
+ //# sourceMappingURL=tvEventStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["ReactNative","_interopRequireWildcard","require","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","MAX_EVENTS","IGNORED_EVENT_TYPES","Set","RN","isTV","Platform","events","seq","armed","menuCaptureArmed","subscription","listeners","emitChange","forEach","listener","handleEvent","raw","event","eventType","eventKeyAction","next","Date","now","length","slice","arm","TVEventHandler","addListener","disarm","remove","setMenuCapture","on","OS","TVEventControl","enableTVMenuKey","disableTVMenuKey","clear","getEventsSince","sinceSeq","Number","isFinite","filter","getState","supported","platform","captureArmed","listening","recent","subscribe","add","delete"],"sourceRoot":"../../../src","sources":["store/tvEventStore.ts"],"mappings":"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","ignoreList":[]}
@@ -1 +1,57 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.tvRemoteSyncAdapter=void 0;var _tvEventStore=require("../store/tvEventStore");const tvRemoteSyncAdapter=exports.tvRemoteSyncAdapter={version:1,getSnapshot:()=>(0,_tvEventStore.getState)(),subscribe:t=>(0,_tvEventStore.subscribe)(t),actions:{arm:()=>((0,_tvEventStore.arm)(),(0,_tvEventStore.getState)()),disarm:()=>((0,_tvEventStore.disarm)(),(0,_tvEventStore.getState)()),getEventsSince(t){const e="number"==typeof t?.seq?t.seq:0;return{seq:(0,_tvEventStore.getState)().seq,events:(0,_tvEventStore.getEventsSince)(e)}},setMenuCapture:t=>((0,_tvEventStore.setMenuCapture)(!0===t?.on),(0,_tvEventStore.getState)()),clear:()=>((0,_tvEventStore.clear)(),(0,_tvEventStore.getState)())}};
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.tvRemoteSyncAdapter = void 0;
7
+ var _tvEventStore = require("../store/tvEventStore");
8
+ /**
9
+ * tvRemoteSyncAdapter — streams captured TV remote events to Buoy Desktop via
10
+ * @buoy-gg/external-sync.
11
+ *
12
+ * Structurally matches external-sync's `ToolSyncAdapter` WITHOUT importing the
13
+ * package (same as every other tool's adapter). Auto-discovery in @buoy-gg/core
14
+ * picks it up by export name and announces the "tv-remote" capability.
15
+ *
16
+ * `getEventsSince` exists because snapshots are throttled 200ms trailing-edge
17
+ * per tool, which is too coarse to time a replay step's echo. Replay polls this
18
+ * awaited action instead and gets the real latency.
19
+ */
20
+
21
+ const tvRemoteSyncAdapter = exports.tvRemoteSyncAdapter = {
22
+ version: 1,
23
+ getSnapshot() {
24
+ return (0, _tvEventStore.getState)();
25
+ },
26
+ subscribe(onChange) {
27
+ return (0, _tvEventStore.subscribe)(onChange);
28
+ },
29
+ actions: {
30
+ arm() {
31
+ (0, _tvEventStore.arm)();
32
+ return (0, _tvEventStore.getState)();
33
+ },
34
+ disarm() {
35
+ (0, _tvEventStore.disarm)();
36
+ return (0, _tvEventStore.getState)();
37
+ },
38
+ /** Cursor-paged echo poll. `seq: 0` returns everything buffered. */
39
+ getEventsSince(params) {
40
+ const since = typeof params?.seq === "number" ? params.seq : 0;
41
+ const state = (0, _tvEventStore.getState)();
42
+ return {
43
+ seq: state.seq,
44
+ events: (0, _tvEventStore.getEventsSince)(since)
45
+ };
46
+ },
47
+ setMenuCapture(params) {
48
+ (0, _tvEventStore.setMenuCapture)(params?.on === true);
49
+ return (0, _tvEventStore.getState)();
50
+ },
51
+ clear() {
52
+ (0, _tvEventStore.clear)();
53
+ return (0, _tvEventStore.getState)();
54
+ }
55
+ }
56
+ };
57
+ //# sourceMappingURL=tvRemoteSyncAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_tvEventStore","require","tvRemoteSyncAdapter","exports","version","getSnapshot","getState","subscribe","onChange","actions","arm","disarm","getEventsSince","params","since","seq","state","events","setMenuCapture","on","clear"],"sourceRoot":"../../../src","sources":["sync/tvRemoteSyncAdapter.ts"],"mappings":";;;;;;AAaA,IAAAA,aAAA,GAAAC,OAAA;AAbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAcO,MAAMC,mBAAmB,GAAAC,OAAA,CAAAD,mBAAA,GAAG;EACjCE,OAAO,EAAE,CAAC;EAEVC,WAAWA,CAAA,EAAkB;IAC3B,OAAO,IAAAC,sBAAQ,EAAC,CAAC;EACnB,CAAC;EAEDC,SAASA,CAACC,QAAoB,EAAc;IAC1C,OAAO,IAAAD,uBAAS,EAACC,QAAQ,CAAC;EAC5B,CAAC;EAEDC,OAAO,EAAE;IACPC,GAAGA,CAAA,EAAkB;MACnB,IAAAA,iBAAG,EAAC,CAAC;MACL,OAAO,IAAAJ,sBAAQ,EAAC,CAAC;IACnB,CAAC;IAEDK,MAAMA,CAAA,EAAkB;MACtB,IAAAA,oBAAM,EAAC,CAAC;MACR,OAAO,IAAAL,sBAAQ,EAAC,CAAC;IACnB,CAAC;IAED;IACAM,cAAcA,CAACC,MAAyB,EAGtC;MACA,MAAMC,KAAK,GAAG,OAAOD,MAAM,EAAEE,GAAG,KAAK,QAAQ,GAAGF,MAAM,CAACE,GAAG,GAAG,CAAC;MAC9D,MAAMC,KAAK,GAAG,IAAAV,sBAAQ,EAAC,CAAC;MACxB,OAAO;QAAES,GAAG,EAAEC,KAAK,CAACD,GAAG;QAAEE,MAAM,EAAE,IAAAL,4BAAc,EAACE,KAAK;MAAE,CAAC;IAC1D,CAAC;IAEDI,cAAcA,CAACL,MAAyB,EAAiB;MACvD,IAAAK,4BAAc,EAACL,MAAM,EAAEM,EAAE,KAAK,IAAI,CAAC;MACnC,OAAO,IAAAb,sBAAQ,EAAC,CAAC;IACnB,CAAC;IAEDc,KAAKA,CAAA,EAAkB;MACrB,IAAAA,mBAAK,EAAC,CAAC;MACP,OAAO,IAAAd,sBAAQ,EAAC,CAAC;IACnB;EACF;AACF,CAAC","ignoreList":[]}
@@ -1 +1,23 @@
1
- "use strict";export{tvRemoteSyncAdapter}from"./sync/tvRemoteSyncAdapter";export{arm,disarm,clear,setMenuCapture,getEventsSince,getState,subscribe}from"./store/tvEventStore";
1
+ "use strict";
2
+
3
+ /**
4
+ * @buoy-gg/tv-remote
5
+ *
6
+ * The device-side half of Buoy's TV remote driver: it CAPTURES the D-pad /
7
+ * select / menu / play-pause events the app actually receives and streams them
8
+ * to Buoy Desktop, which is where presses are injected from (adb / idb) and
9
+ * where macros are recorded and replayed.
10
+ *
11
+ * This package renders nothing and injects nothing. See the README for why.
12
+ */
13
+
14
+ // =============================================================================
15
+ // EXTERNAL SYNC (device → desktop dashboard)
16
+ // =============================================================================
17
+ export { tvRemoteSyncAdapter } from "./sync/tvRemoteSyncAdapter";
18
+
19
+ // =============================================================================
20
+ // CAPTURE STORE (arm/disarm + types)
21
+ // =============================================================================
22
+ export { arm, disarm, clear, setMenuCapture, getEventsSince, getState, subscribe } from "./store/tvEventStore";
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["tvRemoteSyncAdapter","arm","disarm","clear","setMenuCapture","getEventsSince","getState","subscribe"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAASA,mBAAmB,QAAQ,4BAA4B;;AAEhE;AACA;AACA;AACA,SACEC,GAAG,EACHC,MAAM,EACNC,KAAK,EACLC,cAAc,EACdC,cAAc,EACdC,QAAQ,EACRC,SAAS,QACJ,sBAAsB","ignoreList":[]}
@@ -1 +1,157 @@
1
- "use strict";import*as ReactNative from"react-native";const MAX_EVENTS=50,IGNORED_EVENT_TYPES=new Set(["pan","swipeUp","swipeDown","swipeLeft","swipeRight"]),RN=ReactNative,isTV=!0===RN.Platform?.isTV;let events=[],seq=0,armed=!1,menuCaptureArmed=!1,subscription=null;const listeners=new Set;function emitChange(){listeners.forEach(e=>{e()})}function handleEvent(e){if(!armed)return;const t=e,n=t?.eventType;if("string"!=typeof n)return;if(IGNORED_EVENT_TYPES.has(n))return;if(0===t?.eventKeyAction)return;seq+=1;const r={seq:seq,t:Date.now(),eventType:n,eventKeyAction:t?.eventKeyAction};events=events.length>=50?[...events.slice(1),r]:[...events,r],emitChange()}export function arm(){armed||(armed=!0,isTV&&RN.TVEventHandler&&!subscription&&(subscription=RN.TVEventHandler.addListener(handleEvent)),emitChange())}export function disarm(){subscription&&(subscription.remove(),subscription=null),menuCaptureArmed&&setMenuCapture(!1),armed&&(armed=!1,emitChange())}export function setMenuCapture(e){isTV&&"ios"===RN.Platform.OS&&RN.TVEventControl&&e!==menuCaptureArmed&&(e?RN.TVEventControl.enableTVMenuKey():RN.TVEventControl.disableTVMenuKey(),menuCaptureArmed=e,emitChange())}export function clear(){0!==events.length&&(events=[],emitChange())}export function getEventsSince(e){return Number.isFinite(e)?events.filter(t=>t.seq>e):events.slice()}export function getState(){return{supported:isTV,platform:RN.Platform?.OS??"unknown",captureArmed:armed,listening:null!==subscription,menuCaptureArmed:menuCaptureArmed,seq:seq,recent:events.slice()}}export function subscribe(e){return listeners.add(e),()=>{listeners.delete(e)}}
1
+ "use strict";
2
+
3
+ /**
4
+ * tvEventStore — the whole device-side half of the TV remote tool.
5
+ *
6
+ * CONTRACT: this store only ever OBSERVES. It never injects, synthesizes, or
7
+ * fakes a remote press. Presses come from the host (Buoy Desktop shells out to
8
+ * `adb shell input keyevent` / `idb ui key`), because those go through the real
9
+ * platform focus engine; anything we could fake in-process would move focus
10
+ * without firing events, or fire events without moving focus. See
11
+ * TV_REMOTE_DRIVER_PLAN.md §2.
12
+ *
13
+ * It is also deliberately UI-less. On Android TV any focusable view we rendered
14
+ * would become a D-pad stop in the host app's focus order, so the tool would
15
+ * alter the navigation it is supposed to be replaying.
16
+ *
17
+ * Safe to ship in non-TV apps: the native event emitter is never touched unless
18
+ * `Platform.isTV` is true, so the cost on a phone is one boolean.
19
+ */
20
+
21
+ import * as ReactNative from "react-native";
22
+
23
+ /** One captured remote event, as it goes over the wire to the dashboard. */
24
+
25
+ /**
26
+ * Ring buffer depth. Replay polls `getEventsSince` every few dozen ms with a
27
+ * ~2s budget per step, so 50 is many times more than any echo needs; it exists
28
+ * so a human scrubbing the echo strip has some scrollback.
29
+ */
30
+ const MAX_EVENTS = 50;
31
+
32
+ /**
33
+ * Continuous gestures are not presses and are never recorded — the macro format
34
+ * is discrete keys. Dropping them here keeps them out of the ring buffer so
35
+ * they can't push real presses out of it during a replay.
36
+ */
37
+ const IGNORED_EVENT_TYPES = new Set(["pan", "swipeUp", "swipeDown", "swipeLeft", "swipeRight"]);
38
+ /**
39
+ * `TVEventHandler` / `TVEventControl` only exist on the react-native-tvos fork.
40
+ * A namespace read (rather than a named import) keeps this module importable on
41
+ * stock react-native, where those exports are absent.
42
+ */
43
+ const RN = ReactNative;
44
+ const isTV = RN.Platform?.isTV === true;
45
+ let events = [];
46
+ let seq = 0;
47
+ let armed = false;
48
+ let menuCaptureArmed = false;
49
+ let subscription = null;
50
+ const listeners = new Set();
51
+ function emitChange() {
52
+ listeners.forEach(listener => {
53
+ listener();
54
+ });
55
+ }
56
+ function handleEvent(raw) {
57
+ // Disarming removes the subscription, but don't take that on trust: a native
58
+ // emitter that delivered one more event after `remove()` would land a stray
59
+ // press in the buffer, and a stray press is exactly what a replay would
60
+ // mistake for a step's echo.
61
+ if (!armed) return;
62
+ const event = raw;
63
+ const eventType = event?.eventType;
64
+ if (typeof eventType !== "string") return;
65
+ if (IGNORED_EVENT_TYPES.has(eventType)) return;
66
+
67
+ /**
68
+ * Dedupe by ignoring key DOWN, never key UP. tvOS emits keyAction 1 (up)
69
+ * ONLY — taps reach the gesture recognizer at StateEnded — so filtering to
70
+ * "down" would swallow every tvOS event. Android's down-emit is
71
+ * feature-flagged off by default, but dropping it here is the correct
72
+ * invariant either way: one press must produce exactly one echo.
73
+ */
74
+ if (event?.eventKeyAction === 0) return;
75
+ seq += 1;
76
+ const next = {
77
+ seq,
78
+ t: Date.now(),
79
+ eventType,
80
+ eventKeyAction: event?.eventKeyAction
81
+ };
82
+ events = events.length >= MAX_EVENTS ? [...events.slice(1), next] : [...events, next];
83
+ emitChange();
84
+ }
85
+
86
+ /** Start pushing remote events into the buffer. Idempotent. */
87
+ export function arm() {
88
+ if (armed) return;
89
+ armed = true;
90
+ if (isTV && RN.TVEventHandler && !subscription) {
91
+ subscription = RN.TVEventHandler.addListener(handleEvent);
92
+ }
93
+ emitChange();
94
+ }
95
+
96
+ /**
97
+ * Stop capturing and hand the Menu key back to the platform. Every teardown
98
+ * path funnels through here — leaving menu capture on would leave the app
99
+ * unable to navigate back, which is an App Store behavior change.
100
+ */
101
+ export function disarm() {
102
+ if (subscription) {
103
+ subscription.remove();
104
+ subscription = null;
105
+ }
106
+ if (menuCaptureArmed) setMenuCapture(false);
107
+ if (!armed) return;
108
+ armed = false;
109
+ emitChange();
110
+ }
111
+
112
+ /**
113
+ * tvOS: route the Menu key to JS so it can be recorded, instead of letting it
114
+ * pop the navigation stack (and background the app at the root). This changes
115
+ * how the app under test behaves, so it is opt-in per recording session and is
116
+ * always undone on disarm.
117
+ */
118
+ export function setMenuCapture(on) {
119
+ if (!isTV || RN.Platform.OS !== "ios" || !RN.TVEventControl) return;
120
+ if (on === menuCaptureArmed) return;
121
+ if (on) {
122
+ RN.TVEventControl.enableTVMenuKey();
123
+ } else {
124
+ RN.TVEventControl.disableTVMenuKey();
125
+ }
126
+ menuCaptureArmed = on;
127
+ emitChange();
128
+ }
129
+ export function clear() {
130
+ if (events.length === 0) return;
131
+ events = [];
132
+ emitChange();
133
+ }
134
+
135
+ /** Events strictly newer than `sinceSeq` — the replay echo cursor. */
136
+ export function getEventsSince(sinceSeq) {
137
+ if (!Number.isFinite(sinceSeq)) return events.slice();
138
+ return events.filter(event => event.seq > sinceSeq);
139
+ }
140
+ export function getState() {
141
+ return {
142
+ supported: isTV,
143
+ platform: RN.Platform?.OS ?? "unknown",
144
+ captureArmed: armed,
145
+ listening: subscription !== null,
146
+ menuCaptureArmed,
147
+ seq,
148
+ recent: events.slice()
149
+ };
150
+ }
151
+ export function subscribe(listener) {
152
+ listeners.add(listener);
153
+ return () => {
154
+ listeners.delete(listener);
155
+ };
156
+ }
157
+ //# sourceMappingURL=tvEventStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["ReactNative","MAX_EVENTS","IGNORED_EVENT_TYPES","Set","RN","isTV","Platform","events","seq","armed","menuCaptureArmed","subscription","listeners","emitChange","forEach","listener","handleEvent","raw","event","eventType","has","eventKeyAction","next","t","Date","now","length","slice","arm","TVEventHandler","addListener","disarm","remove","setMenuCapture","on","OS","TVEventControl","enableTVMenuKey","disableTVMenuKey","clear","getEventsSince","sinceSeq","Number","isFinite","filter","getState","supported","platform","captureArmed","listening","recent","subscribe","add","delete"],"sourceRoot":"../../../src","sources":["store/tvEventStore.ts"],"mappings":"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","ignoreList":[]}
@@ -1 +1,53 @@
1
- "use strict";import{arm,clear,disarm,getEventsSince,getState,setMenuCapture,subscribe}from"../store/tvEventStore";export const tvRemoteSyncAdapter={version:1,getSnapshot:()=>getState(),subscribe:e=>subscribe(e),actions:{arm:()=>(arm(),getState()),disarm:()=>(disarm(),getState()),getEventsSince(e){const t="number"==typeof e?.seq?e.seq:0;return{seq:getState().seq,events:getEventsSince(t)}},setMenuCapture:e=>(setMenuCapture(!0===e?.on),getState()),clear:()=>(clear(),getState())}};
1
+ "use strict";
2
+
3
+ /**
4
+ * tvRemoteSyncAdapter — streams captured TV remote events to Buoy Desktop via
5
+ * @buoy-gg/external-sync.
6
+ *
7
+ * Structurally matches external-sync's `ToolSyncAdapter` WITHOUT importing the
8
+ * package (same as every other tool's adapter). Auto-discovery in @buoy-gg/core
9
+ * picks it up by export name and announces the "tv-remote" capability.
10
+ *
11
+ * `getEventsSince` exists because snapshots are throttled 200ms trailing-edge
12
+ * per tool, which is too coarse to time a replay step's echo. Replay polls this
13
+ * awaited action instead and gets the real latency.
14
+ */
15
+
16
+ import { arm, clear, disarm, getEventsSince, getState, setMenuCapture, subscribe } from "../store/tvEventStore";
17
+ export const tvRemoteSyncAdapter = {
18
+ version: 1,
19
+ getSnapshot() {
20
+ return getState();
21
+ },
22
+ subscribe(onChange) {
23
+ return subscribe(onChange);
24
+ },
25
+ actions: {
26
+ arm() {
27
+ arm();
28
+ return getState();
29
+ },
30
+ disarm() {
31
+ disarm();
32
+ return getState();
33
+ },
34
+ /** Cursor-paged echo poll. `seq: 0` returns everything buffered. */
35
+ getEventsSince(params) {
36
+ const since = typeof params?.seq === "number" ? params.seq : 0;
37
+ const state = getState();
38
+ return {
39
+ seq: state.seq,
40
+ events: getEventsSince(since)
41
+ };
42
+ },
43
+ setMenuCapture(params) {
44
+ setMenuCapture(params?.on === true);
45
+ return getState();
46
+ },
47
+ clear() {
48
+ clear();
49
+ return getState();
50
+ }
51
+ }
52
+ };
53
+ //# sourceMappingURL=tvRemoteSyncAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["arm","clear","disarm","getEventsSince","getState","setMenuCapture","subscribe","tvRemoteSyncAdapter","version","getSnapshot","onChange","actions","params","since","seq","state","events","on"],"sourceRoot":"../../../src","sources":["sync/tvRemoteSyncAdapter.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SACEA,GAAG,EACHC,KAAK,EACLC,MAAM,EACNC,cAAc,EACdC,QAAQ,EACRC,cAAc,EACdC,SAAS,QAGJ,uBAAuB;AAE9B,OAAO,MAAMC,mBAAmB,GAAG;EACjCC,OAAO,EAAE,CAAC;EAEVC,WAAWA,CAAA,EAAkB;IAC3B,OAAOL,QAAQ,CAAC,CAAC;EACnB,CAAC;EAEDE,SAASA,CAACI,QAAoB,EAAc;IAC1C,OAAOJ,SAAS,CAACI,QAAQ,CAAC;EAC5B,CAAC;EAEDC,OAAO,EAAE;IACPX,GAAGA,CAAA,EAAkB;MACnBA,GAAG,CAAC,CAAC;MACL,OAAOI,QAAQ,CAAC,CAAC;IACnB,CAAC;IAEDF,MAAMA,CAAA,EAAkB;MACtBA,MAAM,CAAC,CAAC;MACR,OAAOE,QAAQ,CAAC,CAAC;IACnB,CAAC;IAED;IACAD,cAAcA,CAACS,MAAyB,EAGtC;MACA,MAAMC,KAAK,GAAG,OAAOD,MAAM,EAAEE,GAAG,KAAK,QAAQ,GAAGF,MAAM,CAACE,GAAG,GAAG,CAAC;MAC9D,MAAMC,KAAK,GAAGX,QAAQ,CAAC,CAAC;MACxB,OAAO;QAAEU,GAAG,EAAEC,KAAK,CAACD,GAAG;QAAEE,MAAM,EAAEb,cAAc,CAACU,KAAK;MAAE,CAAC;IAC1D,CAAC;IAEDR,cAAcA,CAACO,MAAyB,EAAiB;MACvDP,cAAc,CAACO,MAAM,EAAEK,EAAE,KAAK,IAAI,CAAC;MACnC,OAAOb,QAAQ,CAAC,CAAC;IACnB,CAAC;IAEDH,KAAKA,CAAA,EAAkB;MACrBA,KAAK,CAAC,CAAC;MACP,OAAOG,QAAQ,CAAC,CAAC;IACnB;EACF;AACF,CAAC","ignoreList":[]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAKjE,OAAO,EACL,GAAG,EACH,MAAM,EACN,KAAK,EACL,cAAc,EACd,cAAc,EACd,QAAQ,EACR,SAAS,GACV,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tvEventStore.d.ts","sourceRoot":"","sources":["../../../src/store/tvEventStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,4EAA4E;AAC5E,MAAM,WAAW,aAAa;IAC5B,kEAAkE;IAClE,GAAG,EAAE,MAAM,CAAC;IACZ,+BAA+B;IAC/B,CAAC,EAAE,MAAM,CAAC;IACV,+GAA+G;IAC/G,SAAS,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,qEAAqE;IACrE,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB,0EAA0E;IAC1E,gBAAgB,EAAE,OAAO,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAwFD,+DAA+D;AAC/D,wBAAgB,GAAG,IAAI,IAAI,CAO1B;AAED;;;;GAIG;AACH,wBAAgB,MAAM,IAAI,IAAI,CAS7B;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAUhD;AAED,wBAAgB,KAAK,IAAI,IAAI,CAI5B;AAED,sEAAsE;AACtE,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,EAAE,CAGhE;AAED,wBAAgB,QAAQ,IAAI,aAAa,CAUxC;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAK1D"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tvRemoteSyncAdapter.d.ts","sourceRoot":"","sources":["../../../src/sync/tvRemoteSyncAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAQL,KAAK,aAAa,EAClB,KAAK,aAAa,EACnB,MAAM,uBAAuB,CAAC;AAE/B,eAAO,MAAM,mBAAmB;;mBAGf,aAAa;wBAIR,MAAM,IAAI,GAAG,MAAM,IAAI;;eAKlC,aAAa;kBAKV,aAAa;QAKvB,oEAAoE;gCAC5C;YAAE,GAAG,CAAC,EAAE,MAAM,CAAA;SAAE,GAAG;YACzC,GAAG,EAAE,MAAM,CAAC;YACZ,MAAM,EAAE,aAAa,EAAE,CAAC;SACzB;gCAMuB;YAAE,EAAE,CAAC,EAAE,OAAO,CAAA;SAAE,GAAG,aAAa;iBAK/C,aAAa;;CAKzB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buoy-gg/tv-remote",
3
- "version": "7.0.38",
3
+ "version": "7.0.39",
4
4
  "description": "TV remote capture for React Native TV apps — records the D-pad/select/menu events the app actually receives, so Buoy Desktop can drive and replay real remote presses. Part of Buoy devtools.",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",