• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

live-input-vector-output-node / livon-ts / 23547724891

25 Mar 2026 02:55PM UTC coverage: 83.226% (+0.07%) from 83.161%
23547724891

push

github

cr15p1
improvement: raise upsert-one p99 bench budget to 20ms

880 of 1041 branches covered (84.53%)

Branch coverage included in aggregate %.

3918 of 4724 relevant lines covered (82.94%)

37.49 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.84
/packages/sync/src/source/source.ts
1
import { type DraftMode, type EntityId } from '../entity.js';
2
import {
3
  applyEntityRunResult,
4
  clearEntityMembership,
5
  createEntityRunContextMethods,
6
  createRunContextEntryCache,
7
  readOrCreateSharedCacheWriteQueue,
8
  createSerializedKeyCache,
9
  cloneValue,
10
  createUnitSnapshot,
11
  notifyEffectListeners,
12
  resolveInput,
13
  resolveValue,
14
  setManyEntityMembership,
15
  setOneEntityMembership,
16
  serializeKey,
17
  type EffectListener,
18
  type InputUpdater,
19
  type ValueUpdater,
20
} from '../utils/index.js';
21

22
import {
23
  areDraftValuesEqual,
24
  getModeValue,
25
  invokeSourceCleanup,
26
  isCacheRecordExpired,
27
  isEntityArray,
28
  isEntityValue,
29
  isRecordValue,
30
  isSourceCleanup,
31
  readSourceCacheRecord,
32
  resolveCacheLruMaxEntries,
33
  resolveCacheKey,
34
  resolveCacheStorage,
35
  resolveCacheTtl,
36
  serializeSourceCacheRecord,
37
  shouldUseCache,
38
} from './helpers.js';
39
import type {
40
  ReadEntityValueById,
41
  Source,
42
  SourceConfig,
43
  SourceContext,
44
  SourceRunContext,
45
  SourceRunContextEntry,
46
  SourceRunGate,
47
  SourceUnit,
48
  SourceUnitByKeyMap,
49
  SourceUnitInternal,
50
} from './types.js';
51

52
const DEFAULT_DESTROY_DELAY = 250;
37✔
53
const DEFAULT_DRAFT_MODE: DraftMode = 'global';
37✔
54
const RUN_CONTEXT_CACHE_LIMIT = 32;
37✔
55
const SOURCE_CACHE_LRU_STORAGE_KEY_SUFFIX = '__lru__';
37✔
56

57
const createInitialSourceContext = (
37✔
58
  hasCacheStorage: boolean,
59
): SourceContext => {
60
  return {
177✔
61
    cacheState: hasCacheStorage ? 'miss' : 'disabled',
62
    error: null,
63
  };
64
};
65

66
export const source = <
37✔
67
  TInput extends object | undefined,
68
  TPayload = unknown,
69
  TEntity extends object = object,
70
  RResult = unknown,
71
  UUpdate extends RResult = RResult,
72
  TEntityId extends EntityId = string,
