@decky/ui 4.7.0 → 4.7.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.
@@ -25,6 +25,7 @@ export function injectFCTrampoline(component, customHooks) {
25
25
  applyHookStubs(customHooks);
26
26
  window.SP_REACT.createElement = () => {
27
27
  loggingEnabled && logger.debug("createElement hook called");
28
+ loggingEnabled && console.trace("createElement trace");
28
29
  return Object.create(component.prototype);
29
30
  };
30
31
  }
@@ -37,26 +38,36 @@ export function injectFCTrampoline(component, customHooks) {
37
38
  window.SP_REACT.createElement = oldCreateElement;
38
39
  }
39
40
  };
41
+ let renderHookStep = 0;
40
42
  Object.defineProperty(component, "contextType", {
41
43
  configurable: true,
42
44
  get: function () {
43
- loggingEnabled && logger.debug("get contexttype", this, stubsApplied);
44
- applyStubsIfNeeded();
45
+ loggingEnabled && logger.debug("get contexttype", this, stubsApplied, renderHookStep);
46
+ loggingEnabled && console.trace("contextType trace");
47
+ if (renderHookStep == 0)
48
+ renderHookStep = 1;
49
+ else if (renderHookStep == 3)
50
+ renderHookStep = 4;
45
51
  return this._contextType;
46
52
  },
47
53
  set: function (value) {
48
54
  this._contextType = value;
49
55
  }
50
56
  });
51
- Object.defineProperty(component, "getDerivedStateFromProps", {
57
+ Object.defineProperty(component, "contextTypes", {
52
58
  configurable: true,
53
59
  get: function () {
54
- loggingEnabled && logger.debug("get getDerivedStateFromProps", this, stubsApplied);
55
- removeStubsIfNeeded();
56
- return this._getDerivedStateFromProps;
60
+ loggingEnabled && logger.debug("get contexttypes", this, stubsApplied, renderHookStep);
61
+ loggingEnabled && console.trace("contextTypes trace");
62
+ if (renderHookStep == 1) {
63
+ renderHookStep = 2;
64
+ applyStubsIfNeeded();
65
+ }
66
+ ;
67
+ return this._contextTypes;
57
68
  },
58
69
  set: function (value) {
59
- this._getDerivedStateFromProps = value;
70
+ this._contextTypes = value;
60
71
  }
61
72
  });
62
73
  Object.defineProperty(component.prototype, "updater", {
@@ -65,10 +76,29 @@ export function injectFCTrampoline(component, customHooks) {
65
76
  return this._updater;
66
77
  },
67
78
  set: function (value) {
68
- loggingEnabled && logger.debug("set updater", this, value, stubsApplied);
69
- removeStubsIfNeeded();
79
+ loggingEnabled && logger.debug("set updater", this, value, stubsApplied, renderHookStep);
80
+ loggingEnabled && console.trace("updater trace");
81
+ if (renderHookStep == 2) {
82
+ renderHookStep = 0;
83
+ removeStubsIfNeeded();
84
+ }
70
85
  return this._updater = value;
71
86
  }
72
87
  });
88
+ Object.defineProperty(component, "getDerivedStateFromProps", {
89
+ configurable: true,
90
+ get: function () {
91
+ loggingEnabled && logger.debug("get getDerivedStateFromProps", this, stubsApplied, renderHookStep);
92
+ loggingEnabled && console.trace("getDerivedStateFromProps trace");
93
+ if (renderHookStep == 2) {
94
+ renderHookStep = 0;
95
+ removeStubsIfNeeded();
96
+ }
97
+ return this._getDerivedStateFromProps;
98
+ },
99
+ set: function (value) {
100
+ this._getDerivedStateFromProps = value;
101
+ }
102
+ });
73
103
  return userComponent;
74
104
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decky/ui",
3
- "version": "4.7.0",
3
+ "version": "4.7.1",
4
4
  "description": "A library for interacting with the Steam frontend in Decky plugins and elsewhere.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -126,6 +126,7 @@ export interface Navigation {
126
126
  OpenQuickAccessMenu(quickAccessTab?: QuickAccessTab): void;
127
127
  OpenMainMenu(): void;
128
128
  OpenPowerMenu(unknown?: any): void;
129
+ /** if calling this to perform navigation, call it after Navigate to prevent a race condition in desktop Big Picture mode that hides the overlay unintentionally */
129
130
  CloseSideMenus(): void;
130
131
  }
131
132
 
@@ -52,6 +52,7 @@ export function injectFCTrampoline(component: FC, customHooks?: any): FCTrampoli
52
52
  // we have to redirect this to return an object with component's prototype as a constructor returning a value overrides its prototype
53
53
  window.SP_REACT.createElement = () => {
54
54
  loggingEnabled && logger.debug("createElement hook called");
55
+ loggingEnabled && console.trace("createElement trace");
55
56
  return Object.create(component.prototype);
56
57
  };
57
58
  }
@@ -66,12 +67,16 @@ export function injectFCTrampoline(component: FC, customHooks?: any): FCTrampoli
66
67
  }
