@reckona/mreact-compat 0.0.90 → 0.0.92

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.
Files changed (104) hide show
  1. package/README.md +1 -0
  2. package/dist/class-component.d.ts +20 -6
  3. package/dist/class-component.d.ts.map +1 -1
  4. package/dist/class-component.js +94 -51
  5. package/dist/class-component.js.map +1 -1
  6. package/dist/context.d.ts +19 -3
  7. package/dist/context.d.ts.map +1 -1
  8. package/dist/context.js +55 -6
  9. package/dist/context.js.map +1 -1
  10. package/dist/dom-children.d.ts +2 -0
  11. package/dist/dom-children.d.ts.map +1 -1
  12. package/dist/dom-children.js +103 -1
  13. package/dist/dom-children.js.map +1 -1
  14. package/dist/dom-host-rules.d.ts +10 -0
  15. package/dist/dom-host-rules.d.ts.map +1 -0
  16. package/dist/dom-host-rules.js +86 -0
  17. package/dist/dom-host-rules.js.map +1 -0
  18. package/dist/dom-props.d.ts +3 -2
  19. package/dist/dom-props.d.ts.map +1 -1
  20. package/dist/dom-props.js +229 -33
  21. package/dist/dom-props.js.map +1 -1
  22. package/dist/element.d.ts +9 -4
  23. package/dist/element.d.ts.map +1 -1
  24. package/dist/element.js +101 -26
  25. package/dist/element.js.map +1 -1
  26. package/dist/event-listeners.d.ts +4 -4
  27. package/dist/event-listeners.d.ts.map +1 -1
  28. package/dist/event-listeners.js +1 -1
  29. package/dist/event-listeners.js.map +1 -1
  30. package/dist/event-types.d.ts +10 -0
  31. package/dist/event-types.d.ts.map +1 -1
  32. package/dist/event-types.js.map +1 -1
  33. package/dist/events.js +22 -1
  34. package/dist/events.js.map +1 -1
  35. package/dist/fiber-commit.d.ts +2 -1
  36. package/dist/fiber-commit.d.ts.map +1 -1
  37. package/dist/fiber-commit.js +13 -1
  38. package/dist/fiber-commit.js.map +1 -1
  39. package/dist/fiber-reconciler.d.ts.map +1 -1
  40. package/dist/fiber-reconciler.js +28 -7
  41. package/dist/fiber-reconciler.js.map +1 -1
  42. package/dist/fiber-work-loop.d.ts.map +1 -1
  43. package/dist/fiber-work-loop.js +4 -3
  44. package/dist/fiber-work-loop.js.map +1 -1
  45. package/dist/fiber.d.ts +5 -0
  46. package/dist/fiber.d.ts.map +1 -1
  47. package/dist/fiber.js +9 -0
  48. package/dist/fiber.js.map +1 -1
  49. package/dist/hooks-entry.d.ts +3 -0
  50. package/dist/hooks-entry.d.ts.map +1 -0
  51. package/dist/hooks-entry.js +2 -0
  52. package/dist/hooks-entry.js.map +1 -0
  53. package/dist/hooks.d.ts +39 -5
  54. package/dist/hooks.d.ts.map +1 -1
  55. package/dist/hooks.js +373 -326
  56. package/dist/hooks.js.map +1 -1
  57. package/dist/host-reconciler.d.ts +3 -0
  58. package/dist/host-reconciler.d.ts.map +1 -1
  59. package/dist/host-reconciler.js +1152 -64
  60. package/dist/host-reconciler.js.map +1 -1
  61. package/dist/hydration.d.ts +1 -1
  62. package/dist/hydration.d.ts.map +1 -1
  63. package/dist/hydration.js.map +1 -1
  64. package/dist/index.d.ts +2 -1
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +2 -1
  67. package/dist/index.js.map +1 -1
  68. package/dist/react-default.d.ts +4 -4
  69. package/dist/react-default.d.ts.map +1 -1
  70. package/dist/react-default.js +2 -1
  71. package/dist/react-default.js.map +1 -1
  72. package/dist/reconciler.d.ts.map +1 -1
  73. package/dist/reconciler.js +38 -22
  74. package/dist/reconciler.js.map +1 -1
  75. package/dist/root.d.ts.map +1 -1
  76. package/dist/root.js +48 -13
  77. package/dist/root.js.map +1 -1
  78. package/dist/server-render.d.ts +6 -0
  79. package/dist/server-render.d.ts.map +1 -0
  80. package/dist/server-render.js +307 -0
  81. package/dist/server-render.js.map +1 -0
  82. package/package.json +6 -2
  83. package/src/class-component.ts +216 -51
  84. package/src/context.ts +108 -9
  85. package/src/dom-children.ts +155 -1
  86. package/src/dom-host-rules.ts +115 -0
  87. package/src/dom-props.ts +297 -46
  88. package/src/element.ts +141 -31
  89. package/src/event-listeners.ts +6 -6
  90. package/src/event-types.ts +10 -0
  91. package/src/events.ts +32 -10
  92. package/src/fiber-commit.ts +16 -1
  93. package/src/fiber-reconciler.ts +39 -6
  94. package/src/fiber-work-loop.ts +4 -3
  95. package/src/fiber.ts +14 -0
  96. package/src/hooks-entry.ts +24 -0
  97. package/src/hooks.ts +482 -479
  98. package/src/host-reconciler.ts +1628 -94
  99. package/src/hydration.ts +1 -1
  100. package/src/index.ts +1 -1
  101. package/src/react-default.ts +1 -1
  102. package/src/reconciler.ts +61 -22
  103. package/src/root.ts +55 -12
  104. package/src/server-render.ts +478 -0
