| 87 | } |
| 88 | |
| 89 | function testShareSyncCancelWithReason() { |
| 90 | // When cancel(reason) is called, a consumer that hasn't started |
| 91 | // iterating is already detached, so it sees done:true (not the error). |
| 92 | // But a consumer that is mid-iteration when another consumer cancels |
| 93 | // with a reason will see the error on the next pull after cancel. |
| 94 | const enc = new TextEncoder(); |
| 95 | function* gen() { |
| 96 | yield [enc.encode('a')]; |
| 97 | yield [enc.encode('b')]; |
| 98 | yield [enc.encode('c')]; |
| 99 | } |
| 100 | const shared = shareSync(gen(), { highWaterMark: 16 }); |
| 101 | const c1 = shared.pull(); |
| 102 | const c2 = shared.pull(); |
| 103 | |
| 104 | // c1 reads one item, then c2 cancels with a reason |
| 105 | const iter1 = c1[Symbol.iterator](); |
| 106 | const first = iter1.next(); |
| 107 | assert.strictEqual(first.done, false); |
| 108 | |
| 109 | shared.cancel(new Error('sync cancel reason')); |
| 110 | |
| 111 | // c1 was already iterating, it's now detached → done |
| 112 | const next = iter1.next(); |
| 113 | assert.strictEqual(next.done, true); |
| 114 | |
| 115 | // c2 never started, also detached → done (not error) |
| 116 | const batches = []; |
| 117 | for (const batch of c2) { |
| 118 | batches.push(batch); |
| 119 | } |
| 120 | assert.strictEqual(batches.length, 0); |
| 121 | } |
| 122 | |
| 123 | // ============================================================================= |
| 124 | // Source error propagation |