@weapp-vite/react 0.1.0

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 (42) hide show
  1. package/LICENSE +21 -0
  2. package/dist/_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/defineProperty.mjs +1 -0
  3. package/dist/_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/toPrimitive.mjs +1 -0
  4. package/dist/_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/toPropertyKey.mjs +1 -0
  5. package/dist/_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/typeof.mjs +1 -0
  6. package/dist/components.d.mts +8 -0
  7. package/dist/components.mjs +1 -0
  8. package/dist/dev/_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/defineProperty.mjs +14 -0
  9. package/dist/dev/_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/toPrimitive.mjs +16 -0
  10. package/dist/dev/_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/toPropertyKey.mjs +11 -0
  11. package/dist/dev/_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/typeof.mjs +12 -0
  12. package/dist/dev/components.mjs +16 -0
  13. package/dist/dev/components.mjs.map +1 -0
  14. package/dist/dev/event.mjs +56 -0
  15. package/dist/dev/event.mjs.map +1 -0
  16. package/dist/dev/hostTree/index.mjs +173 -0
  17. package/dist/dev/hostTree/index.mjs.map +1 -0
  18. package/dist/dev/hostTree/nodes.mjs +97 -0
  19. package/dist/dev/hostTree/nodes.mjs.map +1 -0
  20. package/dist/dev/hostTree/serialization.mjs +49 -0
  21. package/dist/dev/hostTree/serialization.mjs.map +1 -0
  22. package/dist/dev/hostTree/staticBindings.mjs +84 -0
  23. package/dist/dev/hostTree/staticBindings.mjs.map +1 -0
  24. package/dist/dev/index.mjs +4 -0
  25. package/dist/dev/renderer.mjs +203 -0
  26. package/dist/dev/renderer.mjs.map +1 -0
  27. package/dist/dev/types.mjs +1 -0
  28. package/dist/event.mjs +1 -0
  29. package/dist/hostTree/index.d.mts +48 -0
  30. package/dist/hostTree/index.mjs +1 -0
  31. package/dist/hostTree/nodes.d.mts +30 -0
  32. package/dist/hostTree/nodes.mjs +1 -0
  33. package/dist/hostTree/serialization.d.mts +1 -0
  34. package/dist/hostTree/serialization.mjs +1 -0
  35. package/dist/hostTree/staticBindings.mjs +1 -0
  36. package/dist/index.d.mts +4 -0
  37. package/dist/index.mjs +1 -0
  38. package/dist/renderer.d.mts +17 -0
  39. package/dist/renderer.mjs +1 -0
  40. package/dist/types.d.mts +50 -0
  41. package/dist/types.mjs +1 -0
  42. package/package.json +63 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 ice breaker
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ import e from"./toPropertyKey.mjs";function t(t,n,r){return(n=e(n))in t?Object.defineProperty(t,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[n]=r,t}export{t as default};
@@ -0,0 +1 @@
1
+ import e from"./typeof.mjs";function t(t,n){if(e(t)!=`object`||!t)return t;var r=t[Symbol.toPrimitive];if(r!==void 0){var i=r.call(t,n||`default`);if(e(i)!=`object`)return i;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(n===`string`?String:Number)(t)}export{t as default};
@@ -0,0 +1 @@
1
+ import e from"./typeof.mjs";import t from"./toPrimitive.mjs";function n(n){var r=t(n,`string`);return e(r)==`symbol`?r:r+``}export{n as default};
@@ -0,0 +1 @@
1
+ function e(t){"@babel/helpers - typeof";return e=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},e(t)}export{e as default};
@@ -0,0 +1,8 @@
1
+ import { MiniProgramHostProps } from "./types.mjs";
2
+ //#region src/components.d.ts
3
+ declare const Button: (props: MiniProgramHostProps) => import("react").ReactElement<MiniProgramHostProps, string | import("react").JSXElementConstructor<any>>;
4
+ declare const Input: (props: MiniProgramHostProps) => import("react").ReactElement<MiniProgramHostProps, string | import("react").JSXElementConstructor<any>>;
5
+ declare const Text: (props: MiniProgramHostProps) => import("react").ReactElement<MiniProgramHostProps, string | import("react").JSXElementConstructor<any>>;
6
+ declare const View: (props: MiniProgramHostProps) => import("react").ReactElement<MiniProgramHostProps, string | import("react").JSXElementConstructor<any>>;
7
+ //#endregion
8
+ export { Button, Input, Text, View };
@@ -0,0 +1 @@
1
+ import{createElement as e}from"react";function t(t){return function(n){return e(t,n)}}const n=t(`button`),r=t(`input`),i=t(`text`),a=t(`view`);export{n as Button,r as Input,i as Text,a as View};
@@ -0,0 +1,14 @@
1
+ import toPropertyKey from "./toPropertyKey.mjs";
2
+
3
+ //#region \0@oxc-project+runtime@0.143.0/helpers/esm/defineProperty.js
4
+ function _defineProperty(e, r, t) {
5
+ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
6
+ value: t,
7
+ enumerable: !0,
8
+ configurable: !0,
9
+ writable: !0
10
+ }) : e[r] = t, e;
11
+ }
12
+
13
+ //#endregion
14
+ export { _defineProperty as default };
@@ -0,0 +1,16 @@
1
+ import _typeof from "./typeof.mjs";
2
+
3
+ //#region \0@oxc-project+runtime@0.143.0/helpers/esm/toPrimitive.js
4
+ function toPrimitive(t, r) {
5
+ if ("object" != _typeof(t) || !t) return t;
6
+ var e = t[Symbol.toPrimitive];
7
+ if (void 0 !== e) {
8
+ var i = e.call(t, r || "default");
9
+ if ("object" != _typeof(i)) return i;
10
+ throw new TypeError("@@toPrimitive must return a primitive value.");
11
+ }
12
+ return ("string" === r ? String : Number)(t);
13
+ }
14
+
15
+ //#endregion
16
+ export { toPrimitive as default };
@@ -0,0 +1,11 @@
1
+ import _typeof from "./typeof.mjs";
2
+ import toPrimitive from "./toPrimitive.mjs";
3
+
4
+ //#region \0@oxc-project+runtime@0.143.0/helpers/esm/toPropertyKey.js
5
+ function toPropertyKey(t) {
6
+ var i = toPrimitive(t, "string");
7
+ return "symbol" == _typeof(i) ? i : i + "";
8
+ }
9
+
10
+ //#endregion
11
+ export { toPropertyKey as default };
@@ -0,0 +1,12 @@
1
+ //#region \0@oxc-project+runtime@0.143.0/helpers/esm/typeof.js
2
+ function _typeof(o) {
3
+ "@babel/helpers - typeof";
4
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
5
+ return typeof o;
6
+ } : function(o) {
7
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
8
+ }, _typeof(o);
9
+ }
10
+
11
+ //#endregion
12
+ export { _typeof as default };
@@ -0,0 +1,16 @@
1
+ import { createElement } from "react";
2
+
3
+ //#region src/components.ts
4
+ function createHostComponent(type) {
5
+ return function MiniProgramHostComponent(props) {
6
+ return createElement(type, props);
7
+ };
8
+ }
9
+ const Button = createHostComponent("button");
10
+ const Input = createHostComponent("input");
11
+ const Text = createHostComponent("text");
12
+ const View = createHostComponent("view");
13
+
14
+ //#endregion
15
+ export { Button, Input, Text, View };
16
+ //# sourceMappingURL=components.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components.mjs","names":[],"sources":["../../src/components.ts"],"sourcesContent":["import type { MiniProgramHostProps } from './types'\nimport { createElement } from 'react'\n\nfunction createHostComponent(type: string) {\n return function MiniProgramHostComponent(props: MiniProgramHostProps) {\n return createElement(type, props)\n }\n}\n\nexport const Button = createHostComponent('button')\nexport const Input = createHostComponent('input')\nexport const Text = createHostComponent('text')\nexport const View = createHostComponent('view')\n"],"mappings":";;;AAGA,SAAS,oBAAoB,MAAc;CACzC,OAAO,SAAS,yBAAyB,OAA6B;EACpE,OAAO,cAAc,MAAM,KAAK;CAClC;AACF;AAEA,MAAa,SAAS,oBAAoB,QAAQ;AAClD,MAAa,QAAQ,oBAAoB,OAAO;AAChD,MAAa,OAAO,oBAAoB,MAAM;AAC9C,MAAa,OAAO,oBAAoB,MAAM"}
@@ -0,0 +1,56 @@
1
+ import { HostElement } from "./hostTree/nodes.mjs";
2
+ import { WEAPP_REACT_EVENT_DATASET_KEY } from "@weapp-core/constants";
3
+
4
+ //#region src/event.ts
5
+ function toEventPropName(type) {
6
+ return `on${type.charAt(0).toUpperCase()}${type.slice(1)}`;
7
+ }
8
+ function dispatchHostEvent(root, nativeEvent) {
9
+ var _nativeEvent$currentT, _nativeEvent$detail;
10
+ const rawSid = (_nativeEvent$currentT = nativeEvent.currentTarget) === null || _nativeEvent$currentT === void 0 || (_nativeEvent$currentT = _nativeEvent$currentT.dataset) === null || _nativeEvent$currentT === void 0 ? void 0 : _nativeEvent$currentT[WEAPP_REACT_EVENT_DATASET_KEY];
11
+ if (typeof rawSid !== "string") return;
12
+ const target = root.getNode(rawSid);
13
+ if (!(target instanceof HostElement)) return;
14
+ const path = [];
15
+ let current = target;
16
+ while (current) {
17
+ path.push(current);
18
+ current = current.parent instanceof HostElement ? current.parent : null;
19
+ }
20
+ let stopped = false;
21
+ const event = {
22
+ currentTarget: target,
23
+ detail: (_nativeEvent$detail = nativeEvent.detail) !== null && _nativeEvent$detail !== void 0 ? _nativeEvent$detail : {},
24
+ nativeEvent,
25
+ stopPropagation: () => {
26
+ stopped = true;
27
+ },
28
+ target,
29
+ type: nativeEvent.type
30
+ };
31
+ const propName = toEventPropName(nativeEvent.type);
32
+ for (const node of path.slice().reverse()) {
33
+ const handler = node.props[`${propName}Capture`];
34
+ if (typeof handler === "function") {
35
+ event.currentTarget = node;
36
+ handler(event);
37
+ }
38
+ if (stopped) {
39
+ root.flush();
40
+ return;
41
+ }
42
+ }
43
+ for (const node of path) {
44
+ const handler = node.props[propName];
45
+ if (typeof handler === "function") {
46
+ event.currentTarget = node;
47
+ handler(event);
48
+ }
49
+ if (stopped) break;
50
+ }
51
+ root.flush();
52
+ }
53
+
54
+ //#endregion
55
+ export { dispatchHostEvent };
56
+ //# sourceMappingURL=event.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event.mjs","names":[],"sources":["../../src/event.ts"],"sourcesContent":["import type { HostEventHandler, MiniProgramEventLike } from './types'\nimport { WEAPP_REACT_EVENT_DATASET_KEY } from '@weapp-core/constants'\nimport { HostElement } from './hostTree'\n\ninterface EventHostRoot {\n flush: () => void\n getNode: (sid: string) => unknown\n}\n\nfunction toEventPropName(type: string) {\n return `on${type.charAt(0).toUpperCase()}${type.slice(1)}`\n}\n\nexport function dispatchHostEvent(root: EventHostRoot, nativeEvent: MiniProgramEventLike) {\n const rawSid = nativeEvent.currentTarget?.dataset?.[WEAPP_REACT_EVENT_DATASET_KEY]\n if (typeof rawSid !== 'string') {\n return\n }\n\n const target = root.getNode(rawSid)\n if (!(target instanceof HostElement)) {\n return\n }\n\n const path: HostElement[] = []\n let current: HostElement | null = target\n while (current) {\n path.push(current)\n current = current.parent instanceof HostElement ? current.parent : null\n }\n\n let stopped = false\n const event = {\n currentTarget: target,\n detail: nativeEvent.detail ?? {},\n nativeEvent,\n stopPropagation: () => {\n stopped = true\n },\n target,\n type: nativeEvent.type,\n }\n const propName = toEventPropName(nativeEvent.type)\n\n for (const node of path.slice().reverse()) {\n const handler = node.props[`${propName}Capture`]\n if (typeof handler === 'function') {\n event.currentTarget = node\n ;(handler as HostEventHandler)(event)\n }\n if (stopped) {\n root.flush()\n return\n }\n }\n\n for (const node of path) {\n const handler = node.props[propName]\n if (typeof handler === 'function') {\n event.currentTarget = node\n ;(handler as HostEventHandler)(event)\n }\n if (stopped) {\n break\n }\n }\n root.flush()\n}\n"],"mappings":";;;;AASA,SAAS,gBAAgB,MAAc;CACrC,OAAO,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,KAAK,MAAM,CAAC;AACzD;AAEA,SAAgB,kBAAkB,MAAqB,aAAmC;;CACxF,MAAM,kCAAS,YAAY,8GAAe,uFAAU;CACpD,IAAI,OAAO,WAAW,UACpB;CAGF,MAAM,SAAS,KAAK,QAAQ,MAAM;CAClC,IAAI,EAAE,kBAAkB,cACtB;CAGF,MAAM,OAAsB,CAAC;CAC7B,IAAI,UAA8B;CAClC,OAAO,SAAS;EACd,KAAK,KAAK,OAAO;EACjB,UAAU,QAAQ,kBAAkB,cAAc,QAAQ,SAAS;CACrE;CAEA,IAAI,UAAU;CACd,MAAM,QAAQ;EACZ,eAAe;EACf,+BAAQ,YAAY,2EAAU,CAAC;EAC/B;EACA,uBAAuB;GACrB,UAAU;EACZ;EACA;EACA,MAAM,YAAY;CACpB;CACA,MAAM,WAAW,gBAAgB,YAAY,IAAI;CAEjD,KAAK,MAAM,QAAQ,KAAK,MAAM,CAAC,CAAC,QAAQ,GAAG;EACzC,MAAM,UAAU,KAAK,MAAM,GAAG,SAAS;EACvC,IAAI,OAAO,YAAY,YAAY;GACjC,MAAM,gBAAgB;GACrB,AAAC,QAA6B,KAAK;EACtC;EACA,IAAI,SAAS;GACX,KAAK,MAAM;GACX;EACF;CACF;CAEA,KAAK,MAAM,QAAQ,MAAM;EACvB,MAAM,UAAU,KAAK,MAAM;EAC3B,IAAI,OAAO,YAAY,YAAY;GACjC,MAAM,gBAAgB;GACrB,AAAC,QAA6B,KAAK;EACtC;EACA,IAAI,SACF;CAEJ;CACA,KAAK,MAAM;AACb"}
@@ -0,0 +1,173 @@
1
+ import { hasSerializedPropChanges } from "./serialization.mjs";
2
+ import _defineProperty from "../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/defineProperty.mjs";
3
+ import { HostElement, HostText, attachHostNode } from "./nodes.mjs";
4
+ import { StaticBindingState, hasStaticBindingChanges, readStaticSlot } from "./staticBindings.mjs";
5
+ import { WEAPP_REACT_ROOT_DATA_KEY, WEAPP_REACT_SLOTS_DATA_KEY } from "@weapp-core/constants";
6
+
7
+ //#region src/hostTree/index.ts
8
+ var HostRoot = class HostRoot {
9
+ constructor(adapter, renderMode = "tree") {
10
+ _defineProperty(this, "children", []);
11
+ _defineProperty(this, "renderMode", void 0);
12
+ _defineProperty(this, "dirtyNodes", /* @__PURE__ */ new Set());
13
+ _defineProperty(this, "dirtyStructures", /* @__PURE__ */ new Set());
14
+ _defineProperty(this, "mounted", false);
15
+ _defineProperty(this, "nodeId", 0);
16
+ _defineProperty(this, "nodes", /* @__PURE__ */ new Map());
17
+ _defineProperty(this, "pendingFlush", false);
18
+ _defineProperty(this, "adapter", void 0);
19
+ _defineProperty(this, "staticBindings", new StaticBindingState());
20
+ _defineProperty(this, "staticMismatch", void 0);
21
+ _defineProperty(this, "unmounting", false);
22
+ this.adapter = adapter;
23
+ this.renderMode = renderMode;
24
+ }
25
+ beginUnmount() {
26
+ this.unmounting = true;
27
+ }
28
+ assertStaticTemplateValid() {
29
+ if (!this.staticMismatch) return;
30
+ const error = this.staticMismatch;
31
+ this.staticMismatch = void 0;
32
+ throw error;
33
+ }
34
+ createElementSid(props) {
35
+ return this.renderMode === "static-bindings" ? readStaticSlot(props) : this.nextSid();
36
+ }
37
+ nextSid() {
38
+ this.nodeId += 1;
39
+ return `r${this.nodeId}`;
40
+ }
41
+ register(node) {
42
+ if (this.renderMode === "static-bindings" && node instanceof HostElement && this.nodes.has(node.sid)) throw new Error(`static template slot 冲突:${node.sid}`);
43
+ this.nodes.set(node.sid, node);
44
+ }
45
+ unregisterTree(node) {
46
+ this.nodes.delete(node.sid);
47
+ if (node instanceof HostElement) node.children.forEach((child) => this.unregisterTree(child));
48
+ }
49
+ getNode(sid) {
50
+ return this.nodes.get(sid);
51
+ }
52
+ append(child) {
53
+ attachHostNode(this, child);
54
+ this.markStructure(this);
55
+ }
56
+ insertBefore(child, before) {
57
+ const index = this.children.indexOf(before);
58
+ attachHostNode(this, child, index < 0 ? void 0 : index);
59
+ this.markStructure(this);
60
+ }
61
+ remove(child) {
62
+ const index = this.children.indexOf(child);
63
+ if (index < 0) return;
64
+ this.children.splice(index, 1);
65
+ child.parent = null;
66
+ this.unregisterTree(child);
67
+ this.markStructure(this);
68
+ }
69
+ clear() {
70
+ this.children.forEach((child) => this.unregisterTree(child));
71
+ this.children.length = 0;
72
+ this.markStructure(this);
73
+ }
74
+ markNode(node) {
75
+ this.dirtyNodes.add(node);
76
+ this.scheduleFlush();
77
+ }
78
+ markElementProps(element, previous, next) {
79
+ if (this.renderMode === "static-bindings") {
80
+ this.staticBindings.markProps(element, previous, next);
81
+ this.scheduleFlush();
82
+ return;
83
+ }
84
+ this.markNode(element);
85
+ }
86
+ markStaticText(element) {
87
+ this.staticBindings.markField(element, "text");
88
+ this.scheduleFlush();
89
+ }
90
+ markStructure(parent) {
91
+ if (this.renderMode === "static-bindings") {
92
+ if (this.mounted && !this.unmounting) this.staticMismatch = /* @__PURE__ */ new Error("static template 运行时结构发生变化,需要切换 dynamic island fallback");
93
+ return;
94
+ }
95
+ this.dirtyStructures.add(parent);
96
+ this.scheduleFlush();
97
+ }
98
+ scheduleFlush() {
99
+ if (this.pendingFlush) return;
100
+ this.pendingFlush = true;
101
+ Promise.resolve().then(() => this.flush());
102
+ }
103
+ pathOf(target) {
104
+ if (target instanceof HostRoot) return "root";
105
+ const parent = target.parent;
106
+ if (!parent) return;
107
+ const parentPath = this.pathOf(parent);
108
+ const index = parent.children.indexOf(target);
109
+ return parentPath && index >= 0 ? `${parentPath}.cn[${index}]` : void 0;
110
+ }
111
+ hasStructuralAncestor(node) {
112
+ let parent = node.parent;
113
+ while (parent) {
114
+ if (this.dirtyStructures.has(parent)) return true;
115
+ parent = parent instanceof HostElement ? parent.parent : null;
116
+ }
117
+ return false;
118
+ }
119
+ snapshot() {
120
+ return { cn: this.children.map((child) => child.serialize()) };
121
+ }
122
+ shouldNotifyPropUpdate(previous, next) {
123
+ return this.renderMode === "static-bindings" ? hasStaticBindingChanges(previous, next) : hasSerializedPropChanges(previous, next);
124
+ }
125
+ staticElements() {
126
+ return Array.from(this.nodes.values()).filter((node) => node instanceof HostElement);
127
+ }
128
+ flushStaticBindings() {
129
+ if (this.staticMismatch) {
130
+ this.staticBindings.clear();
131
+ return;
132
+ }
133
+ if (!this.mounted) {
134
+ this.mounted = true;
135
+ this.staticBindings.clear();
136
+ this.adapter.setData({ [WEAPP_REACT_SLOTS_DATA_KEY]: this.staticBindings.snapshot(this.staticElements()) });
137
+ return;
138
+ }
139
+ const payload = this.staticBindings.takePayload();
140
+ if (Object.keys(payload).length > 0 && !this.unmounting) this.adapter.setData(payload);
141
+ }
142
+ flush() {
143
+ this.pendingFlush = false;
144
+ if (this.renderMode === "static-bindings") {
145
+ this.flushStaticBindings();
146
+ return;
147
+ }
148
+ if (!this.mounted) {
149
+ this.mounted = true;
150
+ this.dirtyNodes.clear();
151
+ this.dirtyStructures.clear();
152
+ this.adapter.setData({ [WEAPP_REACT_ROOT_DATA_KEY]: this.snapshot() });
153
+ return;
154
+ }
155
+ const payload = {};
156
+ for (const parent of this.dirtyStructures) {
157
+ const path = this.pathOf(parent);
158
+ if (path) payload[`${path}.cn`] = parent.children.map((child) => child.serialize());
159
+ }
160
+ for (const node of this.dirtyNodes) {
161
+ if (this.hasStructuralAncestor(node)) continue;
162
+ const path = this.pathOf(node);
163
+ if (path) payload[path] = node.serialize();
164
+ }
165
+ this.dirtyNodes.clear();
166
+ this.dirtyStructures.clear();
167
+ if (Object.keys(payload).length > 0) this.adapter.setData(payload);
168
+ }
169
+ };
170
+
171
+ //#endregion
172
+ export { HostElement, HostRoot, HostText };
173
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/hostTree/index.ts"],"sourcesContent":["import type { HostProps, MiniProgramPageAdapter } from '../types'\nimport type { HostNode, HostParent } from './nodes'\nimport { WEAPP_REACT_ROOT_DATA_KEY, WEAPP_REACT_SLOTS_DATA_KEY } from '@weapp-core/constants'\nimport { attachHostNode, HostElement } from './nodes'\nimport { hasSerializedPropChanges } from './serialization'\nimport { hasStaticBindingChanges, readStaticSlot, StaticBindingState } from './staticBindings'\n\nexport { HostElement, HostText } from './nodes'\nexport type { HostNode, HostParent } from './nodes'\nexport { hasSerializedPropChanges } from './serialization'\nexport type HostRenderMode = 'static-bindings' | 'tree'\n\nexport class HostRoot {\n readonly children: HostNode[] = []\n readonly renderMode: HostRenderMode\n private dirtyNodes = new Set<HostNode>()\n private dirtyStructures = new Set<HostParent>()\n private mounted = false\n private nodeId = 0\n private nodes = new Map<string, HostNode>()\n private pendingFlush = false\n private readonly adapter: MiniProgramPageAdapter\n private readonly staticBindings = new StaticBindingState()\n private staticMismatch: Error | undefined\n private unmounting = false\n\n constructor(adapter: MiniProgramPageAdapter, renderMode: HostRenderMode = 'tree') {\n this.adapter = adapter\n this.renderMode = renderMode\n }\n\n beginUnmount() {\n this.unmounting = true\n }\n\n assertStaticTemplateValid() {\n if (!this.staticMismatch) {\n return\n }\n const error = this.staticMismatch\n this.staticMismatch = undefined\n throw error\n }\n\n createElementSid(props: HostProps) {\n return this.renderMode === 'static-bindings' ? readStaticSlot(props) : this.nextSid()\n }\n\n nextSid() {\n this.nodeId += 1\n return `r${this.nodeId}`\n }\n\n register(node: HostNode) {\n if (this.renderMode === 'static-bindings' && node instanceof HostElement && this.nodes.has(node.sid)) {\n throw new Error(`static template slot 冲突:${node.sid}`)\n }\n this.nodes.set(node.sid, node)\n }\n\n unregisterTree(node: HostNode) {\n this.nodes.delete(node.sid)\n if (node instanceof HostElement) {\n node.children.forEach(child => this.unregisterTree(child))\n }\n }\n\n getNode(sid: string) {\n return this.nodes.get(sid)\n }\n\n append(child: HostNode) {\n attachHostNode(this, child)\n this.markStructure(this)\n }\n\n insertBefore(child: HostNode, before: HostNode) {\n const index = this.children.indexOf(before)\n attachHostNode(this, child, index < 0 ? undefined : index)\n this.markStructure(this)\n }\n\n remove(child: HostNode) {\n const index = this.children.indexOf(child)\n if (index < 0) {\n return\n }\n this.children.splice(index, 1)\n child.parent = null\n this.unregisterTree(child)\n this.markStructure(this)\n }\n\n clear() {\n this.children.forEach(child => this.unregisterTree(child))\n this.children.length = 0\n this.markStructure(this)\n }\n\n markNode(node: HostNode) {\n this.dirtyNodes.add(node)\n this.scheduleFlush()\n }\n\n markElementProps(element: HostElement, previous: HostProps, next: HostProps) {\n if (this.renderMode === 'static-bindings') {\n this.staticBindings.markProps(element, previous, next)\n this.scheduleFlush()\n return\n }\n this.markNode(element)\n }\n\n markStaticText(element: HostElement) {\n this.staticBindings.markField(element, 'text')\n this.scheduleFlush()\n }\n\n markStructure(parent: HostParent) {\n if (this.renderMode === 'static-bindings') {\n if (this.mounted && !this.unmounting) {\n this.staticMismatch = new Error('static template 运行时结构发生变化,需要切换 dynamic island fallback')\n }\n return\n }\n this.dirtyStructures.add(parent)\n this.scheduleFlush()\n }\n\n private scheduleFlush() {\n if (this.pendingFlush) {\n return\n }\n this.pendingFlush = true\n Promise.resolve().then(() => this.flush())\n }\n\n private pathOf(target: HostParent | HostNode): string | undefined {\n if (target instanceof HostRoot) {\n return 'root'\n }\n const parent = target.parent\n if (!parent) {\n return undefined\n }\n const parentPath = this.pathOf(parent)\n const index = parent.children.indexOf(target)\n return parentPath && index >= 0 ? `${parentPath}.cn[${index}]` : undefined\n }\n\n private hasStructuralAncestor(node: HostNode) {\n let parent = node.parent\n while (parent) {\n if (this.dirtyStructures.has(parent)) {\n return true\n }\n parent = parent instanceof HostElement ? parent.parent : null\n }\n return false\n }\n\n snapshot() {\n return {\n cn: this.children.map(child => child.serialize()),\n }\n }\n\n shouldNotifyPropUpdate(previous: HostProps, next: HostProps) {\n return this.renderMode === 'static-bindings'\n ? hasStaticBindingChanges(previous, next)\n : hasSerializedPropChanges(previous, next)\n }\n\n private staticElements() {\n return Array.from(this.nodes.values()).filter((node): node is HostElement => node instanceof HostElement)\n }\n\n private flushStaticBindings() {\n if (this.staticMismatch) {\n this.staticBindings.clear()\n return\n }\n if (!this.mounted) {\n this.mounted = true\n this.staticBindings.clear()\n this.adapter.setData({ [WEAPP_REACT_SLOTS_DATA_KEY]: this.staticBindings.snapshot(this.staticElements()) })\n return\n }\n const payload = this.staticBindings.takePayload()\n if (Object.keys(payload).length > 0 && !this.unmounting) {\n this.adapter.setData(payload)\n }\n }\n\n flush() {\n this.pendingFlush = false\n if (this.renderMode === 'static-bindings') {\n this.flushStaticBindings()\n return\n }\n if (!this.mounted) {\n this.mounted = true\n this.dirtyNodes.clear()\n this.dirtyStructures.clear()\n this.adapter.setData({ [WEAPP_REACT_ROOT_DATA_KEY]: this.snapshot() })\n return\n }\n\n const payload: Record<string, unknown> = {}\n for (const parent of this.dirtyStructures) {\n const path = this.pathOf(parent)\n if (path) {\n payload[`${path}.cn`] = parent.children.map(child => child.serialize())\n }\n }\n for (const node of this.dirtyNodes) {\n if (this.hasStructuralAncestor(node)) {\n continue\n }\n const path = this.pathOf(node)\n if (path) {\n payload[path] = node.serialize()\n }\n }\n\n this.dirtyNodes.clear()\n this.dirtyStructures.clear()\n if (Object.keys(payload).length > 0) {\n this.adapter.setData(payload)\n }\n }\n}\n"],"mappings":";;;;;;;AAYA,IAAa,WAAb,MAAa,SAAS;CAcpB,YAAY,SAAiC,aAA6B,QAAQ;wBAbzE,YAAuB,CAAC;wBACxB;wBACD,8BAAa,IAAI,IAAc;wBAC/B,mCAAkB,IAAI,IAAgB;wBACtC,WAAU;wBACV,UAAS;wBACT,yBAAQ,IAAI,IAAsB;wBAClC,gBAAe;wBACN;wBACA,kBAAiB,IAAI,mBAAmB;wBACjD;wBACA,cAAa;EAGnB,KAAK,UAAU;EACf,KAAK,aAAa;CACpB;CAEA,eAAe;EACb,KAAK,aAAa;CACpB;CAEA,4BAA4B;EAC1B,IAAI,CAAC,KAAK,gBACR;EAEF,MAAM,QAAQ,KAAK;EACnB,KAAK,iBAAiB;EACtB,MAAM;CACR;CAEA,iBAAiB,OAAkB;EACjC,OAAO,KAAK,eAAe,oBAAoB,eAAe,KAAK,IAAI,KAAK,QAAQ;CACtF;CAEA,UAAU;EACR,KAAK,UAAU;EACf,OAAO,IAAI,KAAK;CAClB;CAEA,SAAS,MAAgB;EACvB,IAAI,KAAK,eAAe,qBAAqB,gBAAgB,eAAe,KAAK,MAAM,IAAI,KAAK,GAAG,GACjG,MAAM,IAAI,MAAM,2BAA2B,KAAK,KAAK;EAEvD,KAAK,MAAM,IAAI,KAAK,KAAK,IAAI;CAC/B;CAEA,eAAe,MAAgB;EAC7B,KAAK,MAAM,OAAO,KAAK,GAAG;EAC1B,IAAI,gBAAgB,aAClB,KAAK,SAAS,SAAQ,UAAS,KAAK,eAAe,KAAK,CAAC;CAE7D;CAEA,QAAQ,KAAa;EACnB,OAAO,KAAK,MAAM,IAAI,GAAG;CAC3B;CAEA,OAAO,OAAiB;EACtB,eAAe,MAAM,KAAK;EAC1B,KAAK,cAAc,IAAI;CACzB;CAEA,aAAa,OAAiB,QAAkB;EAC9C,MAAM,QAAQ,KAAK,SAAS,QAAQ,MAAM;EAC1C,eAAe,MAAM,OAAO,QAAQ,IAAI,SAAY,KAAK;EACzD,KAAK,cAAc,IAAI;CACzB;CAEA,OAAO,OAAiB;EACtB,MAAM,QAAQ,KAAK,SAAS,QAAQ,KAAK;EACzC,IAAI,QAAQ,GACV;EAEF,KAAK,SAAS,OAAO,OAAO,CAAC;EAC7B,MAAM,SAAS;EACf,KAAK,eAAe,KAAK;EACzB,KAAK,cAAc,IAAI;CACzB;CAEA,QAAQ;EACN,KAAK,SAAS,SAAQ,UAAS,KAAK,eAAe,KAAK,CAAC;EACzD,KAAK,SAAS,SAAS;EACvB,KAAK,cAAc,IAAI;CACzB;CAEA,SAAS,MAAgB;EACvB,KAAK,WAAW,IAAI,IAAI;EACxB,KAAK,cAAc;CACrB;CAEA,iBAAiB,SAAsB,UAAqB,MAAiB;EAC3E,IAAI,KAAK,eAAe,mBAAmB;GACzC,KAAK,eAAe,UAAU,SAAS,UAAU,IAAI;GACrD,KAAK,cAAc;GACnB;EACF;EACA,KAAK,SAAS,OAAO;CACvB;CAEA,eAAe,SAAsB;EACnC,KAAK,eAAe,UAAU,SAAS,MAAM;EAC7C,KAAK,cAAc;CACrB;CAEA,cAAc,QAAoB;EAChC,IAAI,KAAK,eAAe,mBAAmB;GACzC,IAAI,KAAK,WAAW,CAAC,KAAK,YACxB,KAAK,iCAAiB,IAAI,MAAM,wDAAwD;GAE1F;EACF;EACA,KAAK,gBAAgB,IAAI,MAAM;EAC/B,KAAK,cAAc;CACrB;CAEA,AAAQ,gBAAgB;EACtB,IAAI,KAAK,cACP;EAEF,KAAK,eAAe;EACpB,QAAQ,QAAQ,CAAC,CAAC,WAAW,KAAK,MAAM,CAAC;CAC3C;CAEA,AAAQ,OAAO,QAAmD;EAChE,IAAI,kBAAkB,UACpB,OAAO;EAET,MAAM,SAAS,OAAO;EACtB,IAAI,CAAC,QACH;EAEF,MAAM,aAAa,KAAK,OAAO,MAAM;EACrC,MAAM,QAAQ,OAAO,SAAS,QAAQ,MAAM;EAC5C,OAAO,cAAc,SAAS,IAAI,GAAG,WAAW,MAAM,MAAM,KAAK;CACnE;CAEA,AAAQ,sBAAsB,MAAgB;EAC5C,IAAI,SAAS,KAAK;EAClB,OAAO,QAAQ;GACb,IAAI,KAAK,gBAAgB,IAAI,MAAM,GACjC,OAAO;GAET,SAAS,kBAAkB,cAAc,OAAO,SAAS;EAC3D;EACA,OAAO;CACT;CAEA,WAAW;EACT,OAAO,EACL,IAAI,KAAK,SAAS,KAAI,UAAS,MAAM,UAAU,CAAC,EAClD;CACF;CAEA,uBAAuB,UAAqB,MAAiB;EAC3D,OAAO,KAAK,eAAe,oBACvB,wBAAwB,UAAU,IAAI,IACtC,yBAAyB,UAAU,IAAI;CAC7C;CAEA,AAAQ,iBAAiB;EACvB,OAAO,MAAM,KAAK,KAAK,MAAM,OAAO,CAAC,CAAC,CAAC,QAAQ,SAA8B,gBAAgB,WAAW;CAC1G;CAEA,AAAQ,sBAAsB;EAC5B,IAAI,KAAK,gBAAgB;GACvB,KAAK,eAAe,MAAM;GAC1B;EACF;EACA,IAAI,CAAC,KAAK,SAAS;GACjB,KAAK,UAAU;GACf,KAAK,eAAe,MAAM;GAC1B,KAAK,QAAQ,QAAQ,GAAG,6BAA6B,KAAK,eAAe,SAAS,KAAK,eAAe,CAAC,EAAE,CAAC;GAC1G;EACF;EACA,MAAM,UAAU,KAAK,eAAe,YAAY;EAChD,IAAI,OAAO,KAAK,OAAO,CAAC,CAAC,SAAS,KAAK,CAAC,KAAK,YAC3C,KAAK,QAAQ,QAAQ,OAAO;CAEhC;CAEA,QAAQ;EACN,KAAK,eAAe;EACpB,IAAI,KAAK,eAAe,mBAAmB;GACzC,KAAK,oBAAoB;GACzB;EACF;EACA,IAAI,CAAC,KAAK,SAAS;GACjB,KAAK,UAAU;GACf,KAAK,WAAW,MAAM;GACtB,KAAK,gBAAgB,MAAM;GAC3B,KAAK,QAAQ,QAAQ,GAAG,4BAA4B,KAAK,SAAS,EAAE,CAAC;GACrE;EACF;EAEA,MAAM,UAAmC,CAAC;EAC1C,KAAK,MAAM,UAAU,KAAK,iBAAiB;GACzC,MAAM,OAAO,KAAK,OAAO,MAAM;GAC/B,IAAI,MACF,QAAQ,GAAG,KAAK,QAAQ,OAAO,SAAS,KAAI,UAAS,MAAM,UAAU,CAAC;EAE1E;EACA,KAAK,MAAM,QAAQ,KAAK,YAAY;GAClC,IAAI,KAAK,sBAAsB,IAAI,GACjC;GAEF,MAAM,OAAO,KAAK,OAAO,IAAI;GAC7B,IAAI,MACF,QAAQ,QAAQ,KAAK,UAAU;EAEnC;EAEA,KAAK,WAAW,MAAM;EACtB,KAAK,gBAAgB,MAAM;EAC3B,IAAI,OAAO,KAAK,OAAO,CAAC,CAAC,SAAS,GAChC,KAAK,QAAQ,QAAQ,OAAO;CAEhC;AACF"}
@@ -0,0 +1,97 @@
1
+ import { serializeProps, serializeStyle } from "./serialization.mjs";
2
+ import _defineProperty from "../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/defineProperty.mjs";
3
+
4
+ //#region src/hostTree/nodes.ts
5
+ function attach(parent, child, index) {
6
+ if (child.parent) {
7
+ const previousIndex = child.parent.children.indexOf(child);
8
+ if (previousIndex >= 0) child.parent.children.splice(previousIndex, 1);
9
+ }
10
+ child.parent = parent;
11
+ if (index === void 0) parent.children.push(child);
12
+ else parent.children.splice(index, 0, child);
13
+ }
14
+ var HostText = class {
15
+ constructor(root, sid, value) {
16
+ _defineProperty(this, "parent", null);
17
+ _defineProperty(this, "root", void 0);
18
+ _defineProperty(this, "sid", void 0);
19
+ _defineProperty(this, "value", void 0);
20
+ this.root = root;
21
+ this.sid = sid;
22
+ this.value = value;
23
+ root.register(this);
24
+ }
25
+ serialize() {
26
+ return {
27
+ nn: "#text",
28
+ sid: this.sid,
29
+ v: this.value
30
+ };
31
+ }
32
+ setValue(value) {
33
+ if (value === this.value) return;
34
+ this.value = value;
35
+ if (this.root.renderMode === "static-bindings" && this.parent && "props" in this.parent) this.root.markStaticText(this.parent);
36
+ else this.root.markNode(this);
37
+ }
38
+ };
39
+ var HostElement = class {
40
+ constructor(root, sid, type, props) {
41
+ _defineProperty(this, "children", []);
42
+ _defineProperty(this, "parent", null);
43
+ _defineProperty(this, "props", void 0);
44
+ _defineProperty(this, "root", void 0);
45
+ _defineProperty(this, "sid", void 0);
46
+ _defineProperty(this, "type", void 0);
47
+ this.props = props;
48
+ this.root = root;
49
+ this.sid = sid;
50
+ this.type = type;
51
+ root.register(this);
52
+ }
53
+ append(child, notify = true) {
54
+ attach(this, child);
55
+ if (notify) this.root.markStructure(this);
56
+ }
57
+ insertBefore(child, before) {
58
+ const index = this.children.indexOf(before);
59
+ attach(this, child, index < 0 ? void 0 : index);
60
+ this.root.markStructure(this);
61
+ }
62
+ remove(child) {
63
+ const index = this.children.indexOf(child);
64
+ if (index < 0) return;
65
+ this.children.splice(index, 1);
66
+ child.parent = null;
67
+ this.root.unregisterTree(child);
68
+ this.root.markStructure(this);
69
+ }
70
+ serialize() {
71
+ var _this$props$className;
72
+ const className = (_this$props$className = this.props.className) !== null && _this$props$className !== void 0 ? _this$props$className : this.props.class;
73
+ const serialized = {
74
+ nn: this.type,
75
+ sid: this.sid
76
+ };
77
+ if (this.children.length > 0) serialized.cn = this.children.map((child) => child.serialize());
78
+ if (typeof className === "string" && className) serialized.cl = className;
79
+ const style = serializeStyle(this.props.style);
80
+ if (style) serialized.st = style;
81
+ const props = serializeProps(this.props);
82
+ if (props) serialized.p = props;
83
+ return serialized;
84
+ }
85
+ updateProps(props, notify = true) {
86
+ const previous = this.props;
87
+ this.props = props;
88
+ if (notify) this.root.markElementProps(this, previous, props);
89
+ }
90
+ };
91
+ function attachHostNode(parent, child, index) {
92
+ attach(parent, child, index);
93
+ }
94
+
95
+ //#endregion
96
+ export { HostElement, HostText, attachHostNode };
97
+ //# sourceMappingURL=nodes.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nodes.mjs","names":[],"sources":["../../../src/hostTree/nodes.ts"],"sourcesContent":["import type { HostRoot } from '.'\nimport type { HostProps, SerializedHostNode } from '../types'\nimport { serializeProps, serializeStyle } from './serialization'\n\nexport type HostParent = HostElement | HostRoot\nexport type HostNode = HostElement | HostText\n\nfunction attach(parent: HostParent, child: HostNode, index?: number) {\n if (child.parent) {\n const previousIndex = child.parent.children.indexOf(child)\n if (previousIndex >= 0) {\n child.parent.children.splice(previousIndex, 1)\n }\n }\n child.parent = parent\n if (index === undefined) {\n parent.children.push(child)\n }\n else {\n parent.children.splice(index, 0, child)\n }\n}\n\nexport class HostText {\n parent: HostParent | null = null\n readonly root: HostRoot\n readonly sid: string\n value: string\n\n constructor(root: HostRoot, sid: string, value: string) {\n this.root = root\n this.sid = sid\n this.value = value\n root.register(this)\n }\n\n serialize(): SerializedHostNode {\n return {\n nn: '#text',\n sid: this.sid,\n v: this.value,\n }\n }\n\n setValue(value: string) {\n if (value === this.value) {\n return\n }\n this.value = value\n if (this.root.renderMode === 'static-bindings' && this.parent && 'props' in this.parent) {\n this.root.markStaticText(this.parent)\n }\n else {\n this.root.markNode(this)\n }\n }\n}\n\nexport class HostElement {\n readonly children: HostNode[] = []\n parent: HostParent | null = null\n props: HostProps\n readonly root: HostRoot\n readonly sid: string\n readonly type: string\n\n constructor(root: HostRoot, sid: string, type: string, props: HostProps) {\n this.props = props\n this.root = root\n this.sid = sid\n this.type = type\n root.register(this)\n }\n\n append(child: HostNode, notify = true) {\n attach(this, child)\n if (notify) {\n this.root.markStructure(this)\n }\n }\n\n insertBefore(child: HostNode, before: HostNode) {\n const index = this.children.indexOf(before)\n attach(this, child, index < 0 ? undefined : index)\n this.root.markStructure(this)\n }\n\n remove(child: HostNode) {\n const index = this.children.indexOf(child)\n if (index < 0) {\n return\n }\n this.children.splice(index, 1)\n child.parent = null\n this.root.unregisterTree(child)\n this.root.markStructure(this)\n }\n\n serialize(): SerializedHostNode {\n const className = this.props.className ?? this.props.class\n const serialized: SerializedHostNode = {\n nn: this.type,\n sid: this.sid,\n }\n if (this.children.length > 0) {\n serialized.cn = this.children.map(child => child.serialize())\n }\n if (typeof className === 'string' && className) {\n serialized.cl = className\n }\n const style = serializeStyle(this.props.style)\n if (style) {\n serialized.st = style\n }\n const props = serializeProps(this.props)\n if (props) {\n serialized.p = props\n }\n return serialized\n }\n\n updateProps(props: HostProps, notify = true) {\n const previous = this.props\n this.props = props\n if (notify) {\n this.root.markElementProps(this, previous, props)\n }\n }\n}\n\nexport function attachHostNode(parent: HostParent, child: HostNode, index?: number) {\n attach(parent, child, index)\n}\n"],"mappings":";;;;AAOA,SAAS,OAAO,QAAoB,OAAiB,OAAgB;CACnE,IAAI,MAAM,QAAQ;EAChB,MAAM,gBAAgB,MAAM,OAAO,SAAS,QAAQ,KAAK;EACzD,IAAI,iBAAiB,GACnB,MAAM,OAAO,SAAS,OAAO,eAAe,CAAC;CAEjD;CACA,MAAM,SAAS;CACf,IAAI,UAAU,QACZ,OAAO,SAAS,KAAK,KAAK;MAG1B,OAAO,SAAS,OAAO,OAAO,GAAG,KAAK;AAE1C;AAEA,IAAa,WAAb,MAAsB;CAMpB,YAAY,MAAgB,KAAa,OAAe;wBALxD,UAA4B;wBACnB;wBACA;wBACT;EAGE,KAAK,OAAO;EACZ,KAAK,MAAM;EACX,KAAK,QAAQ;EACb,KAAK,SAAS,IAAI;CACpB;CAEA,YAAgC;EAC9B,OAAO;GACL,IAAI;GACJ,KAAK,KAAK;GACV,GAAG,KAAK;EACV;CACF;CAEA,SAAS,OAAe;EACtB,IAAI,UAAU,KAAK,OACjB;EAEF,KAAK,QAAQ;EACb,IAAI,KAAK,KAAK,eAAe,qBAAqB,KAAK,UAAU,WAAW,KAAK,QAC/E,KAAK,KAAK,eAAe,KAAK,MAAM;OAGpC,KAAK,KAAK,SAAS,IAAI;CAE3B;AACF;AAEA,IAAa,cAAb,MAAyB;CAQvB,YAAY,MAAgB,KAAa,MAAc,OAAkB;wBAPhE,YAAuB,CAAC;wBACjC,UAA4B;wBAC5B;wBACS;wBACA;wBACA;EAGP,KAAK,QAAQ;EACb,KAAK,OAAO;EACZ,KAAK,MAAM;EACX,KAAK,OAAO;EACZ,KAAK,SAAS,IAAI;CACpB;CAEA,OAAO,OAAiB,SAAS,MAAM;EACrC,OAAO,MAAM,KAAK;EAClB,IAAI,QACF,KAAK,KAAK,cAAc,IAAI;CAEhC;CAEA,aAAa,OAAiB,QAAkB;EAC9C,MAAM,QAAQ,KAAK,SAAS,QAAQ,MAAM;EAC1C,OAAO,MAAM,OAAO,QAAQ,IAAI,SAAY,KAAK;EACjD,KAAK,KAAK,cAAc,IAAI;CAC9B;CAEA,OAAO,OAAiB;EACtB,MAAM,QAAQ,KAAK,SAAS,QAAQ,KAAK;EACzC,IAAI,QAAQ,GACV;EAEF,KAAK,SAAS,OAAO,OAAO,CAAC;EAC7B,MAAM,SAAS;EACf,KAAK,KAAK,eAAe,KAAK;EAC9B,KAAK,KAAK,cAAc,IAAI;CAC9B;CAEA,YAAgC;;EAC9B,MAAM,qCAAY,KAAK,MAAM,kFAAa,KAAK,MAAM;EACrD,MAAM,aAAiC;GACrC,IAAI,KAAK;GACT,KAAK,KAAK;EACZ;EACA,IAAI,KAAK,SAAS,SAAS,GACzB,WAAW,KAAK,KAAK,SAAS,KAAI,UAAS,MAAM,UAAU,CAAC;EAE9D,IAAI,OAAO,cAAc,YAAY,WACnC,WAAW,KAAK;EAElB,MAAM,QAAQ,eAAe,KAAK,MAAM,KAAK;EAC7C,IAAI,OACF,WAAW,KAAK;EAElB,MAAM,QAAQ,eAAe,KAAK,KAAK;EACvC,IAAI,OACF,WAAW,IAAI;EAEjB,OAAO;CACT;CAEA,YAAY,OAAkB,SAAS,MAAM;EAC3C,MAAM,WAAW,KAAK;EACtB,KAAK,QAAQ;EACb,IAAI,QACF,KAAK,KAAK,iBAAiB,MAAM,UAAU,KAAK;CAEpD;AACF;AAEA,SAAgB,eAAe,QAAoB,OAAiB,OAAgB;CAClF,OAAO,QAAQ,OAAO,KAAK;AAC7B"}
@@ -0,0 +1,49 @@
1
+ //#region src/hostTree/serialization.ts
2
+ const UNITLESS_STYLE_PROPERTIES = /* @__PURE__ */ new Set([
3
+ "flex",
4
+ "flexGrow",
5
+ "flexShrink",
6
+ "fontWeight",
7
+ "lineHeight",
8
+ "opacity",
9
+ "order",
10
+ "zIndex"
11
+ ]);
12
+ const SERIALIZED_PROP_NAMES = /* @__PURE__ */ new Set([
13
+ "checked",
14
+ "disabled",
15
+ "hidden",
16
+ "id",
17
+ "placeholder",
18
+ "type",
19
+ "value"
20
+ ]);
21
+ function toKebabCase(value) {
22
+ return value.replace(/[A-Z]/g, (char) => `-${char.toLowerCase()}`);
23
+ }
24
+ function serializeStyle(value) {
25
+ if (typeof value === "string") return value;
26
+ if (!value || typeof value !== "object" || Array.isArray(value)) return;
27
+ const declarations = [];
28
+ for (const [name, rawValue] of Object.entries(value)) {
29
+ if (rawValue === null || rawValue === void 0 || rawValue === false) continue;
30
+ const normalized = typeof rawValue === "number" && !UNITLESS_STYLE_PROPERTIES.has(name) ? `${rawValue}px` : String(rawValue);
31
+ declarations.push(`${toKebabCase(name)}:${normalized}`);
32
+ }
33
+ return declarations.join(";");
34
+ }
35
+ function serializeProps(props) {
36
+ const serialized = {};
37
+ for (const [name, value] of Object.entries(props)) if (SERIALIZED_PROP_NAMES.has(name) && value !== void 0) serialized[name] = value;
38
+ return Object.keys(serialized).length > 0 ? serialized : void 0;
39
+ }
40
+ function hasSerializedPropChanges(previous, next) {
41
+ var _previous$className, _next$className;
42
+ if (((_previous$className = previous.className) !== null && _previous$className !== void 0 ? _previous$className : previous.class) !== ((_next$className = next.className) !== null && _next$className !== void 0 ? _next$className : next.class)) return true;
43
+ if (serializeStyle(previous.style) !== serializeStyle(next.style)) return true;
44
+ return JSON.stringify(serializeProps(previous)) !== JSON.stringify(serializeProps(next));
45
+ }
46
+
47
+ //#endregion
48
+ export { hasSerializedPropChanges, serializeProps, serializeStyle };
49
+ //# sourceMappingURL=serialization.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialization.mjs","names":[],"sources":["../../../src/hostTree/serialization.ts"],"sourcesContent":["import type { HostProps } from '../types'\n\nconst UNITLESS_STYLE_PROPERTIES = new Set([\n 'flex',\n 'flexGrow',\n 'flexShrink',\n 'fontWeight',\n 'lineHeight',\n 'opacity',\n 'order',\n 'zIndex',\n])\n\nconst SERIALIZED_PROP_NAMES = new Set([\n 'checked',\n 'disabled',\n 'hidden',\n 'id',\n 'placeholder',\n 'type',\n 'value',\n])\n\nfunction toKebabCase(value: string) {\n return value.replace(/[A-Z]/g, char => `-${char.toLowerCase()}`)\n}\n\nexport function serializeStyle(value: unknown) {\n if (typeof value === 'string') {\n return value\n }\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return undefined\n }\n\n const declarations: string[] = []\n for (const [name, rawValue] of Object.entries(value)) {\n if (rawValue === null || rawValue === undefined || rawValue === false) {\n continue\n }\n const normalized = typeof rawValue === 'number' && !UNITLESS_STYLE_PROPERTIES.has(name)\n ? `${rawValue}px`\n : String(rawValue)\n declarations.push(`${toKebabCase(name)}:${normalized}`)\n }\n return declarations.join(';')\n}\n\nexport function serializeProps(props: HostProps) {\n const serialized: Record<string, unknown> = {}\n for (const [name, value] of Object.entries(props)) {\n if (SERIALIZED_PROP_NAMES.has(name) && value !== undefined) {\n serialized[name] = value\n }\n }\n return Object.keys(serialized).length > 0 ? serialized : undefined\n}\n\nexport function hasSerializedPropChanges(previous: HostProps, next: HostProps) {\n const previousClass = previous.className ?? previous.class\n const nextClass = next.className ?? next.class\n if (previousClass !== nextClass) {\n return true\n }\n if (serializeStyle(previous.style) !== serializeStyle(next.style)) {\n return true\n }\n return JSON.stringify(serializeProps(previous)) !== JSON.stringify(serializeProps(next))\n}\n"],"mappings":";AAEA,MAAM,4CAA4B,IAAI,IAAI;CACxC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,MAAM,wCAAwB,IAAI,IAAI;CACpC;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,SAAS,YAAY,OAAe;CAClC,OAAO,MAAM,QAAQ,WAAU,SAAQ,IAAI,KAAK,YAAY,GAAG;AACjE;AAEA,SAAgB,eAAe,OAAgB;CAC7C,IAAI,OAAO,UAAU,UACnB,OAAO;CAET,IAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAC5D;CAGF,MAAM,eAAyB,CAAC;CAChC,KAAK,MAAM,CAAC,MAAM,aAAa,OAAO,QAAQ,KAAK,GAAG;EACpD,IAAI,aAAa,QAAQ,aAAa,UAAa,aAAa,OAC9D;EAEF,MAAM,aAAa,OAAO,aAAa,YAAY,CAAC,0BAA0B,IAAI,IAAI,IAClF,GAAG,SAAS,MACZ,OAAO,QAAQ;EACnB,aAAa,KAAK,GAAG,YAAY,IAAI,EAAE,GAAG,YAAY;CACxD;CACA,OAAO,aAAa,KAAK,GAAG;AAC9B;AAEA,SAAgB,eAAe,OAAkB;CAC/C,MAAM,aAAsC,CAAC;CAC7C,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,KAAK,GAC9C,IAAI,sBAAsB,IAAI,IAAI,KAAK,UAAU,QAC/C,WAAW,QAAQ;CAGvB,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,SAAS,IAAI,aAAa;AAC3D;AAEA,SAAgB,yBAAyB,UAAqB,MAAiB;;CAG7E,4BAFsB,SAAS,8EAAa,SAAS,+BACnC,KAAK,sEAAa,KAAK,QAEvC,OAAO;CAET,IAAI,eAAe,SAAS,KAAK,MAAM,eAAe,KAAK,KAAK,GAC9D,OAAO;CAET,OAAO,KAAK,UAAU,eAAe,QAAQ,CAAC,MAAM,KAAK,UAAU,eAAe,IAAI,CAAC;AACzF"}
@@ -0,0 +1,84 @@
1
+ import { serializeStyle } from "./serialization.mjs";
2
+ import _defineProperty from "../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/defineProperty.mjs";
3
+
4
+ //#region src/hostTree/staticBindings.ts
5
+ function isTextNode(node) {
6
+ return "value" in node;
7
+ }
8
+ function collectText(node) {
9
+ if (isTextNode(node)) return node.value;
10
+ return node.children.map(collectText).join("");
11
+ }
12
+ function readStaticBindingFields(props) {
13
+ const value = props.__bindingFields;
14
+ return typeof value === "string" && value ? value.split(",").filter(Boolean) : [];
15
+ }
16
+ function readStaticSlot(props) {
17
+ const value = props.__slot;
18
+ if (typeof value !== "string" || !value) throw new Error("static template host node 缺少编译期 __slot");
19
+ return value;
20
+ }
21
+ function readBindingValue(element, field, props = element.props) {
22
+ if (field === "text") return element.children.map(collectText).join("");
23
+ if (field === "className") {
24
+ var _ref, _props$className;
25
+ return (_ref = (_props$className = props.className) !== null && _props$className !== void 0 ? _props$className : props.class) !== null && _ref !== void 0 ? _ref : "";
26
+ }
27
+ if (field === "style") {
28
+ var _serializeStyle;
29
+ return (_serializeStyle = serializeStyle(props.style)) !== null && _serializeStyle !== void 0 ? _serializeStyle : "";
30
+ }
31
+ return props[field];
32
+ }
33
+ function hasStaticBindingChanges(previous, next) {
34
+ return readStaticBindingFields(next).some((field) => {
35
+ if (field === "text") return false;
36
+ if (field === "className") {
37
+ var _previous$className, _next$className;
38
+ return ((_previous$className = previous.className) !== null && _previous$className !== void 0 ? _previous$className : previous.class) !== ((_next$className = next.className) !== null && _next$className !== void 0 ? _next$className : next.class);
39
+ }
40
+ if (field === "style") return serializeStyle(previous.style) !== serializeStyle(next.style);
41
+ return previous[field] !== next[field];
42
+ });
43
+ }
44
+ var StaticBindingState = class {
45
+ constructor() {
46
+ _defineProperty(this, "dirty", /* @__PURE__ */ new Map());
47
+ }
48
+ clear() {
49
+ this.dirty.clear();
50
+ }
51
+ markField(element, field) {
52
+ let fields = this.dirty.get(element);
53
+ if (!fields) {
54
+ fields = /* @__PURE__ */ new Set();
55
+ this.dirty.set(element, fields);
56
+ }
57
+ fields.add(field);
58
+ }
59
+ markProps(element, previous, next) {
60
+ for (const field of readStaticBindingFields(next)) {
61
+ if (field === "text") continue;
62
+ if (readBindingValue(element, field, previous) !== readBindingValue(element, field, next)) this.markField(element, field);
63
+ }
64
+ }
65
+ snapshot(elements) {
66
+ const slots = {};
67
+ for (const element of elements) {
68
+ const fields = readStaticBindingFields(element.props);
69
+ if (fields.length === 0) continue;
70
+ slots[element.sid] = Object.fromEntries(fields.map((field) => [field, readBindingValue(element, field)]));
71
+ }
72
+ return slots;
73
+ }
74
+ takePayload() {
75
+ const payload = {};
76
+ for (const [element, fields] of this.dirty) for (const field of fields) payload[`slots.${element.sid}.${field}`] = readBindingValue(element, field);
77
+ this.dirty.clear();
78
+ return payload;
79
+ }
80
+ };
81
+
82
+ //#endregion
83
+ export { StaticBindingState, hasStaticBindingChanges, readStaticBindingFields, readStaticSlot };
84
+ //# sourceMappingURL=staticBindings.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"staticBindings.mjs","names":[],"sources":["../../../src/hostTree/staticBindings.ts"],"sourcesContent":["import type { HostProps } from '../types'\nimport { serializeStyle } from './serialization'\n\ninterface BindingTextNode {\n value: string\n}\n\ninterface BindingElementNode {\n children: BindingNode[]\n props: HostProps\n sid: string\n}\n\ntype BindingNode = BindingElementNode | BindingTextNode\n\nfunction isTextNode(node: BindingNode): node is BindingTextNode {\n return 'value' in node\n}\n\nfunction collectText(node: BindingNode): string {\n if (isTextNode(node)) {\n return node.value\n }\n return node.children.map(collectText).join('')\n}\n\nexport function readStaticBindingFields(props: HostProps) {\n const value = props.__bindingFields\n return typeof value === 'string' && value\n ? value.split(',').filter(Boolean)\n : []\n}\n\nexport function readStaticSlot(props: HostProps) {\n const value = props.__slot\n if (typeof value !== 'string' || !value) {\n throw new Error('static template host node 缺少编译期 __slot')\n }\n return value\n}\n\nfunction readBindingValue(element: BindingElementNode, field: string, props = element.props) {\n if (field === 'text') {\n return element.children.map(collectText).join('')\n }\n if (field === 'className') {\n return props.className ?? props.class ?? ''\n }\n if (field === 'style') {\n return serializeStyle(props.style) ?? ''\n }\n return props[field]\n}\n\nexport function hasStaticBindingChanges(previous: HostProps, next: HostProps) {\n const fields = readStaticBindingFields(next)\n return fields.some((field) => {\n if (field === 'text') {\n return false\n }\n if (field === 'className') {\n return (previous.className ?? previous.class) !== (next.className ?? next.class)\n }\n if (field === 'style') {\n return serializeStyle(previous.style) !== serializeStyle(next.style)\n }\n return previous[field] !== next[field]\n })\n}\n\nexport class StaticBindingState {\n private dirty = new Map<BindingElementNode, Set<string>>()\n\n clear() {\n this.dirty.clear()\n }\n\n markField(element: BindingElementNode, field: string) {\n let fields = this.dirty.get(element)\n if (!fields) {\n fields = new Set<string>()\n this.dirty.set(element, fields)\n }\n fields.add(field)\n }\n\n markProps(element: BindingElementNode, previous: HostProps, next: HostProps) {\n for (const field of readStaticBindingFields(next)) {\n if (field === 'text') {\n continue\n }\n if (readBindingValue(element, field, previous) !== readBindingValue(element, field, next)) {\n this.markField(element, field)\n }\n }\n }\n\n snapshot(elements: Iterable<BindingElementNode>) {\n const slots: Record<string, Record<string, unknown>> = {}\n for (const element of elements) {\n const fields = readStaticBindingFields(element.props)\n if (fields.length === 0) {\n continue\n }\n slots[element.sid] = Object.fromEntries(\n fields.map(field => [field, readBindingValue(element, field)]),\n )\n }\n return slots\n }\n\n takePayload() {\n const payload: Record<string, unknown> = {}\n for (const [element, fields] of this.dirty) {\n for (const field of fields) {\n payload[`slots.${element.sid}.${field}`] = readBindingValue(element, field)\n }\n }\n this.dirty.clear()\n return payload\n }\n}\n"],"mappings":";;;;AAeA,SAAS,WAAW,MAA4C;CAC9D,OAAO,WAAW;AACpB;AAEA,SAAS,YAAY,MAA2B;CAC9C,IAAI,WAAW,IAAI,GACjB,OAAO,KAAK;CAEd,OAAO,KAAK,SAAS,IAAI,WAAW,CAAC,CAAC,KAAK,EAAE;AAC/C;AAEA,SAAgB,wBAAwB,OAAkB;CACxD,MAAM,QAAQ,MAAM;CACpB,OAAO,OAAO,UAAU,YAAY,QAChC,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,OAAO,IAC/B,CAAC;AACP;AAEA,SAAgB,eAAe,OAAkB;CAC/C,MAAM,QAAQ,MAAM;CACpB,IAAI,OAAO,UAAU,YAAY,CAAC,OAChC,MAAM,IAAI,MAAM,wCAAwC;CAE1D,OAAO;AACT;AAEA,SAAS,iBAAiB,SAA6B,OAAe,QAAQ,QAAQ,OAAO;CAC3F,IAAI,UAAU,QACZ,OAAO,QAAQ,SAAS,IAAI,WAAW,CAAC,CAAC,KAAK,EAAE;CAElD,IAAI,UAAU,aAAa;;EACzB,mCAAO,MAAM,wEAAa,MAAM,4CAAS;CAC3C;CACA,IAAI,UAAU,SAAS;;EACrB,0BAAO,eAAe,MAAM,KAAK,8DAAK;CACxC;CACA,OAAO,MAAM;AACf;AAEA,SAAgB,wBAAwB,UAAqB,MAAiB;CAE5E,OADe,wBAAwB,IAC3B,CAAC,CAAC,MAAM,UAAU;EAC5B,IAAI,UAAU,QACZ,OAAO;EAET,IAAI,UAAU,aAAa;;GACzB,+BAAQ,SAAS,8EAAa,SAAS,+BAAY,KAAK,sEAAa,KAAK;EAC5E;EACA,IAAI,UAAU,SACZ,OAAO,eAAe,SAAS,KAAK,MAAM,eAAe,KAAK,KAAK;EAErE,OAAO,SAAS,WAAW,KAAK;CAClC,CAAC;AACH;AAEA,IAAa,qBAAb,MAAgC;;wBACtB,yBAAQ,IAAI,IAAqC;;CAEzD,QAAQ;EACN,KAAK,MAAM,MAAM;CACnB;CAEA,UAAU,SAA6B,OAAe;EACpD,IAAI,SAAS,KAAK,MAAM,IAAI,OAAO;EACnC,IAAI,CAAC,QAAQ;GACX,yBAAS,IAAI,IAAY;GACzB,KAAK,MAAM,IAAI,SAAS,MAAM;EAChC;EACA,OAAO,IAAI,KAAK;CAClB;CAEA,UAAU,SAA6B,UAAqB,MAAiB;EAC3E,KAAK,MAAM,SAAS,wBAAwB,IAAI,GAAG;GACjD,IAAI,UAAU,QACZ;GAEF,IAAI,iBAAiB,SAAS,OAAO,QAAQ,MAAM,iBAAiB,SAAS,OAAO,IAAI,GACtF,KAAK,UAAU,SAAS,KAAK;EAEjC;CACF;CAEA,SAAS,UAAwC;EAC/C,MAAM,QAAiD,CAAC;EACxD,KAAK,MAAM,WAAW,UAAU;GAC9B,MAAM,SAAS,wBAAwB,QAAQ,KAAK;GACpD,IAAI,OAAO,WAAW,GACpB;GAEF,MAAM,QAAQ,OAAO,OAAO,YAC1B,OAAO,KAAI,UAAS,CAAC,OAAO,iBAAiB,SAAS,KAAK,CAAC,CAAC,CAC/D;EACF;EACA,OAAO;CACT;CAEA,cAAc;EACZ,MAAM,UAAmC,CAAC;EAC1C,KAAK,MAAM,CAAC,SAAS,WAAW,KAAK,OACnC,KAAK,MAAM,SAAS,QAClB,QAAQ,SAAS,QAAQ,IAAI,GAAG,WAAW,iBAAiB,SAAS,KAAK;EAG9E,KAAK,MAAM,MAAM;EACjB,OAAO;CACT;AACF"}
@@ -0,0 +1,4 @@
1
+ import { Button, Input, Text, View } from "./components.mjs";
2
+ import { createReactMiniProgramRoot } from "./renderer.mjs";
3
+
4
+ export { Button, Input, Text, View, createReactMiniProgramRoot };
@@ -0,0 +1,203 @@
1
+ import { HostElement, HostText } from "./hostTree/nodes.mjs";
2
+ import { HostRoot } from "./hostTree/index.mjs";
3
+ import { dispatchHostEvent } from "./event.mjs";
4
+ import { createContext } from "react";
5
+ import Reconciler from "react-reconciler";
6
+ import { DefaultEventPriority, NoEventPriority } from "react-reconciler/constants.js";
7
+
8
+ //#region src/renderer.ts
9
+ function propsChanged(previous, next) {
10
+ const previousKeys = Object.keys(previous).filter((key) => key !== "children");
11
+ const nextKeys = Object.keys(next).filter((key) => key !== "children");
12
+ if (previousKeys.length !== nextKeys.length) return true;
13
+ return nextKeys.some((key) => previous[key] !== next[key]);
14
+ }
15
+ let currentUpdatePriority = NoEventPriority;
16
+ const hostContext = {};
17
+ const hostConfig = {
18
+ HostTransitionContext: createContext(null),
19
+ NotPendingTransition: null,
20
+ afterActiveInstanceBlur() {},
21
+ appendChild(parent, child) {
22
+ parent.append(child);
23
+ },
24
+ appendChildToContainer(parent, child) {
25
+ parent.append(child);
26
+ },
27
+ appendInitialChild(parent, child) {
28
+ parent.append(child, false);
29
+ },
30
+ beforeActiveInstanceBlur() {},
31
+ cancelTimeout: clearTimeout,
32
+ clearContainer(container) {
33
+ container.clear();
34
+ },
35
+ commitMount() {},
36
+ commitTextUpdate(text, _previous, next) {
37
+ text.setValue(next);
38
+ },
39
+ commitUpdate(element, _type, previous, next) {
40
+ if (!propsChanged(previous, next)) return;
41
+ element.updateProps(next, element.root.shouldNotifyPropUpdate(previous, next));
42
+ },
43
+ createInstance(type, props, root) {
44
+ return new HostElement(root, root.createElementSid(props), type, props);
45
+ },
46
+ createTextInstance(text, root) {
47
+ return new HostText(root, root.nextSid(), text);
48
+ },
49
+ detachDeletedInstance() {},
50
+ finalizeInitialChildren() {
51
+ return false;
52
+ },
53
+ getChildHostContext(parentContext) {
54
+ return parentContext;
55
+ },
56
+ getCurrentUpdatePriority() {
57
+ return currentUpdatePriority;
58
+ },
59
+ getInstanceFromNode() {
60
+ return null;
61
+ },
62
+ getInstanceFromScope() {
63
+ return null;
64
+ },
65
+ getPublicInstance(instance) {
66
+ return instance;
67
+ },
68
+ getRootHostContext() {
69
+ return hostContext;
70
+ },
71
+ getSuspendedCommitReason() {
72
+ return null;
73
+ },
74
+ hideInstance(instance) {
75
+ instance.updateProps({
76
+ ...instance.props,
77
+ hidden: true
78
+ });
79
+ },
80
+ hideTextInstance(instance) {
81
+ instance.setValue("");
82
+ },
83
+ insertBefore(parent, child, before) {
84
+ parent.insertBefore(child, before);
85
+ },
86
+ insertInContainerBefore(parent, child, before) {
87
+ parent.insertBefore(child, before);
88
+ },
89
+ isPrimaryRenderer: true,
90
+ maySuspendCommit() {
91
+ return false;
92
+ },
93
+ maySuspendCommitInSyncRender() {
94
+ return false;
95
+ },
96
+ maySuspendCommitOnUpdate() {
97
+ return false;
98
+ },
99
+ noTimeout: -1,
100
+ preloadInstance() {
101
+ return true;
102
+ },
103
+ prepareForCommit() {
104
+ return null;
105
+ },
106
+ preparePortalMount() {},
107
+ prepareScopeUpdate() {},
108
+ requestPostPaintCallback(callback) {
109
+ setTimeout(() => callback(Date.now()), 0);
110
+ },
111
+ resetFormInstance() {},
112
+ resolveEventTimeStamp() {
113
+ return -1.1;
114
+ },
115
+ resolveEventType() {
116
+ return null;
117
+ },
118
+ resolveUpdatePriority() {
119
+ return currentUpdatePriority === NoEventPriority ? DefaultEventPriority : currentUpdatePriority;
120
+ },
121
+ removeChild(parent, child) {
122
+ parent.remove(child);
123
+ },
124
+ removeChildFromContainer(parent, child) {
125
+ parent.remove(child);
126
+ },
127
+ resetAfterCommit(container) {
128
+ container.flush();
129
+ },
130
+ resetTextContent() {},
131
+ scheduleMicrotask(callback) {
132
+ Promise.resolve().then(callback);
133
+ },
134
+ scheduleTimeout: setTimeout,
135
+ setCurrentUpdatePriority(priority) {
136
+ currentUpdatePriority = priority;
137
+ },
138
+ shouldAttemptEagerTransition() {
139
+ return false;
140
+ },
141
+ shouldSetTextContent() {
142
+ return false;
143
+ },
144
+ supportsHydration: false,
145
+ supportsMicrotasks: true,
146
+ supportsMutation: true,
147
+ supportsPersistence: false,
148
+ suspendInstance() {},
149
+ startSuspendingCommit() {},
150
+ trackSchedulerEvent() {},
151
+ unhideInstance(instance, props) {
152
+ instance.updateProps(props);
153
+ },
154
+ unhideTextInstance(instance, text) {
155
+ instance.setValue(text);
156
+ },
157
+ waitForCommitToBeReady() {
158
+ return null;
159
+ },
160
+ warnsIfNotActing: true
161
+ };
162
+ const renderer = Reconciler(hostConfig);
163
+ function createContainer(root) {
164
+ return renderer.createContainer(root, 0, null, false, false, "", (error) => {
165
+ throw error;
166
+ }, () => {}, (error) => {
167
+ throw error;
168
+ }, () => {});
169
+ }
170
+ function createReactMiniProgramRoot(adapter, options = {}) {
171
+ const root = new HostRoot(adapter, options.renderMode);
172
+ const container = createContainer(root);
173
+ return {
174
+ dispatchEvent(event) {
175
+ renderer.flushSyncFromReconciler(() => dispatchHostEvent(root, event));
176
+ root.assertStaticTemplateValid();
177
+ root.flush();
178
+ },
179
+ flush() {
180
+ renderer.flushSyncFromReconciler();
181
+ root.flush();
182
+ },
183
+ getSnapshot() {
184
+ return root.snapshot();
185
+ },
186
+ render(element) {
187
+ renderer.updateContainerSync(element, container, null);
188
+ renderer.flushSyncWork();
189
+ root.assertStaticTemplateValid();
190
+ root.flush();
191
+ },
192
+ unmount() {
193
+ root.beginUnmount();
194
+ renderer.updateContainerSync(null, container, null);
195
+ renderer.flushSyncWork();
196
+ root.flush();
197
+ }
198
+ };
199
+ }
200
+
201
+ //#endregion
202
+ export { createReactMiniProgramRoot };
203
+ //# sourceMappingURL=renderer.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.mjs","names":[],"sources":["../../src/renderer.ts"],"sourcesContent":["import type { ReactNode } from 'react'\nimport type { HostRenderMode } from './hostTree'\nimport type { HostProps, MiniProgramEventLike, MiniProgramPageAdapter } from './types'\nimport { createContext } from 'react'\nimport Reconciler from 'react-reconciler'\nimport { DefaultEventPriority, NoEventPriority } from 'react-reconciler/constants'\nimport { dispatchHostEvent } from './event'\nimport { HostElement, HostRoot, HostText } from './hostTree'\n\nfunction propsChanged(previous: HostProps, next: HostProps) {\n const previousKeys = Object.keys(previous).filter(key => key !== 'children')\n const nextKeys = Object.keys(next).filter(key => key !== 'children')\n if (previousKeys.length !== nextKeys.length) {\n return true\n }\n return nextKeys.some(key => previous[key] !== next[key])\n}\n\ntype HostContext = Record<string, never>\ntype HostNode = HostElement | HostText\ntype MiniProgramHostConfig = Reconciler.HostConfig<\n string,\n HostProps,\n HostRoot,\n HostElement,\n HostText,\n never,\n never,\n never,\n HostNode,\n HostContext,\n never,\n ReturnType<typeof setTimeout>,\n -1,\n null\n>\n\ninterface React19HostConfigExtensions {\n getSuspendedCommitReason: () => null\n maySuspendCommitInSyncRender: () => false\n maySuspendCommitOnUpdate: () => false\n}\n\nlet currentUpdatePriority = NoEventPriority\nconst hostContext: HostContext = {}\n\nconst hostConfig: MiniProgramHostConfig & React19HostConfigExtensions = {\n HostTransitionContext: createContext(null) as never,\n NotPendingTransition: null,\n afterActiveInstanceBlur() {},\n appendChild(parent: HostElement, child: HostElement | HostText) {\n parent.append(child)\n },\n appendChildToContainer(parent: HostRoot, child: HostElement | HostText) {\n parent.append(child)\n },\n appendInitialChild(parent: HostElement, child: HostElement | HostText) {\n parent.append(child, false)\n },\n beforeActiveInstanceBlur() {},\n cancelTimeout: clearTimeout,\n clearContainer(container: HostRoot) {\n container.clear()\n },\n commitMount() {},\n commitTextUpdate(text: HostText, _previous: string, next: string) {\n text.setValue(next)\n },\n commitUpdate(\n element: HostElement,\n _type: string,\n previous: HostProps,\n next: HostProps,\n ) {\n if (!propsChanged(previous, next)) {\n return\n }\n element.updateProps(next, element.root.shouldNotifyPropUpdate(previous, next))\n },\n createInstance(type: string, props: HostProps, root: HostRoot) {\n return new HostElement(root, root.createElementSid(props), type, props)\n },\n createTextInstance(text: string, root: HostRoot) {\n return new HostText(root, root.nextSid(), text)\n },\n detachDeletedInstance() {},\n finalizeInitialChildren() {\n return false\n },\n getChildHostContext(parentContext: HostContext) {\n return parentContext\n },\n getCurrentUpdatePriority() {\n return currentUpdatePriority\n },\n getInstanceFromNode() {\n return null\n },\n getInstanceFromScope() {\n return null\n },\n getPublicInstance(instance: HostElement | HostText) {\n return instance\n },\n getRootHostContext(): HostContext {\n return hostContext\n },\n getSuspendedCommitReason() {\n return null\n },\n hideInstance(instance: HostElement) {\n instance.updateProps({\n ...instance.props,\n hidden: true,\n })\n },\n hideTextInstance(instance: HostText) {\n instance.setValue('')\n },\n insertBefore(parent: HostElement, child: HostElement | HostText, before: HostElement | HostText) {\n parent.insertBefore(child, before)\n },\n insertInContainerBefore(parent: HostRoot, child: HostElement | HostText, before: HostElement | HostText) {\n parent.insertBefore(child, before)\n },\n isPrimaryRenderer: true,\n maySuspendCommit() {\n return false\n },\n maySuspendCommitInSyncRender() {\n return false\n },\n maySuspendCommitOnUpdate() {\n return false\n },\n noTimeout: -1,\n preloadInstance() {\n return true\n },\n prepareForCommit() {\n return null\n },\n preparePortalMount() {},\n prepareScopeUpdate() {},\n requestPostPaintCallback(callback: (time: number) => void) {\n setTimeout(() => callback(Date.now()), 0)\n },\n resetFormInstance() {},\n resolveEventTimeStamp() {\n return -1.1\n },\n resolveEventType() {\n return null\n },\n resolveUpdatePriority() {\n return currentUpdatePriority === NoEventPriority ? DefaultEventPriority : currentUpdatePriority\n },\n removeChild(parent: HostElement, child: HostElement | HostText) {\n parent.remove(child)\n },\n removeChildFromContainer(parent: HostRoot, child: HostElement | HostText) {\n parent.remove(child)\n },\n resetAfterCommit(container: HostRoot) {\n container.flush()\n },\n resetTextContent() {},\n scheduleMicrotask(callback: () => void) {\n Promise.resolve().then(callback)\n },\n scheduleTimeout: setTimeout,\n setCurrentUpdatePriority(priority: number) {\n currentUpdatePriority = priority\n },\n shouldAttemptEagerTransition() {\n return false\n },\n shouldSetTextContent() {\n return false\n },\n supportsHydration: false,\n supportsMicrotasks: true,\n supportsMutation: true,\n supportsPersistence: false,\n suspendInstance() {},\n startSuspendingCommit() {},\n trackSchedulerEvent() {},\n unhideInstance(instance: HostElement, props: HostProps) {\n instance.updateProps(props)\n },\n unhideTextInstance(instance: HostText, text: string) {\n instance.setValue(text)\n },\n waitForCommitToBeReady() {\n return null\n },\n warnsIfNotActing: true,\n}\n\nconst renderer = Reconciler(hostConfig)\n\nexport interface ReactMiniProgramRoot {\n dispatchEvent: (event: MiniProgramEventLike) => void\n flush: () => void\n getSnapshot: () => ReturnType<HostRoot['snapshot']>\n render: (element: ReactNode) => void\n unmount: () => void\n}\n\nexport interface ReactMiniProgramRootOptions {\n renderMode?: HostRenderMode\n}\n\nfunction createContainer(root: HostRoot) {\n return renderer.createContainer(\n root,\n 0,\n null,\n false,\n false,\n '',\n (error) => {\n throw error\n },\n () => {},\n (error) => {\n throw error\n },\n () => {},\n )\n}\n\nexport function createReactMiniProgramRoot(\n adapter: MiniProgramPageAdapter,\n options: ReactMiniProgramRootOptions = {},\n): ReactMiniProgramRoot {\n const root = new HostRoot(adapter, options.renderMode)\n const container = createContainer(root)\n\n return {\n dispatchEvent(event) {\n renderer.flushSyncFromReconciler(() => dispatchHostEvent(root, event))\n root.assertStaticTemplateValid()\n root.flush()\n },\n flush() {\n renderer.flushSyncFromReconciler()\n root.flush()\n },\n getSnapshot() {\n return root.snapshot()\n },\n render(element) {\n renderer.updateContainerSync(element, container, null)\n renderer.flushSyncWork()\n root.assertStaticTemplateValid()\n root.flush()\n },\n unmount() {\n root.beginUnmount()\n renderer.updateContainerSync(null, container, null)\n renderer.flushSyncWork()\n root.flush()\n },\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export { };
package/dist/event.mjs ADDED
@@ -0,0 +1 @@
1
+ import{HostElement as e}from"./hostTree/nodes.mjs";import"./hostTree/index.mjs";import{WEAPP_REACT_EVENT_DATASET_KEY as t}from"@weapp-core/constants";function n(e){return`on${e.charAt(0).toUpperCase()}${e.slice(1)}`}function r(r,i){var a,o;let s=(a=i.currentTarget)==null||(a=a.dataset)==null?void 0:a[t];if(typeof s!=`string`)return;let c=r.getNode(s);if(!(c instanceof e))return;let l=[],u=c;for(;u;)l.push(u),u=u.parent instanceof e?u.parent:null;let d=!1,f={currentTarget:c,detail:(o=i.detail)==null?{}:o,nativeEvent:i,stopPropagation:()=>{d=!0},target:c,type:i.type},p=n(i.type);for(let e of l.slice().reverse()){let t=e.props[`${p}Capture`];if(typeof t==`function`&&(f.currentTarget=e,t(f)),d){r.flush();return}}for(let e of l){let t=e.props[p];if(typeof t==`function`&&(f.currentTarget=e,t(f)),d)break}r.flush()}export{r as dispatchHostEvent};
@@ -0,0 +1,48 @@
1
+ import { HostProps, MiniProgramPageAdapter, SerializedHostNode } from "../types.mjs";
2
+ import { HostElement, HostNode, HostParent, HostText } from "./nodes.mjs";
3
+ import "./serialization.mjs";
4
+ import "../index.mjs";
5
+ //#region src/hostTree/index.d.ts
6
+ type HostRenderMode = 'static-bindings' | 'tree';
7
+ declare class HostRoot {
8
+ readonly children: HostNode[];
9
+ readonly renderMode: HostRenderMode;
10
+ private dirtyNodes;
11
+ private dirtyStructures;
12
+ private mounted;
13
+ private nodeId;
14
+ private nodes;
15
+ private pendingFlush;
16
+ private readonly adapter;
17
+ private readonly staticBindings;
18
+ private staticMismatch;
19
+ private unmounting;
20
+ constructor(adapter: MiniProgramPageAdapter, renderMode?: HostRenderMode);
21
+ beginUnmount(): void;
22
+ assertStaticTemplateValid(): void;
23
+ createElementSid(props: HostProps): string;
24
+ nextSid(): string;
25
+ register(node: HostNode): void;
26
+ unregisterTree(node: HostNode): void;
27
+ getNode(sid: string): HostNode | undefined;
28
+ append(child: HostNode): void;
29
+ insertBefore(child: HostNode, before: HostNode): void;
30
+ remove(child: HostNode): void;
31
+ clear(): void;
32
+ markNode(node: HostNode): void;
33
+ markElementProps(element: HostElement, previous: HostProps, next: HostProps): void;
34
+ markStaticText(element: HostElement): void;
35
+ markStructure(parent: HostParent): void;
36
+ private scheduleFlush;
37
+ private pathOf;
38
+ private hasStructuralAncestor;
39
+ snapshot(): {
40
+ cn: SerializedHostNode[];
41
+ };
42
+ shouldNotifyPropUpdate(previous: HostProps, next: HostProps): boolean;
43
+ private staticElements;
44
+ private flushStaticBindings;
45
+ flush(): void;
46
+ }
47
+ //#endregion
48
+ export { HostRenderMode, HostRoot };
@@ -0,0 +1 @@
1
+ import{hasSerializedPropChanges as e}from"./serialization.mjs";import t from"../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/defineProperty.mjs";import{HostElement as n,HostText as r,attachHostNode as i}from"./nodes.mjs";import{StaticBindingState as a,hasStaticBindingChanges as o,readStaticSlot as s}from"./staticBindings.mjs";import{WEAPP_REACT_ROOT_DATA_KEY as c,WEAPP_REACT_SLOTS_DATA_KEY as l}from"@weapp-core/constants";var u=class r{constructor(e,n=`tree`){t(this,`children`,[]),t(this,`renderMode`,void 0),t(this,`dirtyNodes`,new Set),t(this,`dirtyStructures`,new Set),t(this,`mounted`,!1),t(this,`nodeId`,0),t(this,`nodes`,new Map),t(this,`pendingFlush`,!1),t(this,`adapter`,void 0),t(this,`staticBindings`,new a),t(this,`staticMismatch`,void 0),t(this,`unmounting`,!1),this.adapter=e,this.renderMode=n}beginUnmount(){this.unmounting=!0}assertStaticTemplateValid(){if(!this.staticMismatch)return;let e=this.staticMismatch;throw this.staticMismatch=void 0,e}createElementSid(e){return this.renderMode===`static-bindings`?s(e):this.nextSid()}nextSid(){return this.nodeId+=1,`r${this.nodeId}`}register(e){if(this.renderMode===`static-bindings`&&e instanceof n&&this.nodes.has(e.sid))throw Error(`static template slot 冲突:${e.sid}`);this.nodes.set(e.sid,e)}unregisterTree(e){this.nodes.delete(e.sid),e instanceof n&&e.children.forEach(e=>this.unregisterTree(e))}getNode(e){return this.nodes.get(e)}append(e){i(this,e),this.markStructure(this)}insertBefore(e,t){let n=this.children.indexOf(t);i(this,e,n<0?void 0:n),this.markStructure(this)}remove(e){let t=this.children.indexOf(e);t<0||(this.children.splice(t,1),e.parent=null,this.unregisterTree(e),this.markStructure(this))}clear(){this.children.forEach(e=>this.unregisterTree(e)),this.children.length=0,this.markStructure(this)}markNode(e){this.dirtyNodes.add(e),this.scheduleFlush()}markElementProps(e,t,n){if(this.renderMode===`static-bindings`){this.staticBindings.markProps(e,t,n),this.scheduleFlush();return}this.markNode(e)}markStaticText(e){this.staticBindings.markField(e,`text`),this.scheduleFlush()}markStructure(e){if(this.renderMode===`static-bindings`){this.mounted&&!this.unmounting&&(this.staticMismatch=Error(`static template 运行时结构发生变化,需要切换 dynamic island fallback`));return}this.dirtyStructures.add(e),this.scheduleFlush()}scheduleFlush(){this.pendingFlush||(this.pendingFlush=!0,Promise.resolve().then(()=>this.flush()))}pathOf(e){if(e instanceof r)return`root`;let t=e.parent;if(!t)return;let n=this.pathOf(t),i=t.children.indexOf(e);return n&&i>=0?`${n}.cn[${i}]`:void 0}hasStructuralAncestor(e){let t=e.parent;for(;t;){if(this.dirtyStructures.has(t))return!0;t=t instanceof n?t.parent:null}return!1}snapshot(){return{cn:this.children.map(e=>e.serialize())}}shouldNotifyPropUpdate(t,n){return this.renderMode===`static-bindings`?o(t,n):e(t,n)}staticElements(){return Array.from(this.nodes.values()).filter(e=>e instanceof n)}flushStaticBindings(){if(this.staticMismatch){this.staticBindings.clear();return}if(!this.mounted){this.mounted=!0,this.staticBindings.clear(),this.adapter.setData({[l]:this.staticBindings.snapshot(this.staticElements())});return}let e=this.staticBindings.takePayload();Object.keys(e).length>0&&!this.unmounting&&this.adapter.setData(e)}flush(){if(this.pendingFlush=!1,this.renderMode===`static-bindings`){this.flushStaticBindings();return}if(!this.mounted){this.mounted=!0,this.dirtyNodes.clear(),this.dirtyStructures.clear(),this.adapter.setData({[c]:this.snapshot()});return}let e={};for(let t of this.dirtyStructures){let n=this.pathOf(t);n&&(e[`${n}.cn`]=t.children.map(e=>e.serialize()))}for(let t of this.dirtyNodes){if(this.hasStructuralAncestor(t))continue;let n=this.pathOf(t);n&&(e[n]=t.serialize())}this.dirtyNodes.clear(),this.dirtyStructures.clear(),Object.keys(e).length>0&&this.adapter.setData(e)}};export{n as HostElement,u as HostRoot,r as HostText};
@@ -0,0 +1,30 @@
1
+ import { HostProps, SerializedHostNode } from "../types.mjs";
2
+ import { HostRoot } from "./index.mjs";
3
+ //#region src/hostTree/nodes.d.ts
4
+ type HostParent = HostElement | HostRoot;
5
+ type HostNode = HostElement | HostText;
6
+ declare class HostText {
7
+ parent: HostParent | null;
8
+ readonly root: HostRoot;
9
+ readonly sid: string;
10
+ value: string;
11
+ constructor(root: HostRoot, sid: string, value: string);
12
+ serialize(): SerializedHostNode;
13
+ setValue(value: string): void;
14
+ }
15
+ declare class HostElement {
16
+ readonly children: HostNode[];
17
+ parent: HostParent | null;
18
+ props: HostProps;
19
+ readonly root: HostRoot;
20
+ readonly sid: string;
21
+ readonly type: string;
22
+ constructor(root: HostRoot, sid: string, type: string, props: HostProps);
23
+ append(child: HostNode, notify?: boolean): void;
24
+ insertBefore(child: HostNode, before: HostNode): void;
25
+ remove(child: HostNode): void;
26
+ serialize(): SerializedHostNode;
27
+ updateProps(props: HostProps, notify?: boolean): void;
28
+ }
29
+ //#endregion
30
+ export { HostElement, HostNode, HostParent, HostText };
@@ -0,0 +1 @@
1
+ import{serializeProps as e,serializeStyle as t}from"./serialization.mjs";import n from"../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/defineProperty.mjs";function r(e,t,n){if(t.parent){let e=t.parent.children.indexOf(t);e>=0&&t.parent.children.splice(e,1)}t.parent=e,n===void 0?e.children.push(t):e.children.splice(n,0,t)}var i=class{constructor(e,t,r){n(this,`parent`,null),n(this,`root`,void 0),n(this,`sid`,void 0),n(this,`value`,void 0),this.root=e,this.sid=t,this.value=r,e.register(this)}serialize(){return{nn:`#text`,sid:this.sid,v:this.value}}setValue(e){e!==this.value&&(this.value=e,this.root.renderMode===`static-bindings`&&this.parent&&`props`in this.parent?this.root.markStaticText(this.parent):this.root.markNode(this))}},a=class{constructor(e,t,r,i){n(this,`children`,[]),n(this,`parent`,null),n(this,`props`,void 0),n(this,`root`,void 0),n(this,`sid`,void 0),n(this,`type`,void 0),this.props=i,this.root=e,this.sid=t,this.type=r,e.register(this)}append(e,t=!0){r(this,e),t&&this.root.markStructure(this)}insertBefore(e,t){let n=this.children.indexOf(t);r(this,e,n<0?void 0:n),this.root.markStructure(this)}remove(e){let t=this.children.indexOf(e);t<0||(this.children.splice(t,1),e.parent=null,this.root.unregisterTree(e),this.root.markStructure(this))}serialize(){var n;let r=(n=this.props.className)==null?this.props.class:n,i={nn:this.type,sid:this.sid};this.children.length>0&&(i.cn=this.children.map(e=>e.serialize())),typeof r==`string`&&r&&(i.cl=r);let a=t(this.props.style);a&&(i.st=a);let o=e(this.props);return o&&(i.p=o),i}updateProps(e,t=!0){let n=this.props;this.props=e,t&&this.root.markElementProps(this,n,e)}};function o(e,t,n){r(e,t,n)}export{a as HostElement,i as HostText,o as attachHostNode};
@@ -0,0 +1 @@
1
+ import "../types.mjs";
@@ -0,0 +1 @@
1
+ const e=new Set([`flex`,`flexGrow`,`flexShrink`,`fontWeight`,`lineHeight`,`opacity`,`order`,`zIndex`]),t=new Set([`checked`,`disabled`,`hidden`,`id`,`placeholder`,`type`,`value`]);function n(e){return e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)}function r(t){if(typeof t==`string`)return t;if(!t||typeof t!=`object`||Array.isArray(t))return;let r=[];for(let[i,a]of Object.entries(t)){if(a==null||a===!1)continue;let t=typeof a==`number`&&!e.has(i)?`${a}px`:String(a);r.push(`${n(i)}:${t}`)}return r.join(`;`)}function i(e){let n={};for(let[r,i]of Object.entries(e))t.has(r)&&i!==void 0&&(n[r]=i);return Object.keys(n).length>0?n:void 0}function a(e,t){var n,a;return((n=e.className)==null?e.class:n)!==((a=t.className)==null?t.class:a)||r(e.style)!==r(t.style)||JSON.stringify(i(e))!==JSON.stringify(i(t))}export{a as hasSerializedPropChanges,i as serializeProps,r as serializeStyle};
@@ -0,0 +1 @@
1
+ import{serializeStyle as e}from"./serialization.mjs";import t from"../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/defineProperty.mjs";function n(e){return`value`in e}function r(e){return n(e)?e.value:e.children.map(r).join(``)}function i(e){let t=e.__bindingFields;return typeof t==`string`&&t?t.split(`,`).filter(Boolean):[]}function a(e){let t=e.__slot;if(typeof t!=`string`||!t)throw Error(`static template host node 缺少编译期 __slot`);return t}function o(t,n,i=t.props){if(n===`text`)return t.children.map(r).join(``);if(n===`className`){var a,o;return(a=(o=i.className)==null?i.class:o)==null?``:a}if(n===`style`){var s;return(s=e(i.style))==null?``:s}return i[n]}function s(t,n){return i(n).some(r=>{if(r===`text`)return!1;if(r===`className`){var i,a;return((i=t.className)==null?t.class:i)!==((a=n.className)==null?n.class:a)}return r===`style`?e(t.style)!==e(n.style):t[r]!==n[r]})}var c=class{constructor(){t(this,`dirty`,new Map)}clear(){this.dirty.clear()}markField(e,t){let n=this.dirty.get(e);n||(n=new Set,this.dirty.set(e,n)),n.add(t)}markProps(e,t,n){for(let r of i(n))r!==`text`&&o(e,r,t)!==o(e,r,n)&&this.markField(e,r)}snapshot(e){let t={};for(let n of e){let e=i(n.props);e.length!==0&&(t[n.sid]=Object.fromEntries(e.map(e=>[e,o(n,e)])))}return t}takePayload(){let e={};for(let[t,n]of this.dirty)for(let r of n)e[`slots.${t.sid}.${r}`]=o(t,r);return this.dirty.clear(),e}};export{c as StaticBindingState,s as hasStaticBindingChanges,i as readStaticBindingFields,a as readStaticSlot};
@@ -0,0 +1,4 @@
1
+ import { HostEventHandler, HostProps, MiniProgramEventLike, MiniProgramHostProps, MiniProgramPageAdapter, SerializedHostNode } from "./types.mjs";
2
+ import { Button, Input, Text, View } from "./components.mjs";
3
+ import { ReactMiniProgramRoot, ReactMiniProgramRootOptions, createReactMiniProgramRoot } from "./renderer.mjs";
4
+ export { Button, type HostEventHandler, type HostProps, Input, type MiniProgramEventLike, type MiniProgramHostProps, type MiniProgramPageAdapter, type ReactMiniProgramRoot, type ReactMiniProgramRootOptions, type SerializedHostNode, Text, View, createReactMiniProgramRoot };
package/dist/index.mjs ADDED
@@ -0,0 +1 @@
1
+ import{Button as e,Input as t,Text as n,View as r}from"./components.mjs";import{createReactMiniProgramRoot as i}from"./renderer.mjs";export{e as Button,t as Input,n as Text,r as View,i as createReactMiniProgramRoot};
@@ -0,0 +1,17 @@
1
+ import { MiniProgramEventLike, MiniProgramPageAdapter } from "./types.mjs";
2
+ import { HostRenderMode, HostRoot } from "./hostTree/index.mjs";
3
+ import { ReactNode } from "react";
4
+ //#region src/renderer.d.ts
5
+ interface ReactMiniProgramRoot {
6
+ dispatchEvent: (event: MiniProgramEventLike) => void;
7
+ flush: () => void;
8
+ getSnapshot: () => ReturnType<HostRoot['snapshot']>;
9
+ render: (element: ReactNode) => void;
10
+ unmount: () => void;
11
+ }
12
+ interface ReactMiniProgramRootOptions {
13
+ renderMode?: HostRenderMode;
14
+ }
15
+ declare function createReactMiniProgramRoot(adapter: MiniProgramPageAdapter, options?: ReactMiniProgramRootOptions): ReactMiniProgramRoot;
16
+ //#endregion
17
+ export { ReactMiniProgramRoot, ReactMiniProgramRootOptions, createReactMiniProgramRoot };
@@ -0,0 +1 @@
1
+ import{HostElement as e,HostText as t}from"./hostTree/nodes.mjs";import{HostRoot as n}from"./hostTree/index.mjs";import{dispatchHostEvent as r}from"./event.mjs";import{createContext as i}from"react";import a from"react-reconciler";import{DefaultEventPriority as o,NoEventPriority as s}from"react-reconciler/constants.js";function c(e,t){let n=Object.keys(e).filter(e=>e!==`children`),r=Object.keys(t).filter(e=>e!==`children`);return n.length!==r.length||r.some(n=>e[n]!==t[n])}let l=s;const u={},d={HostTransitionContext:i(null),NotPendingTransition:null,afterActiveInstanceBlur(){},appendChild(e,t){e.append(t)},appendChildToContainer(e,t){e.append(t)},appendInitialChild(e,t){e.append(t,!1)},beforeActiveInstanceBlur(){},cancelTimeout:clearTimeout,clearContainer(e){e.clear()},commitMount(){},commitTextUpdate(e,t,n){e.setValue(n)},commitUpdate(e,t,n,r){c(n,r)&&e.updateProps(r,e.root.shouldNotifyPropUpdate(n,r))},createInstance(t,n,r){return new e(r,r.createElementSid(n),t,n)},createTextInstance(e,n){return new t(n,n.nextSid(),e)},detachDeletedInstance(){},finalizeInitialChildren(){return!1},getChildHostContext(e){return e},getCurrentUpdatePriority(){return l},getInstanceFromNode(){return null},getInstanceFromScope(){return null},getPublicInstance(e){return e},getRootHostContext(){return u},getSuspendedCommitReason(){return null},hideInstance(e){e.updateProps({...e.props,hidden:!0})},hideTextInstance(e){e.setValue(``)},insertBefore(e,t,n){e.insertBefore(t,n)},insertInContainerBefore(e,t,n){e.insertBefore(t,n)},isPrimaryRenderer:!0,maySuspendCommit(){return!1},maySuspendCommitInSyncRender(){return!1},maySuspendCommitOnUpdate(){return!1},noTimeout:-1,preloadInstance(){return!0},prepareForCommit(){return null},preparePortalMount(){},prepareScopeUpdate(){},requestPostPaintCallback(e){setTimeout(()=>e(Date.now()),0)},resetFormInstance(){},resolveEventTimeStamp(){return-1.1},resolveEventType(){return null},resolveUpdatePriority(){return l===s?o:l},removeChild(e,t){e.remove(t)},removeChildFromContainer(e,t){e.remove(t)},resetAfterCommit(e){e.flush()},resetTextContent(){},scheduleMicrotask(e){Promise.resolve().then(e)},scheduleTimeout:setTimeout,setCurrentUpdatePriority(e){l=e},shouldAttemptEagerTransition(){return!1},shouldSetTextContent(){return!1},supportsHydration:!1,supportsMicrotasks:!0,supportsMutation:!0,supportsPersistence:!1,suspendInstance(){},startSuspendingCommit(){},trackSchedulerEvent(){},unhideInstance(e,t){e.updateProps(t)},unhideTextInstance(e,t){e.setValue(t)},waitForCommitToBeReady(){return null},warnsIfNotActing:!0},f=a(d);function p(e){return f.createContainer(e,0,null,!1,!1,``,e=>{throw e},()=>{},e=>{throw e},()=>{})}function m(e,t={}){let i=new n(e,t.renderMode),a=p(i);return{dispatchEvent(e){f.flushSyncFromReconciler(()=>r(i,e)),i.assertStaticTemplateValid(),i.flush()},flush(){f.flushSyncFromReconciler(),i.flush()},getSnapshot(){return i.snapshot()},render(e){f.updateContainerSync(e,a,null),f.flushSyncWork(),i.assertStaticTemplateValid(),i.flush()},unmount(){i.beginUnmount(),f.updateContainerSync(null,a,null),f.flushSyncWork(),i.flush()}}}export{m as createReactMiniProgramRoot};
@@ -0,0 +1,50 @@
1
+ import { ReactNode } from "react";
2
+ //#region src/types.d.ts
3
+ interface MiniProgramEventLike {
4
+ currentTarget?: {
5
+ dataset?: Record<string, unknown>;
6
+ };
7
+ detail?: Record<string, unknown>;
8
+ target?: unknown;
9
+ type: string;
10
+ }
11
+ interface MiniProgramPageAdapter {
12
+ setData: (payload: Record<string, unknown>, callback?: () => void) => void;
13
+ }
14
+ interface SerializedHostNode {
15
+ cl?: string;
16
+ cn?: SerializedHostNode[];
17
+ nn: string;
18
+ p?: Record<string, unknown>;
19
+ sid: string;
20
+ st?: string;
21
+ v?: string;
22
+ }
23
+ type HostProps = Record<string, unknown>;
24
+ interface MiniProgramHostProps {
25
+ children?: ReactNode;
26
+ checked?: boolean;
27
+ class?: string;
28
+ className?: string;
29
+ disabled?: boolean;
30
+ hidden?: boolean;
31
+ id?: string;
32
+ onChange?: HostEventHandler;
33
+ onInput?: HostEventHandler;
34
+ onTap?: HostEventHandler;
35
+ onTapCapture?: HostEventHandler;
36
+ placeholder?: string;
37
+ style?: Record<string, string | number | null | undefined> | string;
38
+ type?: string;
39
+ value?: string | number;
40
+ }
41
+ type HostEventHandler = (event: {
42
+ currentTarget: unknown;
43
+ detail: Record<string, unknown>;
44
+ nativeEvent: MiniProgramEventLike;
45
+ stopPropagation: () => void;
46
+ target: unknown;
47
+ type: string;
48
+ }) => unknown;
49
+ //#endregion
50
+ export { HostEventHandler, HostProps, MiniProgramEventLike, MiniProgramHostProps, MiniProgramPageAdapter, SerializedHostNode };
package/dist/types.mjs ADDED
@@ -0,0 +1 @@
1
+ export{};
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@weapp-vite/react",
3
+ "type": "module",
4
+ "version": "0.1.0",
5
+ "description": "React 19 runtime for weapp-vite mini programs",
6
+ "license": "MIT",
7
+ "sideEffects": false,
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.mts",
11
+ "import": "./dist/index.mjs"
12
+ },
13
+ "./dev": {
14
+ "types": "./dist/index.d.mts",
15
+ "import": "./dist/dev/index.mjs"
16
+ },
17
+ "./components": {
18
+ "types": "./dist/components.d.mts",
19
+ "import": "./dist/components.mjs"
20
+ },
21
+ "./types": {
22
+ "types": "./dist/types.d.mts",
23
+ "import": "./dist/types.mjs"
24
+ }
25
+ },
26
+ "main": "./dist/index.mjs",
27
+ "module": "./dist/index.mjs",
28
+ "types": "./dist/index.d.mts",
29
+ "files": [
30
+ "dist"
31
+ ],
32
+ "engines": {
33
+ "node": "^20.19.0 || >=22.12.0"
34
+ },
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "peerDependencies": {
39
+ "miniprogram-api-typings": "^5.0.0",
40
+ "react": "^19.2.0",
41
+ "react-reconciler": "0.33.0"
42
+ },
43
+ "dependencies": {
44
+ "@weapp-core/constants": "0.1.16"
45
+ },
46
+ "devDependencies": {
47
+ "@types/react": "19.2.17",
48
+ "@types/react-reconciler": "0.33.0",
49
+ "miniprogram-api-typings": "^5.2.3",
50
+ "react": "19.2.7",
51
+ "react-reconciler": "0.33.0"
52
+ },
53
+ "scripts": {
54
+ "dev": "tsdown -w",
55
+ "build": "tsdown",
56
+ "build:types": "tsdown --dts",
57
+ "test": "vitest run",
58
+ "test:types": "tsd",
59
+ "typecheck": "tsc --noEmit",
60
+ "lint": "eslint .",
61
+ "lint:fix": "eslint . --fix"
62
+ }
63
+ }