73
>({
74
  entity,
75
  ttl = entity.ttl ?? 0,
76
  draft = entity.draft ?? DEFAULT_DRAFT_MODE,
77
  cache,
78
  destroyDelay = entity.destroyDelay ?? DEFAULT_DESTROY_DELAY,
79
  onDestroy,
80
  run,
81
  defaultValue,
82
}: SourceConfig<TInput, TPayload, TEntity, RResult, TEntityId>,
83
): Source<TInput, TPayload, RResult, UUpdate> => {
84
  const cacheTtl = resolveCacheTtl({
205✔
85
    sourceCache: cache,
86
    entityCache: entity.cache,
87
  });
88
  const cacheLruMaxEntries = resolveCacheLruMaxEntries({
205✔
89
    sourceCache: cache,
90
    entityCache: entity.cache,
91
  });
92
  const cacheStorage = resolveCacheStorage({
205✔
93
    sourceCache: cache,
94
    entityCache: entity.cache,
95
  });
96
  const cacheWriteQueue = cacheStorage
205✔
97
    ? readOrCreateSharedCacheWriteQueue({ storage: cacheStorage })
98
    : undefined;
99
  const cacheKeyPrefix = resolveCacheKey({
205✔
100
    sourceCache: cache,
101
    entityCache: entity.cache,
102
    sourceKey: serializeKey({
103
      mode: Array.isArray(defaultValue ?? null) ? 'many' : 'one',
104
    }),
105
  });
106

107
  const unitsByKey: SourceUnitByKeyMap<TInput, TPayload, TEntityId, RResult, UUpdate> =
108
    new Map<string, SourceUnitInternal<TInput, TPayload, TEntityId, RResult, UUpdate>>();
205✔
109
  const scopedDraftsById = new Map<TEntityId, TEntity>();
205✔
110
  const unitKeyCache = createSerializedKeyCache({
205✔
111
    mode: 'scoped-unit',
112
  });
113

114
  const notifyScopedUnitsById = (id: TEntityId): void => {
205✔
115
    Array.from(unitsByKey.values()).forEach((unitInternal) => {
2✔
116
      const hasMembership = unitInternal.membershipIds.some((membershipId) => membershipId === id);
2✔
117
      if (!hasMembership) {
2✔
118
        return;
×
119
      }
120

121
      notifyUnit(unitInternal);
2✔
122
    });
123
  };
124

125
  const readEntityValueById: ReadEntityValueById<TEntityId, TEntity> = (id) => {
205✔
126
    if (draft === 'off') {
365✔
127
      return entity.getById(id);
4✔
128
    }
129

130
    if (draft === 'global') {
361✔
131
      const globalDraft = entity.getDraftById(id);
349✔
132
      if (globalDraft) {
349✔
133
        return globalDraft;
14✔
134
      }
135

136
      return entity.getById(id);
335✔
137
    }
138

139
    const scopedDraft = scopedDraftsById.get(id);
12✔
140
    if (scopedDraft) {
12✔
141
      return scopedDraft;
2✔
142
    }
143

144
    return entity.getById(id);
10✔
145
  };
146

147
  const setDraftById = (id: TEntityId, value: TEntity): void => {
205✔
148
    if (draft === 'off') {
12✔
149
      return;
×
150
    }
151

152
    if (draft === 'global') {
12✔
153
      entity.setDraftById(id, value);
10✔
154
      return;
10✔
155
    }
156

157
    scopedDraftsById.set(id, value);
2✔
158
    notifyScopedUnitsById(id);
2✔
159
  };
160

161
  const clearDraftById = (id: TEntityId): void => {
205✔
162
    if (draft === 'off') {
3✔
163
      return;
×
164
    }
165

166
    if (draft === 'global') {
3✔
167
      entity.clearDraftById(id);
3✔
168
      return;
3✔
169
    }
170

171
    const existed = scopedDraftsById.delete(id);
×
172
    if (!existed) {
×
173
      return;
×
174
    }
175

176
    notifyScopedUnitsById(id);
×
177
  };
178

179
  const notifyUnit = (
205✔
180
    internal: SourceUnitInternal<TInput, TPayload, TEntityId, RResult, UUpdate>,
181
  ): void => {
182
    internal.state.value = getModeValue(internal, readEntityValueById);
348✔
183

184
    notifyEffectListeners(
348✔
185
      internal.listeners,
186
      createUnitSnapshot({
187
        value: internal.state.value,
188
        status: internal.state.status,
189
        meta: internal.state.meta,
190
        context: internal.state.context,
191
      }),
192
    );
193
  };
194

195
  const sourceFactory: Source<TInput, TPayload, RResult, UUpdate> = (scope) => {
205✔
196
    const key = unitKeyCache.getOrCreateKey(scope);
213✔
197
    const existingUnit = unitsByKey.get(key);
213✔
198

199
    if (existingUnit) {
213✔
200
      return existingUnit.unit;
42✔
201
    }
202

203
    const initialValue = (defaultValue ?? null) as RResult;
171✔
204
    const initialPayload = undefined as TPayload;
213✔
205
    const initialMode: 'one' | 'many' = Array.isArray(initialValue) ? 'many' : 'one';
213✔
206

207
    const internal: SourceUnitInternal<TInput, TPayload, TEntityId, RResult, UUpdate> = {
213✔
208
      key,
209
      ttl,
210
      destroyDelay,
211
      scope,
212
      payload: initialPayload,
213
      state: {
214
        value: initialValue,
215
        status: 'idle',
216
        meta: null,
217
        context: createInitialSourceContext(Boolean(cacheStorage)),
218
      },
219
      mode: initialMode,
220
      modeLocked: false,
221
      hasEntityValue: false,
222
      membershipIds: [],
223
      readWrite: {
224
        subview: entity.readWrite.subview,
225
      },
226
      listeners: new Set<EffectListener<RResult>>(),
227
      inFlightByPayload: new Map<string, Promise<RResult>>(),
228
      runSequence: 0,
229
      latestRunSequence: 0,
230
      lastRunAt: null,
231
      cleanup: null,
232
      stopped: false,
233
      destroyed: false,
234
      destroyHandled: false,
235
      unit: {} as SourceUnit<TInput, TPayload, RResult, UUpdate>,
236
    };
237
    const payloadKeyCache = createSerializedKeyCache({
213✔
238
      mode: 'payload-hot-path',
239
      limit: RUN_CONTEXT_CACHE_LIMIT,
240
    });
241
    const createRunContextEntry = (
213✔
242
      payload: TPayload,
243
    ): SourceRunContextEntry<TInput, TPayload, TEntity, RResult, TEntityId> => {
244
      const gate: SourceRunGate = {
138✔
245
        isLatestRun: () => false,
×
246
      };
247
      const runContextMethods = createEntityRunContextMethods<
138✔
248
        TEntity,
249
        RResult,
250
        TEntityId
251
      >({
252
        entity,
253
        state: internal,
254
        isActive: () => gate.isLatestRun(),
1✔
255
        refreshValue: () => {
256
          internal.state.value = getModeValue(internal, readEntityValueById);
1✔
257
        },
258
        readValue: () => internal.state.value,
1✔
259
      });
260
      const runContextBase: SourceRunContext<
261
        TInput,
262
        TPayload,
263
        TEntity,
264
        RResult,
265
        TEntityId
266
      > = {
138✔
267
        scope: internal.scope,
268
        payload,
269
        setMeta: (metaInput: unknown) => {
270
          if (!gate.isLatestRun()) {
14✔
271
            return;
×
272
          }
273

274
          const nextMeta = resolveValue(
14✔
275
            internal.state.meta,
276
            metaInput,
277
          );
278
          if (Object.is(nextMeta, internal.state.meta)) {
14✔
279
            return;
2✔
280
          }
281

282
          internal.state.meta = nextMeta;
12✔
283
          notifyUnit(internal);
12✔
284
        },
285
        reset: () => {
286
          if (!gate.isLatestRun()) {
1✔
287
            return;
×
288
          }
289

290
          resetState();
1✔
291
        },
292
        ...runContextMethods,
293
      };
294

295
      return {
138✔
296
        gate,
297
        context: runContextBase,
298
      };
299
    };
300
    const runContextEntryCache = createRunContextEntryCache<
213✔
301
      TPayload,
302
      SourceRunContextEntry<TInput, TPayload, TEntity, RResult, TEntityId>
303
    >({
304
      createEntry: createRunContextEntry,
305
      limit: RUN_CONTEXT_CACHE_LIMIT,
306
    });
307

308
    const setContext = (input: Partial<SourceContext>): void => {
213✔
309
      const hasCacheState = Object.prototype.hasOwnProperty.call(input, 'cacheState');
532✔
310
      const hasError = Object.prototype.hasOwnProperty.call(input, 'error');
532✔
311

312
      if (
532✔
313
        (!hasCacheState || input.cacheState === internal.state.context.cacheState)
314
        && (!hasError || Object.is(input.error, internal.state.context.error))
315
      ) {
316
        return;
489✔
317
      }
318

319
      internal.state.context = {
43✔
320
        ...internal.state.context,
321
        ...input,
322
      };
323
    };
324

325
    const cacheEnabled = Boolean(
213✔
326
      cacheStorage
327
      && (cacheTtl === 'infinity' || cacheTtl > 0),
328
    );
329
    const cacheLruEnabled = Boolean(
213✔
330
      cacheEnabled
331
      && cacheLruMaxEntries > 0
332
      && cacheStorage
333
      && cacheWriteQueue,
334
    );
335
    const cacheLruStorageKey = `${cacheKeyPrefix}:${SOURCE_CACHE_LRU_STORAGE_KEY_SUFFIX}`;
213✔
336
    let cacheLruLoaded = false;
213✔
337
    let cacheLruKeys: string[] = [];
213✔
338
    let activePayloadCacheKey: string | null = null;
213✔
339

340
    const loadCacheLruState = (): void => {
213✔
341
      if (!cacheLruEnabled || cacheLruLoaded || !cacheStorage) {
3✔
342
        return;
2✔
343
      }
344

345
      cacheLruLoaded = true;
1✔
346
      const rawLruState = cacheStorage.getItem(cacheLruStorageKey);
1✔
347
      if (!rawLruState) {
1✔
348
        return;
1✔
349
      }
350

351
      try {
×
352
        const parsedLruState: unknown = JSON.parse(rawLruState);
×
353
        if (!isRecordValue(parsedLruState)) {
×
354
          return;
×
355
        }
356

357
        const keysCandidate = parsedLruState.keys;
×
358
        if (!Array.isArray(keysCandidate)) {
×
359
          return;
×
360
        }
361

362
        if (!keysCandidate.every((entry) => typeof entry === 'string')) {
×
363
          return;
×
364
        }
365

366
        cacheLruKeys = keysCandidate;
×
367
      } catch {
368
        return;
×
369
      }
370
    };
371

372
    const persistCacheLruState = (): void => {
213✔
373
      if (!cacheLruEnabled || !cacheWriteQueue) {
3✔
374
        return;
×
375
      }
376

377
      if (cacheLruKeys.length === 0) {
3✔
378
        cacheWriteQueue.enqueueRemove(cacheLruStorageKey);
×
379
        return;
×
380
      }
381

382
      cacheWriteQueue.enqueueSet(
3✔
383
        cacheLruStorageKey,
384
        () => {
385
          return JSON.stringify({
3✔
386
            keys: cacheLruKeys,
387
          });
388
        },
389
      );
390
    };
391

392
    const touchCacheLruKey = (unitCacheKey: string): void => {
213✔
393
      if (!cacheLruEnabled || !cacheWriteQueue) {
14✔
394
        return;
11✔
395
      }
396

397
      loadCacheLruState();
3✔
398
      if (cacheLruKeys[0] === unitCacheKey) {
3✔
399
        return;
×
400
      }
401

402
      const existingIndex = cacheLruKeys.findIndex((entry) => entry === unitCacheKey);
3✔
403
      if (existingIndex > 0) {
3✔
404
        const existingEntry = cacheLruKeys[existingIndex];
×
405
        if (existingEntry === undefined) {
×
406
          return;
×
407
        }
408

409
        cacheLruKeys.splice(existingIndex, 1);
×
410
        cacheLruKeys.unshift(existingEntry);
×
411
        persistCacheLruState();
×
412
        return;
×
413
      }
414

415
      cacheLruKeys.unshift(unitCacheKey);
3✔
416
      const evictedEntry = cacheLruKeys.length > cacheLruMaxEntries
3✔
417
        ? cacheLruKeys.pop()
418
        : undefined;
419
      if (evictedEntry && evictedEntry !== unitCacheKey) {
14✔
420
        cacheWriteQueue.enqueueRemove(evictedEntry);
1✔
421
      }
422

423
      persistCacheLruState();
3✔
424
    };
425

426
    const removeCacheLruKey = (unitCacheKey: string): void => {
213✔
427
      if (!cacheLruEnabled) {
4✔
428
        return;
4✔
429
      }
430

431
      loadCacheLruState();
×
432
      const existingIndex = cacheLruKeys.findIndex((entry) => entry === unitCacheKey);
×
433
      if (existingIndex < 0) {
×
434
        return;
×
435
      }
436

437
      cacheLruKeys.splice(existingIndex, 1);
×
438
      persistCacheLruState();
×
439
    };
440

441
    const resolvePayloadCacheKey = (payload: TPayload): string => {
213✔
442
      return payloadKeyCache.getOrCreateKey(payload);
334✔
443
    };
444

445
    const resolveUnitCacheKey = (payloadCacheKey: string): string => {
213✔
446
      return `${cacheKeyPrefix}:${key}:${payloadCacheKey}`;
32✔
447
    };
448

449
    const syncCacheRecord = (): void => {
213✔
450
      if (!cacheEnabled || !cacheWriteQueue) {
180✔
451
        return;
170✔
452
      }
453

454
      const payloadCacheKey = resolvePayloadCacheKey(internal.payload);
10✔
455
      const unitCacheKey = resolveUnitCacheKey(payloadCacheKey);
10✔
456
      if (!internal.hasEntityValue) {
10✔
457
        removeCacheLruKey(unitCacheKey);
1✔
458
        cacheWriteQueue.enqueueRemove(unitCacheKey);
1✔
459
        return;
1✔
460
      }
461

462
      touchCacheLruKey(unitCacheKey);
9✔
463
      cacheWriteQueue.enqueueSet(unitCacheKey, () => {
9✔
464
        const entities = internal.membershipIds
8✔
465
          .map((id) => entity.getById(id))
8✔
466
          .filter((entry): entry is TEntity => entry !== undefined);
8✔
467

468
        return serializeSourceCacheRecord({
8✔
469
          mode: internal.mode,
470
          entities,
471
          writtenAt: Date.now(),
472
        });
473
      });
474
    };
475

476
    const hydrateFromCache = (payloadCacheKey: string): boolean => {
213✔
477
      if (!cacheStorage) {
239✔
478
        setContext({
184✔
479
          cacheState: 'disabled',
480
        });
481
        return false;
184✔
482
      }
483

484
      if (!cacheEnabled) {
55✔
485
        setContext({
33✔
486
          cacheState: 'disabled',
487
        });
488
        return false;
33✔
489
      }
490

491
      const unitCacheKey = resolveUnitCacheKey(payloadCacheKey);
22✔
492
      const rawRecord = cacheStorage.getItem(unitCacheKey);
22✔
493
      const parsedRecord = readSourceCacheRecord<TEntity>(rawRecord);
22✔
494
      if (!parsedRecord) {
22✔
495
        setContext({
14✔
496
          cacheState: 'miss',
497
        });
498
        return false;
14✔
499
      }
500

501
      if (isCacheRecordExpired({ ttl: cacheTtl, writtenAt: parsedRecord.writtenAt })) {
8✔
502
        removeCacheLruKey(unitCacheKey);
3✔
503
        if (cacheWriteQueue) {
3✔
504
          cacheWriteQueue.enqueueRemove(unitCacheKey);
3✔
505
        } else {
506
          try {
×
507
            cacheStorage.removeItem(unitCacheKey);
×
508
          } catch {
509
            // Ignore storage write errors and continue with stale cache behavior.
510
          }
511
        }
512
        setContext({
3✔
513
          cacheState: 'stale',
514
        });
515
        return false;
3✔
516
      }
517

518
      touchCacheLruKey(unitCacheKey);
5✔
519
      if (parsedRecord.mode === 'one') {
5✔
520
        const firstEntity = parsedRecord.entities[0];
5✔
521
        internal.hasEntityValue = true;
5✔
522

523
        if (firstEntity) {
5✔
524
          const upsertedEntity = entity.upsertOne(firstEntity);
5✔
525
          setOneEntityMembership(internal, {
5✔
526
            entity,
527
            value: upsertedEntity,
528
            operation: 'cache rehydrate one',
529
          });
530
          internal.state.value = getModeValue(internal, readEntityValueById);
5✔
531
        } else {
532
          clearEntityMembership(internal, { clearUnitMembership: entity.clearUnitMembership });
×
533
          internal.state.value = getModeValue(internal, readEntityValueById);
×
534
        }
535
      }
536

537
      if (parsedRecord.mode === 'many') {
5✔
538
        const upsertedEntities = entity.upsertMany(parsedRecord.entities);
×
539
        setManyEntityMembership(internal, {
×
540
          entity,
541
          values: upsertedEntities,
542
          operation: 'cache rehydrate many',
543
        });
544
        internal.state.value = getModeValue(internal, readEntityValueById);
×
545
      }
546

547
      internal.state.status = 'rehydrated';
5✔
548
      setContext({
5✔
549
        cacheState: 'hit',
550
        error: null,
551
      });
552
      return true;
5✔
553
    };
554

555
    const hydrateFromPayloadCache = (payload: TPayload): boolean => {
213✔
556
      const payloadCacheKey = resolvePayloadCacheKey(payload);
324✔
557
      if (activePayloadCacheKey === payloadCacheKey) {
324✔
558
        return false;
85✔
559
      }
560

561
      activePayloadCacheKey = payloadCacheKey;
239✔
562
      return hydrateFromCache(payloadCacheKey);
239✔
563
    };
564

565
    const unregisterFromEntity = entity.registerUnit({
213✔
566
      key: internal.key,
567
      onChange: () => {
568
        if (internal.destroyed) {
34✔
569
          return;
×
570
        }
571

572
        notifyUnit(internal);
34✔
573
        syncCacheRecord();
34✔
574
      },
575
    });
576

577
    hydrateFromPayloadCache(internal.payload);
213✔
578

579
    let singleInFlightPromise: Promise<RResult> | null = null;
213✔
580
    let hasSingleInFlightPayload = false;
213✔
581
    let singleInFlightPayload: TPayload | undefined;
582
    let singleInFlightPayloadKey: string | null = null;
213✔
583

584
    const clearInFlightTracking = (): void => {
213✔
585
      internal.inFlightByPayload.clear();
14✔
586
      singleInFlightPromise = null;
14✔
587
      hasSingleInFlightPayload = false;
14✔
588
      singleInFlightPayload = undefined;
14✔
589
      singleInFlightPayloadKey = null;
14✔
590
    };
591

592
    const stopInternal = (): void => {
213✔
593
      internal.runSequence += 1;
24✔
594
      internal.latestRunSequence = internal.runSequence;
24✔
595
      internal.stopped = true;
24✔
596
      invokeSourceCleanup(internal.cleanup);
24✔
597
      internal.cleanup = null;
24✔
598
    };
599

600
    const resetState = (): void => {
213✔
601
      if (internal.destroyed) {
6✔
602
        return;
×
603
      }
604

605
      const previousMembershipIds = internal.membershipIds;
6✔
606
      stopInternal();
6✔
607
      clearInFlightTracking();
6✔
608
      runContextEntryCache.clear();
6✔
609
      payloadKeyCache.clear();
6✔
610
      activePayloadCacheKey = null;
6✔
611
      internal.payload = initialPayload;
6✔
612

613
      if (draft === 'scoped') {
6✔
614
        previousMembershipIds.forEach((id) => {
×
615
          scopedDraftsById.delete(id);
×
616
        });
617
      }
618

619
      clearEntityMembership(internal, { clearUnitMembership: entity.clearUnitMembership });
6✔
620
      internal.mode = initialMode;
6✔
621
      internal.modeLocked = false;
6✔
622
      internal.lastRunAt = null;
6✔
623
      internal.stopped = false;
6✔
624
      internal.state.value = initialValue;
6✔
625
      internal.state.status = 'idle';
6✔
626
      internal.state.meta = null;
6✔
627
      internal.state.context = createInitialSourceContext(Boolean(cacheStorage));
6✔
628
      notifyUnit(internal);
6✔
629
      syncCacheRecord();
6✔
630
    };
631

632
    const destroyInternal = (): void => {
213✔
633
      if (internal.destroyed) {
9✔
634
        return;
1✔
635
      }
636

637
      stopInternal();
8✔
638
      internal.destroyed = true;
8✔
639
      runContextEntryCache.clear();
8✔
640
      payloadKeyCache.clear();
8✔
641
      activePayloadCacheKey = null;
8✔
642
      clearInFlightTracking();
8✔
643

644
      unregisterFromEntity();
8✔
645
      internal.listeners.clear();
8✔
646

647
      if (!internal.destroyHandled) {
8✔
648
        internal.destroyHandled = true;
8✔
649
        onDestroy?.({
8✔
650
          scope: internal.scope,
651
          payload: internal.payload,
652
        });
653
      }
654

655
      unitsByKey.delete(internal.key);
8✔
656
    };
657

658
    const executeRun = (
213✔
659
      isForce: boolean,
660
      payloadInput?: TPayload | InputUpdater<TPayload>,
661
    ): Promise<RResult> => {
662
      if (internal.destroyed) {
156✔
663
        return Promise.resolve(internal.state.value);
2✔
664
      }
665

666
      const hasPayloadInput = payloadInput !== undefined;
154✔
667
      const nextPayload = resolveInput(internal.payload, payloadInput);
154✔
668
      if (hasPayloadInput) {
154✔
669
        internal.payload = nextPayload;
70✔
670
      }
671
      let payloadKey: string | null = null;
154✔
672
      if (singleInFlightPromise) {
154✔
673
        if (hasSingleInFlightPayload && Object.is(singleInFlightPayload, internal.payload)) {
5✔
674
          return singleInFlightPromise;
×
675
        }
676

677
        payloadKey = payloadKeyCache.getOrCreateKey(internal.payload);
5✔
678
        if (singleInFlightPayloadKey === null && hasSingleInFlightPayload) {
5✔
679
          singleInFlightPayloadKey = payloadKeyCache.getOrCreateKey(singleInFlightPayload);
4✔
680
        }
681

682
        if (singleInFlightPayloadKey === payloadKey) {
5✔
683
          return singleInFlightPromise;
1✔
684
        }
685
      }
686

687
      if (internal.inFlightByPayload.size > 0) {
153✔
688
        payloadKey ??= payloadKeyCache.getOrCreateKey(internal.payload);
1✔
689
        const inFlightForPayload = internal.inFlightByPayload.get(payloadKey);
1✔
690
        if (inFlightForPayload) {
1✔
691
          return inFlightForPayload;
×
692
        }
693
      }
694

695
      internal.stopped = false;
153✔
696
      internal.runSequence += 1;
153✔
697
      internal.latestRunSequence = internal.runSequence;
153✔
698
      const runSequence = internal.runSequence;
153✔
699
      const isLatestRun = () => {
153✔
700
        return internal.latestRunSequence === runSequence && !internal.destroyed;
604✔
701
      };
702

703
      const didHydrateFromPayloadCache = hydrateFromPayloadCache(internal.payload);
153✔
704
      if (didHydrateFromPayloadCache && isLatestRun()) {
153✔
705
        notifyUnit(internal);
1✔
706
      }
707

708
      if (!isForce && !hasPayloadInput && shouldUseCache(internal)) {
153✔
709
        return Promise.resolve(internal.state.value);
2✔
710
      }
711

712
      const shouldUseRefreshingStatus = internal.state.status === 'rehydrated'
151✔
713
        || internal.state.status === 'success';
714
      if (isLatestRun()) {
156✔
715
        internal.state.status = shouldUseRefreshingStatus ? 'refreshing' : 'loading';
151✔
716
        setContext({
151✔
717
          error: null,
718
        });
719
        notifyUnit(internal);
151✔
720
      }
721

722
      const applyRunValue = (nextValue: RResult | void): void => {
151✔
723
        if (!isLatestRun()) {
141✔
724
          return;
×
725
        }
726

727
        applyEntityRunResult({
141✔
728
          entity,
729
          state: internal,
730
          nextValue,
731
          refreshValueFromMembership: () => {
732
            internal.state.value = getModeValue(internal, readEntityValueById);
137✔
733
          },
734
          setRawValue: (value) => {
735
            internal.state.value = value;
3✔
736
          },
737
        });
738
      };
739

740
      const runContextEntry = runContextEntryCache.getOrCreate(internal.payload);
151✔
741
      runContextEntry.gate.isLatestRun = isLatestRun;
151✔
742
      runContextEntry.context.payload = internal.payload;
151✔
743

744
      const usesSingleInFlight = singleInFlightPromise === null && internal.inFlightByPayload.size === 0;
151✔
745
      const trackedPayloadKey = usesSingleInFlight
156✔
746
        ? null
747
        : (payloadKey ?? payloadKeyCache.getOrCreateKey(internal.payload));
748

749
      const runPromise: Promise<RResult> = Promise.resolve(run(runContextEntry.context))
156✔
750
        .then((result) => {
751
          if (!isLatestRun() && isSourceCleanup(result)) {
148✔
752
            invokeSourceCleanup(result);
3✔
753
            return internal.state.value;
3✔
754
          }
755

756
          if (!isLatestRun()) {
145✔
757
            return internal.state.value;
4✔
758
          }
759

760
          if (isSourceCleanup(result)) {
141✔
761
            if (internal.destroyed || internal.stopped) {
×
762
              invokeSourceCleanup(result);
×
763
            } else {
764
              invokeSourceCleanup(internal.cleanup);
×
765
              internal.cleanup = result;
×
766
            }
767

768
            internal.state.value = getModeValue(internal, readEntityValueById);
×
769
          } else {
770
            applyRunValue(result);
141✔
771
          }
772

773
          internal.lastRunAt = Date.now();
140✔
774
          internal.state.status = 'success';
140✔
775
          setContext({
140✔
776
            error: null,
777
          });
778
          notifyUnit(internal);
140✔
779
          syncCacheRecord();
140✔
780

781
          return internal.state.value;
140✔
782
        })
783
        .catch((error: unknown) => {
784
          if (isLatestRun()) {
2✔
785
            internal.state.status = 'error';
2✔
786
            setContext({
2✔
787
              error,
788
            });
789
            notifyUnit(internal);
2✔
790
          }
791

792
          throw error;
2✔
793
        })
794
        .finally(() => {
795
          if (usesSingleInFlight) {
149✔
796
            if (singleInFlightPromise === runPromise) {
146✔
797
              singleInFlightPromise = null;
144✔
798
              hasSingleInFlightPayload = false;
144✔
799
              singleInFlightPayload = undefined;
144✔
800
              singleInFlightPayloadKey = null;
144✔
801
            }
802
            return;
146✔
803
          }
804

805
          if (trackedPayloadKey !== null) {
3✔
806
            internal.inFlightByPayload.delete(trackedPayloadKey);
3✔
807
          }
808
        });
809

810
      if (usesSingleInFlight) {
156✔
811
        singleInFlightPromise = runPromise;
147✔
812
        hasSingleInFlightPayload = true;
147✔
813
        singleInFlightPayload = internal.payload;
147✔
814
        singleInFlightPayloadKey = null;
147✔
815
      } else {
816
        if (trackedPayloadKey !== null) {
4✔
817
          internal.inFlightByPayload.set(trackedPayloadKey, runPromise);
4✔
818
        }
819
      }
820

821
      return runPromise;
151✔
822
    };
823

824
    const unit = ((payloadInput?: TPayload | InputUpdater<TPayload>) => {
213✔
825
      internal.payload = resolveInput(internal.payload, payloadInput);
×
826
      return unit;
×
827
    }) as SourceUnit<TInput, TPayload, RResult, UUpdate>;
828

829
    unit.ttl = ttl;
213✔
830
    unit.cacheTtl = cacheTtl;
213✔
831
    unit.destroyDelay = destroyDelay;
213✔
832
    unit.run = (payloadInput) => executeRun(false, payloadInput);
213✔
833
    unit.get = () => {
213✔
834
      return internal.state.value;
79✔
835
    };
836
    unit.draft = {
213✔
837
      set: (input: UUpdate | ValueUpdater<RResult, UUpdate>) => {
838
        if (internal.destroyed || draft === 'off') {
20✔
839
          return;
2✔
840
        }
841

842
        const previousValue: RResult = getModeValue(internal, readEntityValueById);
18✔
843
        const draftSeed: RResult = cloneValue(previousValue);
18✔
844
        const nextUpdate = resolveValue(draftSeed, input);
18✔
845

846
        if (Object.is(nextUpdate, previousValue)) {
18✔
847
          return;
3✔
848
        }
849

850
        if (areDraftValuesEqual(previousValue, nextUpdate)) {
15✔
851
          return;
3✔
852
        }
853

854
        if (internal.mode === 'one') {
12✔
855
          const firstId = internal.membershipIds[0];
12✔
856
          if (!firstId || !isEntityValue<TEntity>(nextUpdate)) {
12✔
857
            return;
×
858
          }
859

860
          setDraftById(firstId, cloneValue(nextUpdate));
12✔
861
          return;
12✔
862
        }
863

864
        if (internal.mode === 'many') {
×
865
          if (!isEntityArray<TEntity>(nextUpdate)) {
×
866
            return;
×
867
          }
868

869
          nextUpdate.forEach((entry) => {
×
870
            const entryId = entity.idOf(entry);
×
871
            setDraftById(entryId, cloneValue(entry));
×
872
          });
873
        }
874
      },
875
      clean: () => {
876
        if (internal.destroyed || draft === 'off') {
5✔
877
          return;
×
878
        }
879

880
        internal.membershipIds.forEach((id) => {
5✔
881
          clearDraftById(id);
3✔
882
        });
883
      },
884
    };
885
    unit.effect = (listener) => {
213✔
886
      if (internal.destroyed) {
67✔
887
        return undefined;
1✔
888
      }
889

890
      internal.listeners.add(listener);
66✔
891

892
      return () => {
66✔
893
        internal.listeners.delete(listener);
20✔
894
      };
895
    };
896
    unit.refetch = (payloadInput) => {
213✔
897
      const nextPayload = resolveInput(internal.payload, payloadInput);
5✔
898
      return sourceFactory(internal.scope).force(nextPayload);
5✔
899
    };
900
    unit.force = (payloadInput) => executeRun(true, payloadInput);
213✔
901
    unit.reset = () => {
213✔
902
      resetState();
5✔
903
    };
904
    unit.stop = () => {
213✔
905
      if (internal.destroyed) {
10✔
906
        return;
×
907
      }
908

909
      stopInternal();
10✔
910
    };
911
    unit.destroy = () => {
213✔
912
      destroyInternal();
9✔
913
    };
914

915
    Object.defineProperty(unit, 'getSnapshot', {
213✔
916
      configurable: false,
917
      enumerable: false,
918
      writable: false,
919
      value: () => {
920
        return createUnitSnapshot({
23✔
921
          value: internal.state.value,
922
          status: internal.state.status,
923
          meta: internal.state.meta,
924
          context: internal.state.context,
925
        });
926
      },
927
    });
928

929
    internal.unit = unit;
213✔
930
    unitsByKey.set(key, internal);
213✔
931

932
    return unit;
213✔
933
  };
934

935
  return sourceFactory;
205✔
936
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc