@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.
Files changed (81) hide show
  1. package/compat/context.js +3 -3
  2. package/compat/core.js +105 -18
  3. package/compat/dom.js +5 -5
  4. package/compat/hooks.js +18 -3
  5. package/compat/index.d.ts +109 -45
  6. package/compat/jsx-runtime.js +4 -4
  7. package/compat/renderRuntime.js +47 -12
  8. package/component/index.d.ts +6 -7
  9. package/component/index.js +96 -94
  10. package/context/index.d.ts +5 -5
  11. package/context/index.js +27 -17
  12. package/core/createElement.js +14 -17
  13. package/core/flags.js +31 -0
  14. package/core/hostOperations.js +5 -13
  15. package/core/index.d.ts +48 -11
  16. package/core/index.js +4 -2
  17. package/core/internal.d.ts +136 -16
  18. package/core/internal.js +8 -16
  19. package/core/lifecycleEventBus.js +35 -16
  20. package/core/memo.js +4 -1
  21. package/core/mounting.js +70 -150
  22. package/core/mountingChildren.js +11 -29
  23. package/core/patching.js +122 -181
  24. package/core/patchingChildren.js +74 -145
  25. package/core/portal.js +1 -1
  26. package/core/processStack.js +115 -45
  27. package/core/ref.js +1 -0
  28. package/core/rerender.js +20 -22
  29. package/core/runtime.js +10 -2
  30. package/core/unmounting.js +41 -49
  31. package/core/unmountingChildren.js +9 -12
  32. package/core/utils.js +38 -16
  33. package/dom/attach-element-to-dom.js +16 -8
  34. package/dom/events.js +11 -15
  35. package/dom/index.d.ts +6 -5
  36. package/dom/props/attrMaps.js +90 -0
  37. package/dom/props/controlled/select.js +8 -10
  38. package/dom/props/props.js +13 -14
  39. package/hooks/index.d.ts +15 -10
  40. package/hooks/index.js +107 -84
  41. package/package.json +10 -5
  42. package/shared/index.d.ts +10 -6
  43. package/compat/context.d.ts +0 -8
  44. package/compat/core.d.ts +0 -47
  45. package/compat/dom.d.ts +0 -10
  46. package/compat/hooks.d.ts +0 -27
  47. package/compat/jsx-runtime.d.ts +0 -10
  48. package/compat/renderRuntime.d.ts +0 -6
  49. package/core/createElement.d.ts +0 -39
  50. package/core/fragment.d.ts +0 -5
  51. package/core/hostAdapter.d.ts +0 -23
  52. package/core/hostOperations.d.ts +0 -5
  53. package/core/lifecycleEventBus.d.ts +0 -39
  54. package/core/memo.d.ts +0 -8
  55. package/core/mounting.d.ts +0 -7
  56. package/core/mountingChildren.d.ts +0 -4
  57. package/core/patching.d.ts +0 -8
  58. package/core/patchingChildren.d.ts +0 -6
  59. package/core/portal.d.ts +0 -2
  60. package/core/processStack.d.ts +0 -106
  61. package/core/ref.d.ts +0 -18
  62. package/core/rerender.d.ts +0 -4
  63. package/core/runtime.d.ts +0 -17
  64. package/core/unmounting.d.ts +0 -7
  65. package/core/unmountingChildren.d.ts +0 -4
  66. package/core/utils.d.ts +0 -11
  67. package/dom/attach-element-to-dom.d.ts +0 -5
  68. package/dom/domAdapter.d.ts +0 -3
  69. package/dom/events.d.ts +0 -27
  70. package/dom/namespace.d.ts +0 -2
  71. package/dom/props/controlled/index.d.ts +0 -7
  72. package/dom/props/controlled/input.d.ts +0 -7
  73. package/dom/props/controlled/select.d.ts +0 -6
  74. package/dom/props/controlled/textarea.d.ts +0 -6
  75. package/dom/props/dangerInnerHTML.d.ts +0 -7
  76. package/dom/props/index.d.ts +0 -1
  77. package/dom/props/props.d.ts +0 -5
  78. package/dom/props/style.d.ts +0 -1
  79. package/dom/render.d.ts +0 -8
  80. package/shared/lang.d.ts +0 -3
  81. package/shared/utils.d.ts +0 -5
@@ -1,11 +1,11 @@
1
- import { lifecycleEventBus, rerender, SIMP_ELEMENT_FLAG_FC, } from '../core/internal.js';
1
+ import { isFC, registerLifecyclePlugin, rerender, } from '../core/internal.js';
2
2
  import { emptyObject, shallowEqual, } from '../shared/index.js';
3
- const componentSpecificStoreByElementStore = new WeakMap();
4
- function getComponentSpecificStore(store, renderRuntime) {
5
- let hooksSpecificStore = componentSpecificStoreByElementStore.get(store);
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(store, renderRuntime);
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
- componentSpecificStoreByElementStore.set(store, hooksSpecificStore);
20
+ componentSpecificStoreByElement.set(element, hooksSpecificStore);
21
21
  }
22
22
  return hooksSpecificStore;
23
23
  }
24
- lifecycleEventBus.subscribe(event => {
25
- if (event.type === 'errored') {
26
- if (event.handled) {
27
- return;
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
- try {
44
- for (let i = 0; i < catchers.length; i++) {
45
- catchers[i](curError);
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
- return;
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
- case 'afterRender': {
69
- if (!store.context.effects) {
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
- for (let i = 0; i < store.context.effects.length; i++) {
73
- const renderEffectState = store.context.effects[i];
74
- let state = (store.effectStates ||= [])[i];
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
- if (!shallowEqual(renderEffectState.deps, state.deps)) {
83
- state.effect = renderEffectState.effect;
84
- state.deps = renderEffectState.deps || null;
85
- (store.pendingEffectStates ||= []).push(state);
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
- const effects = store.pendingEffectStates;
95
- store.pendingEffectStates = null;
96
- for (const state of effects) {
97
- if (typeof state.cleanup === 'function') {
98
- state.cleanup();
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
- const effects = store.pendingEffectStates;
109
- store.pendingEffectStates = null;
110
- for (const state of effects) {
111
- if (typeof state.cleanup === 'function') {
112
- state.cleanup();
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
- const effects = store.effectStates;
123
- store.effectStates = null;
124
- for (const state of effects) {
125
- if (state && 'cleanup' in state && typeof state.cleanup === 'function') {
126
- state.cleanup();
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.store, renderRuntime);
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.flag & SIMP_ELEMENT_FLAG_FC && element.type._isComponent;
165
+ return isFC(element) && element.type._isComponent;
164
166
  }
@@ -1,4 +1,4 @@
1
- import type { FunctionalComponent, SimpNode } from '../core/index.js';
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> = FunctionalComponent<ProviderProps<T>>;
20
- export type Consumer<T> = FunctionalComponent<ConsumerProps<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 { lifecycleEventBus, MOUNTING_PHASE, rerender, } from '../core/internal.js';
2
- lifecycleEventBus.subscribe(event => {
3
- if (event.type === 'unmounted' && event.element.context) {
4
- const contextMap = event.element.context;
5
- for (const entry of contextMap.values()) {
6
- entry.subs.delete(event.element.store);
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.currentRenderingFCElement;
16
- const renderPhase = renderRuntime.renderPhase;
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 (renderPhase === MOUNTING_PHASE) {
32
+ else if (isFirstRender) {
22
33
  currentElement.context = contextMap = new Map(currentElement.context);
34
+ providerElements.add(currentElement);
23
35
  }
24
- if (renderPhase === MOUNTING_PHASE) {
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.currentRenderingFCElement;
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(store);
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.currentRenderingFCElement;
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(store);
76
+ entry.subs.add(currentElement);
67
77
  return entry.value;
68
78
  };
69
79
  }
@@ -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 const SIMP_ELEMENT_FLAG_HOST = 1;
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 || null,
33
+ className: props?.className ?? props?.class ?? null,
42
34
  reference: null,
43
- store: null,
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
- store: null,
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
- store: null,
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
- store: null,
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
- store: null,
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
- currentKey = `${(currentKey ?? '').slice(0, -2)}${element.key}`;
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
+ }
@@ -1,15 +1,7 @@
1
- import { HOST_OPS_PLACE_ELEMENT_BEFORE_ANCHOR, HOST_OPS_REPLACE_CHILD, } from './processStack.js';
2
- export function _pushHostOperationPlaceElement(element, meta) {
3
- meta.renderRuntime.renderStack.push({
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 _pushHostOperationReplaceElement(element, renderRuntime, meta) {
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
- import type { HostAdapter } from './hostAdapter.js';
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 = {}>(Component: FC<P>, compare?: (objA: Readonly<P>, objB: Readonly<P>) => boolean): FC<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
- export { createElement, Fragment, memo, createPortal };
6
- export default { createElement, Fragment, memo, createPortal };
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 };