vite-plugin-taro-runtime 0.7.11 → 0.7.12-beta.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.
@@ -322,7 +322,6 @@ function createReactApp(App, react, dom, config) {
322
322
  // appWrapper ? cb() : appWrapperPromise.then(() => cb())
323
323
  }
324
324
  function renderReactRoot() {
325
- var _a, _b;
326
325
  const appId = (config === null || config === void 0 ? void 0 : config.appId) || 'app';
327
326
  let container = document.getElementById(appId);
328
327
  if (container == null) {
@@ -343,18 +342,9 @@ function createReactApp(App, react, dom, config) {
343
342
  * batches across Page surfaces. No detached scheduler node, second React root, or host-property override participates.
344
343
  */
345
344
  container.ctx = { setData: broadcastAppUpdate };
346
- /*
347
- * Upstream enables createRoot only for a React 18 version string, which skips the entire App render on React 19.
348
- * Detect the renderer capability instead: React 18/19 take the modern path and older renderers retain the fallback.
349
- */
350
- if (typeof ReactDOM$1.createRoot === 'function') {
351
- const root = ReactDOM$1.createRoot(container);
352
- (_a = root.render) === null || _a === void 0 ? void 0 : _a.call(root, h$1(AppWrapper));
353
- }
354
- else {
355
- // eslint-disable-next-line react/no-deprecated
356
- (_b = ReactDOM$1.render) === null || _b === void 0 ? void 0 : _b.call(ReactDOM$1, h$1(AppWrapper), container);
357
- }
345
+ // VPT requires React 19: both the Mini renderer and react-dom/client provide concurrent roots.
346
+ const root = ReactDOM$1.createRoot(container);
347
+ root.render(h$1(AppWrapper));
358
348
  /*
359
349
  * Return the exact host passed to ReactDOM. AppWrapper.mount closes over this immutable value when a Page is added,
360
350
  * guaranteeing that its initial snapshot comes from the same singleton App tree without a host registry or lookup.
@@ -371,10 +361,14 @@ function createReactApp(App, react, dom, config) {
371
361
  appWrapperResolver(this);
372
362
  }
373
363
  mount(pageComponent, id, cb) {
374
- const pageWrapper = connectReactPage(react, id)(pageComponent);
375
- const key = id + pageKeyId();
376
- const page = () => h$1(pageWrapper, { key, tid: id });
377
- this.pages.push(page);
364
+ // Prerender and onLoad share an identity, even when both mounts arrive before the queued Page renders.
365
+ if (!this.pages.some(page => page.tid === id) && !this.elements.some(element => element.props.tid === id)) {
366
+ const pageWrapper = connectReactPage(react, id)(pageComponent);
367
+ const key = id + pageKeyId();
368
+ const page = () => h$1(pageWrapper, { key, tid: id });
369
+ page.tid = id;
370
+ this.pages.push(page);
371
+ }
378
372
  this.forceUpdate((...args) => {
379
373
  perf.stop(PAGE_INIT);
380
374
  if (process.env.TARO_PLATFORM !== 'web') {
@@ -669,8 +663,10 @@ function initNativeComponentEntry(params) {
669
663
  (_a = app === null || app === void 0 ? void 0 : app.parentNode) === null || _a === void 0 ? void 0 : _a.appendChild(nativeApp);
670
664
  app = nativeApp;
671
665
  }
672
- // eslint-disable-next-line react/no-deprecated
673
- ReactDOM.render(h(Entry, {}), app);
666
+ // Native created/attached callbacks require Entry.componentDidMount to install the App before setup returns.
667
+ ReactDOM.flushSync(() => {
668
+ ReactDOM.createRoot(app).render(h(Entry, {}));
669
+ });
674
670
  }
675
671
  function createNativePageConfig(Component, pageName, data, react, reactDOM, pageConfig) {
676
672
  reactMeta.R = react;
@@ -1,10 +1,9 @@
1
1
  import { internalInstanceKey } from './constant';
2
- import { createRoot, render } from './render';
2
+ import { createRoot } from './render';
3
3
  import type { TaroElement } from 'vite-plugin-taro-runtime/runtime/mini';
4
4
  import type { ReactNode } from 'react';
5
5
  declare const unstable_batchedUpdates: (fn: any, a: any) => any;
6
6
  declare function unmountComponentAtNode(dom: TaroElement): boolean;
7
- declare function findDOMNode(comp?: TaroElement | ReactNode): string | number | boolean | TaroElement | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null;
8
7
  declare function createPortal(children: ReactNode, containerInfo: TaroElement, key?: string): {
9
8
  $$typeof: number | symbol;
10
9
  key: string | null;
@@ -16,9 +15,8 @@ declare const flushSync: {
16
15
  (): void;
17
16
  <R>(fn: () => R): R;
18
17
  };
19
- export { createPortal, createRoot, findDOMNode, flushSync, internalInstanceKey, render, unmountComponentAtNode, unstable_batchedUpdates, };
18
+ export { createPortal, createRoot, flushSync, internalInstanceKey, unmountComponentAtNode, unstable_batchedUpdates };
20
19
  declare const _default: {
21
- render: typeof render;
22
20
  flushSync: {
23
21
  (): void;
24
22
  <R>(fn: () => R): R;
@@ -26,7 +24,6 @@ declare const _default: {
26
24
  createRoot: typeof createRoot;
27
25
  unstable_batchedUpdates: (fn: any, a: any) => any;
28
26
  unmountComponentAtNode: typeof unmountComponentAtNode;
29
- findDOMNode: typeof findDOMNode;
30
27
  createPortal: typeof createPortal;
31
28
  internalInstanceKey: string;
32
29
  };
@@ -1,7 +1,9 @@
1
1
  import { PLATFORM_TYPE, isObject, isEnableTTDom, isString, isFunction, toCamelCase, UNITLESS_PROPERTIES_SET, isNumber, capitalize, internalComponents, isUndefined, noop, isBoolean, hooks, ensure } from '@tarojs/shared';
2
2
  import { setInnerHTML, FormElement, convertNumber2PX, eventHandlerTTDom, document } from '@tarojs/runtime';
3
+ import { version } from 'react';
3
4
  import Reconciler from 'react-reconciler';
4
5
  import {
6
+ ConcurrentRoot,
5
7
  ContinuousEventPriority,
6
8
  DefaultEventPriority,
7
9
  DiscreteEventPriority,
@@ -599,6 +601,7 @@ function styleObjectToCss(style) {
599
601
  }
600
602
 
601
603
  /* eslint-disable @typescript-eslint/indent */
604
+ // React and native event dispatch share this scoped priority; nested dispatch restores its caller's priority.
602
605
  let taroCurrentUpdatePriority = NoEventPriority;
603
606
  const taroNotPendingTransition = null;
604
607
  const taroHostTransitionContext = {
@@ -790,9 +793,6 @@ const hostConfig = {
790
793
  }
791
794
  return false;
792
795
  },
793
- prepareUpdate(instance, _, oldProps, newProps) {
794
- return getUpdatePayload(instance, oldProps, newProps);
795
- },
796
796
  shouldSetTextContent() {
797
797
  return false;
798
798
  },
@@ -815,9 +815,6 @@ const hostConfig = {
815
815
  preparePortalMount: noop,
816
816
  prepareScopeUpdate: noop,
817
817
  getInstanceFromScope: () => null,
818
- getCurrentEventPriority() {
819
- return DefaultEventPriority;
820
- },
821
818
  detachDeletedInstance: noop,
822
819
  // -------------------
823
820
  // Microtasks
@@ -847,11 +844,8 @@ const hostConfig = {
847
844
  textInst.nodeValue = newText;
848
845
  },
849
846
  commitMount: noop,
850
- commitUpdate(dom, updatePayloadOrType, maybeOldProps, maybeNewProps, maybeFiber) {
851
- const isReact19Signature = typeof updatePayloadOrType === 'string';
852
- const oldProps = isReact19Signature ? maybeOldProps : maybeNewProps;
853
- const newProps = isReact19Signature ? maybeNewProps : maybeFiber;
854
- const updatePayload = isReact19Signature ? getUpdatePayload(dom, oldProps, newProps) : updatePayloadOrType;
847
+ commitUpdate(dom, _type, oldProps, newProps) {
848
+ const updatePayload = getUpdatePayload(dom, oldProps, newProps);
855
849
  if (!updatePayload)
856
850
  return;
857
851
  // payload 只包含 children 的时候,不应该再继续触发后续的属性比较和更新的逻辑了
@@ -897,8 +891,8 @@ const hostConfig = {
897
891
  }
898
892
  };
899
893
  const TaroReconciler = Reconciler(hostConfig);
900
- TaroReconciler.flushSync = TaroReconciler.flushSync || TaroReconciler.flushSyncFromReconciler || TaroReconciler.flushSyncWork;
901
- TaroReconciler.runWithPriority = TaroReconciler.runWithPriority || ((priority, fn) => {
894
+ // react-reconciler 0.34 delegates native event priority to the host, not a runWithPriority export.
895
+ function runWithPriority(priority, fn) {
902
896
  const previousPriority = hostConfig.getCurrentUpdatePriority();
903
897
  try {
904
898
  hostConfig.setCurrentUpdatePriority(priority);
@@ -907,11 +901,11 @@ TaroReconciler.runWithPriority = TaroReconciler.runWithPriority || ((priority, f
907
901
  finally {
908
902
  hostConfig.setCurrentUpdatePriority(previousPriority);
909
903
  }
910
- });
904
+ }
911
905
  if (process.env.NODE_ENV !== 'production') {
912
906
  const foundDevTools = TaroReconciler.injectIntoDevTools({
913
907
  bundleType: 1,
914
- version: '18.0.0',
908
+ version,
915
909
  rendererPackageName: 'taro-react'
916
910
  });
917
911
  if (!foundDevTools) {
@@ -959,7 +953,7 @@ function needsStateRestore() {
959
953
  function finishEventHandler() {
960
954
  const controlledComponentsHavePendingUpdates = needsStateRestore();
961
955
  if (controlledComponentsHavePendingUpdates) {
962
- TaroReconciler.flushSync();
956
+ TaroReconciler.flushSyncWork();
963
957
  restoreStateIfNeeded();
964
958
  }
965
959
  }
@@ -995,92 +989,55 @@ function restoreStateOfTarget(item) {
995
989
  }
996
990
  }
997
991
 
992
+ // Native teardown looks up the one concurrent root per host; unmount removes its entry after the commit.
998
993
  const ContainerMap = new WeakMap();
994
+ function reportRootError(error) {
995
+ console.error(error);
996
+ }
997
+ function reportCaughtError(error, errorInfo) {
998
+ console.error(error);
999
+ if (errorInfo.componentStack) {
1000
+ console.error(errorInfo.componentStack);
1001
+ }
1002
+ }
999
1003
  class Root {
1000
- constructor(renderer, domContainer, options) {
1001
- this.renderer = renderer;
1002
- this.initInternalRoot(renderer, domContainer, options);
1003
- }
1004
- initInternalRoot(renderer, domContainer, options) {
1005
- // Since react-reconciler v0.27, createContainer need more parameters
1006
- // @see:https://github.com/facebook/react/blob/0b974418c9a56f6c560298560265dcf4b65784bc/packages/react-reconciler/src/ReactFiberReconciler.js#L248
1007
- const containerInfo = domContainer;
1008
- if (options) {
1009
- const tag = 1; // ConcurrentRoot
1010
- const concurrentUpdatesByDefaultOverride = false;
1011
- let isStrictMode = false;
1012
- let identifierPrefix = '';
1013
- let onUncaughtError = (error) => console.error(error);
1014
- let onCaughtError = (error, errorInfo) => {
1015
- console.error(error);
1016
- if (errorInfo === null || errorInfo === void 0 ? void 0 : errorInfo.componentStack) {
1017
- console.error(errorInfo.componentStack);
1018
- }
1019
- };
1020
- let onRecoverableError = (error) => console.error(error);
1021
- const onDefaultTransitionIndicator = null;
1022
- if (options.unstable_strictMode === true) {
1023
- isStrictMode = true;
1024
- }
1025
- if (options.identifierPrefix !== undefined) {
1026
- identifierPrefix = options.identifierPrefix;
1027
- }
1028
- if (options.onUncaughtError !== undefined) {
1029
- onUncaughtError = options.onUncaughtError;
1030
- }
1031
- if (options.onCaughtError !== undefined) {
1032
- onCaughtError = options.onCaughtError;
1033
- }
1034
- if (options.onRecoverableError !== undefined) {
1035
- onRecoverableError = options.onRecoverableError;
1036
- }
1037
- this.internalRoot = renderer.createContainer(containerInfo, tag, null, // hydrationCallbacks
1038
- isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, onDefaultTransitionIndicator);
1039
- }
1040
- else {
1041
- const tag = 0; // LegacyRoot
1042
- this.internalRoot = renderer.createContainer(containerInfo, tag, null, // hydrationCallbacks
1043
- false, // isStrictMode
1044
- false, // concurrentUpdatesByDefaultOverride,
1045
- '', // identifierPrefix
1046
- (error) => console.error(error), // onUncaughtError
1047
- (error) => console.error(error), // onCaughtError
1048
- (error) => console.error(error), // onRecoverableError
1004
+ constructor(domContainer, options) {
1005
+ this.domContainer = domContainer;
1006
+ this.internalRoot = TaroReconciler.createContainer(
1007
+ domContainer,
1008
+ ConcurrentRoot,
1009
+ null, // hydrationCallbacks
1010
+ options.unstable_strictMode === true,
1011
+ false, // concurrentUpdatesByDefaultOverride
1012
+ options.identifierPrefix ?? '',
1013
+ options.onUncaughtError ?? reportRootError,
1014
+ options.onCaughtError ?? reportCaughtError,
1015
+ options.onRecoverableError ?? reportRootError,
1049
1016
  null // onDefaultTransitionIndicator
1050
- );
1051
- }
1017
+ );
1052
1018
  }
1053
1019
  render(children, cb) {
1054
- const { renderer, internalRoot } = this;
1055
- renderer.updateContainer(children, internalRoot, null, cb);
1056
- return renderer.getPublicRootInstance(internalRoot);
1020
+ TaroReconciler.updateContainer(children, this.internalRoot, null, cb);
1057
1021
  }
1058
1022
  unmount(cb) {
1059
- this.renderer.updateContainer(null, this.internalRoot, null, cb);
1023
+ TaroReconciler.updateContainer(null, this.internalRoot, null, () => {
1024
+ ContainerMap.delete(this.domContainer);
1025
+ this.domContainer[internalContainerInstanceKey] = null;
1026
+ cb?.();
1027
+ });
1060
1028
  }
1061
1029
  }
1062
- function render(element, domContainer, cb) {
1063
- const oldRoot = ContainerMap.get(domContainer);
1064
- if (oldRoot != null) {
1065
- return oldRoot.render(element, cb);
1066
- }
1067
- const root = new Root(TaroReconciler, domContainer);
1068
- ContainerMap.set(domContainer, root);
1069
- return root.render(element, cb);
1070
- }
1071
- function createRoot(domContainer, options = {}) {
1072
- var _a;
1030
+ function createRoot(domContainer, options) {
1073
1031
  const oldRoot = ContainerMap.get(domContainer);
1074
1032
  if (oldRoot != null) {
1075
1033
  return oldRoot;
1076
1034
  }
1077
- // options should be an object
1078
- const root = new Root(TaroReconciler, domContainer, options);
1035
+ const root = new Root(domContainer, options ?? {});
1079
1036
  ContainerMap.set(domContainer, root);
1080
- markContainerAsRoot((_a = root === null || root === void 0 ? void 0 : root.internalRoot) === null || _a === void 0 ? void 0 : _a.current, domContainer);
1037
+ markContainerAsRoot(root.internalRoot.current, domContainer);
1081
1038
  hooks.tap('dispatchTaroEvent', (e, node) => {
1082
1039
  const eventPriority = getEventPriority(e.type);
1083
- TaroReconciler.runWithPriority(eventPriority, () => {
1040
+ runWithPriority(eventPriority, () => {
1084
1041
  node.dispatchEvent(e);
1085
1042
  });
1086
1043
  });
@@ -1121,22 +1078,10 @@ function unmountComponentAtNode(dom) {
1121
1078
  if (!root)
1122
1079
  return false;
1123
1080
  unstable_batchedUpdates(() => {
1124
- root.unmount(() => {
1125
- ContainerMap.delete(dom);
1126
- });
1081
+ root.unmount();
1127
1082
  }, null);
1128
1083
  return true;
1129
1084
  }
1130
- function findDOMNode(comp) {
1131
- if (comp == null) {
1132
- return null;
1133
- }
1134
- const nodeType = comp.nodeType;
1135
- if (nodeType === 1 || nodeType === 3) {
1136
- return comp;
1137
- }
1138
- return TaroReconciler.findHostInstance(comp);
1139
- }
1140
1085
  const portalType = isFunction(Symbol) && Symbol.for
1141
1086
  ? Symbol.for('react.portal')
1142
1087
  : 0xeaca;
@@ -1149,17 +1094,16 @@ function createPortal(children, containerInfo, key) {
1149
1094
  implementation: null
1150
1095
  };
1151
1096
  }
1152
- const flushSync = TaroReconciler.flushSync;
1097
+ // Public flushSync runs a callback at synchronous priority; controlled-input restoration only flushes queued sync work.
1098
+ const flushSync = TaroReconciler.flushSyncFromReconciler;
1153
1099
  var index = {
1154
- render,
1155
1100
  flushSync,
1156
1101
  createRoot,
1157
1102
  unstable_batchedUpdates,
1158
1103
  unmountComponentAtNode,
1159
- findDOMNode,
1160
1104
  createPortal,
1161
1105
  internalInstanceKey
1162
1106
  };
1163
1107
 
1164
- export { createPortal, createRoot, index as default, findDOMNode, flushSync, internalInstanceKey, render, unmountComponentAtNode, unstable_batchedUpdates };
1108
+ export { createPortal, createRoot, index as default, flushSync, internalInstanceKey, unmountComponentAtNode, unstable_batchedUpdates };
1165
1109
  //# sourceMappingURL=react.esm.js.map
@@ -1,25 +1,21 @@
1
- import { TaroReconciler } from './reconciler';
2
1
  import type { TaroElement } from 'vite-plugin-taro-runtime/runtime/mini';
3
- import type { ReactNode } from 'react';
2
+ import type { ErrorInfo, ReactNode } from 'react';
4
3
  import type { OpaqueRoot } from 'react-reconciler';
5
4
  export declare const ContainerMap: WeakMap<TaroElement, Root>;
6
- type Renderer = typeof TaroReconciler;
7
5
  type CreateRootOptions = {
8
6
  unstable_strictMode?: boolean;
9
- unstable_concurrentUpdatesByDefault?: boolean;
10
- unstable_transitionCallbacks?: any;
11
7
  identifierPrefix?: string;
12
- onRecoverableError?: (error: any) => void;
8
+ onUncaughtError?: (error: unknown, errorInfo: ErrorInfo) => void;
9
+ onCaughtError?: (error: unknown, errorInfo: ErrorInfo) => void;
10
+ onRecoverableError?: (error: unknown, errorInfo: ErrorInfo) => void;
13
11
  };
14
- export type Callback = () => void | null | undefined;
12
+ export type Callback = () => void;
15
13
  declare class Root {
16
- private renderer;
14
+ private domContainer;
17
15
  internalRoot: OpaqueRoot;
18
- constructor(renderer: Renderer, domContainer: TaroElement, options?: CreateRootOptions);
19
- private initInternalRoot;
20
- render(children: ReactNode, cb: Callback): TaroElement | import("react").Component<any, any, any> | null;
21
- unmount(cb: Callback): void;
16
+ constructor(domContainer: TaroElement, options: CreateRootOptions);
17
+ render(children: ReactNode, cb?: Callback): void;
18
+ unmount(cb?: Callback): void;
22
19
  }
23
- export declare function render(element: ReactNode, domContainer: TaroElement, cb: Callback): TaroElement | import("react").Component<any, any, any> | null;
24
20
  export declare function createRoot(domContainer: TaroElement, options?: CreateRootOptions): Root;
25
21
  export {};
@@ -95,8 +95,12 @@ function createPageConfig(component, pageName, data, pageConfig) {
95
95
  Current.page = this;
96
96
  this.config = pageConfig || {};
97
97
  // this.$taroPath 是页面唯一标识
98
- const uniqueOptions = Object.assign({}, options, { $taroTimestamp: Date.now() });
99
- const $taroPath = this.$taroPath = getPath(id, uniqueOptions);
98
+ const prerenderIdentity = config.__vpt_meta?.prerenderIdentity;
99
+ if (prerenderIdentity) {
100
+ config.__vpt_meta.prerenderIdentity = undefined;
101
+ }
102
+ const uniqueOptions = prerenderIdentity?.params ?? Object.assign({}, options, { $taroTimestamp: Date.now() });
103
+ const $taroPath = this.$taroPath = prerenderIdentity?.path ?? getPath(id, uniqueOptions);
100
104
  if (process.env.TARO_PLATFORM === 'web') {
101
105
  config.path = $taroPath;
102
106
  }
@@ -56,8 +56,10 @@ interface PageLifeCycle extends Show {
56
56
  onUnload?(): void;
57
57
  }
58
58
  interface PageInstance extends PageLifeCycle {
59
+ /** @internal VPT metadata; native onLoad consumes the prepared identity once. */
60
+ __vpt_meta?: { prerenderIdentity?: { path: string; params: Record<string, unknown> } };
59
61
  /** 页面的初始数据 */
60
- data?: Record<string, unknown>;
62
+ data?: Record<string, unknown> | (() => Record<string, unknown>);
61
63
  /** 页面路径 */
62
64
  path?: string;
63
65
  /** 页面的组件选项 */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-taro-runtime",
3
- "version": "0.7.11",
3
+ "version": "0.7.12-beta.0",
4
4
  "description": "Taro runtime, React, and platform support for vite-plugin-taro.",
5
5
  "author": "sep2",
6
6
  "license": "MIT",