@@ -4,31 +4,185 @@ export function syncChildNodes(parent: ParentNode, nextNodes: readonly Node[]):
4
4
  syncScopedChildNodes(parent, null, null, nextNodes);
5
5
  }
6
6
 
7
+ export function syncOwnedChildNodes(
8
+ parent: ParentNode,
9
+ previousNodes: readonly Node[],
10
+ nextNodes: readonly Node[],
11
+ ): void {
12
+ const nextSet = new Set(nextNodes);
13
+
14
+ for (const node of nextNodes) {
15
+ if (node.parentNode !== parent || node.nextSibling !== null) {
16
+ parent.appendChild(node);
17
+ }
18
+ }
19
+
20
+ for (const child of previousNodes) {
21
+ if (!nextSet.has(child)) {
22
+ removeChildIfPresent(parent, child);
23
+ }
24
+ }
25
+ }
26
+
7
27
  export function syncScopedChildNodes(
8
28
  parent: ParentNode,
9
29
  before: ChildNode | null,
10
30
  after: ChildNode | null,
11
31
  nextNodes: readonly Node[],
12
32
  ): void {
33
+ if (replaceDisjointFullChildList(parent, before, after, nextNodes)) {
34
+ return;
35
+ }
36
+
37
+ if (
38
+ nextNodes.length > 16 &&
39
+ hasSingleExtraScopedChild(parent, before, after, nextNodes.length) &&
40
+ removeSingleMissingChild(parent, before, after, nextNodes)
41
+ ) {
42
+ return;
43
+ }
44
+
13
45
  let cursor = parent.firstChild;
14
46
 
15
47
  if (before !== null) {
16
48
  cursor = before.nextSibling;
17
49
  }
18
50
 
51
+ let changed = false;
52
+
19
53
  for (const node of nextNodes) {
20
54
  if (node !== cursor) {
21
55
  parent.insertBefore(node, cursor === after ? after : cursor);
56
+ changed = true;
22
57
  }
23
58
 
24
59
  cursor = node.nextSibling;
25
60
  }
26
61
 
62
+ if (!changed && cursor === after) {
63
+ return;
64
+ }
65
+
66
+ if (!changed && after === null && cursor === null) {
67
+ return;
68
+ }
69
+
27
70
  const nextSet = new Set(nextNodes);
28
71
 
29
72
  for (const child of collectScopedNodes(parent, before, after)) {
30
73
  if (!nextSet.has(child)) {
31
- parent.removeChild(child);
74
+ removeChildIfPresent(parent, child);
75
+ }
76
+ }
77
+ }
78
+
79
+ function replaceDisjointFullChildList(
80
+ parent: ParentNode,
81
+ before: ChildNode | null,
82
+ after: ChildNode | null,
83
+ nextNodes: readonly Node[],
84
+ ): boolean {
85
+ if (before !== null || after !== null || nextNodes.length <= 16) {
86
+ return false;
87
+ }
88
+
89
+ const currentNodes = parent.childNodes;
90
+
91
+ if (currentNodes.length <= 16 || currentNodes.length !== nextNodes.length) {
92
+ return false;
93
+ }
94
+
95
+ const nextSet = new Set(nextNodes);
96
+
97
+ for (let index = 0; index < currentNodes.length; index += 1) {
98
+ if (nextSet.has(currentNodes[index]!)) {
99
+ return false;
32
100
  }
33
101
  }
102
+
103
+ parent.replaceChildren(...nextNodes);
104
+ return true;
105
+ }
106
+
107
+ function hasSingleExtraScopedChild(
108
+ parent: ParentNode,
109
+ before: ChildNode | null,
110
+ after: ChildNode | null,
111
+ nextCount: number,
112
+ ): boolean {
113
+ if (before === null && after === null) {
114
+ return parent.childNodes.length === nextCount + 1;
115
+ }
116
+
117
+ let cursor = before === null ? parent.firstChild : before.nextSibling;
118
+ let currentCount = 0;
119
+
120
+ while (cursor !== null && cursor !== after && currentCount <= nextCount + 1) {
121
+ currentCount += 1;
122
+ cursor = cursor.nextSibling;
123
+ }
124
+
125
+ return currentCount === nextCount + 1 && (cursor === null || cursor === after);
126
+ }
127
+
128
+ function removeSingleMissingChild(
129
+ parent: ParentNode,
130
+ before: ChildNode | null,
131
+ after: ChildNode | null,
132
+ nextNodes: readonly Node[],
133
+ ): boolean {
134
+ let cursor = before === null ? parent.firstChild : before.nextSibling;
135
+ let removed = false;
136
+
137
+ for (const nextNode of nextNodes) {
138
+ if (cursor === nextNode) {
139
+ cursor = cursor.nextSibling;
140
+ continue;
141
+ }
142
+
143
+ if (removed || cursor === null || cursor === after || cursor.nextSibling !== nextNode) {
144
+ return false;
145
+ }
146
+
147
+ const missing = cursor;
148
+ cursor = nextNode.nextSibling;
149
+ removeChildIfPresent(parent, missing);
150
+ removed = true;
151
+ }
152
+
153
+ if (cursor === after || cursor === null) {
154
+ return removed;
155
+ }
156
+
157
+ if (removed || cursor.nextSibling !== after) {
158
+ return false;
159
+ }
160
+
161
+ removeChildIfPresent(parent, cursor);
162
+ return true;
163
+ }
164
+
165
+ export function removeChildIfPresent(parent: ParentNode, child: Node): void {
166
+ if (child.parentNode !== parent) {
167
+ return;
168
+ }
169
+
170
+ try {
171
+ parent.removeChild(child);
172
+ } catch (error) {
173
+ if (child.parentNode !== parent && isNotFoundError(error)) {
174
+ return;
175
+ }
176
+
177
+ throw error;
178
+ }
179
+ }
180
+
181
+ function isNotFoundError(error: unknown): boolean {
182
+ const maybeError = error as { message?: unknown; name?: unknown };
183
+
184
+ return (
185
+ maybeError.name === "NotFoundError" ||
186
+ (typeof maybeError.message === "string" && maybeError.message.includes("not a child"))
187
+ );
34
188
  }