67
68
  }
68
69
 
70
+ let renderHookStep = 0;
71
+
69
72
  // Accessed two times, once directly before class instantiation, and again in some extra logic we don't need to worry about that we hanlde below just in case.
70
73
  Object.defineProperty(component, "contextType", {
71
74
  configurable: true,
72
75
  get: function () {
73
- loggingEnabled && logger.debug("get contexttype", this, stubsApplied);
74
- applyStubsIfNeeded();
76
+ loggingEnabled && logger.debug("get contexttype", this, stubsApplied, renderHookStep);
77
+ loggingEnabled && console.trace("contextType trace");
78
+ if (renderHookStep == 0) renderHookStep = 1;
79
+ else if (renderHookStep == 3) renderHookStep = 4;
75
80
  return this._contextType;
76
81
  },
77
82
  set: function (value) {
@@ -79,16 +84,20 @@ export function injectFCTrampoline(component: FC, customHooks?: any): FCTrampoli
79
84
  }
80
85
  });
81
86
 
82
- // Undoes the second contextType access we can't detect shortly before render before it's able to cause any damage
83
- Object.defineProperty(component, "getDerivedStateFromProps", {
87
+ // Always accessed directly after contextType for the path we want to catch.
88
+ Object.defineProperty(component, "contextTypes", {
84
89
  configurable: true,
85
90
  get: function () {
86
- loggingEnabled && logger.debug("get getDerivedStateFromProps", this, stubsApplied);
87
- removeStubsIfNeeded();
88
- return this._getDerivedStateFromProps;
91
+ loggingEnabled && logger.debug("get contexttypes", this, stubsApplied, renderHookStep);
92
+ loggingEnabled && console.trace("contextTypes trace");
93
+ if (renderHookStep == 1) {
94
+ renderHookStep = 2;
95
+ applyStubsIfNeeded();
96
+ };
97
+ return this._contextTypes;
89
98
  },
90
99
  set: function (value) {
91
- this._getDerivedStateFromProps = value;
100
+ this._contextTypes = value;
92
101
  }
93
102
  });
94
103
 
@@ -99,11 +108,32 @@ export function injectFCTrampoline(component: FC, customHooks?: any): FCTrampoli
99
108
  return this._updater;
100
109
  },
101
110
  set: function (value) {
102
- loggingEnabled && logger.debug("set updater", this, value, stubsApplied);
103
- removeStubsIfNeeded();
111
+ loggingEnabled && logger.debug("set updater", this, value, stubsApplied, renderHookStep);
112
+ loggingEnabled && console.trace("updater trace");
113
+ if (renderHookStep == 2) {
114
+ renderHookStep = 0;
115
+ removeStubsIfNeeded();
116
+ }
104
117
  return this._updater = value;
105
118
  }
106
119
  });
107
120
 
121
+ // Prevents the second contextType+contextTypes access from leaving its hooks around
122
+ Object.defineProperty(component, "getDerivedStateFromProps", {
123
+ configurable: true,
124
+ get: function () {
125
+ loggingEnabled && logger.debug("get getDerivedStateFromProps", this, stubsApplied, renderHookStep);
126
+ loggingEnabled && console.trace("getDerivedStateFromProps trace");
127
+ if (renderHookStep == 2) {
128
+ renderHookStep = 0;
129
+ removeStubsIfNeeded();
130
+ }
131
+ return this._getDerivedStateFromProps;
132
+ },
133
+ set: function (value) {
134
+ this._getDerivedStateFromProps = value;
135
+ }
136
+ });
137
+
108
138
  return userComponent;
109
139
  }
@@ -104,19 +104,15 @@ export function wrapReactClass(node: any, prop: any = 'type') {
104
104
 
105
105
  export function getReactRoot(o: HTMLElement | Element | Node) {
106
106
  return (
107
- // @ts-expect-error 7053
108
- o[Object.keys(o).find((k) => k.startsWith('__reactContainer$')) as string] ||
109
- // @ts-expect-error 7053
110
- o['_reactRootContainer']?._internalRoot?.current
107
+ (o as any)[Object.keys(o).find((k) => k.startsWith('__reactContainer$')) as string] ||
108
+ (o as any)['_reactRootContainer']?._internalRoot?.current
111
109
  );
112
110
  }
113
111
 
114
112
  export function getReactInstance(o: HTMLElement | Element | Node) {
115
113
  return (
116
- // @ts-expect-error 7053
117
- o[Object.keys(o).find((k) => k.startsWith('__reactFiber')) as string] ||
118
- // @ts-expect-error 7053
119
- o[Object.keys(o).find((k) => k.startsWith('__reactInternalInstance')) as string]
114
+ (o as any)[Object.keys(o).find((k) => k.startsWith('__reactFiber')) as string] ||
115
+ (o as any)[Object.keys(o).find((k) => k.startsWith('__reactInternalInstance')) as string]
120
116
  );
121
117
  }
122
118