@simpreact/simpreact 0.0.2 → 0.0.4

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 (48) hide show
  1. package/compat/context.d.ts +8 -0
  2. package/compat/context.js +7 -0
  3. package/compat/core.d.ts +43 -0
  4. package/compat/core.js +90 -0
  5. package/compat/dom.d.ts +11 -0
  6. package/compat/dom.js +10 -0
  7. package/compat/hooks.d.ts +24 -0
  8. package/compat/hooks.js +75 -0
  9. package/compat/index.d.ts +43 -0
  10. package/compat/index.js +17 -0
  11. package/compat/jsx-runtime.d.ts +10 -0
  12. package/compat/jsx-runtime.js +9 -0
  13. package/context/index.d.ts +24 -0
  14. package/context/index.js +64 -0
  15. package/core/createElement.d.ts +6 -9
  16. package/core/createElement.js +4 -25
  17. package/core/index.d.ts +4 -23
  18. package/core/index.js +3 -3
  19. package/core/internal.d.ts +1 -1
  20. package/core/internal.js +1 -1
  21. package/core/lifecycleEventBus.d.ts +4 -0
  22. package/core/memo.d.ts +10 -0
  23. package/core/memo.js +11 -0
  24. package/core/mounting.d.ts +6 -9
  25. package/core/mounting.js +44 -49
  26. package/core/patching.d.ts +4 -5
  27. package/core/patching.js +81 -68
  28. package/core/ref.d.ts +4 -4
  29. package/core/rerender.d.ts +7 -6
  30. package/core/rerender.js +91 -32
  31. package/core/unmounting.js +7 -3
  32. package/dom/attach-element-to-dom.js +11 -2
  33. package/dom/events.d.ts +9 -1
  34. package/dom/events.js +21 -5
  35. package/dom/props/controlled/input.js +5 -5
  36. package/dom/props/controlled/select.js +3 -3
  37. package/dom/props/controlled/textarea.js +5 -5
  38. package/dom/props/style.js +6 -3
  39. package/dom/render.js +3 -3
  40. package/hooks/index.d.ts +7 -3
  41. package/hooks/index.js +46 -14
  42. package/package.json +7 -1
  43. package/shared/index.d.ts +6 -0
  44. package/shared/index.js +12 -3
  45. package/shared/utils.d.ts +2 -0
  46. package/shared/utils.js +36 -0
  47. package/core/context.d.ts +0 -18
  48. package/core/context.js +0 -18
@@ -0,0 +1,8 @@
1
+ import * as SimpReactContext from '../context/index.js';
2
+ export declare const createContext: typeof SimpReactContext.createContext;
3
+ export declare const useContext: typeof SimpReactContext.useContext;
4
+ declare const _default: {
5
+ createContext: typeof SimpReactContext.createContext;
6
+ useContext: typeof SimpReactContext.useContext;
7
+ };
8
+ export default _default;
@@ -0,0 +1,7 @@
1
+ import * as SimpReactContext from '../context/index.js';
2
+ export const createContext = SimpReactContext.createContext;
3
+ export const useContext = SimpReactContext.useContext;
4
+ export default {
5
+ createContext,
6
+ useContext,
7
+ };
@@ -0,0 +1,43 @@
1
+ import * as SimpReactInternal from '../core/internal.js';
2
+ export declare const Children: {
3
+ map(children: SimpReactInternal.SimpNode, fn: (child: SimpReactInternal.SimpNode, index: number) => SimpReactInternal.SimpNode): SimpReactInternal.SimpNode[];
4
+ forEach(children: SimpReactInternal.SimpNode, fn: (child: SimpReactInternal.SimpNode, index: number) => void): void;
5
+ count(children: SimpReactInternal.SimpNode): number;
6
+ toArray(children: SimpReactInternal.SimpNode): SimpReactInternal.SimpNode[];
7
+ only(children: SimpReactInternal.SimpNode): SimpReactInternal.SimpElement;
8
+ };
9
+ export declare function cloneElement(element: SimpReactInternal.SimpElement, props?: any, ...children: SimpReactInternal.SimpNode[]): SimpReactInternal.SimpElement;
10
+ export declare function isValidElement(element: unknown): element is SimpReactInternal.SimpElement;
11
+ export declare function Suspense(props: {
12
+ fallback: SimpReactInternal.SimpNode;
13
+ children: SimpReactInternal.SimpNode;
14
+ }): SimpReactInternal.SimpNode;
15
+ export declare function forwardRef<P, T>(Component: (props: P, ref: SimpReactInternal.Ref<T>) => any): (props: P) => any;
16
+ export declare const Fragment: SimpReactInternal.Fragment;
17
+ export declare const createElement: typeof SimpReactInternal.createElement;
18
+ export declare const createPortal: typeof SimpReactInternal.createPortal;
19
+ export declare const memo: typeof SimpReactInternal.memo;
20
+ export declare const flushSync: (value: any) => any;
21
+ export declare class Component {
22
+ constructor();
23
+ }
24
+ declare const _default: {
25
+ Children: {
26
+ map(children: SimpReactInternal.SimpNode, fn: (child: SimpReactInternal.SimpNode, index: number) => SimpReactInternal.SimpNode): SimpReactInternal.SimpNode[];
27
+ forEach(children: SimpReactInternal.SimpNode, fn: (child: SimpReactInternal.SimpNode, index: number) => void): void;
28
+ count(children: SimpReactInternal.SimpNode): number;
29
+ toArray(children: SimpReactInternal.SimpNode): SimpReactInternal.SimpNode[];
30
+ only(children: SimpReactInternal.SimpNode): SimpReactInternal.SimpElement;
31
+ };
32
+ cloneElement: typeof cloneElement;
33
+ isValidElement: typeof isValidElement;
34
+ Suspense: typeof Suspense;
35
+ forwardRef: typeof forwardRef;
36
+ Fragment: SimpReactInternal.Fragment;
37
+ createElement: typeof SimpReactInternal.createElement;
38
+ createPortal: typeof SimpReactInternal.createPortal;
39
+ memo: typeof SimpReactInternal.memo;
40
+ flushSync: (value: any) => any;
41
+ Component: typeof Component;
42
+ };
43
+ export default _default;
package/compat/core.js ADDED
@@ -0,0 +1,90 @@
1
+ import * as SimpReactInternal from '../core/internal.js';
2
+ import * as SimpReactHooks from '../hooks/index.js';
3
+ export const Children = {
4
+ map(children, fn) {
5
+ return Children.toArray(children).map(fn);
6
+ },
7
+ forEach(children, fn) {
8
+ Children.toArray(children).forEach(fn);
9
+ },
10
+ count(children) {
11
+ return Children.toArray(children).length;
12
+ },
13
+ toArray(children) {
14
+ const result = [];
15
+ function traverse(node) {
16
+ if (node == null || typeof node === 'boolean') {
17
+ return;
18
+ }
19
+ if (Array.isArray(node)) {
20
+ for (const child of node) {
21
+ traverse(child);
22
+ }
23
+ return;
24
+ }
25
+ result.push(node);
26
+ }
27
+ traverse(children);
28
+ return result;
29
+ },
30
+ only(children) {
31
+ const array = Children.toArray(children);
32
+ if (array.length !== 1 || !isValidElement(array[0])) {
33
+ throw new Error('Children.only expected a single SimpElement child.');
34
+ }
35
+ return array[0];
36
+ },
37
+ };
38
+ export function cloneElement(element, props, ...children) {
39
+ if (!isValidElement(element)) {
40
+ throw new Error(`cloneElement: expected a SimpElement, got ${element}`);
41
+ }
42
+ if (element.flag === 'PORTAL') {
43
+ throw new Error('cloneElement: the argument must be a SimpElement, but you passed a portal instead.');
44
+ }
45
+ return SimpReactInternal.createElement(element.flag === 'FRAGMENT' ? SimpReactInternal.Fragment : element.type, Object.assign({}, element.props, props), arguments.length > 2 ? children : props.children || element.children);
46
+ }
47
+ export function isValidElement(element) {
48
+ return typeof element === 'object' && element !== null && 'flag' in element;
49
+ }
50
+ export function Suspense(props) {
51
+ const [isSuspended, setIsSuspended] = SimpReactHooks.useState(false);
52
+ SimpReactHooks.useCatch(error => {
53
+ if (isSuspended) {
54
+ return;
55
+ }
56
+ if (error instanceof Promise) {
57
+ setIsSuspended(true);
58
+ error.then(() => setIsSuspended(false));
59
+ }
60
+ });
61
+ return isSuspended ? props.fallback : props.children;
62
+ }
63
+ export function forwardRef(Component) {
64
+ return function Forwarded(props) {
65
+ return Component(props, props?.ref || null);
66
+ };
67
+ }
68
+ export const Fragment = SimpReactInternal.Fragment;
69
+ export const createElement = SimpReactInternal.createElement;
70
+ export const createPortal = SimpReactInternal.createPortal;
71
+ export const memo = SimpReactInternal.memo;
72
+ export const flushSync = (value) => value;
73
+ export class Component {
74
+ constructor() {
75
+ throw new Error('Not implemented.');
76
+ }
77
+ }
78
+ export default {
79
+ Children,
80
+ cloneElement,
81
+ isValidElement,
82
+ Suspense,
83
+ forwardRef,
84
+ Fragment,
85
+ createElement,
86
+ createPortal,
87
+ memo,
88
+ flushSync,
89
+ Component,
90
+ };
@@ -0,0 +1,11 @@
1
+ import * as SimpReactDOM from '../dom/index.js';
2
+ import * as SimpReactShared from '../shared/index.js';
3
+ export declare const hydrate: typeof SimpReactShared.noop;
4
+ export declare const render: typeof SimpReactDOM.render;
5
+ export declare const createRoot: typeof SimpReactDOM.createRoot;
6
+ declare const _default: {
7
+ hydrate: typeof SimpReactShared.noop;
8
+ render: typeof SimpReactDOM.render;
9
+ createRoot: typeof SimpReactDOM.createRoot;
10
+ };
11
+ export default _default;
package/compat/dom.js ADDED
@@ -0,0 +1,10 @@
1
+ import * as SimpReactDOM from '../dom/index.js';
2
+ import * as SimpReactShared from '../shared/index.js';
3
+ export const hydrate = SimpReactShared.noop;
4
+ export const render = SimpReactDOM.render;
5
+ export const createRoot = SimpReactDOM.createRoot;
6
+ export default {
7
+ hydrate,
8
+ render,
9
+ createRoot,
10
+ };
@@ -0,0 +1,24 @@
1
+ import * as SimpReactHooks from '../hooks/index.js';
2
+ export declare function useSyncExternalStore<T>(subscribe: (callback: () => void) => () => void, getSnapshot: () => T): T;
3
+ export declare function useReducer<R extends (state: any, action: any) => any, I>(reducer: R, initializerArg: I, initializer?: (arg: I) => ReturnType<R>): [ReturnType<R>, (action: Parameters<R>[1]) => void];
4
+ export declare function useId(prefix?: string): string;
5
+ export declare function useMemo<T>(factory: () => T, deps: SimpReactHooks.DependencyList): T;
6
+ export declare function useCallback<T>(cb: T, deps: SimpReactHooks.DependencyList): T;
7
+ export declare const useState: typeof SimpReactHooks.useState;
8
+ export declare const useEffect: typeof SimpReactHooks.useEffect;
9
+ export declare const useLayoutEffect: typeof SimpReactHooks.useEffect;
10
+ export declare const useInsertionEffect: typeof SimpReactHooks.useEffect;
11
+ export declare const useRef: typeof SimpReactHooks.useRef;
12
+ declare const _default: {
13
+ useSyncExternalStore: typeof useSyncExternalStore;
14
+ useReducer: typeof useReducer;
15
+ useId: typeof useId;
16
+ useMemo: typeof useMemo;
17
+ useCallback: typeof useCallback;
18
+ useState: typeof SimpReactHooks.useState;
19
+ useEffect: typeof SimpReactHooks.useEffect;
20
+ useLayoutEffect: typeof SimpReactHooks.useEffect;
21
+ useInsertionEffect: typeof SimpReactHooks.useEffect;
22
+ useRef: typeof SimpReactHooks.useRef;
23
+ };
24
+ export default _default;
@@ -0,0 +1,75 @@
1
+ import * as SimpReactHooks from '../hooks/index.js';
2
+ export function useSyncExternalStore(subscribe, getSnapshot) {
3
+ const rerender = SimpReactHooks.useRerender();
4
+ const lastSnapshotRef = SimpReactHooks.useRef(getSnapshot());
5
+ SimpReactHooks.useEffect(() => {
6
+ function checkForUpdates() {
7
+ const nextSnapshot = getSnapshot();
8
+ if (!Object.is(lastSnapshotRef.current, nextSnapshot)) {
9
+ lastSnapshotRef.current = nextSnapshot;
10
+ rerender();
11
+ }
12
+ }
13
+ const unsubscribe = subscribe(checkForUpdates);
14
+ checkForUpdates();
15
+ return unsubscribe;
16
+ }, [subscribe, getSnapshot]);
17
+ return lastSnapshotRef.current;
18
+ }
19
+ export function useReducer(reducer, initializerArg, initializer) {
20
+ const rerender = SimpReactHooks.useRerender();
21
+ const reducerRef = SimpReactHooks.useRef(reducer);
22
+ reducerRef.current = reducer;
23
+ const stateRef = SimpReactHooks.useRef([
24
+ initializer ? initializer(initializerArg) : initializerArg,
25
+ function dispatch(action) {
26
+ const newState = reducerRef.current(stateRef.current[0], action);
27
+ if (Object.is(newState, stateRef.current[0])) {
28
+ return;
29
+ }
30
+ stateRef.current[0] = newState;
31
+ rerender();
32
+ },
33
+ ]);
34
+ return stateRef.current;
35
+ }
36
+ let globalId = 0;
37
+ export function useId(prefix = 'id') {
38
+ const idRef = SimpReactHooks.useRef('');
39
+ if (idRef.current === '') {
40
+ globalId += 1;
41
+ idRef.current = `${prefix}-${globalId}`;
42
+ }
43
+ return idRef.current;
44
+ }
45
+ export function useMemo(factory, deps) {
46
+ const ref = SimpReactHooks.useRef({
47
+ deps: undefined,
48
+ value: undefined,
49
+ });
50
+ if (!SimpReactHooks.areDepsEqual(ref.current.deps, deps)) {
51
+ ref.current.value = factory();
52
+ ref.current.deps = deps;
53
+ }
54
+ return ref.current.value;
55
+ }
56
+ export function useCallback(cb, deps) {
57
+ return useMemo(() => cb, deps);
58
+ }
59
+ export const useState = SimpReactHooks.useState;
60
+ export const useEffect = SimpReactHooks.useEffect;
61
+ export const useLayoutEffect = SimpReactHooks.useEffect;
62
+ export const useInsertionEffect = SimpReactHooks.useEffect;
63
+ export const useRef = SimpReactHooks.useRef;
64
+ export default {
65
+ useSyncExternalStore,
66
+ useReducer,
67
+ useId,
68
+ useMemo,
69
+ useCallback,
70
+ useState,
71
+ useEffect,
72
+ useLayoutEffect,
73
+ useInsertionEffect,
74
+ useRef,
75
+ };
@@ -0,0 +1,43 @@
1
+ export * from './context.js';
2
+ export * from './core.js';
3
+ export * from './dom.js';
4
+ export * from './hooks.js';
5
+ export * from './jsx-runtime.js';
6
+ declare const _default: {
7
+ jsx: typeof import("../jsx-runtime/index.js").jsx;
8
+ jsxDEV: typeof import("../jsx-runtime/index.js").jsx;
9
+ jsxs: typeof import("../jsx-runtime/index.js").jsx;
10
+ useSyncExternalStore: typeof import("./hooks.js").useSyncExternalStore;
11
+ useReducer: typeof import("./hooks.js").useReducer;
12
+ useId: typeof import("./hooks.js").useId;
13
+ useMemo: typeof import("./hooks.js").useMemo;
14
+ useCallback: typeof import("./hooks.js").useCallback;
15
+ useState: typeof import("../hooks/index.js").useState;
16
+ useEffect: typeof import("../hooks/index.js").useEffect;
17
+ useLayoutEffect: typeof import("../hooks/index.js").useEffect;
18
+ useInsertionEffect: typeof import("../hooks/index.js").useEffect;
19
+ useRef: typeof import("../hooks/index.js").useRef;
20
+ hydrate: typeof import("../shared/utils.js").noop;
21
+ render: typeof import("../dom/render.js").render;
22
+ createRoot: typeof import("../dom/render.js").createRoot;
23
+ Children: {
24
+ map(children: import("../core/createElement.js").SimpNode, fn: (child: import("../core/createElement.js").SimpNode, index: number) => import("../core/createElement.js").SimpNode): import("../core/createElement.js").SimpNode[];
25
+ forEach(children: import("../core/createElement.js").SimpNode, fn: (child: import("../core/createElement.js").SimpNode, index: number) => void): void;
26
+ count(children: import("../core/createElement.js").SimpNode): number;
27
+ toArray(children: import("../core/createElement.js").SimpNode): import("../core/createElement.js").SimpNode[];
28
+ only(children: import("../core/createElement.js").SimpNode): import("../core/createElement.js").SimpElement;
29
+ };
30
+ cloneElement: typeof import("./core.js").cloneElement;
31
+ isValidElement: typeof import("./core.js").isValidElement;
32
+ Suspense: typeof import("./core.js").Suspense;
33
+ forwardRef: typeof import("./core.js").forwardRef;
34
+ Fragment: import("../core/fragment.js").Fragment;
35
+ createElement: typeof import("../core/createElement.js").createElement;
36
+ createPortal: typeof import("../core/portal.js").createPortal;
37
+ memo: typeof import("../core/memo.js").memo;
38
+ flushSync: (value: any) => any;
39
+ Component: typeof import("./core.js").Component;
40
+ createContext: typeof import("../context/index.js").createContext;
41
+ useContext: typeof import("../context/index.js").useContext;
42
+ };
43
+ export default _default;
@@ -0,0 +1,17 @@
1
+ import contextDefault from './context.js';
2
+ import coreDefault from './core.js';
3
+ import domDefault from './dom.js';
4
+ import hooksDefault from './hooks.js';
5
+ import jsxRuntimeDefault from './jsx-runtime.js';
6
+ export * from './context.js';
7
+ export * from './core.js';
8
+ export * from './dom.js';
9
+ export * from './hooks.js';
10
+ export * from './jsx-runtime.js';
11
+ export default {
12
+ ...contextDefault,
13
+ ...coreDefault,
14
+ ...domDefault,
15
+ ...hooksDefault,
16
+ ...jsxRuntimeDefault,
17
+ };
@@ -0,0 +1,10 @@
1
+ import * as SimpReactJSXRuntime from '../jsx-runtime/index.js';
2
+ export declare const jsx: typeof SimpReactJSXRuntime.jsx;
3
+ export declare const jsxDEV: typeof SimpReactJSXRuntime.jsx;
4
+ export declare const jsxs: typeof SimpReactJSXRuntime.jsx;
5
+ declare const _default: {
6
+ jsx: typeof SimpReactJSXRuntime.jsx;
7
+ jsxDEV: typeof SimpReactJSXRuntime.jsx;
8
+ jsxs: typeof SimpReactJSXRuntime.jsx;
9
+ };
10
+ export default _default;
@@ -0,0 +1,9 @@
1
+ import * as SimpReactJSXRuntime from '../jsx-runtime/index.js';
2
+ export const jsx = SimpReactJSXRuntime.jsx;
3
+ export const jsxDEV = SimpReactJSXRuntime.jsxDEV;
4
+ export const jsxs = SimpReactJSXRuntime.jsxs;
5
+ export default {
6
+ jsx,
7
+ jsxDEV,
8
+ jsxs,
9
+ };
@@ -0,0 +1,24 @@
1
+ import type { FunctionComponent, SimpNode } from '../core/index.js';
2
+
3
+ export interface ProviderProps<T> {
4
+ value: T;
5
+ children?: SimpNode;
6
+ }
7
+
8
+ export interface ConsumerProps<T> {
9
+ children: (value: T) => SimpNode;
10
+ }
11
+
12
+ export type SimpContext<T> = {
13
+ Provider: Provider<T>;
14
+ Consumer: Consumer<T>;
15
+ };
16
+
17
+ export type ContextType<C extends SimpContext<any>> = C extends SimpContext<infer T> ? T : never;
18
+
19
+ export type Provider<T> = FunctionComponent<ProviderProps<T>>;
20
+ export type Consumer<T> = FunctionComponent<ConsumerProps<T>>;
21
+
22
+ declare function createContext<T>(defaultValue: T): SimpContext<T>;
23
+
24
+ declare function useContext<T>(context: SimpContext<T>): T;
@@ -0,0 +1,64 @@
1
+ import { lifecycleEventBus, rerender } from '../core/internal.js';
2
+ // In runtime these variables are nullable.
3
+ let currentElement;
4
+ let phase;
5
+ lifecycleEventBus.subscribe(event => {
6
+ if (event.type === 'beforeRender') {
7
+ currentElement = event.element;
8
+ phase = event.phase;
9
+ }
10
+ if (event.type === 'afterRender') {
11
+ currentElement = null;
12
+ phase = null;
13
+ }
14
+ if (event.type === 'unmounted') {
15
+ event.element.context?.forEach(value => value.subs.delete(event.element.store));
16
+ }
17
+ });
18
+ export function createContext(defaultValue) {
19
+ const context = {
20
+ defaultValue,
21
+ Provider(props) {
22
+ if (!currentElement.context) {
23
+ currentElement.context = new Map();
24
+ }
25
+ else if (phase === 'mounting') {
26
+ currentElement.context = new Map(currentElement.context);
27
+ }
28
+ if (phase === 'mounting') {
29
+ currentElement.context.set(context, { value: props.value, subs: new Set() });
30
+ return props.children;
31
+ }
32
+ let contextEntry = currentElement.context.get(context);
33
+ if (!contextEntry) {
34
+ contextEntry = { value: props.value, subs: new Set() };
35
+ currentElement.context.set(context, contextEntry);
36
+ return props.children;
37
+ }
38
+ if (Object.is(contextEntry.value, props.value)) {
39
+ return props.children;
40
+ }
41
+ contextEntry.value = props.value;
42
+ for (let sub of contextEntry.subs) {
43
+ sub.forceRender = true;
44
+ rerender(sub.latestElement);
45
+ }
46
+ return props.children;
47
+ },
48
+ Consumer(props) {
49
+ return props.children(currentElement.context?.get(context)?.value ?? defaultValue);
50
+ },
51
+ };
52
+ return context;
53
+ }
54
+ export function useContext(context) {
55
+ const contextEntry = currentElement.context?.get(context);
56
+ if (!contextEntry) {
57
+ // No provider above: just return the default value, don't subscribe
58
+ return context.defaultValue;
59
+ }
60
+ if (!contextEntry.subs.has(currentElement.store)) {
61
+ contextEntry.subs.add(currentElement.store);
62
+ }
63
+ return contextEntry.value;
64
+ }
@@ -1,33 +1,30 @@
1
1
  import type { Many, Maybe, Nullable, SimpText } from '../shared/index.js';
2
2
  import type { HostReference } from './hostAdapter.js';
3
- import type { SimpContextMap } from './context.js';
4
3
  export type SimpNode = SimpElement | SimpText | Array<SimpNode> | boolean | null | undefined;
5
4
  export type Key = string | number | bigint;
6
- export interface FunctionComponent {
7
- (props: any): SimpNode;
8
- }
9
- export type FC = FunctionComponent;
10
- export type SimpElementFlag = 'FC' | 'HOST' | 'TEXT' | 'FRAGMENT' | 'PROVIDER' | 'CONSUMER' | 'PORTAL';
5
+ export type FC = (props: any) => SimpNode;
6
+ export type SimpElementFlag = 'FC' | 'HOST' | 'TEXT' | 'FRAGMENT' | 'PORTAL';
11
7
  export interface SimpElementStore {
12
8
  latestElement?: Maybe<SimpElement>;
13
9
  hostNamespace?: Maybe<string>;
10
+ forceRender?: boolean;
14
11
  [key: string]: unknown;
15
12
  }
16
13
  export interface SimpElement {
17
14
  flag: SimpElementFlag;
18
15
  parent: Nullable<SimpElement>;
19
16
  key?: Maybe<Key>;
20
- type?: Maybe<string | FunctionComponent>;
17
+ type?: string | FC;
21
18
  props?: any;
22
19
  children?: Maybe<SimpNode>;
23
20
  className?: Maybe<string>;
24
21
  reference?: Maybe<HostReference>;
25
22
  store?: SimpElementStore;
26
- contextMap?: Maybe<SimpContextMap>;
23
+ context?: any;
27
24
  ref?: any;
28
25
  unmounted?: boolean;
29
26
  }
30
- export declare function createElement(type: string | FunctionComponent, props?: any, ...children: SimpNode[]): SimpElement;
27
+ export declare function createElement(type: string | FC, props?: any, ...children: SimpNode[]): SimpElement;
31
28
  export declare function createTextElement(text: SimpText): SimpElement;
32
29
  export declare function normalizeChildren(children: SimpNode, skipIgnoredCheck: boolean): Maybe<Many<SimpElement>>;
33
30
  export declare function normalizeRoot(node: SimpNode, skipIgnoredCheck: boolean): Maybe<SimpElement>;
@@ -1,6 +1,5 @@
1
1
  import { isSimpText } from '../shared/index.js';
2
2
  import { Fragment } from './fragment.js';
3
- import { isConsumer, isProvider } from './context.js';
4
3
  export function createElement(type, props, ...children) {
5
4
  let newProps;
6
5
  let className;
@@ -31,7 +30,9 @@ export function createElement(type, props, ...children) {
31
30
  definedChildren = props[propName];
32
31
  }
33
32
  }
34
- else if (propName === 'ref') {
33
+ else if (propName === 'ref' &&
34
+ // Handle only a callback ref or an object ref with `current`.
35
+ props[propName]) {
35
36
  ref = {
36
37
  value: props[propName],
37
38
  };
@@ -81,28 +82,6 @@ export function createElement(type, props, ...children) {
81
82
  }
82
83
  return element;
83
84
  }
84
- else if (isProvider(type)) {
85
- const element = { flag: 'PROVIDER', type, props: { value: props.value }, parent: null };
86
- if ((definedChildren = normalizeChildren(definedChildren || props.children, false))) {
87
- element.children = definedChildren;
88
- }
89
- if (props != null && props.key) {
90
- element.key = props?.key;
91
- }
92
- return element;
93
- }
94
- else if (isConsumer(type)) {
95
- const element = {
96
- flag: 'CONSUMER',
97
- type,
98
- props: { children: definedChildren || (props != null ? props.children : null) },
99
- parent: null,
100
- };
101
- if (props != null && props.key) {
102
- element.key = props?.key;
103
- }
104
- return element;
105
- }
106
85
  else {
107
86
  if (props != null) {
108
87
  for (const propName in props) {
@@ -208,7 +187,7 @@ function isIgnoredNode(node) {
208
187
  if (isSimpText(node)) {
209
188
  return false;
210
189
  }
211
- if (node.flag === 'FRAGMENT' || node.flag === 'PROVIDER' || node.flag === 'PORTAL') {
190
+ if (node.flag === 'FRAGMENT' || node.flag === 'PORTAL') {
212
191
  return node.children == null;
213
192
  }
214
193
  return false;
package/core/index.d.ts CHANGED
@@ -4,9 +4,9 @@ export type ComponentType<P = {}> = FunctionComponent<P>;
4
4
 
5
5
  export type RefObject<T> = { current: T };
6
6
  export type RefCallback<T> = {
7
- bivarianceHack(instance: T | null): (() => void | undefined) | void;
7
+ bivarianceHack(instance: T): (() => void | undefined) | void;
8
8
  }['bivarianceHack'];
9
- export type Ref<T> = RefCallback<T> | RefObject<T> | null;
9
+ export type Ref<T> = RefCallback<T> | RefObject<T | null> | null;
10
10
 
11
11
  export type Key = string | number | bigint;
12
12
 
@@ -26,25 +26,6 @@ export interface SimpElement<P = unknown, T extends string | FunctionComponent<P
26
26
 
27
27
  export type SimpNode = SimpElement | SimpText | Array<SimpNode> | boolean | null | undefined;
28
28
 
29
- export interface ProviderProps<T> {
30
- value: T;
31
- children?: SimpNode | undefined;
32
- }
33
-
34
- export interface ConsumerProps<T> {
35
- children: (value: T) => SimpNode;
36
- }
37
-
38
- export type SimpContext<T> = {
39
- Provider: Provider<T>;
40
- Consumer: Consumer<T>;
41
- };
42
-
43
- export type ContextType<C extends SimpContext<any>> = C extends SimpContext<infer T> ? T : never;
44
-
45
- export type Provider<T> = FunctionComponent<ProviderProps<T>>;
46
- export type Consumer<T> = FunctionComponent<ConsumerProps<T>>;
47
-
48
29
  declare function createElement<P extends {}, T>(
49
30
  type: string,
50
31
  props?: (RefAttributes<T> & P) | null,
@@ -58,11 +39,11 @@ declare function createElement<P extends {}>(
58
39
 
59
40
  declare function createPortal<HostRef = {}>(children: SimpNode, container: HostRef): SimpElement;
60
41
 
61
- declare function createContext<T>(defaultValue: T): SimpContext<T>;
62
-
63
42
  declare function Fragment(props: PropsWithChildren): SimpElement;
64
43
 
65
44
  export type FunctionComponent<P = {}> = (props: P) => SimpNode;
66
45
  export type FC<P = {}> = FunctionComponent<P>;
67
46
 
68
47
  export type PropsWithChildren<P = {}> = P & { children?: SimpNode | undefined };
48
+
49
+ declare function memo<P = {}>(Component: FC<P>, compare?: (objA: Readonly<P>, objB: Readonly<P>) => boolean): FC<P>;
package/core/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { createElement } from './createElement.js';
2
2
  import { Fragment } from './fragment.js';
3
- import { createContext } from './context.js';
3
+ import { memo } from './memo.js';
4
4
  import { createPortal } from './portal.js';
5
- export { createElement, Fragment, createContext, createPortal };
6
- export default { createElement, Fragment, createContext, createPortal };
5
+ export { createElement, Fragment, memo, createPortal };
6
+ export default { createElement, Fragment, memo, createPortal };
@@ -1,8 +1,8 @@
1
- export * from './context.js';
2
1
  export * from './createElement.js';
3
2
  export * from './fragment.js';
4
3
  export * from './hostAdapter.js';
5
4
  export * from './lifecycleEventBus.js';
5
+ export * from './memo.js';
6
6
  export * from './mounting.js';
7
7
  export * from './patching.js';
8
8
  export * from './portal.js';
package/core/internal.js CHANGED
@@ -1,8 +1,8 @@
1
- export * from './context.js';
2
1
  export * from './createElement.js';
3
2
  export * from './fragment.js';
4
3
  export * from './hostAdapter.js';
5
4
  export * from './lifecycleEventBus.js';
5
+ export * from './memo.js';
6
6
  export * from './mounting.js';
7
7
  export * from './patching.js';
8
8
  export * from './portal.js';
@@ -6,7 +6,11 @@ export type LifecycleEvent = {
6
6
  phase: 'mounting' | 'updating';
7
7
  } | {
8
8
  type: 'afterRender';
9
+ element: SimpElement;
9
10
  phase: 'mounting' | 'updating';
11
+ } | {
12
+ type: 'triedToRerender';
13
+ element: SimpElement;
10
14
  } | {
11
15
  type: 'mounted';
12
16
  element: SimpElement;
package/core/memo.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { shallowEqual } from '../shared/index.js';
2
+ import type { FC, SimpNode } from './createElement.js';
3
+ export interface MemoizedComponent {
4
+ (props: any): SimpNode;
5
+ _isMemo: true;
6
+ _render: FC;
7
+ _compare: (prevProps: any, nextProps: any) => boolean;
8
+ }
9
+ export declare function memo(Component: FC, compare?: typeof shallowEqual): MemoizedComponent;
10
+ export declare function isMemo(type: any): type is MemoizedComponent;