@graphrefly/graphrefly 0.22.0 → 0.23.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 (78) hide show
  1. package/dist/{chunk-RHI3GHZW.js → chunk-263BEJJO.js} +3 -3
  2. package/dist/{chunk-44HD4BTA.js → chunk-2GQLMQVJ.js} +3 -3
  3. package/dist/chunk-32N5A454.js +36 -0
  4. package/dist/chunk-32N5A454.js.map +1 -0
  5. package/dist/{chunk-IR3KMOLX.js → chunk-CWYPA63G.js} +3 -383
  6. package/dist/chunk-CWYPA63G.js.map +1 -0
  7. package/dist/{chunk-TH6COGOP.js → chunk-HVBX5KIW.js} +2 -2
  8. package/dist/chunk-JFONSPNF.js +391 -0
  9. package/dist/chunk-JFONSPNF.js.map +1 -0
  10. package/dist/{chunk-QA3RP5NH.js → chunk-NZMBRXQV.js} +101 -5
  11. package/dist/chunk-NZMBRXQV.js.map +1 -0
  12. package/dist/{chunk-MQBQOFDS.js → chunk-PNUZM7PC.js} +12 -31
  13. package/dist/chunk-PNUZM7PC.js.map +1 -0
  14. package/dist/{chunk-EQUZ5NLD.js → chunk-PX6PDUJ5.js} +11 -16
  15. package/dist/chunk-PX6PDUJ5.js.map +1 -0
  16. package/dist/{chunk-NXC35KC5.js → chunk-XRFJJ2IU.js} +3 -3
  17. package/dist/{chunk-BLD3IFYF.js → chunk-XTLYW4FR.js} +9 -7
  18. package/dist/{chunk-BLD3IFYF.js.map → chunk-XTLYW4FR.js.map} +1 -1
  19. package/dist/compat/nestjs/index.cjs +100 -4
  20. package/dist/compat/nestjs/index.cjs.map +1 -1
  21. package/dist/compat/nestjs/index.d.cts +6 -6
  22. package/dist/compat/nestjs/index.d.ts +6 -6
  23. package/dist/compat/nestjs/index.js +9 -7
  24. package/dist/core/index.cjs +100 -4
  25. package/dist/core/index.cjs.map +1 -1
  26. package/dist/core/index.d.cts +3 -3
  27. package/dist/core/index.d.ts +3 -3
  28. package/dist/core/index.js +3 -3
  29. package/dist/extra/index.cjs +100 -4
  30. package/dist/extra/index.cjs.map +1 -1
  31. package/dist/extra/index.d.cts +4 -4
  32. package/dist/extra/index.d.ts +4 -4
  33. package/dist/extra/index.js +9 -7
  34. package/dist/graph/index.cjs +100 -4
  35. package/dist/graph/index.cjs.map +1 -1
  36. package/dist/graph/index.d.cts +5 -5
  37. package/dist/graph/index.d.ts +5 -5
  38. package/dist/graph/index.js +4 -4
  39. package/dist/{graph-ab1yPwIB.d.cts → graph-BtdSRHUc.d.cts} +3 -3
  40. package/dist/{graph-DFr0diXB.d.ts → graph-CEO2FkLY.d.ts} +3 -3
  41. package/dist/{index-BvWfZCTt.d.cts → index-B0tfuXwV.d.cts} +3 -3
  42. package/dist/{index-Dy04P4W3.d.cts → index-BFGjXbiP.d.cts} +2 -2
  43. package/dist/{index-DrJq9B1T.d.cts → index-BPlWVAKY.d.cts} +3 -3
  44. package/dist/{index-C9z6rU9P.d.cts → index-BUj3ASVe.d.cts} +25 -7
  45. package/dist/{index-DLE1Sp-L.d.cts → index-C59uSJAH.d.cts} +2 -2
  46. package/dist/{index-DsGxLfwL.d.ts → index-CkElcUY6.d.ts} +2 -2
  47. package/dist/{index-HdJx_BjO.d.ts → index-DSPc5rkv.d.ts} +25 -7
  48. package/dist/{index-D36MAQ3f.d.ts → index-DgscL7v0.d.ts} +3 -3
  49. package/dist/{index-BbYZma8G.d.ts → index-RXN94sHK.d.ts} +3 -3
  50. package/dist/{index-BHm3Ba5q.d.ts → index-jEtF4N7L.d.ts} +2 -2
  51. package/dist/index.cjs +109 -14
  52. package/dist/index.cjs.map +1 -1
  53. package/dist/index.d.cts +15 -15
  54. package/dist/index.d.ts +15 -15
  55. package/dist/index.js +26 -22
  56. package/dist/index.js.map +1 -1
  57. package/dist/{meta-n3FoVWML.d.ts → meta-3QjzotRv.d.ts} +1 -1
  58. package/dist/{meta--fr9sxRM.d.cts → meta-B-Lbs4-O.d.cts} +1 -1
  59. package/dist/{node-C5UD5MGq.d.cts → node-C7PD3sn9.d.cts} +42 -0
  60. package/dist/{node-C5UD5MGq.d.ts → node-C7PD3sn9.d.ts} +42 -0
  61. package/dist/{observable-CQRBtEbq.d.ts → observable-EyO-moQY.d.ts} +1 -1
  62. package/dist/{observable-DWydVy5b.d.cts → observable-axpzv1K2.d.cts} +1 -1
  63. package/dist/patterns/reactive-layout/index.cjs +214 -117
  64. package/dist/patterns/reactive-layout/index.cjs.map +1 -1
  65. package/dist/patterns/reactive-layout/index.d.cts +5 -5
  66. package/dist/patterns/reactive-layout/index.d.ts +5 -5
  67. package/dist/patterns/reactive-layout/index.js +6 -4
  68. package/dist/{storage-C9fZfMfM.d.ts → storage-CHT5WE9m.d.ts} +1 -1
  69. package/dist/{storage-Bew05Xy6.d.cts → storage-DIgAr7M_.d.cts} +1 -1
  70. package/package.json +2 -1
  71. package/dist/chunk-EQUZ5NLD.js.map +0 -1
  72. package/dist/chunk-IR3KMOLX.js.map +0 -1
  73. package/dist/chunk-MQBQOFDS.js.map +0 -1
  74. package/dist/chunk-QA3RP5NH.js.map +0 -1
  75. /package/dist/{chunk-RHI3GHZW.js.map → chunk-263BEJJO.js.map} +0 -0
  76. /package/dist/{chunk-44HD4BTA.js.map → chunk-2GQLMQVJ.js.map} +0 -0
  77. /package/dist/{chunk-TH6COGOP.js.map → chunk-HVBX5KIW.js.map} +0 -0
  78. /package/dist/{chunk-NXC35KC5.js.map → chunk-XRFJJ2IU.js.map} +0 -0
