@viewfly/core 1.0.4 → 1.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.
@@ -570,23 +570,6 @@ function getObjectChanges(newProps, oldProps) {
570
570
  }
571
571
  return changes;
572
572
  }
573
- function getArrayChanges(left, right) {
574
- const changes = {
575
- add: [],
576
- remove: []
577
- };
578
- for (const i of left) {
579
- if (!right.includes(i)) {
580
- changes.remove.push(i);
581
- }
582
- }
583
- for (const i of right) {
584
- if (!left.includes(i)) {
585
- changes.add.push(i);
586
- }
587
- }
588
- return changes;
589
- }
590
573
  function classToString(config) {
591
574
  if (typeof config === 'string') {
592
575
  return config;
@@ -635,8 +618,28 @@ const TextAtomType = Symbol('Text');
635
618
  const ElementAtomType = Symbol('Element');
636
619
  const ComponentAtomType = Symbol('Component');
637
620
 
621
+ class Listener {
622
+ constructor(effect) {
623
+ this.effect = effect;
624
+ this.destroyCallbacks = [];
625
+ }
626
+ destroy() {
627
+ this.destroyCallbacks.forEach(fn => fn());
628
+ this.destroyCallbacks = [];
629
+ }
630
+ }
631
+ const listeners = [];
632
+ function getCurrentListener() {
633
+ return listeners.at(-1);
634
+ }
635
+ function pushListener(listener) {
636
+ listeners.push(listener);
637
+ }
638
+ function popListener() {
639
+ listeners.pop();
640
+ }
641
+
638
642
  const componentSetupStack = [];
639
- const signalDepsStack = [];
640
643
  const componentErrorFn = makeError('component');
641
644
  function getSetupContext(need = true) {
642
645
  const current = componentSetupStack[componentSetupStack.length - 1];
@@ -646,9 +649,6 @@ function getSetupContext(need = true) {
646
649
  }
647
650
  return current;
648
651
  }
649
- function getSignalDepsContext() {
650
- return signalDepsStack[signalDepsStack.length - 1];
651
- }
652
652
  /**
653
653
  * Viewfly 组件管理类,用于管理组件的生命周期,上下文等
654
654
  */
@@ -675,6 +675,9 @@ class Component extends ReflectiveInjector {
675
675
  this._changed = true;
676
676
  this.isFirstRendering = true;
677
677
  this.refs = null;
678
+ this.listener = new Listener(() => {
679
+ this.markAsDirtied();
680
+ });
678
681
  }
679
682
  markAsDirtied() {
680
683
  this._dirty = true;
@@ -728,12 +731,9 @@ class Component extends ReflectiveInjector {
728
731
  }
729
732
  isSetup = false;
730
733
  componentSetupStack.pop();
731
- signalDepsStack.push([]);
734
+ pushListener(this.listener);
732
735
  const template = this.instance.$render();
733
- const deps = signalDepsStack.pop();
734
- this.unWatch = watch(Array.from(new Set(deps)), () => {
735
- this.markAsDirtied();
736
- });
736
+ popListener();
737
737
  update(template, this.instance.$portalHost);
738
738
  this.rendered();
739
739
  }
@@ -772,13 +772,10 @@ class Component extends ReflectiveInjector {
772
772
  return;
773
773
  }
774
774
  }
775
- this.unWatch();
776
- signalDepsStack.push([]);
775
+ this.listener.destroy();
776
+ pushListener(this.listener);
777
777
  const template = this.instance.$render();
778
- const deps = signalDepsStack.pop();
779
- this.unWatch = watch(Array.from(new Set(deps)), () => {
780
- this.markAsDirtied();
781
- });
778
+ popListener();
782
779
  updateChildren(template);
783
780
  this.rendered();
784
781
  }
@@ -788,7 +785,7 @@ class Component extends ReflectiveInjector {
788
785
  }