@@ -0,0 +1,115 @@
1
+ export type HostElement = HTMLElement | SVGElement;
2
+ export type HostNamespace = "html" | "svg";
3
+
4
+ const htmlNamespace = "http://www.w3.org/1999/xhtml";
5
+ const svgNamespace = "http://www.w3.org/2000/svg";
6
+
7
+ const isUnitlessNumberStyle = new Set([
8
+ "animationIterationCount",
9
+ "aspectRatio",
10
+ "borderImageOutset",
11
+ "borderImageSlice",
12
+ "borderImageWidth",
13
+ "boxFlex",
14
+ "boxFlexGroup",
15
+ "boxOrdinalGroup",
16
+ "columnCount",
17
+ "columns",
18
+ "flex",
19
+ "flexGrow",
20
+ "flexPositive",
21
+ "flexShrink",
22
+ "flexNegative",
23
+ "flexOrder",
24
+ "gridArea",
25
+ "gridRow",
26
+ "gridRowEnd",
27
+ "gridRowSpan",
28
+ "gridRowStart",
29
+ "gridColumn",
30
+ "gridColumnEnd",
31
+ "gridColumnSpan",
32
+ "gridColumnStart",
33
+ "fontWeight",
34
+ "lineClamp",
35
+ "lineHeight",
36
+ "opacity",
37
+ "order",
38
+ "orphans",
39
+ "scale",
40
+ "tabSize",
41
+ "widows",
42
+ "zIndex",
43
+ "zoom",
44
+ "fillOpacity",
45
+ "floodOpacity",
46
+ "stopOpacity",
47
+ "strokeDasharray",
48
+ "strokeDashoffset",
49
+ "strokeMiterlimit",
50
+ "strokeOpacity",
51
+ "strokeWidth",
52
+ ]);
53
+
54
+ export function createHostElement(
55
+ documentRef: Document,
56
+ tagName: string,
57
+ namespace: HostNamespace,
58
+ ): HostElement {
59
+ if (namespaceForHostElement(namespace, tagName) === "svg") {
60
+ return documentRef.createElementNS(svgNamespace, tagName);
61
+ }
62
+
63
+ return documentRef.createElement(tagName);
64
+ }
65
+
66
+ export function isHostElement(value: unknown): value is HostElement {
67
+ return value instanceof HTMLElement || value instanceof SVGElement;
68
+ }
69
+
70
+ export function namespaceForHostElement(
71
+ parentNamespace: HostNamespace,
72
+ tagName: string,
73
+ ): HostNamespace {
74
+ if (tagName === "svg") {
75
+ return "svg";
76
+ }
77
+
78
+ return parentNamespace;
79
+ }
80
+
81
+ export function namespaceForHostChildren(
82
+ elementNamespace: HostNamespace,
83
+ tagName: string,
84
+ ): HostNamespace {
85
+ return elementNamespace === "svg" && tagName === "foreignObject" ? "html" : elementNamespace;
86
+ }
87
+
88
+ export function hostElementMatches(
89
+ element: HostElement,
90
+ tagName: string,
91
+ namespace: HostNamespace,
92
+ ): boolean {
93
+ return element.tagName.toLowerCase() === tagName && element.namespaceURI === namespaceUri(namespace);
94
+ }
95
+
96
+ export function serializeClientStyleValue(name: string, value: unknown): string {
97
+ if (typeof value === "number" && value !== 0 && !name.startsWith("--") && !isUnitlessNumberStyle.has(name)) {
98
+ return `${value}px`;
99
+ }
100
+
101
+ return String(value);
102
+ }
103
+
104
+ export function styleNameToCssName(name: string): string {
105
+ if (name.startsWith("--")) {
106
+ return name;
107
+ }
108
+
109
+ const cssName = name.replace(/[A-Z]/g, (char) => `-${char.toLowerCase()}`);
110
+ return cssName.startsWith("ms-") ? `-${cssName}` : cssName;
111
+ }
112
+
113
+ function namespaceUri(namespace: HostNamespace): string {
114
+ return namespace === "svg" ? svgNamespace : htmlNamespace;
115
+ }