@simpreact/simpreact 0.0.7 → 0.0.9
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/compat/context.js +3 -3
- package/compat/core.js +105 -18
- package/compat/dom.js +5 -5
- package/compat/hooks.js +18 -3
- package/compat/index.d.ts +109 -45
- package/compat/jsx-runtime.js +4 -4
- package/compat/renderRuntime.js +47 -12
- package/component/index.d.ts +6 -7
- package/component/index.js +96 -94
- package/context/index.d.ts +5 -5
- package/context/index.js +27 -17
- package/core/createElement.js +14 -17
- package/core/flags.js +31 -0
- package/core/hostOperations.js +5 -13
- package/core/index.d.ts +48 -11
- package/core/index.js +4 -2
- package/core/internal.d.ts +136 -16
- package/core/internal.js +8 -16
- package/core/lifecycleEventBus.js +35 -16
- package/core/memo.js +4 -1
- package/core/mounting.js +70 -150
- package/core/mountingChildren.js +11 -29
- package/core/patching.js +122 -181
- package/core/patchingChildren.js +74 -145
- package/core/portal.js +1 -1
- package/core/processStack.js +115 -45
- package/core/ref.js +1 -0
- package/core/rerender.js +20 -22
- package/core/runtime.js +10 -2
- package/core/unmounting.js +41 -49
- package/core/unmountingChildren.js +9 -12
- package/core/utils.js +38 -16
- package/dom/attach-element-to-dom.js +16 -8
- package/dom/events.js +11 -15
- package/dom/index.d.ts +6 -5
- package/dom/props/attrMaps.js +90 -0
- package/dom/props/controlled/select.js +8 -10
- package/dom/props/props.js +13 -14
- package/hooks/index.d.ts +15 -10
- package/hooks/index.js +107 -84
- package/package.json +10 -5
- package/shared/index.d.ts +10 -6
- package/compat/context.d.ts +0 -8
- package/compat/core.d.ts +0 -47
- package/compat/dom.d.ts +0 -10
- package/compat/hooks.d.ts +0 -27
- package/compat/jsx-runtime.d.ts +0 -10
- package/compat/renderRuntime.d.ts +0 -6
- package/core/createElement.d.ts +0 -39
- package/core/fragment.d.ts +0 -5
- package/core/hostAdapter.d.ts +0 -23
- package/core/hostOperations.d.ts +0 -5
- package/core/lifecycleEventBus.d.ts +0 -39
- package/core/memo.d.ts +0 -8
- package/core/mounting.d.ts +0 -7
- package/core/mountingChildren.d.ts +0 -4
- package/core/patching.d.ts +0 -8
- package/core/patchingChildren.d.ts +0 -6
- package/core/portal.d.ts +0 -2
- package/core/processStack.d.ts +0 -106
- package/core/ref.d.ts +0 -18
- package/core/rerender.d.ts +0 -4
- package/core/runtime.d.ts +0 -17
- package/core/unmounting.d.ts +0 -7
- package/core/unmountingChildren.d.ts +0 -4
- package/core/utils.d.ts +0 -11
- package/dom/attach-element-to-dom.d.ts +0 -5
- package/dom/domAdapter.d.ts +0 -3
- package/dom/events.d.ts +0 -27
- package/dom/namespace.d.ts +0 -2
- package/dom/props/controlled/index.d.ts +0 -7
- package/dom/props/controlled/input.d.ts +0 -7
- package/dom/props/controlled/select.d.ts +0 -6
- package/dom/props/controlled/textarea.d.ts +0 -6
- package/dom/props/dangerInnerHTML.d.ts +0 -7
- package/dom/props/index.d.ts +0 -1
- package/dom/props/props.d.ts +0 -5
- package/dom/props/style.d.ts +0 -1
- package/dom/render.d.ts +0 -8
- package/shared/lang.d.ts +0 -3
- package/shared/utils.d.ts +0 -5
package/component/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isFC, registerLifecyclePlugin, rerender, } from '../core/internal.js';
|
|
2
2
|
import { emptyObject, shallowEqual, } from '../shared/index.js';
|
|
3
|
-
const
|
|
4
|
-
function getComponentSpecificStore(
|
|
5
|
-
let hooksSpecificStore =
|
|
3
|
+
const componentSpecificStoreByElement = new WeakMap();
|
|
4
|
+
function getComponentSpecificStore(element, renderRuntime) {
|
|
5
|
+
let hooksSpecificStore = componentSpecificStoreByElement.get(element);
|
|
6
6
|
if (!hooksSpecificStore) {
|
|
7
7
|
function _rerender() {
|
|
8
|
-
rerender(
|
|
8
|
+
rerender(element, renderRuntime);
|
|
9
9
|
}
|
|
10
10
|
hooksSpecificStore = {
|
|
11
11
|
context: {
|
|
@@ -17,121 +17,123 @@ function getComponentSpecificStore(store, renderRuntime) {
|
|
|
17
17
|
pendingEffectStates: null,
|
|
18
18
|
effectStates: null,
|
|
19
19
|
};
|
|
20
|
-
|
|
20
|
+
componentSpecificStoreByElement.set(element, hooksSpecificStore);
|
|
21
21
|
}
|
|
22
22
|
return hooksSpecificStore;
|
|
23
23
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (event.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
let element = event.element;
|
|
30
|
-
let curError = event.error;
|
|
31
|
-
let catchers;
|
|
32
|
-
while (element) {
|
|
33
|
-
if (!isComponentElement(element)) {
|
|
34
|
-
element = element.parent;
|
|
35
|
-
continue;
|
|
36
|
-
}
|
|
37
|
-
const store = getComponentSpecificStore(element.store, event.renderRuntime);
|
|
38
|
-
catchers = store.context.catchers;
|
|
39
|
-
if (!catchers) {
|
|
40
|
-
element = element.parent;
|
|
41
|
-
continue;
|
|
24
|
+
registerLifecyclePlugin(bus => {
|
|
25
|
+
bus.subscribe(event => {
|
|
26
|
+
if (event.type === 'errored') {
|
|
27
|
+
if (event.handled) {
|
|
28
|
+
return;
|
|
42
29
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
30
|
+
let element = event.element;
|
|
31
|
+
let curError = event.error;
|
|
32
|
+
let catchers;
|
|
33
|
+
while (element) {
|
|
34
|
+
if (!isComponentElement(element)) {
|
|
35
|
+
element = element.parent;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
const store = getComponentSpecificStore(element, event.renderRuntime);
|
|
39
|
+
catchers = store.context.catchers;
|
|
40
|
+
if (!catchers) {
|
|
41
|
+
element = element.parent;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
for (let i = 0; i < catchers.length; i++) {
|
|
46
|
+
catchers[i](curError);
|
|
47
|
+
}
|
|
48
|
+
event.handled = true;
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
element = element.parent;
|
|
53
|
+
curError = error;
|
|
46
54
|
}
|
|
47
|
-
event.handled = true;
|
|
48
|
-
break;
|
|
49
|
-
}
|
|
50
|
-
catch (error) {
|
|
51
|
-
element = element.parent;
|
|
52
|
-
curError = error;
|
|
53
55
|
}
|
|
56
|
+
return;
|
|
54
57
|
}
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
if (!isComponentElement(event.element)) {
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
const store = getComponentSpecificStore(event.element.store, event.renderRuntime);
|
|
61
|
-
switch (event.type) {
|
|
62
|
-
case 'beforeRender': {
|
|
63
|
-
store.context.effects = [];
|
|
64
|
-
store.context.catchers = [];
|
|
65
|
-
store.pendingEffectStates = null;
|
|
58
|
+
if (!isComponentElement(event.element)) {
|
|
66
59
|
return;
|
|
67
60
|
}
|
|
68
|
-
|
|
69
|
-
|
|
61
|
+
const store = getComponentSpecificStore(event.element, event.renderRuntime);
|
|
62
|
+
switch (event.type) {
|
|
63
|
+
case 'beforeRender': {
|
|
64
|
+
store.context.effects = [];
|
|
65
|
+
store.context.catchers = [];
|
|
66
|
+
store.pendingEffectStates = null;
|
|
70
67
|
return;
|
|
71
68
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if (!state) {
|
|
76
|
-
state = store.effectStates[i] = {
|
|
77
|
-
effect: renderEffectState.effect,
|
|
78
|
-
deps: null,
|
|
79
|
-
cleanup: null,
|
|
80
|
-
};
|
|
69
|
+
case 'afterRender': {
|
|
70
|
+
if (!store.context.effects) {
|
|
71
|
+
return;
|
|
81
72
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
state
|
|
85
|
-
|
|
73
|
+
for (let i = 0; i < store.context.effects.length; i++) {
|
|
74
|
+
const renderEffectState = store.context.effects[i];
|
|
75
|
+
let state = (store.effectStates ||= [])[i];
|
|
76
|
+
if (!state) {
|
|
77
|
+
state = store.effectStates[i] = {
|
|
78
|
+
effect: renderEffectState.effect,
|
|
79
|
+
deps: null,
|
|
80
|
+
cleanup: null,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (!shallowEqual(renderEffectState.deps, state.deps)) {
|
|
84
|
+
state.effect = renderEffectState.effect;
|
|
85
|
+
state.deps = renderEffectState.deps || null;
|
|
86
|
+
(store.pendingEffectStates ||= []).push(state);
|
|
87
|
+
}
|
|
86
88
|
}
|
|
87
|
-
}
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
case 'mounted': {
|
|
91
|
-
if (!store.pendingEffectStates) {
|
|
92
89
|
return;
|
|
93
90
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
91
|
+
case 'mounted': {
|
|
92
|
+
if (!store.pendingEffectStates) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const effects = store.pendingEffectStates;
|
|
96
|
+
store.pendingEffectStates = null;
|
|
97
|
+
for (const state of effects) {
|
|
98
|
+
if (typeof state.cleanup === 'function') {
|
|
99
|
+
state.cleanup();
|
|
100
|
+
}
|
|
101
|
+
state.cleanup = state.effect() || null;
|
|
99
102
|
}
|
|
100
|
-
state.cleanup = state.effect() || null;
|
|
101
|
-
}
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
case 'updated': {
|
|
105
|
-
if (!store.pendingEffectStates) {
|
|
106
103
|
return;
|
|
107
104
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
105
|
+
case 'updated': {
|
|
106
|
+
if (!store.pendingEffectStates) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const effects = store.pendingEffectStates;
|
|
110
|
+
store.pendingEffectStates = null;
|
|
111
|
+
for (const state of effects) {
|
|
112
|
+
if (typeof state.cleanup === 'function') {
|
|
113
|
+
state.cleanup();
|
|
114
|
+
}
|
|
115
|
+
state.cleanup = state.effect() || null;
|
|
113
116
|
}
|
|
114
|
-
state.cleanup = state.effect() || null;
|
|
115
|
-
}
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
case 'unmounted': {
|
|
119
|
-
if (!store.effectStates) {
|
|
120
117
|
return;
|
|
121
118
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
119
|
+
case 'unmounted': {
|
|
120
|
+
if (!store.effectStates) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const effects = store.effectStates;
|
|
124
|
+
store.effectStates = null;
|
|
125
|
+
for (const state of effects) {
|
|
126
|
+
if (state && 'cleanup' in state && typeof state.cleanup === 'function') {
|
|
127
|
+
state.cleanup();
|
|
128
|
+
}
|
|
127
129
|
}
|
|
128
130
|
}
|
|
129
131
|
}
|
|
130
|
-
}
|
|
132
|
+
});
|
|
131
133
|
});
|
|
132
134
|
export function componentRenderer(component, element, renderRuntime) {
|
|
133
135
|
if (isComponentElement(element)) {
|
|
134
|
-
const store = getComponentSpecificStore(element
|
|
136
|
+
const store = getComponentSpecificStore(element, renderRuntime);
|
|
135
137
|
return component(element.props || emptyObject, store.context);
|
|
136
138
|
}
|
|
137
139
|
else {
|
|
@@ -160,5 +162,5 @@ export function createState(onChange) {
|
|
|
160
162
|
});
|
|
161
163
|
}
|
|
162
164
|
export function isComponentElement(element) {
|
|
163
|
-
return element
|
|
165
|
+
return isFC(element) && element.type._isComponent;
|
|
164
166
|
}
|
package/context/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { FC, SimpNode, SimpRenderRuntime } from '../core/index.js';
|
|
2
2
|
|
|
3
3
|
export interface ProviderProps<T> {
|
|
4
4
|
value: T;
|
|
@@ -16,16 +16,16 @@ export type SimpContext<T> = {
|
|
|
16
16
|
|
|
17
17
|
export type ContextType<C extends SimpContext<any>> = C extends SimpContext<infer T> ? T : never;
|
|
18
18
|
|
|
19
|
-
export type Provider<T> =
|
|
20
|
-
export type Consumer<T> =
|
|
19
|
+
export type Provider<T> = FC<ProviderProps<T>>;
|
|
20
|
+
export type Consumer<T> = FC<ConsumerProps<T>>;
|
|
21
21
|
|
|
22
22
|
export interface CreateContext {
|
|
23
23
|
<T>(defaultValue: T): SimpContext<T>;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
declare function createCreateContext(renderRuntime: SimpRenderRuntime): CreateContext;
|
|
26
|
+
export declare function createCreateContext(renderRuntime: SimpRenderRuntime): CreateContext;
|
|
27
27
|
|
|
28
28
|
export interface UseContext {
|
|
29
29
|
<T>(context: SimpContext<T>): T;
|
|
30
30
|
}
|
|
31
|
-
declare function createUseContext(renderRuntime: SimpRenderRuntime): UseContext;
|
|
31
|
+
export declare function createUseContext(renderRuntime: SimpRenderRuntime): UseContext;
|
package/context/index.js
CHANGED
|
@@ -1,27 +1,39 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { registerLifecyclePlugin, rerender, } from '../core/internal.js';
|
|
2
|
+
const currentFCByRuntime = new WeakMap();
|
|
3
|
+
registerLifecyclePlugin(bus => {
|
|
4
|
+
bus.subscribe(event => {
|
|
5
|
+
if (event.type === 'beforeRender') {
|
|
6
|
+
currentFCByRuntime.set(event.renderRuntime, event.element);
|
|
7
7
|
}
|
|
8
|
-
|
|
8
|
+
else if (event.type === 'afterRender' || event.type === 'errored') {
|
|
9
|
+
currentFCByRuntime.set(event.renderRuntime, null);
|
|
10
|
+
}
|
|
11
|
+
if (event.type === 'unmounted' && event.element.context) {
|
|
12
|
+
const contextMap = event.element.context;
|
|
13
|
+
for (const entry of contextMap.values()) {
|
|
14
|
+
entry.subs.delete(event.element);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
});
|
|
9
18
|
});
|
|
10
19
|
export function createCreateContext(renderRuntime) {
|
|
11
20
|
return defaultValue => {
|
|
21
|
+
const providerElements = new WeakSet();
|
|
12
22
|
const context = {
|
|
13
23
|
defaultValue,
|
|
14
24
|
Provider(props) {
|
|
15
|
-
const currentElement = renderRuntime
|
|
16
|
-
const
|
|
25
|
+
const currentElement = currentFCByRuntime.get(renderRuntime);
|
|
26
|
+
const isFirstRender = !providerElements.has(currentElement);
|
|
17
27
|
let contextMap = currentElement.context;
|
|
18
28
|
if (!contextMap) {
|
|
19
29
|
currentElement.context = contextMap = new Map();
|
|
30
|
+
providerElements.add(currentElement);
|
|
20
31
|
}
|
|
21
|
-
else if (
|
|
32
|
+
else if (isFirstRender) {
|
|
22
33
|
currentElement.context = contextMap = new Map(currentElement.context);
|
|
34
|
+
providerElements.add(currentElement);
|
|
23
35
|
}
|
|
24
|
-
if (
|
|
36
|
+
if (isFirstRender) {
|
|
25
37
|
contextMap.set(context, { value: props.value, subs: new Set() });
|
|
26
38
|
return props.children;
|
|
27
39
|
}
|
|
@@ -40,14 +52,13 @@ export function createCreateContext(renderRuntime) {
|
|
|
40
52
|
return props.children;
|
|
41
53
|
},
|
|
42
54
|
Consumer(props) {
|
|
43
|
-
const currentElement = renderRuntime
|
|
55
|
+
const currentElement = currentFCByRuntime.get(renderRuntime);
|
|
44
56
|
const contextMap = currentElement.context;
|
|
45
|
-
const store = currentElement.store;
|
|
46
57
|
const entry = contextMap?.get(context);
|
|
47
58
|
if (!entry) {
|
|
48
59
|
return props.children(defaultValue);
|
|
49
60
|
}
|
|
50
|
-
entry.subs.add(
|
|
61
|
+
entry.subs.add(currentElement);
|
|
51
62
|
return props.children(entry.value);
|
|
52
63
|
},
|
|
53
64
|
};
|
|
@@ -56,14 +67,13 @@ export function createCreateContext(renderRuntime) {
|
|
|
56
67
|
}
|
|
57
68
|
export function createUseContext(renderRuntime) {
|
|
58
69
|
return context => {
|
|
59
|
-
const currentElement = renderRuntime
|
|
70
|
+
const currentElement = currentFCByRuntime.get(renderRuntime);
|
|
60
71
|
const contextMap = currentElement.context;
|
|
61
|
-
const store = currentElement.store;
|
|
62
72
|
const entry = contextMap?.get(context);
|
|
63
73
|
if (!entry) {
|
|
64
74
|
return context.defaultValue;
|
|
65
75
|
}
|
|
66
|
-
entry.subs.add(
|
|
76
|
+
entry.subs.add(currentElement);
|
|
67
77
|
return entry.value;
|
|
68
78
|
};
|
|
69
79
|
}
|
package/core/createElement.js
CHANGED
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
import { isSimpText } from '../shared/index.js';
|
|
2
|
+
import { SIMP_ELEMENT_CHILD_FLAG_ELEMENT, SIMP_ELEMENT_CHILD_FLAG_EMPTY, SIMP_ELEMENT_CHILD_FLAG_LIST, SIMP_ELEMENT_CHILD_FLAG_TEXT, SIMP_ELEMENT_CHILD_FLAG_UNKNOWN, SIMP_ELEMENT_FLAG_FC, SIMP_ELEMENT_FLAG_FRAGMENT, SIMP_ELEMENT_FLAG_HOST, SIMP_ELEMENT_FLAG_PORTAL, SIMP_ELEMENT_FLAG_TEXT, } from './flags.js';
|
|
2
3
|
import { Fragment } from './fragment.js';
|
|
3
|
-
export
|
|
4
|
-
export const SIMP_ELEMENT_FLAG_FC = 1 << 1;
|
|
5
|
-
export const SIMP_ELEMENT_FLAG_TEXT = 1 << 2;
|
|
6
|
-
export const SIMP_ELEMENT_FLAG_PORTAL = 1 << 3;
|
|
7
|
-
export const SIMP_ELEMENT_FLAG_FRAGMENT = 1 << 4;
|
|
8
|
-
export const SIMP_ELEMENT_CHILD_FLAG_EMPTY = 1;
|
|
9
|
-
export const SIMP_ELEMENT_CHILD_FLAG_UNKNOWN = 1 << 1;
|
|
10
|
-
export const SIMP_ELEMENT_CHILD_FLAG_ELEMENT = 1 << 2;
|
|
11
|
-
export const SIMP_ELEMENT_CHILD_FLAG_LIST = 1 << 3;
|
|
12
|
-
export const SIMP_ELEMENT_CHILD_FLAG_TEXT = 1 << 4;
|
|
4
|
+
export * from './flags.js';
|
|
13
5
|
export function createElement(type, props) {
|
|
14
6
|
let definedChildren;
|
|
15
7
|
const argLength = arguments.length;
|
|
@@ -38,9 +30,9 @@ export function createElement(type, props) {
|
|
|
38
30
|
type,
|
|
39
31
|
props: props || null,
|
|
40
32
|
children: null,
|
|
41
|
-
className: props?.className
|
|
33
|
+
className: props?.className ?? props?.class ?? null,
|
|
42
34
|
reference: null,
|
|
43
|
-
|
|
35
|
+
hostNamespace: null,
|
|
44
36
|
context: null,
|
|
45
37
|
ref: props?.ref ? { value: props.ref } : null,
|
|
46
38
|
unmounted: null,
|
|
@@ -63,7 +55,7 @@ export function createElement(type, props) {
|
|
|
63
55
|
children: null,
|
|
64
56
|
className: props?.className || null,
|
|
65
57
|
reference: null,
|
|
66
|
-
|
|
58
|
+
hostNamespace: null,
|
|
67
59
|
context: null,
|
|
68
60
|
ref: props?.ref ? { value: props.ref } : null,
|
|
69
61
|
unmounted: null,
|
|
@@ -84,7 +76,7 @@ export function createElement(type, props) {
|
|
|
84
76
|
children: null,
|
|
85
77
|
className: null,
|
|
86
78
|
reference: null,
|
|
87
|
-
|
|
79
|
+
hostNamespace: null,
|
|
88
80
|
context: null,
|
|
89
81
|
ref: null,
|
|
90
82
|
unmounted: null,
|
|
@@ -92,6 +84,9 @@ export function createElement(type, props) {
|
|
|
92
84
|
};
|
|
93
85
|
}
|
|
94
86
|
default: {
|
|
87
|
+
if (type !== Fragment) {
|
|
88
|
+
throw new Error(`Invalid element type: ${String(type)}`);
|
|
89
|
+
}
|
|
95
90
|
return normalizeChildren({
|
|
96
91
|
flag: SIMP_ELEMENT_FLAG_FRAGMENT,
|
|
97
92
|
childFlag: SIMP_ELEMENT_CHILD_FLAG_UNKNOWN,
|
|
@@ -102,7 +97,7 @@ export function createElement(type, props) {
|
|
|
102
97
|
children: null,
|
|
103
98
|
className: null,
|
|
104
99
|
reference: null,
|
|
105
|
-
|
|
100
|
+
hostNamespace: null,
|
|
106
101
|
context: null,
|
|
107
102
|
ref: null,
|
|
108
103
|
unmounted: null,
|
|
@@ -122,7 +117,7 @@ export function createTextElement(text) {
|
|
|
122
117
|
children: text.toString(),
|
|
123
118
|
className: null,
|
|
124
119
|
reference: null,
|
|
125
|
-
|
|
120
|
+
hostNamespace: null,
|
|
126
121
|
context: null,
|
|
127
122
|
ref: null,
|
|
128
123
|
unmounted: null,
|
|
@@ -170,7 +165,9 @@ function normalizeNode(child, result, currentKey = null, skipIgnoredCheck) {
|
|
|
170
165
|
}
|
|
171
166
|
const element = child;
|
|
172
167
|
if (element.key != null) {
|
|
173
|
-
|
|
168
|
+
const prefix = currentKey ?? '';
|
|
169
|
+
const lastDot = prefix.lastIndexOf('.');
|
|
170
|
+
currentKey = lastDot <= 0 ? String(element.key) : `${prefix.slice(0, lastDot)}${element.key}`;
|
|
174
171
|
}
|
|
175
172
|
element.key = currentKey;
|
|
176
173
|
element.index = result.length;
|
package/core/flags.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export const SIMP_ELEMENT_FLAG_HOST = 1;
|
|
2
|
+
export const SIMP_ELEMENT_FLAG_FC = 1 << 1;
|
|
3
|
+
export const SIMP_ELEMENT_FLAG_TEXT = 1 << 2;
|
|
4
|
+
export const SIMP_ELEMENT_FLAG_PORTAL = 1 << 3;
|
|
5
|
+
export const SIMP_ELEMENT_FLAG_FRAGMENT = 1 << 4;
|
|
6
|
+
export const SIMP_ELEMENT_CHILD_FLAG_EMPTY = 1;
|
|
7
|
+
export const SIMP_ELEMENT_CHILD_FLAG_UNKNOWN = 1 << 1;
|
|
8
|
+
export const SIMP_ELEMENT_CHILD_FLAG_ELEMENT = 1 << 2;
|
|
9
|
+
export const SIMP_ELEMENT_CHILD_FLAG_LIST = 1 << 3;
|
|
10
|
+
export const SIMP_ELEMENT_CHILD_FLAG_TEXT = 1 << 4;
|
|
11
|
+
export function isFC(element) {
|
|
12
|
+
return (element.flag & SIMP_ELEMENT_FLAG_FC) !== 0;
|
|
13
|
+
}
|
|
14
|
+
export function isFragment(element) {
|
|
15
|
+
return (element.flag & SIMP_ELEMENT_FLAG_FRAGMENT) !== 0;
|
|
16
|
+
}
|
|
17
|
+
export function isHost(element) {
|
|
18
|
+
return (element.flag & SIMP_ELEMENT_FLAG_HOST) !== 0;
|
|
19
|
+
}
|
|
20
|
+
export function isPortal(element) {
|
|
21
|
+
return (element.flag & SIMP_ELEMENT_FLAG_PORTAL) !== 0;
|
|
22
|
+
}
|
|
23
|
+
export function isText(element) {
|
|
24
|
+
return (element.flag & SIMP_ELEMENT_FLAG_TEXT) !== 0;
|
|
25
|
+
}
|
|
26
|
+
export function hasListChildren(element) {
|
|
27
|
+
return element.childFlag === SIMP_ELEMENT_CHILD_FLAG_LIST;
|
|
28
|
+
}
|
|
29
|
+
export function hasElementChild(element) {
|
|
30
|
+
return element.childFlag === SIMP_ELEMENT_CHILD_FLAG_ELEMENT;
|
|
31
|
+
}
|
package/core/hostOperations.js
CHANGED
|
@@ -1,15 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export function
|
|
3
|
-
|
|
4
|
-
node: element,
|
|
5
|
-
kind: HOST_OPS_PLACE_ELEMENT_BEFORE_ANCHOR,
|
|
6
|
-
meta,
|
|
7
|
-
});
|
|
1
|
+
import { acquirePlaceFrame, acquireReplaceFrame } from './processStack.js';
|
|
2
|
+
export function pushHostOperationPlaceElement(element, renderRuntime, parentReference, subtreeRightBoundary) {
|
|
3
|
+
renderRuntime.renderStack.push(acquirePlaceFrame(renderRuntime, element, parentReference, subtreeRightBoundary));
|
|
8
4
|
}
|
|
9
|
-
export function
|
|
10
|
-
renderRuntime.renderStack.push(
|
|
11
|
-
node: element,
|
|
12
|
-
kind: HOST_OPS_REPLACE_CHILD,
|
|
13
|
-
meta,
|
|
14
|
-
});
|
|
5
|
+
export function pushHostOperationReplaceElement(element, renderRuntime, parentReference, prevElement) {
|
|
6
|
+
renderRuntime.renderStack.push(acquireReplaceFrame(renderRuntime, element, parentReference, prevElement));
|
|
15
7
|
}
|
package/core/index.d.ts
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
|
-
import type { Nullable, SimpText } from '../shared/index.js';
|
|
2
|
-
|
|
1
|
+
import type { Maybe, Nullable, SimpText } from '../shared/index.js';
|
|
2
|
+
|
|
3
|
+
export interface HostAdapter<HostRef = unknown, HostTextRef = unknown, NS = string> {
|
|
4
|
+
createReference(type: string, namespace?: Maybe<NS>): HostRef;
|
|
5
|
+
createTextReference(text: string): HostTextRef;
|
|
6
|
+
mountProps(reference: HostRef, element: SimpElement, renderRuntime: SimpRenderRuntime, namespace?: Maybe<NS>): void;
|
|
7
|
+
patchProps(
|
|
8
|
+
reference: HostRef,
|
|
9
|
+
prevElement: SimpElement,
|
|
10
|
+
nextElement: SimpElement,
|
|
11
|
+
renderRuntime: SimpRenderRuntime,
|
|
12
|
+
namespace?: Maybe<NS>
|
|
13
|
+
): void;
|
|
14
|
+
unmountProps(reference: HostRef, element: SimpElement, renderRuntime: SimpRenderRuntime): void;
|
|
15
|
+
setClassname(reference: HostRef, className: Maybe<string>, namespace?: Maybe<NS>): void;
|
|
16
|
+
setTextContent(reference: HostRef, text: string, referenceHasOnlyTextElement?: boolean): void;
|
|
17
|
+
removeChild(parent: HostRef, child: HostRef | HostTextRef): void;
|
|
18
|
+
replaceChild(parent: HostRef, replacer: HostRef | HostTextRef, toBeReplaced: HostRef | HostTextRef): void;
|
|
19
|
+
insertOrAppend(parent: HostRef, child: HostRef | HostTextRef, before: Nullable<HostRef | HostTextRef>): void;
|
|
20
|
+
clearNode(reference: HostRef | HostTextRef): void;
|
|
21
|
+
attachElementToReference(
|
|
22
|
+
element: SimpElement,
|
|
23
|
+
reference: HostRef | HostTextRef,
|
|
24
|
+
renderRuntime: SimpRenderRuntime
|
|
25
|
+
): void;
|
|
26
|
+
detachElementFromReference(reference: HostRef | HostTextRef, renderRuntime: SimpRenderRuntime): void;
|
|
27
|
+
getElementFromReference(reference: HostRef | HostTextRef, renderRuntime: SimpRenderRuntime): Nullable<SimpElement>;
|
|
28
|
+
getHostNamespaces(
|
|
29
|
+
element: SimpElement,
|
|
30
|
+
currentNamespace: Maybe<NS>
|
|
31
|
+
): Nullable<{ self: Nullable<NS>; children: Nullable<NS> }>;
|
|
32
|
+
}
|
|
3
33
|
|
|
4
34
|
export type ComponentType<P = {}> = FunctionalComponent<P>;
|
|
5
35
|
|
|
@@ -27,37 +57,44 @@ export interface SimpElement<P = unknown, T extends string | FunctionalComponent
|
|
|
27
57
|
|
|
28
58
|
export type SimpNode = SimpElement | SimpText | Array<SimpNode> | boolean | null | undefined;
|
|
29
59
|
|
|
30
|
-
declare function createElement<P extends {}, T>(
|
|
60
|
+
export declare function createElement<P extends {}, T>(
|
|
31
61
|
type: string,
|
|
32
62
|
props?: (RefAttributes<T> & P) | null,
|
|
33
63
|
...children: SimpNode[]
|
|
34
64
|
): SimpElement<P>;
|
|
35
|
-
declare function createElement<P extends {}>(
|
|
65
|
+
export declare function createElement<P extends {}>(
|
|
36
66
|
type: FunctionalComponent<P>,
|
|
37
67
|
props?: (Attributes & P) | null,
|
|
38
68
|
...children: SimpNode[]
|
|
39
69
|
): SimpElement<P>;
|
|
40
70
|
|
|
41
|
-
declare function createPortal<HostRef = {}>(children: SimpNode, container: HostRef): SimpElement;
|
|
71
|
+
export declare function createPortal<HostRef = {}>(children: SimpNode, container: HostRef): SimpElement;
|
|
42
72
|
|
|
43
|
-
declare function Fragment(props: PropsWithChildren): SimpElement;
|
|
73
|
+
export declare function Fragment(props: PropsWithChildren): SimpElement;
|
|
44
74
|
|
|
45
75
|
export type FunctionalComponent<P = {}> = (props: P) => SimpNode;
|
|
46
76
|
export type FC<P = {}> = FunctionalComponent<P>;
|
|
47
77
|
|
|
48
78
|
export type PropsWithChildren<P = {}> = P & { children?: SimpNode | undefined };
|
|
49
79
|
|
|
50
|
-
declare function memo<P = {}>(
|
|
80
|
+
export declare function memo<P = {}>(
|
|
81
|
+
Component: FC<P>,
|
|
82
|
+
compare?: (objA: Readonly<P>, objB: Readonly<P>) => boolean
|
|
83
|
+
): FC<P>;
|
|
84
|
+
|
|
85
|
+
export declare function withSyncRerender(runtime: SimpRenderRuntime, callback: () => void): void;
|
|
51
86
|
|
|
52
87
|
export interface SimpRuntimeFCRenderer {
|
|
53
|
-
(component: FC, element: SimpElement): SimpNode;
|
|
88
|
+
(component: FC, element: SimpElement, renderRuntime: SimpRenderRuntime): SimpNode;
|
|
54
89
|
}
|
|
55
90
|
|
|
56
91
|
export interface SimpRenderRuntime {
|
|
57
92
|
hostAdapter: HostAdapter;
|
|
58
93
|
renderer: SimpRuntimeFCRenderer;
|
|
59
94
|
renderStack: Array<{ node: SimpElement; kind: number; meta: any }>;
|
|
60
|
-
elementToHostMap: Map<unknown, SimpElement>;
|
|
61
|
-
currentRenderingFCElement: Nullable<SimpElement>;
|
|
62
|
-
renderPhase: Nullable<number>;
|
|
63
95
|
}
|
|
96
|
+
|
|
97
|
+
export declare function createRenderRuntime(
|
|
98
|
+
hostAdapter: HostAdapter,
|
|
99
|
+
renderer: SimpRuntimeFCRenderer
|
|
100
|
+
): SimpRenderRuntime;
|
package/core/index.js
CHANGED
|
@@ -2,5 +2,7 @@ import { createElement } from './createElement.js';
|
|
|
2
2
|
import { Fragment } from './fragment.js';
|
|
3
3
|
import { memo } from './memo.js';
|
|
4
4
|
import { createPortal } from './portal.js';
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
import { withSyncRerender } from './rerender.js';
|
|
6
|
+
import { createRenderRuntime } from './runtime.js';
|
|
7
|
+
export { createElement, createRenderRuntime, Fragment, memo, createPortal, withSyncRerender };
|
|
8
|
+
export default { createElement, createRenderRuntime, Fragment, memo, createPortal, withSyncRerender };
|