@reckona/mreact-compat 0.0.182 → 0.0.184
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/README.md +1 -0
- package/dist/devtools.d.ts.map +1 -1
- package/dist/devtools.js +25 -0
- package/dist/devtools.js.map +1 -1
- package/dist/dom-props.d.ts +5 -0
- package/dist/dom-props.d.ts.map +1 -1
- package/dist/dom-props.js +46 -0
- package/dist/dom-props.js.map +1 -1
- package/dist/host-reconciler.js +2 -2
- package/dist/host-reconciler.js.map +1 -1
- package/dist/reactive-prop-cell.d.ts.map +1 -1
- package/dist/reactive-prop-cell.js +3 -0
- package/dist/reactive-prop-cell.js.map +1 -1
- package/dist/root.d.ts.map +1 -1
- package/dist/root.js +35 -24
- package/dist/root.js.map +1 -1
- package/dist/server-render.d.ts +5 -0
- package/dist/server-render.d.ts.map +1 -1
- package/dist/server-render.js +59 -16
- package/dist/server-render.js.map +1 -1
- package/dist/server.d.ts +8 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +6 -0
- package/dist/server.js.map +1 -0
- package/package.json +8 -3
- package/src/devtools.ts +32 -0
- package/src/dom-props.ts +59 -0
- package/src/host-reconciler.ts +4 -2
- package/src/reactive-prop-cell.ts +4 -0
- package/src/root.ts +52 -36
- package/src/server-render.ts +83 -17
- package/src/server.ts +62 -0
package/src/server-render.ts
CHANGED
|
@@ -369,39 +369,61 @@ function isEventHandlerName(name: string): boolean {
|
|
|
369
369
|
);
|
|
370
370
|
}
|
|
371
371
|
|
|
372
|
+
type AttributeNameClassification =
|
|
373
|
+
| { kind: "skip" }
|
|
374
|
+
| { kind: "style" }
|
|
375
|
+
| {
|
|
376
|
+
kind: "attribute";
|
|
377
|
+
attributeName: string;
|
|
378
|
+
booleanishString: boolean;
|
|
379
|
+
dataAttribute: boolean;
|
|
380
|
+
dangerousHtml: boolean;
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
const ATTRIBUTE_CLASSIFICATION_CACHE = new Map<string, AttributeNameClassification>();
|
|
384
|
+
const ATTRIBUTE_CLASSIFICATION_CACHE_LIMIT = 1024;
|
|
385
|
+
let attributeClassificationCacheMissCount = 0;
|
|
386
|
+
|
|
387
|
+
export const __serverRenderAttributeCacheForTesting = {
|
|
388
|
+
clear() {
|
|
389
|
+
ATTRIBUTE_CLASSIFICATION_CACHE.clear();
|
|
390
|
+
attributeClassificationCacheMissCount = 0;
|
|
391
|
+
},
|
|
392
|
+
missCount() {
|
|
393
|
+
return attributeClassificationCacheMissCount;
|
|
394
|
+
},
|
|
395
|
+
size() {
|
|
396
|
+
return ATTRIBUTE_CLASSIFICATION_CACHE.size;
|
|
397
|
+
},
|
|
398
|
+
};
|
|
399
|
+
|
|
372
400
|
function renderHtmlAttribute(name: string, value: unknown): string {
|
|
373
401
|
if (
|
|
374
402
|
value === null ||
|
|
375
403
|
value === undefined ||
|
|
376
|
-
typeof value === "function"
|
|
377
|
-
name === "children" ||
|
|
378
|
-
name === "key" ||
|
|
379
|
-
name === "ref" ||
|
|
380
|
-
isEventHandlerName(name)
|
|
404
|
+
typeof value === "function"
|
|
381
405
|
) {
|
|
382
406
|
return "";
|
|
383
407
|
}
|
|
384
408
|
|
|
385
|
-
|
|
386
|
-
const style = renderStyleAttribute(value);
|
|
387
|
-
return style === "" ? "" : ` style="${escapeHtml(style)}"`;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
const attributeName = toHtmlAttributeName(name);
|
|
409
|
+
const classification = classifyAttributeName(name);
|
|
391
410
|
|
|
392
|
-
if (
|
|
411
|
+
if (classification.kind === "skip") {
|
|
393
412
|
return "";
|
|
394
413
|
}
|
|
395
414
|
|
|
396
|
-
if (
|
|
397
|
-
|
|
415
|
+
if (classification.kind === "style") {
|
|
416
|
+
const style = renderStyleAttribute(value);
|
|
417
|
+
return style === "" ? "" : ` style="${escapeHtml(style)}"`;
|
|
398
418
|
}
|
|
399
419
|
|
|
400
|
-
|
|
420
|
+
const { attributeName } = classification;
|
|
421
|
+
|
|
422
|
+
if (typeof value === "boolean" && classification.booleanishString) {
|
|
401
423
|
return ` ${attributeName}="${value ? "true" : "false"}"`;
|
|
402
424
|
}
|
|
403
425
|
|
|
404
|
-
if (typeof value === "boolean" &&
|
|
426
|
+
if (typeof value === "boolean" && classification.dataAttribute) {
|
|
405
427
|
return ` ${attributeName}="${value ? "true" : "false"}"`;
|
|
406
428
|
}
|
|
407
429
|
|
|
@@ -409,7 +431,7 @@ function renderHtmlAttribute(name: string, value: unknown): string {
|
|
|
409
431
|
return "";
|
|
410
432
|
}
|
|
411
433
|
|
|
412
|
-
if (
|
|
434
|
+
if (classification.dangerousHtml) {
|
|
413
435
|
return isDangerousHtmlOptIn(value)
|
|
414
436
|
? ` ${attributeName}="${escapeHtml(value.__html)}"`
|
|
415
437
|
: "";
|
|
@@ -434,6 +456,50 @@ function renderHtmlAttribute(name: string, value: unknown): string {
|
|
|
434
456
|
|
|
435
457
|
const VALID_ATTRIBUTE_NAME = /^[A-Za-z_][\w.\-:]*$/;
|
|
436
458
|
|
|
459
|
+
function classifyAttributeName(name: string): AttributeNameClassification {
|
|
460
|
+
const cached = ATTRIBUTE_CLASSIFICATION_CACHE.get(name);
|
|
461
|
+
if (cached !== undefined) {
|
|
462
|
+
return cached;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
attributeClassificationCacheMissCount += 1;
|
|
466
|
+
|
|
467
|
+
const classification = createAttributeNameClassification(name);
|
|
468
|
+
if (ATTRIBUTE_CLASSIFICATION_CACHE.size < ATTRIBUTE_CLASSIFICATION_CACHE_LIMIT) {
|
|
469
|
+
ATTRIBUTE_CLASSIFICATION_CACHE.set(name, classification);
|
|
470
|
+
}
|
|
471
|
+
return classification;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
function createAttributeNameClassification(name: string): AttributeNameClassification {
|
|
475
|
+
if (
|
|
476
|
+
name === "children" ||
|
|
477
|
+
name === "key" ||
|
|
478
|
+
name === "ref" ||
|
|
479
|
+
isEventHandlerName(name)
|
|
480
|
+
) {
|
|
481
|
+
return { kind: "skip" };
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
if (name === "style") {
|
|
485
|
+
return { kind: "style" };
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
const attributeName = toHtmlAttributeName(name);
|
|
489
|
+
|
|
490
|
+
if (!VALID_ATTRIBUTE_NAME.test(attributeName) || isEventHandlerName(attributeName)) {
|
|
491
|
+
return { kind: "skip" };
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
return {
|
|
495
|
+
kind: "attribute",
|
|
496
|
+
attributeName,
|
|
497
|
+
booleanishString: isBooleanishStringAttribute(attributeName),
|
|
498
|
+
dataAttribute: isDataAttribute(attributeName),
|
|
499
|
+
dangerousHtml: isDangerousHtmlAttribute(attributeName),
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
|
|
437
503
|
function isBooleanishStringAttribute(attributeName: string): boolean {
|
|
438
504
|
// Callers pass the already-mapped HTML attribute name.
|
|
439
505
|
const lowerCased = attributeName.toLowerCase();
|
package/src/server.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export {
|
|
2
|
+
Component,
|
|
3
|
+
PureComponent,
|
|
4
|
+
} from "./class-component.js";
|
|
5
|
+
export {
|
|
6
|
+
Fragment,
|
|
7
|
+
Activity,
|
|
8
|
+
Profiler,
|
|
9
|
+
Suspense,
|
|
10
|
+
SuspenseList,
|
|
11
|
+
StrictMode,
|
|
12
|
+
Children,
|
|
13
|
+
cloneElement,
|
|
14
|
+
createElement,
|
|
15
|
+
createErrorBoundary,
|
|
16
|
+
createRef,
|
|
17
|
+
forwardRef,
|
|
18
|
+
isValidElement,
|
|
19
|
+
lazy,
|
|
20
|
+
memo,
|
|
21
|
+
} from "./element.js";
|
|
22
|
+
export type {
|
|
23
|
+
ErrorBoundaryOptions,
|
|
24
|
+
ElementType,
|
|
25
|
+
ReactCompatElement,
|
|
26
|
+
ReactCompatNode,
|
|
27
|
+
ReactCompatRenderableElement,
|
|
28
|
+
} from "./element.js";
|
|
29
|
+
export {
|
|
30
|
+
createContext,
|
|
31
|
+
renderContextConsumerToString,
|
|
32
|
+
renderContextProviderToString,
|
|
33
|
+
useContext,
|
|
34
|
+
} from "./context.js";
|
|
35
|
+
export {
|
|
36
|
+
useCallback,
|
|
37
|
+
useDebugValue,
|
|
38
|
+
useDeferredValue,
|
|
39
|
+
useEffectEvent,
|
|
40
|
+
useEffect,
|
|
41
|
+
useId,
|
|
42
|
+
useImperativeHandle,
|
|
43
|
+
useInsertionEffect,
|
|
44
|
+
useLayoutEffect,
|
|
45
|
+
useMemo,
|
|
46
|
+
useOptimistic,
|
|
47
|
+
useReducer,
|
|
48
|
+
useRef,
|
|
49
|
+
useState,
|
|
50
|
+
useSyncExternalStore,
|
|
51
|
+
use,
|
|
52
|
+
useActionState,
|
|
53
|
+
cache,
|
|
54
|
+
cacheSignal,
|
|
55
|
+
captureOwnerStack,
|
|
56
|
+
startTransition,
|
|
57
|
+
unstable_useCacheRefresh,
|
|
58
|
+
useTransition,
|
|
59
|
+
version,
|
|
60
|
+
} from "./hooks.js";
|
|
61
|
+
export { renderChildToString, renderToString } from "./server-render.js";
|
|
62
|
+
export type { StartTransition, TransitionScope } from "./hooks.js";
|