@@ -1,3 +1,3 @@
1
- export { A as Actor, C as COMPLETE, c as COMPLETE_MSG, d as COMPLETE_ONLY_BATCH, D as DATA, e as DEFAULT_ACTOR, f as DIRTY, g as DIRTY_MSG, h as DIRTY_ONLY_BATCH, i as DepRecord, E as ERROR, F as FnCtx, G as GlobalInspectorEvent, j as GlobalInspectorHook, k as GraphReFlyConfig, l as GuardAction, m as GuardDenied, n as GuardDeniedDetails, H as HashFn, I as INVALIDATE, o as INVALIDATE_MSG, p as INVALIDATE_ONLY_BATCH, M as Message, q as MessageContext, r as MessageTypeRegistration, s as MessageTypeRegistrationInput, t as Messages, N as Node, b as NodeActions, u as NodeCtx, v as NodeDescribeKind, w as NodeFn, x as NodeFnCleanup, y as NodeGuard, z as NodeImpl, B as NodeInspectorHook, J as NodeInspectorHookEvent, a as NodeOptions, K as NodeSink, L as NodeStatus, O as NodeTransportOptions, P as NodeVersionInfo, Q as OnMessageHandler, R as OnSubscribeHandler, S as PAUSE, T as PolicyAllow, U as PolicyDeny, V as PolicyRuleData, W as RESOLVED, X as RESOLVED_MSG, Y as RESOLVED_ONLY_BATCH, Z as RESUME, _ as START, $ as START_MSG, a0 as SubscribeContext, a1 as TEARDOWN, a2 as TEARDOWN_MSG, a3 as TEARDOWN_ONLY_BATCH, a4 as V0, a5 as V1, a6 as VersioningLevel, a7 as VersioningOptions, a8 as accessHintForGuard, a9 as advanceVersion, aa as configure, ab as createVersioning, ac as defaultConfig, ad as defaultHash, ae as isV1, af as node, ag as normalizeActor, ah as policy, ai as policyFromRules, aj as registerBuiltins } from '../node-C5UD5MGq.cjs';
2
- export { A as AutoTrackOptions, D as DerivedFn, a as DynamicFn, E as EffectFn, P as PipeOperator, b as ProducerFn, T as TrackFn, c as autoTrackNode, d as batch, e as derived, f as downWithBatch, g as dynamicNode, h as effect, j as isBatching, m as monotonicNs, p as pipe, k as producer, s as state, w as wallClockNs } from '../index-C9z6rU9P.cjs';
3
- export { D as DescribeDetail, a as DescribeField, b as DescribeNodeOutput, r as resolveDescribeFields } from '../meta--fr9sxRM.cjs';
1
+ export { A as Actor, C as COMPLETE, c as COMPLETE_MSG, d as COMPLETE_ONLY_BATCH, D as DATA, e as DEFAULT_ACTOR, f as DIRTY, g as DIRTY_MSG, h as DIRTY_ONLY_BATCH, i as DepRecord, E as ERROR, F as FnCtx, G as GlobalInspectorEvent, j as GlobalInspectorHook, k as GraphReFlyConfig, l as GuardAction, m as GuardDenied, n as GuardDeniedDetails, H as HashFn, I as INVALIDATE, o as INVALIDATE_MSG, p as INVALIDATE_ONLY_BATCH, M as Message, q as MessageContext, r as MessageTypeRegistration, s as MessageTypeRegistrationInput, t as Messages, N as Node, b as NodeActions, u as NodeCtx, v as NodeDescribeKind, w as NodeFn, x as NodeFnCleanup, y as NodeGuard, z as NodeImpl, B as NodeInspectorHook, J as NodeInspectorHookEvent, a as NodeOptions, K as NodeSink, L as NodeStatus, O as NodeTransportOptions, P as NodeVersionInfo, Q as OnMessageHandler, R as OnSubscribeHandler, S as PAUSE, T as PolicyAllow, U as PolicyDeny, V as PolicyRuleData, W as RESOLVED, X as RESOLVED_MSG, Y as RESOLVED_ONLY_BATCH, Z as RESUME, _ as START, $ as START_MSG, a0 as SubscribeContext, a1 as TEARDOWN, a2 as TEARDOWN_MSG, a3 as TEARDOWN_ONLY_BATCH, a4 as V0, a5 as V1, a6 as VersioningLevel, a7 as VersioningOptions, a8 as accessHintForGuard, a9 as advanceVersion, aa as configure, ab as createVersioning, ac as defaultConfig, ad as defaultHash, ae as isV1, af as node, ag as normalizeActor, ah as policy, ai as policyFromRules, aj as registerBuiltins } from '../node-C7PD3sn9.cjs';
2
+ export { A as AutoTrackOptions, D as DerivedFn, a as DynamicFn, E as EffectFn, P as PipeOperator, b as ProducerFn, T as TrackFn, c as autoTrackNode, d as batch, e as derived, f as downWithBatch, g as dynamicNode, h as effect, j as isBatching, m as monotonicNs, p as pipe, k as producer, s as state, w as wallClockNs } from '../index-BUj3ASVe.cjs';
3
+ export { D as DescribeDetail, a as DescribeField, b as DescribeNodeOutput, r as resolveDescribeFields } from '../meta-B-Lbs4-O.cjs';
@@ -1,3 +1,3 @@
1
- export { A as Actor, C as COMPLETE, c as COMPLETE_MSG, d as COMPLETE_ONLY_BATCH, D as DATA, e as DEFAULT_ACTOR, f as DIRTY, g as DIRTY_MSG, h as DIRTY_ONLY_BATCH, i as DepRecord, E as ERROR, F as FnCtx, G as GlobalInspectorEvent, j as GlobalInspectorHook, k as GraphReFlyConfig, l as GuardAction, m as GuardDenied, n as GuardDeniedDetails, H as HashFn, I as INVALIDATE, o as INVALIDATE_MSG, p as INVALIDATE_ONLY_BATCH, M as Message, q as MessageContext, r as MessageTypeRegistration, s as MessageTypeRegistrationInput, t as Messages, N as Node, b as NodeActions, u as NodeCtx, v as NodeDescribeKind, w as NodeFn, x as NodeFnCleanup, y as NodeGuard, z as NodeImpl, B as NodeInspectorHook, J as NodeInspectorHookEvent, a as NodeOptions, K as NodeSink, L as NodeStatus, O as NodeTransportOptions, P as NodeVersionInfo, Q as OnMessageHandler, R as OnSubscribeHandler, S as PAUSE, T as PolicyAllow, U as PolicyDeny, V as PolicyRuleData, W as RESOLVED, X as RESOLVED_MSG, Y as RESOLVED_ONLY_BATCH, Z as RESUME, _ as START, $ as START_MSG, a0 as SubscribeContext, a1 as TEARDOWN, a2 as TEARDOWN_MSG, a3 as TEARDOWN_ONLY_BATCH, a4 as V0, a5 as V1, a6 as VersioningLevel, a7 as VersioningOptions, a8 as accessHintForGuard, a9 as advanceVersion, aa as configure, ab as createVersioning, ac as defaultConfig, ad as defaultHash, ae as isV1, af as node, ag as normalizeActor, ah as policy, ai as policyFromRules, aj as registerBuiltins } from '../node-C5UD5MGq.js';
2
- export { A as AutoTrackOptions, D as DerivedFn, a as DynamicFn, E as EffectFn, P as PipeOperator, b as ProducerFn, T as TrackFn, c as autoTrackNode, d as batch, e as derived, f as downWithBatch, g as dynamicNode, h as effect, j as isBatching, m as monotonicNs, p as pipe, k as producer, s as state, w as wallClockNs } from '../index-HdJx_BjO.js';
3
- export { D as DescribeDetail, a as DescribeField, b as DescribeNodeOutput, r as resolveDescribeFields } from '../meta-n3FoVWML.js';
1
+ export { A as Actor, C as COMPLETE, c as COMPLETE_MSG, d as COMPLETE_ONLY_BATCH, D as DATA, e as DEFAULT_ACTOR, f as DIRTY, g as DIRTY_MSG, h as DIRTY_ONLY_BATCH, i as DepRecord, E as ERROR, F as FnCtx, G as GlobalInspectorEvent, j as GlobalInspectorHook, k as GraphReFlyConfig, l as GuardAction, m as GuardDenied, n as GuardDeniedDetails, H as HashFn, I as INVALIDATE, o as INVALIDATE_MSG, p as INVALIDATE_ONLY_BATCH, M as Message, q as MessageContext, r as MessageTypeRegistration, s as MessageTypeRegistrationInput, t as Messages, N as Node, b as NodeActions, u as NodeCtx, v as NodeDescribeKind, w as NodeFn, x as NodeFnCleanup, y as NodeGuard, z as NodeImpl, B as NodeInspectorHook, J as NodeInspectorHookEvent, a as NodeOptions, K as NodeSink, L as NodeStatus, O as NodeTransportOptions, P as NodeVersionInfo, Q as OnMessageHandler, R as OnSubscribeHandler, S as PAUSE, T as PolicyAllow, U as PolicyDeny, V as PolicyRuleData, W as RESOLVED, X as RESOLVED_MSG, Y as RESOLVED_ONLY_BATCH, Z as RESUME, _ as START, $ as START_MSG, a0 as SubscribeContext, a1 as TEARDOWN, a2 as TEARDOWN_MSG, a3 as TEARDOWN_ONLY_BATCH, a4 as V0, a5 as V1, a6 as VersioningLevel, a7 as VersioningOptions, a8 as accessHintForGuard, a9 as advanceVersion, aa as configure, ab as createVersioning, ac as defaultConfig, ad as defaultHash, ae as isV1, af as node, ag as normalizeActor, ah as policy, ai as policyFromRules, aj as registerBuiltins } from '../node-C7PD3sn9.js';
2
+ export { A as AutoTrackOptions, D as DerivedFn, a as DynamicFn, E as EffectFn, P as PipeOperator, b as ProducerFn, T as TrackFn, c as autoTrackNode, d as batch, e as derived, f as downWithBatch, g as dynamicNode, h as effect, j as isBatching, m as monotonicNs, p as pipe, k as producer, s as state, w as wallClockNs } from '../index-DSPc5rkv.js';
3
+ export { D as DescribeDetail, a as DescribeField, b as DescribeNodeOutput, r as resolveDescribeFields } from '../meta-3QjzotRv.js';
@@ -1,7 +1,7 @@
1
- import "../chunk-RHI3GHZW.js";
1
+ import "../chunk-263BEJJO.js";
2
2
  import {
3
3
  resolveDescribeFields
4
- } from "../chunk-TH6COGOP.js";
4
+ } from "../chunk-HVBX5KIW.js";
5
5
  import {
6
6
  COMPLETE,
7
7
  COMPLETE_MSG,
@@ -52,7 +52,7 @@ import {
52
52
  registerBuiltins,
53
53
  state,
54
54
  wallClockNs
55
- } from "../chunk-QA3RP5NH.js";
55
+ } from "../chunk-NZMBRXQV.js";
56
56
  export {
57
57
  COMPLETE,
58
58
  COMPLETE_MSG,
@@ -210,9 +210,20 @@ var flushInProgress = false;
210
210
  var drainPhase2 = [];
211
211
  var drainPhase3 = [];
212
212
  var drainPhase4 = [];
213
+ var flushHooks = [];
213
214
  function isBatching() {
214
215
  return batchDepth > 0 || flushInProgress;
215
216
  }
217
+ function isExplicitlyBatching() {
218
+ return batchDepth > 0;
219
+ }
220
+ function registerBatchFlushHook(hook) {
221
+ if (batchDepth > 0) {
222
+ flushHooks.push(hook);
223
+ } else {
224
+ hook();
225
+ }
226
+ }
216
227
  function batch(fn) {
217
228
  batchDepth += 1;
218
229
  let threw = false;
@@ -226,6 +237,13 @@ function batch(fn) {
226
237
  if (batchDepth === 0) {
227
238
  if (threw) {
228
239
  if (!flushInProgress) {
240
+ const hooks = flushHooks.splice(0);
241
+ for (const h of hooks) {
242
+ try {
243
+ h();
244
+ } catch {
245
+ }
246
+ }
229
247
  drainPhase2.length = 0;
230
248
  drainPhase3.length = 0;
231
249
  drainPhase4.length = 0;
@@ -242,7 +260,18 @@ function drainPending() {
242
260
  const errors = [];
243
261
  let iterations = 0;
244
262
  try {
245
- while (drainPhase2.length > 0 || drainPhase3.length > 0 || drainPhase4.length > 0) {
263
+ while (drainPhase2.length > 0 || drainPhase3.length > 0 || drainPhase4.length > 0 || ownsFlush && flushHooks.length > 0) {
264
+ if (ownsFlush && flushHooks.length > 0) {
265
+ const hooks = flushHooks.splice(0);
266
+ for (const h of hooks) {
267
+ try {
268
+ h();
269
+ } catch (e) {
270
+ errors.push(e);
271
+ }
272
+ }
273
+ continue;
274
+ }
246
275
  iterations += 1;
247
276
  if (iterations > MAX_DRAIN_ITERATIONS) {
248
277
  drainPhase2.length = 0;
@@ -900,6 +929,22 @@ var NodeImpl = class _NodeImpl {
900
929
  * treats `0` as "wave settled" — O(1) check for full dep settlement.
901
930
  */
902
931
  _dirtyDepCount = 0;
932
+ // --- Per-batch emit accumulator (Bug 2: K+1 fan-in fix) ---
933
+ /**
934
+ * Inside an explicit `batch(() => ...)` scope, every `_emit` accumulates
935
+ * its already-framed messages here instead of dispatching synchronously.
936
+ * At batch end, `_flushBatchPending` runs (registered via
937
+ * `registerBatchFlushHook`) and delivers the whole accumulated batch as
938
+ * one `downWithBatch` call — collapsing what would otherwise be K
939
+ * separate sink invocations into one. This is the fix for the diamond
940
+ * fan-in K+1 over-fire.
941
+ *
942
+ * `null` outside batch (or after flush). Only ever appended to within
943
+ * a single explicit batch lifetime; reset to `null` on flush. State
944
+ * updates (cache, version, status) still happen per-emit via
945
+ * `_updateState` — only the downstream delivery is coalesced.
946
+ */
947
+ _batchPendingMessages = null;
903
948
  // --- PAUSE/RESUME lock tracking (C0) ---
904
949
  /**
905
950
  * Set of active pause locks held against this node. Every `[PAUSE, lockId]`
@@ -1277,7 +1322,10 @@ var NodeImpl = class _NodeImpl {
1277
1322
  dep.unsub = noopUnsub;
1278
1323
  dep.unsub = dep.node.subscribe((msgs) => {
1279
1324
  if (dep.unsub === null) return;
1325
+ const tierOf = this._config.tierOf;
1326
+ let sawSettlement = false;
1280
1327
  for (const m of msgs) {
1328
+ if (tierOf(m[0]) >= 3) sawSettlement = true;
1281
1329
  this._config.onMessage(
1282
1330
  this,
1283
1331
  m,
@@ -1285,6 +1333,7 @@ var NodeImpl = class _NodeImpl {
1285
1333
  this._actions
1286
1334
  );
1287
1335
  }
1336
+ if (sawSettlement) this._maybeRunFnOnSettlement();
1288
1337
  });
1289
1338
  subscribedCount++;
1290
1339
  }
@@ -1339,7 +1388,10 @@ var NodeImpl = class _NodeImpl {
1339
1388
  try {
1340
1389
  record.unsub = depNode.subscribe((msgs) => {
1341
1390
  if (record.unsub === null) return;
1391
+ const tierOf = this._config.tierOf;
1392
+ let sawSettlement = false;
1342
1393
  for (const m of msgs) {
1394
+ if (tierOf(m[0]) >= 3) sawSettlement = true;
1343
1395
  this._config.onMessage(
1344
1396
  this,
1345
1397
  m,
@@ -1347,6 +1399,7 @@ var NodeImpl = class _NodeImpl {
1347
1399
  this._actions
1348
1400
  );
1349
1401
  }
1402
+ if (sawSettlement) this._maybeRunFnOnSettlement();
1350
1403
  });
1351
1404
  } catch (err) {
1352
1405
  record.unsub = null;
@@ -1468,7 +1521,6 @@ var NodeImpl = class _NodeImpl {
1468
1521
  }
1469
1522
  return;
1470
1523
  }
1471
- this._maybeRunFnOnSettlement();
1472
1524
  }
1473
1525
  // --- Centralized dep-state transitions (A3 settlement counters) ---
1474
1526
  //
@@ -1840,10 +1892,10 @@ var NodeImpl = class _NodeImpl {
1840
1892
  }
1841
1893
  }
1842
1894
  if (immediate.length > 0) {
1843
- downWithBatch(this._deliverToSinks, immediate, tierOf);
1895
+ this._dispatchOrAccumulate(immediate);
1844
1896
  }
1845
1897
  } else {
1846
- downWithBatch(this._deliverToSinks, finalMessages, this._config.tierOf);
1898
+ this._dispatchOrAccumulate(finalMessages);
1847
1899
  }
1848
1900
  }
1849
1901
  if (equalsError != null) {
@@ -1966,6 +2018,50 @@ var NodeImpl = class _NodeImpl {
1966
2018
  const snapshot = [...this._sinks];
1967
2019
  for (const sink of snapshot) sink(messages);
1968
2020
  };
2021
+ /**
2022
+ * @internal Dispatch entry point that respects the per-batch emit
2023
+ * accumulator (Bug 2). Inside an explicit `batch()` scope, append to
2024
+ * `_batchPendingMessages` and register a flush hook on first append.
2025
+ * Outside batch — or during a drain (where `flushInProgress` is true
2026
+ * but `batchDepth` is 0) — dispatch synchronously through `downWithBatch`.
2027
+ *
2028
+ * Per-emit state updates (`_frameBatch`, `_updateState`) have already
2029
+ * happened by the time we reach here; only the **downstream delivery**
2030
+ * is coalesced. Cache, version, and status are visible mid-batch on
2031
+ * the emitting node itself.
2032
+ */
2033
+ _dispatchOrAccumulate(messages) {
2034
+ if (isExplicitlyBatching()) {
2035
+ if (this._batchPendingMessages === null) {
2036
+ this._batchPendingMessages = [];
2037
+ registerBatchFlushHook(() => this._flushBatchPending());
2038
+ }
2039
+ for (const m of messages) this._batchPendingMessages.push(m);
2040
+ return;
2041
+ }
2042
+ downWithBatch(this._deliverToSinks, messages, this._config.tierOf);
2043
+ }
2044
+ /**
2045
+ * @internal Flushes the accumulated batch through `downWithBatch` and
2046
+ * clears the pending state. Idempotent — safe to call when pending is
2047
+ * already null or empty (e.g. on a `batch()` throw, where the hook
2048
+ * fires for cleanup but the drainPhase queues are wiped after).
2049
+ *
2050
+ * Critical: the accumulated batch is interleaved per-emit framings like
2051
+ * `[DIRTY, DATA(1), DIRTY, DATA(2)]` — non-monotone tier order. We must
2052
+ * re-frame to sort by tier before handing to `downWithBatch`, which
2053
+ * assumes pre-sorted input. `_frameBatch` also handles the synthetic
2054
+ * DIRTY prepend rule (no-op here — `hasDirty` is true since each
2055
+ * accumulated emit already carries its own DIRTY prefix).
2056
+ */
2057
+ _flushBatchPending() {
2058
+ const pending = this._batchPendingMessages;
2059
+ if (pending === null) return;
2060
+ this._batchPendingMessages = null;
2061
+ if (pending.length === 0) return;
2062
+ const framed = this._frameBatch(pending);
2063
+ downWithBatch(this._deliverToSinks, framed, this._config.tierOf);
2064
+ }
1969
2065
  };
1970
2066
  var isNodeArray = (value) => Array.isArray(value);
1971
2067
  var isNodeOptionsObject = (value) => typeof value === "object" && value != null && !Array.isArray(value);