what-react 0.12.3 → 0.13.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/package.json +2 -2
- package/src/hooks.js +7 -3
- package/src/index.js +9 -5
- package/src/runtime.js +17 -11
- package/src/vite-plugin.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "what-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "React compatibility layer for What Framework — real React semantics (value hooks, re-renders, context) on a dedicated compat runtime",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"compatibility"
|
|
54
54
|
],
|
|
55
55
|
"peerDependencies": {
|
|
56
|
-
"what-core": "^0.
|
|
56
|
+
"what-core": "^0.13.0"
|
|
57
57
|
},
|
|
58
58
|
"author": "ZVN DEV (https://zvndev.com)",
|
|
59
59
|
"license": "MIT",
|
package/src/hooks.js
CHANGED
|
@@ -240,7 +240,7 @@ export function useContext(context) {
|
|
|
240
240
|
// ---- useSyncExternalStore ----
|
|
241
241
|
// Spec-compliant: returns the snapshot VALUE and re-renders on store change.
|
|
242
242
|
|
|
243
|
-
export function useSyncExternalStore(subscribe, getSnapshot,
|
|
243
|
+
export function useSyncExternalStore(subscribe, getSnapshot, _getServerSnapshot) {
|
|
244
244
|
const inst = _requireInstance('useSyncExternalStore');
|
|
245
245
|
const slot = _getHookSlot(inst);
|
|
246
246
|
if (!slot.init) {
|
|
@@ -306,7 +306,7 @@ export function useId() {
|
|
|
306
306
|
|
|
307
307
|
// ---- useDebugValue ----
|
|
308
308
|
|
|
309
|
-
export function useDebugValue() {}
|
|
309
|
+
export function useDebugValue(_value, _format) {}
|
|
310
310
|
|
|
311
311
|
// ---- use (React 19-style, minimal) ----
|
|
312
312
|
// Context → useContext. Thenable → resolved value or throw for Suspense.
|
|
@@ -330,7 +330,11 @@ export function use(usable) {
|
|
|
330
330
|
return useContext(usable);
|
|
331
331
|
}
|
|
332
332
|
}
|
|
333
|
-
|
|
333
|
+
// ERROR_CODES.USE_INVALID_ARG
|
|
334
|
+
throw Object.assign(
|
|
335
|
+
new Error('[what-react] use() expects a promise or a context.'),
|
|
336
|
+
{ code: 'ERR_USE_INVALID_ARG' },
|
|
337
|
+
);
|
|
334
338
|
}
|
|
335
339
|
|
|
336
340
|
// ---- useSignal (escape hatch) ----
|
package/src/index.js
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import { Fragment as WhatFragment } from 'what-core';
|
|
20
|
-
import { getBridge, _getCurrentInstance, flushUpdates, _drainAll
|
|
20
|
+
import { getBridge, _getCurrentInstance, flushUpdates, _drainAll } from './runtime.js';
|
|
21
21
|
import {
|
|
22
22
|
useState,
|
|
23
23
|
useReducer,
|
|
@@ -126,7 +126,7 @@ function getClassWrapper(ClassComp) {
|
|
|
126
126
|
if (derived != null) instance.state = { ...instance.state, ...derived };
|
|
127
127
|
}
|
|
128
128
|
if (instance.componentDidCatch) {
|
|
129
|
-
try { instance.componentDidCatch(error, { componentStack: '' }); } catch
|
|
129
|
+
try { instance.componentDidCatch(error, { componentStack: '' }); } catch { /* boundary error */ }
|
|
130
130
|
}
|
|
131
131
|
forceRender();
|
|
132
132
|
};
|
|
@@ -166,7 +166,7 @@ function getClassWrapper(ClassComp) {
|
|
|
166
166
|
// Copy static properties (defaultProps, contextType, custom statics)
|
|
167
167
|
for (const key of Object.getOwnPropertyNames(ClassComp)) {
|
|
168
168
|
if (key !== 'prototype' && key !== 'length' && key !== 'name' && key !== 'caller' && key !== 'arguments') {
|
|
169
|
-
try { wrapper[key] = ClassComp[key]; } catch
|
|
169
|
+
try { wrapper[key] = ClassComp[key]; } catch { /* read-only static */ }
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
172
|
|
|
@@ -382,7 +382,11 @@ export const Children = {
|
|
|
382
382
|
only(children) {
|
|
383
383
|
const arr = Children.toArray(children);
|
|
384
384
|
if (arr.length !== 1) {
|
|
385
|
-
|
|
385
|
+
// ERROR_CODES.CHILDREN_ONLY
|
|
386
|
+
throw Object.assign(
|
|
387
|
+
new Error('React.Children.only expected to receive a single React element child.'),
|
|
388
|
+
{ code: 'ERR_CHILDREN_ONLY' },
|
|
389
|
+
);
|
|
386
390
|
}
|
|
387
391
|
return arr[0];
|
|
388
392
|
},
|
|
@@ -422,7 +426,7 @@ export function cloneElement(element, props, ...children) {
|
|
|
422
426
|
|
|
423
427
|
export function createFactory(type) {
|
|
424
428
|
const factory = createElement.bind(null, type);
|
|
425
|
-
factory.type = type;
|
|
429
|
+
/** @type {any} */ (factory).type = type;
|
|
426
430
|
return factory;
|
|
427
431
|
}
|
|
428
432
|
|
package/src/runtime.js
CHANGED
|
@@ -57,11 +57,15 @@ export function _getCurrentInstance() {
|
|
|
57
57
|
|
|
58
58
|
export function _requireInstance(hookName) {
|
|
59
59
|
if (!currentInstance) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
// ERROR_CODES.HOOK_OUTSIDE_RENDER
|
|
61
|
+
throw Object.assign(
|
|
62
|
+
new Error(
|
|
63
|
+
`[what-react] ${hookName}() called outside of a component render. ` +
|
|
64
|
+
`Hooks can only be called while a what-react component is rendering. ` +
|
|
65
|
+
`If this happens inside a React library, make sure ALL react imports are ` +
|
|
66
|
+
`aliased to what-react (one module instance) — see the reactCompat() vite plugin.`
|
|
67
|
+
),
|
|
68
|
+
{ code: 'ERR_HOOK_OUTSIDE_RENDER' },
|
|
65
69
|
);
|
|
66
70
|
}
|
|
67
71
|
return currentInstance;
|
|
@@ -519,7 +523,7 @@ function mountElement(v, container, svg, owner) {
|
|
|
519
523
|
|
|
520
524
|
const rn = {
|
|
521
525
|
kind: KIND_ELEMENT, vnode: v, key: v.key ?? null, dom: el,
|
|
522
|
-
children: [], ref: props.ref || null,
|
|
526
|
+
children: /** @type {any[]} */ ([]), ref: props.ref || null,
|
|
523
527
|
};
|
|
524
528
|
|
|
525
529
|
// Children
|
|
@@ -578,7 +582,7 @@ function mountPortal(v, container, owner) {
|
|
|
578
582
|
const dom = document.createComment('w:portal');
|
|
579
583
|
container.appendChild(dom);
|
|
580
584
|
const target = v.props && v.props.container;
|
|
581
|
-
const rn = { kind: KIND_PORTAL, vnode: v, key: v.key ?? null, dom, container: target || null, children: [] };
|
|
585
|
+
const rn = { kind: KIND_PORTAL, vnode: v, key: v.key ?? null, dom, container: target || null, children: /** @type {any[]} */ ([]) };
|
|
582
586
|
if (!target) {
|
|
583
587
|
console.warn('[what-react] createPortal: target container not found');
|
|
584
588
|
return rn;
|
|
@@ -620,10 +624,10 @@ function mountOpaque(v, container) {
|
|
|
620
624
|
let n = start.nextSibling;
|
|
621
625
|
while (n && n !== end) {
|
|
622
626
|
const next = n.nextSibling;
|
|
623
|
-
holder.appendChild(n);
|
|
627
|
+
/** @type {DocumentFragment} */ (holder).appendChild(n);
|
|
624
628
|
n = next;
|
|
625
629
|
}
|
|
626
|
-
try { dispose(); } catch
|
|
630
|
+
try { dispose(); } catch { /* already disposed */ }
|
|
627
631
|
}),
|
|
628
632
|
};
|
|
629
633
|
}
|
|
@@ -984,7 +988,7 @@ export function getBridge(renderFn) {
|
|
|
984
988
|
const rn = runInCommit(() => mountRNode(vnode, KIND_COMPONENT, frag, false, null));
|
|
985
989
|
try {
|
|
986
990
|
whatOnCleanup(() => unmountRNode(rn, false));
|
|
987
|
-
} catch
|
|
991
|
+
} catch {
|
|
988
992
|
// Not inside a core component (unusual) — leak-free unmount unavailable.
|
|
989
993
|
}
|
|
990
994
|
return frag;
|
|
@@ -1054,6 +1058,7 @@ function changeEventFor(el) {
|
|
|
1054
1058
|
return 'change';
|
|
1055
1059
|
}
|
|
1056
1060
|
|
|
1061
|
+
/** @this {any} */
|
|
1057
1062
|
function eventProxy(e) {
|
|
1058
1063
|
if (!e.nativeEvent) e.nativeEvent = e;
|
|
1059
1064
|
if (!e.persist) e.persist = noop;
|
|
@@ -1061,6 +1066,7 @@ function eventProxy(e) {
|
|
|
1061
1066
|
if (handler) return handler(e);
|
|
1062
1067
|
}
|
|
1063
1068
|
|
|
1069
|
+
/** @this {any} */
|
|
1064
1070
|
function eventProxyCapture(e) {
|
|
1065
1071
|
if (!e.nativeEvent) e.nativeEvent = e;
|
|
1066
1072
|
if (!e.persist) e.persist = noop;
|
|
@@ -1180,7 +1186,7 @@ export function setProperty(el, name, value, oldValue, svg) {
|
|
|
1180
1186
|
try {
|
|
1181
1187
|
el[name] = value == null ? '' : value;
|
|
1182
1188
|
return;
|
|
1183
|
-
} catch
|
|
1189
|
+
} catch { /* read-only property — fall through to attribute */ }
|
|
1184
1190
|
}
|
|
1185
1191
|
if (value == null || value === false) el.removeAttribute(name);
|
|
1186
1192
|
else el.setAttribute(name, value === true ? '' : value);
|
package/src/vite-plugin.js
CHANGED
|
@@ -156,7 +156,7 @@ export function reactCompat(options = {}) {
|
|
|
156
156
|
name: 'what-react-compat',
|
|
157
157
|
enforce: 'pre',
|
|
158
158
|
|
|
159
|
-
config(config, {
|
|
159
|
+
config(config, { }) {
|
|
160
160
|
const root = config.root || process.cwd();
|
|
161
161
|
|
|
162
162
|
// Resolve what-react and what-core paths from installed packages
|