@wcstack/state 1.21.4 → 1.21.5

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.
package/dist/index.esm.js CHANGED
@@ -5049,14 +5049,6 @@ function isPhysicallyAfter(lastNode, firstNode) {
5049
5049
  return (position & Node.DOCUMENT_POSITION_FOLLOWING) !== 0
5050
5050
  && (position & Node.DOCUMENT_POSITION_DISCONNECTED) === 0;
5051
5051
  }
5052
- function getContent(node, listIndex) {
5053
- let contentByListIndex = contentByListIndexByNode.get(node);
5054
- if (typeof contentByListIndex === 'undefined') {
5055
- return null;
5056
- }
5057
- const content = contentByListIndex.get(listIndex);
5058
- return typeof content === 'undefined' ? null : content;
5059
- }
5060
5052
  function setContent(node, listIndex, content) {
5061
5053
  let contentByListIndex = contentByListIndexByNode.get(node);
5062
5054
  if (typeof contentByListIndex === 'undefined') {
@@ -5100,22 +5092,35 @@ function applyChangeToFor(bindingInfo, context, newValue) {
5100
5092
  // teardown(listener 解除・アドレス台帳・loopContext 掃除)を丸ごと省略して
5101
5093
  // ノードごと GC に任せる(tryDestroy)。プール行きの分だけ従来どおり解体する
5102
5094
  // (プール行は binding が生存し続けるため address キャッシュのクリアが必須)。
5095
+ // content 台帳の WeakMap ビルトインは V8 プロファイルで本関数の self に計上される
5096
+ // ホットスポット: 外側の node→map 解決はループ外に持ち上げ、fullDelete(旧全行が
5097
+ // deleteIndexSet に載る=台帳の全エントリが消える)では per-index delete を廃して
5098
+ // 台帳ごと 1 回で手放す。
5099
+ let contentMap = contentByListIndexByNode.get(bindingInfo.node);
5103
5100
  let poolBudget = fullDelete
5104
5101
  ? maxPooledContents - getPooledContents(bindingInfo).length
5105
5102
  : Number.POSITIVE_INFINITY;
5106
- for (const deleteIndex of diff.deleteIndexSet) {
5107
- const content = getContent(bindingInfo.node, deleteIndex);
5108
- if (content !== null) {
5109
- if (poolBudget <= 0 && content.tryDestroy()) {
5110
- deleteContentByNode(bindingInfo.node, content);
5111
- }
5112
- else {
5113
- deactivateContent(content);
5114
- content.unmount();
5115
- setPooledContent(bindingInfo, content);
5116
- poolBudget -= 1;
5103
+ if (typeof contentMap !== 'undefined') {
5104
+ for (const deleteIndex of diff.deleteIndexSet) {
5105
+ const content = contentMap.get(deleteIndex);
5106
+ if (typeof content !== 'undefined') {
5107
+ if (poolBudget <= 0 && content.tryDestroy()) {
5108
+ deleteContentByNode(bindingInfo.node, content);
5109
+ }
5110
+ else {
5111
+ deactivateContent(content);
5112
+ content.unmount();
5113
+ setPooledContent(bindingInfo, content);
5114
+ poolBudget -= 1;
5115
+ }
5116
+ if (!fullDelete) {
5117
+ contentMap.delete(deleteIndex);
5118
+ }
5117
5119
  }
5118
- setContent(bindingInfo.node, deleteIndex, null);
5120
+ }
5121
+ if (fullDelete) {
5122
+ contentByListIndexByNode.delete(bindingInfo.node);
5123
+ contentMap = undefined;
5119
5124
  }
5120
5125
  }
5121
5126
  let lastNode = bindingInfo.node;
@@ -5136,14 +5141,16 @@ function applyChangeToFor(bindingInfo, context, newValue) {
5136
5141
  }
5137
5142
  const ssrMode = inSsr();
5138
5143
  const uuid = bindingInfo.uuid ?? '';
5144
+ // 追加行ごとの WeakMap 解決を避けるためプール配列も 1 回だけ引く(プールの配列
5145
+ // 実体は setPooledContent が一度作ったら不変なので、delete ループ後の参照で安定)
5146
+ const pooledContents = pooledContentsByNode.get(bindingInfo.node);
5139
5147
  for (const index of diff.newIndexes) {
5140
5148
  let content;
5141
5149
  // add
5142
5150
  if (diff.addIndexSet.has(index)) {
5143
5151
  const stateAddress = createStateAddress(elementPathInfo, index);
5144
5152
  loopContextStack.createLoopContext(stateAddress, (loopContext) => {
5145
- const pooledContents = getPooledContents(bindingInfo);
5146
- content = pooledContents.pop();
5153
+ content = typeof pooledContents !== 'undefined' ? pooledContents.pop() : undefined;
5147
5154
  if (typeof content === 'undefined') {
5148
5155
  content = createContent(bindingInfo);
5149
5156
  }
@@ -5182,7 +5189,8 @@ function applyChangeToFor(bindingInfo, context, newValue) {
5182
5189
  }
5183
5190
  }
5184
5191
  else {
5185
- content = getContent(bindingInfo.node, index);
5192
+ // getContent 相当(undefined→null 正規化は後段の raiseError 判定が null 比較のため維持)
5193
+ content = (typeof contentMap !== 'undefined' ? contentMap.get(index) ?? null : null);
5186
5194
  if (diff.changeIndexSet.has(index)) {
5187
5195
  // change
5188
5196
  const indexBindings = getIndexBindingsByContent(content);
@@ -5206,7 +5214,11 @@ function applyChangeToFor(bindingInfo, context, newValue) {
5206
5214
  }
5207
5215
  }
5208
5216
  lastNode = content.lastNode || lastNode;
5209
- setContent(bindingInfo.node, index, content);
5217
+ if (typeof contentMap === 'undefined') {
5218
+ contentMap = new WeakMap();
5219
+ contentByListIndexByNode.set(bindingInfo.node, contentMap);
5220
+ }
5221
+ contentMap.set(index, content);
5210
5222
  }
5211
5223
  lastNodeByNode.set(bindingInfo.node, lastNode);
5212
5224
  if (fragment !== null) {
@@ -6371,7 +6383,7 @@ async function buildBindings(root) {
6371
6383
  }
6372
6384
  }
6373
6385
 
6374
- var version = "1.21.4";
6386
+ var version = "1.21.5";
6375
6387
  var pkg = {
6376
6388
  version: version};
6377
6389