789
786
  destroy() {
790
787
  var _a, _b, _c;
791
- this.unWatch();
788
+ this.listener.destroy();
792
789
  (_a = this.updatedDestroyCallbacks) === null || _a === void 0 ? void 0 : _a.forEach(fn => {
793
790
  fn();
794
791
  });
@@ -1050,173 +1047,6 @@ class StaticRef extends DynamicRef {
1050
1047
  function createRef() {
1051
1048
  return new StaticRef();
1052
1049
  }
1053
- const depsKey = Symbol('deps');
1054
- /**
1055
- * 组件状态管理器
1056
- * @param state 初始状态
1057
- * @example
1058
- * ```tsx
1059
- * function App() {
1060
- * // 初始化状态
1061
- * const state = createSignal(1)
1062
- *
1063
- * return () => {
1064
- * <div>
1065
- * <div>当前值为:{state()}</div>
1066
- * <div>
1067
- * <button type="button" onClick={() => {
1068
- * // 当点击时更新状态
1069
- * state.set(state() + 1)
1070
- * }
1071
- * }>updateState</button>
1072
- * </div>
1073
- * </div>
1074
- * }
1075
- * }
1076
- */
1077
- function createSignal(state) {
1078
- function signal() {
1079
- const depsContext = getSignalDepsContext();
1080
- if (depsContext) {
1081
- depsContext.push(signal);
1082
- }
1083
- return state;
1084
- }
1085
- signal.$isSignal = true;
1086
- signal.set = function (newState) {
1087
- if (newState === state) {
1088
- return;
1089
- }
1090
- state = newState;
1091
- const depCallbacks = Array.from(signal[depsKey]);
1092
- for (const fn of depCallbacks) {
1093
- // 回调中可能会对依赖做出修改,故需先缓存起来
1094
- fn();
1095
- }
1096
- };
1097
- //
1098
- // signal.toString = function () {
1099
- // return String(state)
1100
- // }
1101
- //
1102
- // signal.valueOf = function () {
1103
- // return state
1104
- // }
1105
- signal[depsKey] = new Set();
1106
- return signal;
1107
- }
1108
- function invokeDepFn(fn) {
1109
- const deps = [];
1110
- signalDepsStack.push(deps);
1111
- const data = fn();
1112
- signalDepsStack.pop();
1113
- return {
1114
- deps: Array.from(new Set(deps)),
1115
- data
1116
- };
1117
- }
1118
- function listen(model, deps, callback, isContinue) {
1119
- let isStop = false;
1120
- const nextListen = () => {
1121
- if (isStop) {
1122
- return;
1123
- }
1124
- isStop = true;
1125
- const { data: nextData, deps: nextDeps } = invokeDepFn(callback);
1126
- model.set(nextData);
1127
- if (typeof isContinue === 'function' && isContinue(nextData) === false) {
1128
- unListen();
1129
- return;
1130
- }
1131
- const changes = getArrayChanges(deps, nextDeps);
1132
- deps = deps.filter(i => {
1133
- const has = changes.remove.includes(i);
1134
- if (has) {
1135
- i[depsKey].delete(nextListen);
1136
- return false;
1137
- }
1138
- return true;
1139
- });
1140
- for (const s of changes.add) {
1141
- s[depsKey].add(nextListen);
1142
- }
1143
- deps.push(...changes.add);
1144
- isStop = false;
1145
- };
1146
- const unListen = () => {
1147
- for (const s of deps) {
1148
- s[depsKey].delete(nextListen);
1149
- }
1150
- };
1151
- for (const s of deps) {
1152
- s[depsKey].add(nextListen);
1153
- }
1154
- return unListen;
1155
- }
1156
- /**
1157
- * 使用派生值,Viewfly 会收集回调函数内同步执行时访问的 Signal,
1158
- * 并在你获取 useDerived 函数返回的 Signal 的值时,自动计算最新的值。
1159
- *
1160
- * @param callback
1161
- * @param isContinue 可选的停止函数,在每次值更新后调用,当返回值为 false 时,将不再监听依赖的变化
1162
- */
1163
- function createDerived(callback, isContinue) {
1164
- const { data, deps } = invokeDepFn(callback);
1165
- const signal = createSignal(data);
1166
- const component = getSetupContext(false);
1167
- const unListen = listen(signal, deps, callback, isContinue);
1168
- if (component) {
1169
- if (!component.unmountedCallbacks) {
1170
- component.unmountedCallbacks = [];
1171
- }
1172
- component.unmountedCallbacks.push(() => {
1173
- unListen();
1174
- });
1175
- }
1176
- return signal;
1177
- }
1178
- /* eslint-enable max-len*/
1179
- function watch(deps, callback) {
1180
- if (typeof deps === 'function' && !deps.$isSignal) {
1181
- deps = createDerived(deps);
1182
- }
1183
- const signals = Array.isArray(deps) ? deps : [deps];
1184
- let oldValues = signals.map(s => s());
1185
- let prevCleanup;
1186
- function effectCallback() {
1187
- if (typeof prevCleanup === 'function') {
1188
- prevCleanup();
1189
- }
1190
- const newValues = signals.map(s => s());
1191
- prevCleanup = Array.isArray(deps) ? callback(newValues, oldValues) : callback(newValues[0], oldValues[0]);
1192
- oldValues = newValues;
1193
- }
1194
- for (const dep of signals) {
1195
- dep[depsKey].add(effectCallback);
1196
- }
1197
- const component = getSetupContext(false);
1198
- let isClean = false;
1199
- const destroyFn = () => {
1200
- if (isClean) {
1201
- return;
1202
- }
1203
- isClean = true;
1204
- if (component === null || component === void 0 ? void 0 : component.unmountedCallbacks) {
1205
- const index = component.unmountedCallbacks.indexOf(destroyFn);
1206
- component.unmountedCallbacks.splice(index, 1);
1207
- }
1208
- for (const dep of signals) {
1209
- dep[depsKey].delete(effectCallback);
1210
- }
1211
- };
1212
- if (component) {
1213
- if (!component.unmountedCallbacks) {
1214
- component.unmountedCallbacks = [];
1215
- }
1216
- component.unmountedCallbacks.push(destroyFn);
1217
- }
1218
- return destroyFn;
1219
- }
1220
1050
  /**
1221
1051
  * 给组件添加注解
1222
1052
  * @param annotation
@@ -1266,10 +1096,21 @@ function Fragment(props) {
1266
1096
  };
1267
1097
  }
1268
1098
  function Context(props) {
1269
- const instance = getCurrentInstance();
1270
- instance.provide(props.providers);
1099
+ function createContextComponent(providers) {
1100
+ return withAnnotation({
1101
+ providers,
1102
+ }, () => {
1103
+ return () => {
1104
+ return props.children;
1105
+ };
1106
+ });
1107
+ }
1108
+ let contextComponent = createContextComponent(props.providers);
1109
+ onPropsChanged((newProps) => {
1110
+ contextComponent = createContextComponent(newProps.providers);
1111
+ });
1271
1112
  return () => {
1272
- return props.children;
1113
+ return jsx(contextComponent, {});
1273
1114
  };
1274
1115
  }
1275
1116
  function jsx(type, props, key) {
@@ -1293,9 +1134,13 @@ function withMemo(canUseMemo, render) {
1293
1134
  };
1294
1135
  }
1295
1136
 
1137
+ const ElementNamespaceMap = {
1138
+ svg: 'svg',
1139
+ math: 'mathml',
1140
+ };
1296
1141
  const componentViewCache = new WeakMap();
1297
1142
  const listenerReg = /^on[A-Z]/;
1298
- function createRenderer(component, nativeRenderer) {
1143
+ function createRenderer(component, nativeRenderer, namespace) {
1299
1144
  let isInit = true;
1300
1145
  return function render(host) {
1301
1146
  if (isInit) {
@@ -1308,7 +1153,7 @@ function createRenderer(component, nativeRenderer) {
1308
1153
  sibling: null,
1309
1154
  child: null,
1310
1155
  nativeNode: null,
1311
- isSvg: false
1156
+ namespace
1312
1157
  };
1313
1158
  componentRender(nativeRenderer, component, atom, {
1314
1159
  isParent: true,
@@ -1361,7 +1206,7 @@ function updateView(nativeRenderer, component, needMove) {
1361
1206
  function applyChanges(nativeRenderer, component, atom, context, needMove) {
1362
1207
  const diffAtom = atom.child;
1363
1208
  component.update(component.props, newTemplate => {
1364
- atom.child = createChildChain(newTemplate, atom.isSvg);
1209
+ atom.child = createChildChain(newTemplate, atom.namespace);
1365
1210
  diff(nativeRenderer, component, atom.child, diffAtom, context, needMove);
1366
1211
  const next = atom.sibling;
1367
1212
  if (next && next.jsxNode instanceof Component) {
@@ -1474,7 +1319,7 @@ function updateComponent(newAtom, reusedAtom, nativeRenderer, context) {
1474
1319
  newAtom.jsxNode = component;
1475
1320
  component.update(newProps, newTemplate => {
1476
1321
  if (newTemplate) {
1477
- newAtom.child = createChildChain(newTemplate, newAtom.isSvg);
1322
+ newAtom.child = createChildChain(newTemplate, newAtom.namespace);
1478
1323
  }
1479
1324
  if (newAtom.child) {
1480
1325
  diff(nativeRenderer, component, newAtom.child, reusedAtom.child, context, needMove || newAtom.index - offset !== reusedAtom.index);
@@ -1534,7 +1379,7 @@ function reuseElementChildrenView(nativeRenderer, atom, context, skipSubComponen
1534
1379
  }
1535
1380
  function cleanElementChildren(atom, nativeRenderer) {
1536
1381
  let child = atom.child;
1537
- nativeRenderer.cleanChildren(atom.nativeNode, atom.isSvg);
1382
+ nativeRenderer.cleanChildren(atom.nativeNode, atom.namespace);
1538
1383
  while (child) {
1539
1384
  cleanView(nativeRenderer, child, false);
1540
1385
  child = child.sibling;
@@ -1543,7 +1388,7 @@ function cleanElementChildren(atom, nativeRenderer) {
1543
1388
  function cleanView(nativeRenderer, atom, needClean) {
1544
1389
  if (atom.nativeNode) {
1545
1390
  if (needClean) {
1546
- nativeRenderer.remove(atom.nativeNode, atom.isSvg);
1391
+ nativeRenderer.remove(atom.nativeNode, atom.namespace);
1547
1392
  needClean = false;
1548
1393
  }
1549
1394
  if (atom.type === ElementAtomType) {
@@ -1565,7 +1410,7 @@ function cleanView(nativeRenderer, atom, needClean) {
1565
1410
  }
1566
1411
  function componentRender(nativeRenderer, component, from, context) {
1567
1412
  component.render((template, portalHost) => {
1568
- from.child = createChildChain(template, from.isSvg);
1413
+ from.child = createChildChain(template, from.namespace);
1569
1414
  context = portalHost ? { isParent: true, host: portalHost, rootHost: portalHost } : context;
1570
1415
  componentViewCache.set(component, Object.assign({ atom: from }, context));
1571
1416
  let child = from.child;
@@ -1575,7 +1420,7 @@ function componentRender(nativeRenderer, component, from, context) {
1575
1420
  }
1576
1421
  });
1577
1422
  }
1578
- function createChainByJSXNode(type, jsxNode, nodeType, prevAtom, isSvg, key) {
1423
+ function createChainByJSXNode(type, jsxNode, nodeType, prevAtom, namespace, key) {
1579
1424
  const atom = {
1580
1425
  type,
1581
1426
  index: prevAtom.index + 1,
@@ -1583,88 +1428,88 @@ function createChainByJSXNode(type, jsxNode, nodeType, prevAtom, isSvg, key) {
1583
1428
  sibling: null,
1584
1429
  child: null,
1585
1430
  nativeNode: null,
1586
- isSvg,
1431
+ namespace,
1587
1432
  nodeType,
1588
1433
  key
1589
1434
  };
1590
1435
  prevAtom.sibling = atom;
1591
1436
  return atom;
1592
1437
  }
1593
- function createChainByNode(jsxNode, prevAtom, isSvg) {
1438
+ function createChainByNode(jsxNode, prevAtom, elementNamespace) {
1594
1439
  const type = typeof jsxNode;
1595
1440
  if (jsxNode !== null && type !== 'undefined' && type !== 'boolean') {
1596
1441
  if (typeof jsxNode === 'string') {
1597
- return createChainByJSXNode(TextAtomType, jsxNode, jsxNode, prevAtom, isSvg);
1442
+ return createChainByJSXNode(TextAtomType, jsxNode, jsxNode, prevAtom, elementNamespace);
1598
1443
  }
1599
1444
  if (Array.isArray(jsxNode)) {
1600
- return createChainByChildren(jsxNode, prevAtom, isSvg);
1445
+ return createChainByChildren(jsxNode, prevAtom, elementNamespace);
1601
1446
  }
1602
1447
  if (type === 'object') {
1603
1448
  const nodeType = typeof jsxNode.type;
1604
1449
  if (nodeType === 'string') {
1605
- return createChainByJSXNode(ElementAtomType, jsxNode, jsxNode.type, prevAtom, isSvg || jsxNode.type === 'svg', jsxNode.key);
1450
+ return createChainByJSXNode(ElementAtomType, jsxNode, jsxNode.type, prevAtom, elementNamespace || ElementNamespaceMap[jsxNode.type], jsxNode.key);
1606
1451
  }
1607
1452
  else if (nodeType === 'function') {
1608
- return createChainByJSXNode(ComponentAtomType, jsxNode, jsxNode.type, prevAtom, isSvg, jsxNode.key);
1453
+ return createChainByJSXNode(ComponentAtomType, jsxNode, jsxNode.type, prevAtom, ElementNamespaceMap[jsxNode.type], jsxNode.key);
1609
1454
  }
1610
1455
  }
1611
1456
  const text = String(jsxNode);
1612
- return createChainByJSXNode(TextAtomType, text, text, prevAtom, isSvg);
1457
+ return createChainByJSXNode(TextAtomType, text, text, prevAtom, ElementNamespaceMap[jsxNode.type]);
1613
1458
  }
1614
1459
  return prevAtom;
1615
1460
  }
1616
- function createChainByChildren(children, prevAtom, isSvg) {
1461
+ function createChainByChildren(children, prevAtom, elementNamespace) {
1617
1462
  for (const item of children) {
1618
- prevAtom = createChainByNode(item, prevAtom, isSvg);
1463
+ prevAtom = createChainByNode(item, prevAtom, elementNamespace);
1619
1464
  }
1620
1465
  return prevAtom;
1621
1466
  }
1622
- function createChildChain(template, isSvg) {
1467
+ function createChildChain(template, namespace) {
1623
1468
  const beforeAtom = { sibling: null, index: -1 };
1624
- createChainByNode(template, beforeAtom, isSvg);
1469
+ createChainByNode(template, beforeAtom, namespace);
1625
1470
  return beforeAtom.sibling;
1626
1471
  }
1627
1472
  function insertNode(nativeRenderer, atom, context) {
1628
1473
  if (context.isParent) {
1629
1474
  if (context.host === context.rootHost) {
1630
- nativeRenderer.appendChild(context.host, atom.nativeNode, atom.isSvg);
1475
+ nativeRenderer.appendChild(context.host, atom.nativeNode, atom.namespace);
1631
1476
  }
1632
1477
  else {
1633
- nativeRenderer.prependChild(context.host, atom.nativeNode, atom.isSvg);
1478
+ nativeRenderer.prependChild(context.host, atom.nativeNode, atom.namespace);
1634
1479
  }
1635
1480
  }
1636
1481
  else {
1637
- nativeRenderer.insertAfter(atom.nativeNode, context.host, atom.isSvg);
1482
+ nativeRenderer.insertAfter(atom.nativeNode, context.host, atom.namespace);
1638
1483
  }
1639
1484
  }
1640
1485
  function createElement(nativeRenderer, atom, parentComponent, context) {
1641
- const { isSvg, jsxNode } = atom;
1642
- const nativeNode = nativeRenderer.createElement(jsxNode.type, isSvg);
1486
+ const { namespace, jsxNode } = atom;
1487
+ const nativeNode = nativeRenderer.createElement(jsxNode.type, namespace);
1643
1488
  const props = jsxNode.props;
1644
1489
  let bindingRefs;
1645
1490
  for (const key in props) {
1646
1491
  if (key === 'children') {
1647
- atom.child = createChildChain(jsxNode.props.children, isSvg);
1492
+ atom.child = createChildChain(jsxNode.props.children, namespace);
1648
1493
  continue;
1649
1494
  }
1650
1495
  if (key === 'class') {
1651
1496
  const className = classToString(props[key]);
1652
1497
  if (className) {
1653
- nativeRenderer.setClass(nativeNode, className, isSvg);
1498
+ nativeRenderer.setClass(nativeNode, className, namespace);
1654
1499
  }
1655
1500
  continue;
1656
1501
  }
1657
1502
  if (key === 'style') {
1658
1503
  const style = styleToObject(props.style);
1659
1504
  for (const key in style) {
1660
- nativeRenderer.setStyle(nativeNode, key, style[key], isSvg);
1505
+ nativeRenderer.setStyle(nativeNode, key, style[key], namespace);
1661
1506
  }
1662
1507
  continue;
1663
1508
  }
1664
1509
  if (listenerReg.test(key)) {
1665
1510
  const listener = props[key];
1666
1511
  if (typeof listener === 'function') {
1667
- nativeRenderer.listen(nativeNode, key, listener, isSvg);
1512
+ nativeRenderer.listen(nativeNode, key, listener, namespace);
1668
1513
  }
1669
1514
  continue;
1670
1515
  }
@@ -1672,7 +1517,7 @@ function createElement(nativeRenderer, atom, parentComponent, context) {
1672
1517
  bindingRefs = props[key];
1673
1518
  continue;
1674
1519
  }
1675
- nativeRenderer.setProperty(nativeNode, key, props[key], isSvg);
1520
+ nativeRenderer.setProperty(nativeNode, key, props[key], namespace);
1676
1521
  }
1677
1522
  atom.nativeNode = nativeNode;
1678
1523
  insertNode(nativeRenderer, atom, context);
@@ -1686,7 +1531,7 @@ function createElement(nativeRenderer, atom, parentComponent, context) {
1686
1531
  applyRefs(bindingRefs, nativeNode, true);
1687
1532
  }
1688
1533
  function createTextNode(nativeRenderer, atom, context) {
1689
- const nativeNode = nativeRenderer.createTextNode(atom.jsxNode, atom.isSvg);
1534
+ const nativeNode = nativeRenderer.createTextNode(atom.jsxNode, atom.namespace);
1690
1535
  atom.nativeNode = nativeNode;
1691
1536
  insertNode(nativeRenderer, atom, context);
1692
1537
  context.host = nativeNode;
@@ -1694,7 +1539,7 @@ function createTextNode(nativeRenderer, atom, context) {
1694
1539
  }
1695
1540
  function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComponent, context) {
1696
1541
  const newVNode = newAtom.jsxNode;
1697
- const isSvg = newAtom.isSvg;
1542
+ const isSvg = newAtom.namespace;
1698
1543
  const nativeNode = newAtom.nativeNode;
1699
1544
  const oldVNode = oldAtom.jsxNode;
1700
1545
  if (newVNode === oldVNode) {
@@ -1741,6 +1586,9 @@ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComp
1741
1586
  if (!newAtom.child) {
1742
1587
  cleanElementChildren(oldAtom, nativeRenderer);
1743
1588
  }
1589
+ else if (!oldAtom.child) {
1590
+ buildElementChildren(newAtom, nativeRenderer, parentComponent, context);
1591
+ }
1744
1592
  else {
1745
1593
  diff(nativeRenderer, parentComponent, newAtom.child, oldAtom.child, context, false);
1746
1594
  }
@@ -1841,6 +1689,133 @@ class RootComponent extends Component {
1841
1689
  }
1842
1690
  }
1843
1691
 
1692
+ /**
1693
+ * 组件状态管理器
1694
+ * @param state 初始状态
1695
+ * @example
1696
+ * ```tsx
1697
+ * function App() {
1698
+ * // 初始化状态
1699
+ * const state = createSignal(1)
1700
+ *
1701
+ * return () => {
1702
+ * <div>
1703
+ * <div>当前值为:{state()}</div>
1704
+ * <div>
1705
+ * <button type="button" onClick={() => {
1706
+ * // 当点击时更新状态
1707
+ * state.set(state() + 1)
1708
+ * }
1709
+ * }>updateState</button>
1710
+ * </div>
1711
+ * </div>
1712
+ * }
1713
+ * }
1714
+ */
1715
+ function createSignal(state) {
1716
+ const subscribers = new Set();
1717
+ function signal() {
1718
+ const listener = getCurrentListener();
1719
+ if (listener) {
1720
+ listener.destroyCallbacks.push(() => {
1721
+ subscribers.delete(listener);
1722
+ });
1723
+ subscribers.add(listener);
1724
+ }
1725
+ return state;
1726
+ }
1727
+ signal.set = function (newValue) {
1728
+ if (newValue === state) {
1729
+ return;
1730
+ }
1731
+ state = newValue;
1732
+ const listeners = Array.from(subscribers);
1733
+ listeners.forEach(listener => listener.effect());
1734
+ };
1735
+ return signal;
1736
+ }
1737
+ /**
1738
+ * 使用派生值,Viewfly 会收集回调函数内同步执行时访问的 Signal,
1739
+ * 并在你获取 createDerived 函数返回的 Signal 的值时,自动计算最新的值。
1740
+ *
1741
+ * @param fn
1742
+ * @param isContinue 可选的停止函数,在每次值更新后调用,当返回值为 false 时,将不再监听依赖的变化
1743
+ */
1744
+ function computed(fn, isContinue) {
1745
+ let isStop = false;
1746
+ function canListen(value) {
1747
+ if (isContinue) {
1748
+ const b = isContinue(value);
1749
+ if (b === false) {
1750
+ listener.destroy();
1751
+ return false;
1752
+ }
1753
+ }
1754
+ return true;
1755
+ }
1756
+ const listener = new Listener(() => {
1757
+ if (isStop) {
1758
+ return;
1759
+ }
1760
+ isStop = true;
1761
+ listener.destroy();
1762
+ pushListener(listener);
1763
+ const value = fn();
1764
+ popListener();
1765
+ signal.set(value);
1766
+ canListen(value);
1767
+ isStop = false;
1768
+ });
1769
+ pushListener(listener);
1770
+ const value = fn();
1771
+ const signal = createSignal(value);
1772
+ popListener();
1773
+ isStop = false;
1774
+ if (canListen(value)) {
1775
+ registryComponentDestroyCallback(() => listener.destroy());
1776
+ }
1777
+ return signal;
1778
+ }
1779
+ const createDerived = computed;
1780
+ /* eslint-enable max-len*/
1781
+ function watch(deps, callback) {
1782
+ let prevFn;
1783
+ const isArray = Array.isArray(deps);
1784
+ const effect = new Listener(function () {
1785
+ if (prevFn) {
1786
+ prevFn();
1787
+ }
1788
+ const newValue = isArray ? deps.map(fn => fn()) : deps();
1789
+ prevFn = callback(newValue, oldValue);
1790
+ oldValue = newValue;
1791
+ });
1792
+ pushListener(effect);
1793
+ let oldValue = isArray ? deps.map(fn => fn()) : deps();
1794
+ popListener();
1795
+ let isUnWatch = false;
1796
+ function unWatch() {
1797
+ if (isUnWatch) {
1798
+ return;
1799
+ }
1800
+ isUnWatch = true;
1801
+ if (prevFn) {
1802
+ prevFn();
1803
+ }
1804
+ effect.destroy();
1805
+ }
1806
+ registryComponentDestroyCallback(unWatch);
1807
+ return unWatch;
1808
+ }
1809
+ function registryComponentDestroyCallback(fn) {
1810
+ const component = getSetupContext(false);
1811
+ if (component) {
1812
+ if (!component.unmountedCallbacks) {
1813
+ component.unmountedCallbacks = [];
1814
+ }
1815
+ component.unmountedCallbacks.push(fn);
1816
+ }
1817
+ }
1818
+
1844
1819
  const viewflyErrorFn = makeError('Viewfly');
1845
1820
  function viewfly(config) {
1846
1821
  const { context, nativeRenderer, autoUpdate, root } = Object.assign({ autoUpdate: true }, config);
@@ -1864,7 +1839,7 @@ function viewfly(config) {
1864
1839
  render(appHost);
1865
1840
  });
1866
1841
  });
1867
- const render = createRenderer(rootComponent, nativeRenderer);
1842
+ const render = createRenderer(rootComponent, nativeRenderer, config.elementNamespace);
1868
1843
  let isStarted = false;
1869
1844
  let task = null;
1870
1845
  function nextTick(callback) {
@@ -1928,4 +1903,4 @@ function viewfly(config) {
1928
1903
  return app;
1929
1904
  }
1930
1905
 
1931
- export { Component, Context, DynamicRef, ForwardRef, Fragment, Inject, InjectFlags, Injectable, InjectionToken, Injector, JSXNodeFactory, NativeRenderer, NullInjector, Optional, Prop, ReflectiveInjector, RootComponent, Scope, Self, SkipSelf, StaticRef, THROW_IF_NOT_FOUND, Type, createDerived, createDynamicRef, createRef, createRenderer, createSignal, forwardRef, getCurrentInstance, inject, jsx, jsxs, makeError, normalizeProvider, onMounted, onPropsChanged, onUnmounted, onUpdated, viewfly, watch, withAnnotation, withMemo };
1906
+ export { Component, Context, DynamicRef, ElementNamespaceMap, ForwardRef, Fragment, Inject, InjectFlags, Injectable, InjectionToken, Injector, JSXNodeFactory, NativeRenderer, NullInjector, Optional, Prop, ReflectiveInjector, RootComponent, Scope, Self, SkipSelf, StaticRef, THROW_IF_NOT_FOUND, Type, computed, createDerived, createDynamicRef, createRef, createRenderer, createSignal, forwardRef, getCurrentInstance, getSetupContext, inject, jsx, jsxs, makeError, normalizeProvider, onMounted, onPropsChanged, onUnmounted, onUpdated, viewfly, watch, withAnnotation, withMemo };