@graphrefly/graphrefly 0.6.0 → 0.8.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.
- package/README.md +30 -14
- package/dist/{chunk-HP7OKEOE.js → chunk-A2AJJOSJ.js} +3 -3
- package/dist/chunk-A2AJJOSJ.js.map +1 -0
- package/dist/{chunk-CP6MNKAA.js → chunk-E7OH6ZAZ.js} +10 -4
- package/dist/{chunk-CP6MNKAA.js.map → chunk-E7OH6ZAZ.js.map} +1 -1
- package/dist/chunk-LR2CLSEF.js +106 -0
- package/dist/chunk-LR2CLSEF.js.map +1 -0
- package/dist/{chunk-5X3LAO3B.js → chunk-QTZSBQGJ.js} +79 -20
- package/dist/chunk-QTZSBQGJ.js.map +1 -0
- package/dist/{chunk-V3UACY6A.js → chunk-TZLX4KIT.js} +790 -203
- package/dist/chunk-TZLX4KIT.js.map +1 -0
- package/dist/{chunk-QW7H3ICI.js → chunk-UCW3VWMN.js} +4 -4
- package/dist/{chunk-6W5SGIGB.js → chunk-WYI7YW54.js} +142 -30
- package/dist/chunk-WYI7YW54.js.map +1 -0
- package/dist/chunk-WZ2Z2CRV.js +32 -0
- package/dist/chunk-WZ2Z2CRV.js.map +1 -0
- package/dist/{chunk-Z4Y4FMQN.js → chunk-XCZPGOVP.js} +7 -7
- package/dist/{chunk-KWXPDASV.js → chunk-YWTP2XRJ.js} +2 -2
- package/dist/compat/nestjs/index.cjs +268 -61
- package/dist/compat/nestjs/index.cjs.map +1 -1
- package/dist/compat/nestjs/index.d.cts +4 -4
- package/dist/compat/nestjs/index.d.ts +4 -4
- package/dist/compat/nestjs/index.js +8 -7
- package/dist/core/index.cjs +163 -35
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +2 -2
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +10 -4
- package/dist/extra/index.cjs +892 -221
- package/dist/extra/index.cjs.map +1 -1
- package/dist/extra/index.d.cts +4 -4
- package/dist/extra/index.d.ts +4 -4
- package/dist/extra/index.js +22 -3
- package/dist/graph/index.cjs +268 -61
- package/dist/graph/index.cjs.map +1 -1
- package/dist/graph/index.d.cts +3 -3
- package/dist/graph/index.d.ts +3 -3
- package/dist/graph/index.js +4 -4
- package/dist/{graph-CL_ZDAj9.d.cts → graph-DqTICAY2.d.cts} +69 -12
- package/dist/{graph-D18qmsNm.d.ts → graph-X9uwnD_z.d.ts} +69 -12
- package/dist/{index-C3BMRmmp.d.cts → index-3U0WxdD-.d.cts} +3 -3
- package/dist/{index-Bk_idZm1.d.cts → index-BP1t_38S.d.cts} +406 -61
- package/dist/{index-BtK55IE2.d.ts → index-BPCeYDS4.d.ts} +4 -2
- package/dist/{index-Bvy_6CaN.d.ts → index-BVG5pjin.d.ts} +50 -5
- package/dist/{index-C5mqLhMX.d.cts → index-BYEgosAX.d.cts} +50 -5
- package/dist/{index-D_geH2Bm.d.cts → index-BYa2YMat.d.cts} +3 -3
- package/dist/{index-CP_QvbWu.d.ts → index-DLO8wnYU.d.ts} +3 -3
- package/dist/{index-B7eOdgEx.d.ts → index-DMv1Etbi.d.ts} +3 -3
- package/dist/{index-BvhgZRHK.d.cts → index-DbwgQ4Cw.d.cts} +4 -2
- package/dist/{index-B2jmzVxL.d.ts → index-a5gHmH5b.d.ts} +406 -61
- package/dist/index.cjs +2966 -1790
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +112 -14
- package/dist/index.d.ts +112 -14
- package/dist/index.js +385 -20
- package/dist/index.js.map +1 -1
- package/dist/{meta-BsF6Sag9.d.cts → meta-BJEU8fYz.d.cts} +31 -4
- package/dist/{meta-BsF6Sag9.d.ts → meta-BJEU8fYz.d.ts} +31 -4
- package/dist/patterns/reactive-layout/index.cjs +268 -61
- package/dist/patterns/reactive-layout/index.cjs.map +1 -1
- package/dist/patterns/reactive-layout/index.d.cts +3 -3
- package/dist/patterns/reactive-layout/index.d.ts +3 -3
- package/dist/patterns/reactive-layout/index.js +4 -4
- package/dist/{reactive-log-BfvfNWQh.d.cts → reactive-log-BfX6bOSZ.d.cts} +2 -2
- package/dist/{reactive-log-ohLmTXoZ.d.ts → reactive-log-RhgIog2Z.d.ts} +2 -2
- package/package.json +29 -18
- package/dist/chunk-5X3LAO3B.js.map +0 -1
- package/dist/chunk-6W5SGIGB.js.map +0 -1
- package/dist/chunk-HP7OKEOE.js.map +0 -1
- package/dist/chunk-O3PI7W45.js +0 -68
- package/dist/chunk-O3PI7W45.js.map +0 -1
- package/dist/chunk-V3UACY6A.js.map +0 -1
- /package/dist/{chunk-QW7H3ICI.js.map → chunk-UCW3VWMN.js.map} +0 -0
- /package/dist/{chunk-Z4Y4FMQN.js.map → chunk-XCZPGOVP.js.map} +0 -0
- /package/dist/{chunk-KWXPDASV.js.map → chunk-YWTP2XRJ.js.map} +0 -0
package/dist/extra/index.cjs
CHANGED
|
@@ -27,11 +27,14 @@ __export(extra_exports, {
|
|
|
27
27
|
NS_PER_MS: () => NS_PER_MS,
|
|
28
28
|
NS_PER_SEC: () => NS_PER_SEC,
|
|
29
29
|
SqliteCheckpointAdapter: () => SqliteCheckpointAdapter,
|
|
30
|
+
TimeoutError: () => TimeoutError,
|
|
30
31
|
audit: () => audit,
|
|
31
32
|
buffer: () => buffer,
|
|
32
33
|
bufferCount: () => bufferCount,
|
|
33
34
|
bufferTime: () => bufferTime,
|
|
35
|
+
cache: () => cache,
|
|
34
36
|
cached: () => cached,
|
|
37
|
+
cascadingCache: () => cascadingCache,
|
|
35
38
|
catchError: () => catchError,
|
|
36
39
|
checkpointNodeValue: () => checkpointNodeValue,
|
|
37
40
|
checkpointToRedis: () => checkpointToRedis,
|
|
@@ -56,6 +59,7 @@ __export(extra_exports, {
|
|
|
56
59
|
escapeRegexChar: () => escapeRegexChar,
|
|
57
60
|
exhaustMap: () => exhaustMap,
|
|
58
61
|
exponential: () => exponential,
|
|
62
|
+
fallback: () => fallback,
|
|
59
63
|
fibonacci: () => fibonacci,
|
|
60
64
|
filter: () => filter,
|
|
61
65
|
find: () => find,
|
|
@@ -68,6 +72,7 @@ __export(extra_exports, {
|
|
|
68
72
|
fromCSV: () => fromCSV,
|
|
69
73
|
fromClickHouseWatch: () => fromClickHouseWatch,
|
|
70
74
|
fromCron: () => fromCron,
|
|
75
|
+
fromDrizzle: () => fromDrizzle,
|
|
71
76
|
fromEvent: () => fromEvent,
|
|
72
77
|
fromFSWatch: () => fromFSWatch,
|
|
73
78
|
fromGitHook: () => fromGitHook,
|
|
@@ -76,10 +81,12 @@ __export(extra_exports, {
|
|
|
76
81
|
fromIDBTransaction: () => fromIDBTransaction,
|
|
77
82
|
fromIter: () => fromIter,
|
|
78
83
|
fromKafka: () => fromKafka,
|
|
84
|
+
fromKysely: () => fromKysely,
|
|
79
85
|
fromMCP: () => fromMCP,
|
|
80
86
|
fromNATS: () => fromNATS,
|
|
81
87
|
fromNDJSON: () => fromNDJSON,
|
|
82
88
|
fromOTel: () => fromOTel,
|
|
89
|
+
fromPrisma: () => fromPrisma,
|
|
83
90
|
fromPrometheus: () => fromPrometheus,
|
|
84
91
|
fromPromise: () => fromPromise,
|
|
85
92
|
fromPulsar: () => fromPulsar,
|
|
@@ -97,6 +104,7 @@ __export(extra_exports, {
|
|
|
97
104
|
last: () => last,
|
|
98
105
|
linear: () => linear,
|
|
99
106
|
logSlice: () => logSlice,
|
|
107
|
+
lru: () => lru,
|
|
100
108
|
map: () => map,
|
|
101
109
|
matchesAnyPattern: () => matchesAnyPattern,
|
|
102
110
|
matchesCron: () => matchesCron,
|
|
@@ -146,6 +154,7 @@ __export(extra_exports, {
|
|
|
146
154
|
throttle: () => throttle,
|
|
147
155
|
throttleTime: () => throttleTime,
|
|
148
156
|
throwError: () => throwError,
|
|
157
|
+
tieredStorage: () => tieredStorage,
|
|
149
158
|
timeout: () => timeout,
|
|
150
159
|
toArray: () => toArray,
|
|
151
160
|
toCSV: () => toCSV,
|
|
@@ -330,10 +339,14 @@ function partitionForBatch(messages) {
|
|
|
330
339
|
}
|
|
331
340
|
return { immediate, deferred, terminal };
|
|
332
341
|
}
|
|
333
|
-
function emitWithBatch(emit, messages, phase = 2) {
|
|
342
|
+
function emitWithBatch(emit, messages, phase = 2, options) {
|
|
334
343
|
if (messages.length === 0) {
|
|
335
344
|
return;
|
|
336
345
|
}
|
|
346
|
+
if (options?.strategy === "sequential") {
|
|
347
|
+
_emitSequential(emit, messages, phase);
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
337
350
|
const queue = phase === 3 ? pendingPhase3 : pendingPhase2;
|
|
338
351
|
if (messages.length === 1) {
|
|
339
352
|
const t = messages[0][0];
|
|
@@ -374,6 +387,29 @@ function emitWithBatch(emit, messages, phase = 2) {
|
|
|
374
387
|
}
|
|
375
388
|
}
|
|
376
389
|
}
|
|
390
|
+
function _emitSequential(emit, messages, phase = 2) {
|
|
391
|
+
const dataQueue = phase === 3 ? pendingPhase3 : pendingPhase2;
|
|
392
|
+
for (const msg of messages) {
|
|
393
|
+
const tier = messageTier(msg[0]);
|
|
394
|
+
if (tier === 2) {
|
|
395
|
+
if (isBatching()) {
|
|
396
|
+
const m = msg;
|
|
397
|
+
dataQueue.push(() => emit([m]));
|
|
398
|
+
} else {
|
|
399
|
+
emit([msg]);
|
|
400
|
+
}
|
|
401
|
+
} else if (tier >= 3) {
|
|
402
|
+
if (isBatching()) {
|
|
403
|
+
const m = msg;
|
|
404
|
+
pendingPhase3.push(() => emit([m]));
|
|
405
|
+
} else {
|
|
406
|
+
emit([msg]);
|
|
407
|
+
}
|
|
408
|
+
} else {
|
|
409
|
+
emit([msg]);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
377
413
|
|
|
378
414
|
// src/core/clock.ts
|
|
379
415
|
function monotonicNs() {
|
|
@@ -472,6 +508,7 @@ function advanceVersion(info, newValue, hashFn) {
|
|
|
472
508
|
}
|
|
473
509
|
|
|
474
510
|
// src/core/node.ts
|
|
511
|
+
var NO_VALUE = /* @__PURE__ */ Symbol.for("graphrefly/NO_VALUE");
|
|
475
512
|
function createIntBitSet() {
|
|
476
513
|
let bits = 0;
|
|
477
514
|
return {
|
|
@@ -601,10 +638,10 @@ var NodeImpl = class {
|
|
|
601
638
|
this._hasDeps = deps.length > 0;
|
|
602
639
|
this._autoComplete = opts.completeWhenDepsComplete ?? true;
|
|
603
640
|
this._isSingleDep = deps.length === 1 && fn != null;
|
|
604
|
-
this._cached = opts.initial;
|
|
641
|
+
this._cached = "initial" in opts ? opts.initial : NO_VALUE;
|
|
605
642
|
this._status = this._hasDeps ? "disconnected" : "settled";
|
|
606
643
|
this._hashFn = opts.versioningHash ?? defaultHash;
|
|
607
|
-
this._versioning = opts.versioning != null ? createVersioning(opts.versioning, this._cached, {
|
|
644
|
+
this._versioning = opts.versioning != null ? createVersioning(opts.versioning, this._cached === NO_VALUE ? void 0 : this._cached, {
|
|
608
645
|
id: opts.versioningId,
|
|
609
646
|
hash: this._hashFn
|
|
610
647
|
}) : void 0;
|
|
@@ -688,10 +725,14 @@ var NodeImpl = class {
|
|
|
688
725
|
_applyVersioning(level, opts) {
|
|
689
726
|
if (this._versioning != null) return;
|
|
690
727
|
this._hashFn = opts?.hash ?? this._hashFn;
|
|
691
|
-
this._versioning = createVersioning(
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
728
|
+
this._versioning = createVersioning(
|
|
729
|
+
level,
|
|
730
|
+
this._cached === NO_VALUE ? void 0 : this._cached,
|
|
731
|
+
{
|
|
732
|
+
id: opts?.id,
|
|
733
|
+
hash: this._hashFn
|
|
734
|
+
}
|
|
735
|
+
);
|
|
695
736
|
}
|
|
696
737
|
hasGuard() {
|
|
697
738
|
return this._guard != null;
|
|
@@ -701,7 +742,7 @@ var NodeImpl = class {
|
|
|
701
742
|
return this._guard(normalizeActor(actor), "observe");
|
|
702
743
|
}
|
|
703
744
|
get() {
|
|
704
|
-
return this._cached;
|
|
745
|
+
return this._cached === NO_VALUE ? void 0 : this._cached;
|
|
705
746
|
}
|
|
706
747
|
down(messages, options) {
|
|
707
748
|
if (messages.length === 0) return;
|
|
@@ -758,6 +799,7 @@ var NodeImpl = class {
|
|
|
758
799
|
}
|
|
759
800
|
if (this._terminal && this._opts.resubscribable) {
|
|
760
801
|
this._terminal = false;
|
|
802
|
+
this._cached = NO_VALUE;
|
|
761
803
|
this._status = this._hasDeps ? "disconnected" : "settled";
|
|
762
804
|
this._opts.onResubscribe?.();
|
|
763
805
|
}
|
|
@@ -857,7 +899,7 @@ var NodeImpl = class {
|
|
|
857
899
|
const cleanupFn = this._cleanup;
|
|
858
900
|
this._cleanup = void 0;
|
|
859
901
|
cleanupFn?.();
|
|
860
|
-
this._cached =
|
|
902
|
+
this._cached = NO_VALUE;
|
|
861
903
|
this._lastDepValues = void 0;
|
|
862
904
|
}
|
|
863
905
|
this._status = statusAfterMessage(this._status, m);
|
|
@@ -866,7 +908,7 @@ var NodeImpl = class {
|
|
|
866
908
|
}
|
|
867
909
|
if (t === TEARDOWN) {
|
|
868
910
|
if (this._opts.resetOnTeardown) {
|
|
869
|
-
this._cached =
|
|
911
|
+
this._cached = NO_VALUE;
|
|
870
912
|
}
|
|
871
913
|
const teardownCleanup = this._cleanup;
|
|
872
914
|
this._cleanup = void 0;
|
|
@@ -897,7 +939,15 @@ var NodeImpl = class {
|
|
|
897
939
|
}
|
|
898
940
|
_emitAutoValue(value) {
|
|
899
941
|
const wasDirty = this._status === "dirty";
|
|
900
|
-
|
|
942
|
+
let unchanged;
|
|
943
|
+
try {
|
|
944
|
+
unchanged = this._cached !== NO_VALUE && this._equals(this._cached, value);
|
|
945
|
+
} catch (eqErr) {
|
|
946
|
+
const eqMsg = eqErr instanceof Error ? eqErr.message : String(eqErr);
|
|
947
|
+
const wrapped = new Error(`Node "${this.name}": equals threw: ${eqMsg}`, { cause: eqErr });
|
|
948
|
+
this._downInternal([[ERROR, wrapped]]);
|
|
949
|
+
return;
|
|
950
|
+
}
|
|
901
951
|
if (unchanged) {
|
|
902
952
|
this._downInternal(wasDirty ? [[RESOLVED]] : [[DIRTY], [RESOLVED]]);
|
|
903
953
|
return;
|
|
@@ -944,7 +994,9 @@ var NodeImpl = class {
|
|
|
944
994
|
if (out === void 0) return;
|
|
945
995
|
this._emitAutoValue(out);
|
|
946
996
|
} catch (err) {
|
|
947
|
-
|
|
997
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
998
|
+
const wrapped = new Error(`Node "${this.name}": fn threw: ${errMsg}`, { cause: err });
|
|
999
|
+
this._downInternal([[ERROR, wrapped]]);
|
|
948
1000
|
}
|
|
949
1001
|
}
|
|
950
1002
|
_onDepDirty(index) {
|
|
@@ -979,7 +1031,11 @@ var NodeImpl = class {
|
|
|
979
1031
|
try {
|
|
980
1032
|
if (this._onMessage(msg, index, this._actions)) continue;
|
|
981
1033
|
} catch (err) {
|
|
982
|
-
|
|
1034
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
1035
|
+
const wrapped = new Error(`Node "${this.name}": onMessage threw: ${errMsg}`, {
|
|
1036
|
+
cause: err
|
|
1037
|
+
});
|
|
1038
|
+
this._downInternal([[ERROR, wrapped]]);
|
|
983
1039
|
return;
|
|
984
1040
|
}
|
|
985
1041
|
}
|
|
@@ -1194,6 +1250,34 @@ function resolveBackoffPreset(name) {
|
|
|
1194
1250
|
);
|
|
1195
1251
|
}
|
|
1196
1252
|
|
|
1253
|
+
// src/core/timer.ts
|
|
1254
|
+
var ResettableTimer = class {
|
|
1255
|
+
_timer;
|
|
1256
|
+
_gen = 0;
|
|
1257
|
+
/** Schedule callback after delayMs. Cancels any pending timer. */
|
|
1258
|
+
start(delayMs, callback) {
|
|
1259
|
+
this.cancel();
|
|
1260
|
+
this._gen += 1;
|
|
1261
|
+
const gen = this._gen;
|
|
1262
|
+
this._timer = setTimeout(() => {
|
|
1263
|
+
this._timer = void 0;
|
|
1264
|
+
if (gen !== this._gen) return;
|
|
1265
|
+
callback();
|
|
1266
|
+
}, delayMs);
|
|
1267
|
+
}
|
|
1268
|
+
/** Cancel the pending timer (if any). */
|
|
1269
|
+
cancel() {
|
|
1270
|
+
if (this._timer !== void 0) {
|
|
1271
|
+
clearTimeout(this._timer);
|
|
1272
|
+
this._timer = void 0;
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
/** Whether a timer is currently pending. */
|
|
1276
|
+
get pending() {
|
|
1277
|
+
return this._timer !== void 0;
|
|
1278
|
+
}
|
|
1279
|
+
};
|
|
1280
|
+
|
|
1197
1281
|
// src/extra/resilience.ts
|
|
1198
1282
|
function operatorOpts(opts) {
|
|
1199
1283
|
return { describeKind: "operator", ...opts };
|
|
@@ -1223,14 +1307,7 @@ function retry(source, opts) {
|
|
|
1223
1307
|
let stopped = false;
|
|
1224
1308
|
let prevDelay = null;
|
|
1225
1309
|
let unsub;
|
|
1226
|
-
|
|
1227
|
-
let timerGen = 0;
|
|
1228
|
-
function cancelTimer() {
|
|
1229
|
-
if (timer !== void 0) {
|
|
1230
|
-
clearTimeout(timer);
|
|
1231
|
-
timer = void 0;
|
|
1232
|
-
}
|
|
1233
|
-
}
|
|
1310
|
+
const timer = new ResettableTimer();
|
|
1234
1311
|
function disconnectUpstream() {
|
|
1235
1312
|
unsub?.();
|
|
1236
1313
|
unsub = void 0;
|
|
@@ -1246,20 +1323,18 @@ function retry(source, opts) {
|
|
|
1246
1323
|
const delayNs = coerceDelayNs(raw === void 0 ? null : raw);
|
|
1247
1324
|
prevDelay = delayNs;
|
|
1248
1325
|
attempt += 1;
|
|
1249
|
-
timerGen += 1;
|
|
1250
|
-
const gen = timerGen;
|
|
1251
1326
|
disconnectUpstream();
|
|
1252
1327
|
const delayMs = delayNs > 0 ? delayNs / NS_PER_MS : 1;
|
|
1253
|
-
timer
|
|
1254
|
-
|
|
1255
|
-
if (stopped || gen !== timerGen) return;
|
|
1328
|
+
timer.start(delayMs, () => {
|
|
1329
|
+
if (stopped) return;
|
|
1256
1330
|
connect();
|
|
1257
|
-
}
|
|
1331
|
+
});
|
|
1258
1332
|
}
|
|
1259
1333
|
function connect() {
|
|
1260
|
-
|
|
1334
|
+
timer.cancel();
|
|
1261
1335
|
disconnectUpstream();
|
|
1262
1336
|
unsub = source.subscribe((msgs) => {
|
|
1337
|
+
if (stopped) return;
|
|
1263
1338
|
for (const m of msgs) {
|
|
1264
1339
|
const t = m[0];
|
|
1265
1340
|
if (t === DIRTY) a.down([[DIRTY]]);
|
|
@@ -1281,8 +1356,7 @@ function retry(source, opts) {
|
|
|
1281
1356
|
connect();
|
|
1282
1357
|
return () => {
|
|
1283
1358
|
stopped = true;
|
|
1284
|
-
|
|
1285
|
-
cancelTimer();
|
|
1359
|
+
timer.cancel();
|
|
1286
1360
|
disconnectUpstream();
|
|
1287
1361
|
};
|
|
1288
1362
|
},
|
|
@@ -1462,14 +1536,7 @@ function rateLimiter(source, maxEvents, windowNs) {
|
|
|
1462
1536
|
(_d, a) => {
|
|
1463
1537
|
const times = [];
|
|
1464
1538
|
const pending = [];
|
|
1465
|
-
|
|
1466
|
-
let timerGen = 0;
|
|
1467
|
-
function cancelTimer() {
|
|
1468
|
-
if (timer !== void 0) {
|
|
1469
|
-
clearTimeout(timer);
|
|
1470
|
-
timer = void 0;
|
|
1471
|
-
}
|
|
1472
|
-
}
|
|
1539
|
+
const timer = new ResettableTimer();
|
|
1473
1540
|
function prune(now) {
|
|
1474
1541
|
const boundary = now - windowNs;
|
|
1475
1542
|
while (times.length > 0 && times[0] <= boundary) times.shift();
|
|
@@ -1483,15 +1550,10 @@ function rateLimiter(source, maxEvents, windowNs) {
|
|
|
1483
1550
|
a.emit(pending.shift());
|
|
1484
1551
|
} else {
|
|
1485
1552
|
const oldest = times[0];
|
|
1486
|
-
cancelTimer();
|
|
1487
|
-
timerGen += 1;
|
|
1488
|
-
const gen = timerGen;
|
|
1489
1553
|
const delayNs = Math.max(0, oldest + windowNs - monotonicNs());
|
|
1490
|
-
timer
|
|
1491
|
-
timer = void 0;
|
|
1492
|
-
if (gen !== timerGen) return;
|
|
1554
|
+
timer.start(delayNs / NS_PER_MS, () => {
|
|
1493
1555
|
tryEmit();
|
|
1494
|
-
}
|
|
1556
|
+
});
|
|
1495
1557
|
return;
|
|
1496
1558
|
}
|
|
1497
1559
|
}
|
|
@@ -1505,14 +1567,12 @@ function rateLimiter(source, maxEvents, windowNs) {
|
|
|
1505
1567
|
tryEmit();
|
|
1506
1568
|
} else if (t === RESOLVED) a.down([[RESOLVED]]);
|
|
1507
1569
|
else if (t === COMPLETE) {
|
|
1508
|
-
|
|
1509
|
-
cancelTimer();
|
|
1570
|
+
timer.cancel();
|
|
1510
1571
|
pending.length = 0;
|
|
1511
1572
|
times.length = 0;
|
|
1512
1573
|
a.down([[COMPLETE]]);
|
|
1513
1574
|
} else if (t === ERROR) {
|
|
1514
|
-
|
|
1515
|
-
cancelTimer();
|
|
1575
|
+
timer.cancel();
|
|
1516
1576
|
pending.length = 0;
|
|
1517
1577
|
times.length = 0;
|
|
1518
1578
|
a.down([m]);
|
|
@@ -1520,8 +1580,7 @@ function rateLimiter(source, maxEvents, windowNs) {
|
|
|
1520
1580
|
}
|
|
1521
1581
|
});
|
|
1522
1582
|
return () => {
|
|
1523
|
-
|
|
1524
|
-
cancelTimer();
|
|
1583
|
+
timer.cancel();
|
|
1525
1584
|
unsub();
|
|
1526
1585
|
};
|
|
1527
1586
|
},
|
|
@@ -1582,6 +1641,147 @@ function withStatus(src, options) {
|
|
|
1582
1641
|
error: out.meta.error
|
|
1583
1642
|
};
|
|
1584
1643
|
}
|
|
1644
|
+
var TimeoutError = class extends Error {
|
|
1645
|
+
name = "TimeoutError";
|
|
1646
|
+
constructor(ns) {
|
|
1647
|
+
super(`Timed out after ${ns / NS_PER_MS}ms`);
|
|
1648
|
+
}
|
|
1649
|
+
};
|
|
1650
|
+
function isNode(x) {
|
|
1651
|
+
return x != null && typeof x.subscribe === "function" && typeof x.get === "function";
|
|
1652
|
+
}
|
|
1653
|
+
function fallback(source, fb) {
|
|
1654
|
+
return producer(
|
|
1655
|
+
(_d, a) => {
|
|
1656
|
+
let fallbackUnsub;
|
|
1657
|
+
let sourceUnsub;
|
|
1658
|
+
sourceUnsub = source.subscribe((msgs) => {
|
|
1659
|
+
for (const m of msgs) {
|
|
1660
|
+
const t = m[0];
|
|
1661
|
+
if (t === DIRTY) a.down([[DIRTY]]);
|
|
1662
|
+
else if (t === DATA) a.emit(m[1]);
|
|
1663
|
+
else if (t === RESOLVED) a.down([[RESOLVED]]);
|
|
1664
|
+
else if (t === COMPLETE) a.down([[COMPLETE]]);
|
|
1665
|
+
else if (t === ERROR) {
|
|
1666
|
+
sourceUnsub?.();
|
|
1667
|
+
if (isNode(fb)) {
|
|
1668
|
+
fallbackUnsub = fb.subscribe((fMsgs) => {
|
|
1669
|
+
a.down(fMsgs);
|
|
1670
|
+
});
|
|
1671
|
+
const cur = fb.get();
|
|
1672
|
+
if (cur !== void 0) a.down([[DATA, cur]]);
|
|
1673
|
+
} else {
|
|
1674
|
+
a.emit(fb);
|
|
1675
|
+
a.down([[COMPLETE]]);
|
|
1676
|
+
}
|
|
1677
|
+
return;
|
|
1678
|
+
} else if (t === TEARDOWN) {
|
|
1679
|
+
fallbackUnsub?.();
|
|
1680
|
+
a.down([m]);
|
|
1681
|
+
return;
|
|
1682
|
+
} else a.down([m]);
|
|
1683
|
+
}
|
|
1684
|
+
});
|
|
1685
|
+
return () => {
|
|
1686
|
+
sourceUnsub?.();
|
|
1687
|
+
fallbackUnsub?.();
|
|
1688
|
+
};
|
|
1689
|
+
},
|
|
1690
|
+
{
|
|
1691
|
+
...operatorOpts(),
|
|
1692
|
+
initial: source.get()
|
|
1693
|
+
}
|
|
1694
|
+
);
|
|
1695
|
+
}
|
|
1696
|
+
function timeout(source, timeoutNs) {
|
|
1697
|
+
if (timeoutNs <= 0) throw new RangeError("timeoutNs must be > 0");
|
|
1698
|
+
return producer(
|
|
1699
|
+
(_d, a) => {
|
|
1700
|
+
let stopped = false;
|
|
1701
|
+
const timer = new ResettableTimer();
|
|
1702
|
+
function startTimer() {
|
|
1703
|
+
const delayMs = timeoutNs / NS_PER_MS;
|
|
1704
|
+
timer.start(delayMs, () => {
|
|
1705
|
+
if (stopped) return;
|
|
1706
|
+
stopped = true;
|
|
1707
|
+
unsub();
|
|
1708
|
+
a.down([[ERROR, new TimeoutError(timeoutNs)]]);
|
|
1709
|
+
});
|
|
1710
|
+
}
|
|
1711
|
+
const unsub = source.subscribe((msgs) => {
|
|
1712
|
+
for (const m of msgs) {
|
|
1713
|
+
if (stopped) return;
|
|
1714
|
+
const t = m[0];
|
|
1715
|
+
if (t === DIRTY) a.down([[DIRTY]]);
|
|
1716
|
+
else if (t === DATA) {
|
|
1717
|
+
startTimer();
|
|
1718
|
+
a.emit(m[1]);
|
|
1719
|
+
} else if (t === RESOLVED) a.down([[RESOLVED]]);
|
|
1720
|
+
else if (t === COMPLETE) {
|
|
1721
|
+
timer.cancel();
|
|
1722
|
+
stopped = true;
|
|
1723
|
+
a.down([[COMPLETE]]);
|
|
1724
|
+
return;
|
|
1725
|
+
} else if (t === ERROR) {
|
|
1726
|
+
timer.cancel();
|
|
1727
|
+
stopped = true;
|
|
1728
|
+
a.down([m]);
|
|
1729
|
+
return;
|
|
1730
|
+
} else if (t === TEARDOWN) {
|
|
1731
|
+
timer.cancel();
|
|
1732
|
+
stopped = true;
|
|
1733
|
+
a.down([m]);
|
|
1734
|
+
return;
|
|
1735
|
+
} else a.down([m]);
|
|
1736
|
+
}
|
|
1737
|
+
});
|
|
1738
|
+
startTimer();
|
|
1739
|
+
return () => {
|
|
1740
|
+
stopped = true;
|
|
1741
|
+
timer.cancel();
|
|
1742
|
+
unsub();
|
|
1743
|
+
};
|
|
1744
|
+
},
|
|
1745
|
+
{
|
|
1746
|
+
...operatorOpts(),
|
|
1747
|
+
initial: source.get()
|
|
1748
|
+
}
|
|
1749
|
+
);
|
|
1750
|
+
}
|
|
1751
|
+
function cache(source, ttlNs) {
|
|
1752
|
+
if (ttlNs <= 0) throw new RangeError("ttlNs must be > 0");
|
|
1753
|
+
let cachedValue;
|
|
1754
|
+
let cachedAt = 0;
|
|
1755
|
+
let hasCached = false;
|
|
1756
|
+
return producer(
|
|
1757
|
+
(_d, a) => {
|
|
1758
|
+
if (hasCached && monotonicNs() - cachedAt < ttlNs) {
|
|
1759
|
+
a.down([[DATA, cachedValue]]);
|
|
1760
|
+
}
|
|
1761
|
+
const unsub = source.subscribe((msgs) => {
|
|
1762
|
+
for (const m of msgs) {
|
|
1763
|
+
const t = m[0];
|
|
1764
|
+
if (t === DATA) {
|
|
1765
|
+
cachedValue = m[1];
|
|
1766
|
+
cachedAt = monotonicNs();
|
|
1767
|
+
hasCached = true;
|
|
1768
|
+
a.emit(cachedValue);
|
|
1769
|
+
} else if (t === DIRTY) a.down([[DIRTY]]);
|
|
1770
|
+
else if (t === RESOLVED) a.down([[RESOLVED]]);
|
|
1771
|
+
else if (t === COMPLETE) a.down([[COMPLETE]]);
|
|
1772
|
+
else if (t === ERROR) a.down([m]);
|
|
1773
|
+
else a.down([m]);
|
|
1774
|
+
}
|
|
1775
|
+
});
|
|
1776
|
+
return unsub;
|
|
1777
|
+
},
|
|
1778
|
+
{
|
|
1779
|
+
...operatorOpts(),
|
|
1780
|
+
resubscribable: true,
|
|
1781
|
+
initial: source.get()
|
|
1782
|
+
}
|
|
1783
|
+
);
|
|
1784
|
+
}
|
|
1585
1785
|
|
|
1586
1786
|
// src/extra/sources.ts
|
|
1587
1787
|
var import_node_fs = require("fs");
|
|
@@ -1939,11 +2139,11 @@ function fromAsyncIter(iterable, opts) {
|
|
|
1939
2139
|
};
|
|
1940
2140
|
}, sourceOpts(rest));
|
|
1941
2141
|
}
|
|
1942
|
-
function
|
|
2142
|
+
function isNode2(x) {
|
|
1943
2143
|
return x != null && typeof x.subscribe === "function" && typeof x.get === "function";
|
|
1944
2144
|
}
|
|
1945
2145
|
function fromAny(input, opts) {
|
|
1946
|
-
if (
|
|
2146
|
+
if (isNode2(input)) {
|
|
1947
2147
|
return input;
|
|
1948
2148
|
}
|
|
1949
2149
|
if (isThenable(input)) {
|
|
@@ -2075,6 +2275,17 @@ function firstValueFrom(source) {
|
|
|
2075
2275
|
var shareReplay = replay;
|
|
2076
2276
|
|
|
2077
2277
|
// src/extra/adapters.ts
|
|
2278
|
+
function createSinkErrorHandler(userHandler) {
|
|
2279
|
+
const errorsNode = state(null);
|
|
2280
|
+
const handler = (err) => {
|
|
2281
|
+
userHandler?.(err);
|
|
2282
|
+
try {
|
|
2283
|
+
errorsNode.down([[DATA, err]]);
|
|
2284
|
+
} catch {
|
|
2285
|
+
}
|
|
2286
|
+
};
|
|
2287
|
+
return { errorsNode, handler };
|
|
2288
|
+
}
|
|
2078
2289
|
function sourceOpts2(opts) {
|
|
2079
2290
|
return { describeKind: "producer", ...opts };
|
|
2080
2291
|
}
|
|
@@ -2825,6 +3036,7 @@ function toKafka(source, kafkaProducer, topic, opts) {
|
|
|
2825
3036
|
onTransportError,
|
|
2826
3037
|
...rest
|
|
2827
3038
|
} = opts ?? {};
|
|
3039
|
+
const { errorsNode, handler } = createSinkErrorHandler(onTransportError);
|
|
2828
3040
|
const inner = node([source], () => void 0, {
|
|
2829
3041
|
describeKind: "effect",
|
|
2830
3042
|
...rest,
|
|
@@ -2836,7 +3048,7 @@ function toKafka(source, kafkaProducer, topic, opts) {
|
|
|
2836
3048
|
try {
|
|
2837
3049
|
serialized = serialize(value);
|
|
2838
3050
|
} catch (err) {
|
|
2839
|
-
|
|
3051
|
+
handler({
|
|
2840
3052
|
stage: "serialize",
|
|
2841
3053
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
2842
3054
|
value
|
|
@@ -2847,7 +3059,7 @@ function toKafka(source, kafkaProducer, topic, opts) {
|
|
|
2847
3059
|
topic,
|
|
2848
3060
|
messages: [{ key, value: Buffer.from(serialized) }]
|
|
2849
3061
|
}).catch((err) => {
|
|
2850
|
-
|
|
3062
|
+
handler({
|
|
2851
3063
|
stage: "send",
|
|
2852
3064
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
2853
3065
|
value
|
|
@@ -2858,8 +3070,15 @@ function toKafka(source, kafkaProducer, topic, opts) {
|
|
|
2858
3070
|
return false;
|
|
2859
3071
|
}
|
|
2860
3072
|
});
|
|
2861
|
-
|
|
3073
|
+
const unsub = inner.subscribe(() => {
|
|
2862
3074
|
});
|
|
3075
|
+
return {
|
|
3076
|
+
dispose: () => {
|
|
3077
|
+
unsub();
|
|
3078
|
+
errorsNode.down([[TEARDOWN]]);
|
|
3079
|
+
},
|
|
3080
|
+
errors: errorsNode
|
|
3081
|
+
};
|
|
2863
3082
|
}
|
|
2864
3083
|
function fromRedisStream(client, key, opts) {
|
|
2865
3084
|
const {
|
|
@@ -2924,6 +3143,7 @@ function toRedisStream(source, client, key, opts) {
|
|
|
2924
3143
|
onTransportError,
|
|
2925
3144
|
...rest
|
|
2926
3145
|
} = opts ?? {};
|
|
3146
|
+
const { errorsNode, handler } = createSinkErrorHandler(onTransportError);
|
|
2927
3147
|
const inner = node([source], () => void 0, {
|
|
2928
3148
|
describeKind: "effect",
|
|
2929
3149
|
...rest,
|
|
@@ -2934,7 +3154,7 @@ function toRedisStream(source, client, key, opts) {
|
|
|
2934
3154
|
try {
|
|
2935
3155
|
fields = serialize(value);
|
|
2936
3156
|
} catch (err) {
|
|
2937
|
-
|
|
3157
|
+
handler({
|
|
2938
3158
|
stage: "serialize",
|
|
2939
3159
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
2940
3160
|
value
|
|
@@ -2943,7 +3163,7 @@ function toRedisStream(source, client, key, opts) {
|
|
|
2943
3163
|
}
|
|
2944
3164
|
const send = maxLen !== void 0 ? client.xadd(key, "MAXLEN", "~", String(maxLen), "*", ...fields) : client.xadd(key, "*", ...fields);
|
|
2945
3165
|
void send.catch((err) => {
|
|
2946
|
-
|
|
3166
|
+
handler({
|
|
2947
3167
|
stage: "send",
|
|
2948
3168
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
2949
3169
|
value
|
|
@@ -2954,8 +3174,15 @@ function toRedisStream(source, client, key, opts) {
|
|
|
2954
3174
|
return false;
|
|
2955
3175
|
}
|
|
2956
3176
|
});
|
|
2957
|
-
|
|
3177
|
+
const unsub = inner.subscribe(() => {
|
|
2958
3178
|
});
|
|
3179
|
+
return {
|
|
3180
|
+
dispose: () => {
|
|
3181
|
+
unsub();
|
|
3182
|
+
errorsNode.down([[TEARDOWN]]);
|
|
3183
|
+
},
|
|
3184
|
+
errors: errorsNode
|
|
3185
|
+
};
|
|
2959
3186
|
}
|
|
2960
3187
|
function fromCSV(source, opts) {
|
|
2961
3188
|
const {
|
|
@@ -3182,6 +3409,7 @@ function toPulsar(source, pulsarProducer, opts) {
|
|
|
3182
3409
|
onTransportError,
|
|
3183
3410
|
...rest
|
|
3184
3411
|
} = opts ?? {};
|
|
3412
|
+
const { errorsNode, handler } = createSinkErrorHandler(onTransportError);
|
|
3185
3413
|
const inner = node([source], () => void 0, {
|
|
3186
3414
|
describeKind: "effect",
|
|
3187
3415
|
...rest,
|
|
@@ -3192,7 +3420,7 @@ function toPulsar(source, pulsarProducer, opts) {
|
|
|
3192
3420
|
try {
|
|
3193
3421
|
data = serialize(value);
|
|
3194
3422
|
} catch (err) {
|
|
3195
|
-
|
|
3423
|
+
handler({
|
|
3196
3424
|
stage: "serialize",
|
|
3197
3425
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3198
3426
|
value
|
|
@@ -3204,7 +3432,7 @@ function toPulsar(source, pulsarProducer, opts) {
|
|
|
3204
3432
|
partitionKey: keyExtractor?.(value),
|
|
3205
3433
|
properties: propertiesExtractor?.(value)
|
|
3206
3434
|
}).catch((err) => {
|
|
3207
|
-
|
|
3435
|
+
handler({
|
|
3208
3436
|
stage: "send",
|
|
3209
3437
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3210
3438
|
value
|
|
@@ -3215,8 +3443,15 @@ function toPulsar(source, pulsarProducer, opts) {
|
|
|
3215
3443
|
return false;
|
|
3216
3444
|
}
|
|
3217
3445
|
});
|
|
3218
|
-
|
|
3446
|
+
const unsub = inner.subscribe(() => {
|
|
3219
3447
|
});
|
|
3448
|
+
return {
|
|
3449
|
+
dispose: () => {
|
|
3450
|
+
unsub();
|
|
3451
|
+
errorsNode.down([[TEARDOWN]]);
|
|
3452
|
+
},
|
|
3453
|
+
errors: errorsNode
|
|
3454
|
+
};
|
|
3220
3455
|
}
|
|
3221
3456
|
function fromNATS(client, subject, opts) {
|
|
3222
3457
|
const decoder = new TextDecoder();
|
|
@@ -3272,6 +3507,7 @@ function toNATS(source, client, subject, opts) {
|
|
|
3272
3507
|
onTransportError,
|
|
3273
3508
|
...rest
|
|
3274
3509
|
} = opts ?? {};
|
|
3510
|
+
const { errorsNode, handler } = createSinkErrorHandler(onTransportError);
|
|
3275
3511
|
const inner = node([source], () => void 0, {
|
|
3276
3512
|
describeKind: "effect",
|
|
3277
3513
|
...rest,
|
|
@@ -3282,7 +3518,7 @@ function toNATS(source, client, subject, opts) {
|
|
|
3282
3518
|
try {
|
|
3283
3519
|
data = serialize(value);
|
|
3284
3520
|
} catch (err) {
|
|
3285
|
-
|
|
3521
|
+
handler({
|
|
3286
3522
|
stage: "serialize",
|
|
3287
3523
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3288
3524
|
value
|
|
@@ -3292,7 +3528,7 @@ function toNATS(source, client, subject, opts) {
|
|
|
3292
3528
|
try {
|
|
3293
3529
|
client.publish(subject, data);
|
|
3294
3530
|
} catch (err) {
|
|
3295
|
-
|
|
3531
|
+
handler({
|
|
3296
3532
|
stage: "send",
|
|
3297
3533
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3298
3534
|
value
|
|
@@ -3303,8 +3539,15 @@ function toNATS(source, client, subject, opts) {
|
|
|
3303
3539
|
return false;
|
|
3304
3540
|
}
|
|
3305
3541
|
});
|
|
3306
|
-
|
|
3542
|
+
const unsub = inner.subscribe(() => {
|
|
3307
3543
|
});
|
|
3544
|
+
return {
|
|
3545
|
+
dispose: () => {
|
|
3546
|
+
unsub();
|
|
3547
|
+
errorsNode.down([[TEARDOWN]]);
|
|
3548
|
+
},
|
|
3549
|
+
errors: errorsNode
|
|
3550
|
+
};
|
|
3308
3551
|
}
|
|
3309
3552
|
function fromRabbitMQ(channel, queue, opts) {
|
|
3310
3553
|
const {
|
|
@@ -3366,6 +3609,7 @@ function toRabbitMQ(source, channel, exchange, opts) {
|
|
|
3366
3609
|
onTransportError,
|
|
3367
3610
|
...rest
|
|
3368
3611
|
} = opts ?? {};
|
|
3612
|
+
const { errorsNode, handler } = createSinkErrorHandler(onTransportError);
|
|
3369
3613
|
const inner = node([source], () => void 0, {
|
|
3370
3614
|
describeKind: "effect",
|
|
3371
3615
|
...rest,
|
|
@@ -3376,7 +3620,7 @@ function toRabbitMQ(source, channel, exchange, opts) {
|
|
|
3376
3620
|
try {
|
|
3377
3621
|
routingKey = routingKeyExtractor(value);
|
|
3378
3622
|
} catch (err) {
|
|
3379
|
-
|
|
3623
|
+
handler({
|
|
3380
3624
|
stage: "routing_key",
|
|
3381
3625
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3382
3626
|
value
|
|
@@ -3387,7 +3631,7 @@ function toRabbitMQ(source, channel, exchange, opts) {
|
|
|
3387
3631
|
try {
|
|
3388
3632
|
content = serialize(value);
|
|
3389
3633
|
} catch (err) {
|
|
3390
|
-
|
|
3634
|
+
handler({
|
|
3391
3635
|
stage: "serialize",
|
|
3392
3636
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3393
3637
|
value
|
|
@@ -3397,7 +3641,7 @@ function toRabbitMQ(source, channel, exchange, opts) {
|
|
|
3397
3641
|
try {
|
|
3398
3642
|
channel.publish(exchange, routingKey, content);
|
|
3399
3643
|
} catch (err) {
|
|
3400
|
-
|
|
3644
|
+
handler({
|
|
3401
3645
|
stage: "send",
|
|
3402
3646
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3403
3647
|
value
|
|
@@ -3408,8 +3652,15 @@ function toRabbitMQ(source, channel, exchange, opts) {
|
|
|
3408
3652
|
return false;
|
|
3409
3653
|
}
|
|
3410
3654
|
});
|
|
3411
|
-
|
|
3655
|
+
const unsub = inner.subscribe(() => {
|
|
3412
3656
|
});
|
|
3657
|
+
return {
|
|
3658
|
+
dispose: () => {
|
|
3659
|
+
unsub();
|
|
3660
|
+
errorsNode.down([[TEARDOWN]]);
|
|
3661
|
+
},
|
|
3662
|
+
errors: errorsNode
|
|
3663
|
+
};
|
|
3413
3664
|
}
|
|
3414
3665
|
function toFile(source, writer, opts) {
|
|
3415
3666
|
const {
|
|
@@ -3421,8 +3672,10 @@ function toFile(source, writer, opts) {
|
|
|
3421
3672
|
mode: _mode,
|
|
3422
3673
|
...rest
|
|
3423
3674
|
} = opts ?? {};
|
|
3675
|
+
const { errorsNode, handler } = createSinkErrorHandler(onTransportError);
|
|
3424
3676
|
let buffer2 = [];
|
|
3425
3677
|
let timer;
|
|
3678
|
+
let disposed = false;
|
|
3426
3679
|
const doFlush = () => {
|
|
3427
3680
|
if (buffer2.length === 0) return;
|
|
3428
3681
|
const chunk = buffer2.join("");
|
|
@@ -3430,7 +3683,7 @@ function toFile(source, writer, opts) {
|
|
|
3430
3683
|
try {
|
|
3431
3684
|
writer.write(chunk);
|
|
3432
3685
|
} catch (err) {
|
|
3433
|
-
|
|
3686
|
+
handler({
|
|
3434
3687
|
stage: "send",
|
|
3435
3688
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3436
3689
|
value: chunk
|
|
@@ -3438,7 +3691,7 @@ function toFile(source, writer, opts) {
|
|
|
3438
3691
|
}
|
|
3439
3692
|
};
|
|
3440
3693
|
const scheduleFlush = () => {
|
|
3441
|
-
if (flushIntervalMs > 0 && timer === void 0) {
|
|
3694
|
+
if (flushIntervalMs > 0 && timer === void 0 && !disposed) {
|
|
3442
3695
|
timer = setTimeout(() => {
|
|
3443
3696
|
timer = void 0;
|
|
3444
3697
|
doFlush();
|
|
@@ -3456,7 +3709,7 @@ function toFile(source, writer, opts) {
|
|
|
3456
3709
|
try {
|
|
3457
3710
|
line = serialize(value);
|
|
3458
3711
|
} catch (err) {
|
|
3459
|
-
|
|
3712
|
+
handler({
|
|
3460
3713
|
stage: "serialize",
|
|
3461
3714
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3462
3715
|
value
|
|
@@ -3471,7 +3724,7 @@ function toFile(source, writer, opts) {
|
|
|
3471
3724
|
try {
|
|
3472
3725
|
writer.write(line);
|
|
3473
3726
|
} catch (err) {
|
|
3474
|
-
|
|
3727
|
+
handler({
|
|
3475
3728
|
stage: "send",
|
|
3476
3729
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3477
3730
|
value
|
|
@@ -3480,7 +3733,7 @@ function toFile(source, writer, opts) {
|
|
|
3480
3733
|
}
|
|
3481
3734
|
return true;
|
|
3482
3735
|
}
|
|
3483
|
-
if (msg[0]
|
|
3736
|
+
if (messageTier(msg[0]) >= 3) {
|
|
3484
3737
|
doFlush();
|
|
3485
3738
|
}
|
|
3486
3739
|
return false;
|
|
@@ -3489,18 +3742,25 @@ function toFile(source, writer, opts) {
|
|
|
3489
3742
|
const unsub = inner.subscribe(() => {
|
|
3490
3743
|
});
|
|
3491
3744
|
const dispose = () => {
|
|
3745
|
+
if (disposed) return;
|
|
3746
|
+
disposed = true;
|
|
3492
3747
|
if (timer !== void 0) {
|
|
3493
3748
|
clearTimeout(timer);
|
|
3494
3749
|
timer = void 0;
|
|
3495
3750
|
}
|
|
3496
3751
|
doFlush();
|
|
3497
|
-
|
|
3752
|
+
try {
|
|
3753
|
+
writer.end();
|
|
3754
|
+
} catch {
|
|
3755
|
+
}
|
|
3498
3756
|
unsub();
|
|
3757
|
+
errorsNode.down([[TEARDOWN]]);
|
|
3499
3758
|
};
|
|
3500
3759
|
return {
|
|
3501
3760
|
dispose,
|
|
3761
|
+
errors: errorsNode,
|
|
3502
3762
|
flush: async () => {
|
|
3503
|
-
doFlush();
|
|
3763
|
+
if (!disposed) doFlush();
|
|
3504
3764
|
}
|
|
3505
3765
|
};
|
|
3506
3766
|
}
|
|
@@ -3551,25 +3811,29 @@ function toClickHouse(source, client, table, opts) {
|
|
|
3551
3811
|
onTransportError,
|
|
3552
3812
|
...rest
|
|
3553
3813
|
} = opts ?? {};
|
|
3814
|
+
const { errorsNode, handler } = createSinkErrorHandler(onTransportError);
|
|
3554
3815
|
let buffer2 = [];
|
|
3555
3816
|
let timer;
|
|
3556
|
-
let
|
|
3817
|
+
let disposed = false;
|
|
3818
|
+
const inFlight = /* @__PURE__ */ new Set();
|
|
3557
3819
|
const doFlush = () => {
|
|
3558
3820
|
if (buffer2.length === 0) return Promise.resolve();
|
|
3559
3821
|
const batch2 = buffer2;
|
|
3560
3822
|
buffer2 = [];
|
|
3561
3823
|
try {
|
|
3562
3824
|
const p = client.insert({ table, values: batch2, format }).catch((err) => {
|
|
3563
|
-
|
|
3825
|
+
handler({
|
|
3564
3826
|
stage: "send",
|
|
3565
3827
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3566
3828
|
value: batch2
|
|
3567
3829
|
});
|
|
3830
|
+
}).finally(() => {
|
|
3831
|
+
inFlight.delete(p);
|
|
3568
3832
|
});
|
|
3569
|
-
|
|
3833
|
+
inFlight.add(p);
|
|
3570
3834
|
return p;
|
|
3571
3835
|
} catch (err) {
|
|
3572
|
-
|
|
3836
|
+
handler({
|
|
3573
3837
|
stage: "send",
|
|
3574
3838
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3575
3839
|
value: batch2
|
|
@@ -3578,7 +3842,7 @@ function toClickHouse(source, client, table, opts) {
|
|
|
3578
3842
|
}
|
|
3579
3843
|
};
|
|
3580
3844
|
const scheduleFlush = () => {
|
|
3581
|
-
if (timer === void 0) {
|
|
3845
|
+
if (timer === void 0 && !disposed) {
|
|
3582
3846
|
timer = setTimeout(() => {
|
|
3583
3847
|
timer = void 0;
|
|
3584
3848
|
doFlush();
|
|
@@ -3594,7 +3858,7 @@ function toClickHouse(source, client, table, opts) {
|
|
|
3594
3858
|
try {
|
|
3595
3859
|
buffer2.push(transform(value));
|
|
3596
3860
|
} catch (err) {
|
|
3597
|
-
|
|
3861
|
+
handler({
|
|
3598
3862
|
stage: "serialize",
|
|
3599
3863
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3600
3864
|
value
|
|
@@ -3605,7 +3869,7 @@ function toClickHouse(source, client, table, opts) {
|
|
|
3605
3869
|
else scheduleFlush();
|
|
3606
3870
|
return true;
|
|
3607
3871
|
}
|
|
3608
|
-
if (msg[0]
|
|
3872
|
+
if (messageTier(msg[0]) >= 3) {
|
|
3609
3873
|
doFlush();
|
|
3610
3874
|
}
|
|
3611
3875
|
return false;
|
|
@@ -3614,16 +3878,24 @@ function toClickHouse(source, client, table, opts) {
|
|
|
3614
3878
|
const unsub = inner.subscribe(() => {
|
|
3615
3879
|
});
|
|
3616
3880
|
const dispose = () => {
|
|
3881
|
+
if (disposed) return;
|
|
3882
|
+
disposed = true;
|
|
3617
3883
|
if (timer !== void 0) {
|
|
3618
3884
|
clearTimeout(timer);
|
|
3619
3885
|
timer = void 0;
|
|
3620
3886
|
}
|
|
3621
3887
|
doFlush();
|
|
3622
3888
|
unsub();
|
|
3889
|
+
errorsNode.down([[TEARDOWN]]);
|
|
3623
3890
|
};
|
|
3624
3891
|
return {
|
|
3625
3892
|
dispose,
|
|
3626
|
-
|
|
3893
|
+
errors: errorsNode,
|
|
3894
|
+
flush: () => {
|
|
3895
|
+
const p = disposed ? Promise.resolve() : doFlush();
|
|
3896
|
+
return p.then(() => Promise.all(inFlight)).then(() => {
|
|
3897
|
+
});
|
|
3898
|
+
}
|
|
3627
3899
|
};
|
|
3628
3900
|
}
|
|
3629
3901
|
function toS3(source, client, bucket, opts) {
|
|
@@ -3640,10 +3912,12 @@ function toS3(source, client, bucket, opts) {
|
|
|
3640
3912
|
onTransportError,
|
|
3641
3913
|
...rest
|
|
3642
3914
|
} = opts ?? {};
|
|
3915
|
+
const { errorsNode, handler } = createSinkErrorHandler(onTransportError);
|
|
3643
3916
|
let buffer2 = [];
|
|
3644
3917
|
let timer;
|
|
3645
3918
|
let seq = 0;
|
|
3646
|
-
let
|
|
3919
|
+
let disposed = false;
|
|
3920
|
+
const inFlight = /* @__PURE__ */ new Set();
|
|
3647
3921
|
const doFlush = () => {
|
|
3648
3922
|
if (buffer2.length === 0) return Promise.resolve();
|
|
3649
3923
|
const batch2 = buffer2;
|
|
@@ -3656,16 +3930,18 @@ function toS3(source, client, bucket, opts) {
|
|
|
3656
3930
|
try {
|
|
3657
3931
|
const p = client.putObject({ Bucket: bucket, Key: key, Body: body, ContentType: contentType }).then(() => {
|
|
3658
3932
|
}).catch((err) => {
|
|
3659
|
-
|
|
3933
|
+
handler({
|
|
3660
3934
|
stage: "send",
|
|
3661
3935
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3662
3936
|
value: batch2
|
|
3663
3937
|
});
|
|
3938
|
+
}).finally(() => {
|
|
3939
|
+
inFlight.delete(p);
|
|
3664
3940
|
});
|
|
3665
|
-
|
|
3941
|
+
inFlight.add(p);
|
|
3666
3942
|
return p;
|
|
3667
3943
|
} catch (err) {
|
|
3668
|
-
|
|
3944
|
+
handler({
|
|
3669
3945
|
stage: "send",
|
|
3670
3946
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3671
3947
|
value: batch2
|
|
@@ -3674,7 +3950,7 @@ function toS3(source, client, bucket, opts) {
|
|
|
3674
3950
|
}
|
|
3675
3951
|
};
|
|
3676
3952
|
const scheduleFlush = () => {
|
|
3677
|
-
if (timer === void 0) {
|
|
3953
|
+
if (timer === void 0 && !disposed) {
|
|
3678
3954
|
timer = setTimeout(() => {
|
|
3679
3955
|
timer = void 0;
|
|
3680
3956
|
doFlush();
|
|
@@ -3690,7 +3966,7 @@ function toS3(source, client, bucket, opts) {
|
|
|
3690
3966
|
try {
|
|
3691
3967
|
buffer2.push(transform(value));
|
|
3692
3968
|
} catch (err) {
|
|
3693
|
-
|
|
3969
|
+
handler({
|
|
3694
3970
|
stage: "serialize",
|
|
3695
3971
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3696
3972
|
value
|
|
@@ -3701,7 +3977,7 @@ function toS3(source, client, bucket, opts) {
|
|
|
3701
3977
|
else scheduleFlush();
|
|
3702
3978
|
return true;
|
|
3703
3979
|
}
|
|
3704
|
-
if (msg[0]
|
|
3980
|
+
if (messageTier(msg[0]) >= 3) {
|
|
3705
3981
|
doFlush();
|
|
3706
3982
|
}
|
|
3707
3983
|
return false;
|
|
@@ -3710,16 +3986,24 @@ function toS3(source, client, bucket, opts) {
|
|
|
3710
3986
|
const unsub = inner.subscribe(() => {
|
|
3711
3987
|
});
|
|
3712
3988
|
const dispose = () => {
|
|
3989
|
+
if (disposed) return;
|
|
3990
|
+
disposed = true;
|
|
3713
3991
|
if (timer !== void 0) {
|
|
3714
3992
|
clearTimeout(timer);
|
|
3715
3993
|
timer = void 0;
|
|
3716
3994
|
}
|
|
3717
3995
|
doFlush();
|
|
3718
3996
|
unsub();
|
|
3997
|
+
errorsNode.down([[TEARDOWN]]);
|
|
3719
3998
|
};
|
|
3720
3999
|
return {
|
|
3721
4000
|
dispose,
|
|
3722
|
-
|
|
4001
|
+
errors: errorsNode,
|
|
4002
|
+
flush: () => {
|
|
4003
|
+
const p = disposed ? Promise.resolve() : doFlush();
|
|
4004
|
+
return p.then(() => Promise.all(inFlight)).then(() => {
|
|
4005
|
+
});
|
|
4006
|
+
}
|
|
3723
4007
|
};
|
|
3724
4008
|
}
|
|
3725
4009
|
function toPostgres(source, client, table, opts) {
|
|
@@ -3731,6 +4015,7 @@ function toPostgres(source, client, table, opts) {
|
|
|
3731
4015
|
onTransportError,
|
|
3732
4016
|
...rest
|
|
3733
4017
|
} = opts ?? {};
|
|
4018
|
+
const { errorsNode, handler } = createSinkErrorHandler(onTransportError);
|
|
3734
4019
|
const inner = node([source], () => void 0, {
|
|
3735
4020
|
describeKind: "effect",
|
|
3736
4021
|
...rest,
|
|
@@ -3741,7 +4026,7 @@ function toPostgres(source, client, table, opts) {
|
|
|
3741
4026
|
try {
|
|
3742
4027
|
query = toSQL(value, table);
|
|
3743
4028
|
} catch (err) {
|
|
3744
|
-
|
|
4029
|
+
handler({
|
|
3745
4030
|
stage: "serialize",
|
|
3746
4031
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3747
4032
|
value
|
|
@@ -3749,7 +4034,7 @@ function toPostgres(source, client, table, opts) {
|
|
|
3749
4034
|
return true;
|
|
3750
4035
|
}
|
|
3751
4036
|
void client.query(query.sql, query.params).catch((err) => {
|
|
3752
|
-
|
|
4037
|
+
handler({
|
|
3753
4038
|
stage: "send",
|
|
3754
4039
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3755
4040
|
value
|
|
@@ -3760,11 +4045,19 @@ function toPostgres(source, client, table, opts) {
|
|
|
3760
4045
|
return false;
|
|
3761
4046
|
}
|
|
3762
4047
|
});
|
|
3763
|
-
|
|
4048
|
+
const unsub = inner.subscribe(() => {
|
|
3764
4049
|
});
|
|
4050
|
+
return {
|
|
4051
|
+
dispose: () => {
|
|
4052
|
+
unsub();
|
|
4053
|
+
errorsNode.down([[TEARDOWN]]);
|
|
4054
|
+
},
|
|
4055
|
+
errors: errorsNode
|
|
4056
|
+
};
|
|
3765
4057
|
}
|
|
3766
4058
|
function toMongo(source, collection, opts) {
|
|
3767
4059
|
const { toDocument = (v) => v, onTransportError, ...rest } = opts ?? {};
|
|
4060
|
+
const { errorsNode, handler } = createSinkErrorHandler(onTransportError);
|
|
3768
4061
|
const inner = node([source], () => void 0, {
|
|
3769
4062
|
describeKind: "effect",
|
|
3770
4063
|
...rest,
|
|
@@ -3775,7 +4068,7 @@ function toMongo(source, collection, opts) {
|
|
|
3775
4068
|
try {
|
|
3776
4069
|
doc = toDocument(value);
|
|
3777
4070
|
} catch (err) {
|
|
3778
|
-
|
|
4071
|
+
handler({
|
|
3779
4072
|
stage: "serialize",
|
|
3780
4073
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3781
4074
|
value
|
|
@@ -3783,7 +4076,7 @@ function toMongo(source, collection, opts) {
|
|
|
3783
4076
|
return true;
|
|
3784
4077
|
}
|
|
3785
4078
|
void collection.insertOne(doc).catch((err) => {
|
|
3786
|
-
|
|
4079
|
+
handler({
|
|
3787
4080
|
stage: "send",
|
|
3788
4081
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3789
4082
|
value
|
|
@@ -3794,8 +4087,15 @@ function toMongo(source, collection, opts) {
|
|
|
3794
4087
|
return false;
|
|
3795
4088
|
}
|
|
3796
4089
|
});
|
|
3797
|
-
|
|
4090
|
+
const unsub = inner.subscribe(() => {
|
|
3798
4091
|
});
|
|
4092
|
+
return {
|
|
4093
|
+
dispose: () => {
|
|
4094
|
+
unsub();
|
|
4095
|
+
errorsNode.down([[TEARDOWN]]);
|
|
4096
|
+
},
|
|
4097
|
+
errors: errorsNode
|
|
4098
|
+
};
|
|
3799
4099
|
}
|
|
3800
4100
|
function toLoki(source, client, opts) {
|
|
3801
4101
|
const {
|
|
@@ -3805,6 +4105,7 @@ function toLoki(source, client, opts) {
|
|
|
3805
4105
|
onTransportError,
|
|
3806
4106
|
...rest
|
|
3807
4107
|
} = opts ?? {};
|
|
4108
|
+
const { errorsNode, handler } = createSinkErrorHandler(onTransportError);
|
|
3808
4109
|
const inner = node([source], () => void 0, {
|
|
3809
4110
|
describeKind: "effect",
|
|
3810
4111
|
...rest,
|
|
@@ -3815,7 +4116,7 @@ function toLoki(source, client, opts) {
|
|
|
3815
4116
|
try {
|
|
3816
4117
|
line = toLine(value);
|
|
3817
4118
|
} catch (err) {
|
|
3818
|
-
|
|
4119
|
+
handler({
|
|
3819
4120
|
stage: "serialize",
|
|
3820
4121
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3821
4122
|
value
|
|
@@ -3826,7 +4127,7 @@ function toLoki(source, client, opts) {
|
|
|
3826
4127
|
try {
|
|
3827
4128
|
streamLabels = toLabels ? { ...labels, ...toLabels(value) } : labels;
|
|
3828
4129
|
} catch (err) {
|
|
3829
|
-
|
|
4130
|
+
handler({
|
|
3830
4131
|
stage: "serialize",
|
|
3831
4132
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3832
4133
|
value
|
|
@@ -3835,7 +4136,7 @@ function toLoki(source, client, opts) {
|
|
|
3835
4136
|
}
|
|
3836
4137
|
const ts = `${wallClockNs()}`;
|
|
3837
4138
|
void client.push({ streams: [{ stream: streamLabels, values: [[ts, line]] }] }).catch((err) => {
|
|
3838
|
-
|
|
4139
|
+
handler({
|
|
3839
4140
|
stage: "send",
|
|
3840
4141
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3841
4142
|
value
|
|
@@ -3846,11 +4147,19 @@ function toLoki(source, client, opts) {
|
|
|
3846
4147
|
return false;
|
|
3847
4148
|
}
|
|
3848
4149
|
});
|
|
3849
|
-
|
|
4150
|
+
const unsub = inner.subscribe(() => {
|
|
3850
4151
|
});
|
|
4152
|
+
return {
|
|
4153
|
+
dispose: () => {
|
|
4154
|
+
unsub();
|
|
4155
|
+
errorsNode.down([[TEARDOWN]]);
|
|
4156
|
+
},
|
|
4157
|
+
errors: errorsNode
|
|
4158
|
+
};
|
|
3851
4159
|
}
|
|
3852
4160
|
function toTempo(source, client, opts) {
|
|
3853
4161
|
const { toResourceSpans = (v) => [v], onTransportError, ...rest } = opts ?? {};
|
|
4162
|
+
const { errorsNode, handler } = createSinkErrorHandler(onTransportError);
|
|
3854
4163
|
const inner = node([source], () => void 0, {
|
|
3855
4164
|
describeKind: "effect",
|
|
3856
4165
|
...rest,
|
|
@@ -3861,7 +4170,7 @@ function toTempo(source, client, opts) {
|
|
|
3861
4170
|
try {
|
|
3862
4171
|
spans = toResourceSpans(value);
|
|
3863
4172
|
} catch (err) {
|
|
3864
|
-
|
|
4173
|
+
handler({
|
|
3865
4174
|
stage: "serialize",
|
|
3866
4175
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3867
4176
|
value
|
|
@@ -3869,7 +4178,7 @@ function toTempo(source, client, opts) {
|
|
|
3869
4178
|
return true;
|
|
3870
4179
|
}
|
|
3871
4180
|
void client.push({ resourceSpans: spans }).catch((err) => {
|
|
3872
|
-
|
|
4181
|
+
handler({
|
|
3873
4182
|
stage: "send",
|
|
3874
4183
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3875
4184
|
value
|
|
@@ -3880,15 +4189,22 @@ function toTempo(source, client, opts) {
|
|
|
3880
4189
|
return false;
|
|
3881
4190
|
}
|
|
3882
4191
|
});
|
|
3883
|
-
|
|
4192
|
+
const unsub = inner.subscribe(() => {
|
|
3884
4193
|
});
|
|
4194
|
+
return {
|
|
4195
|
+
dispose: () => {
|
|
4196
|
+
unsub();
|
|
4197
|
+
errorsNode.down([[TEARDOWN]]);
|
|
4198
|
+
},
|
|
4199
|
+
errors: errorsNode
|
|
4200
|
+
};
|
|
3885
4201
|
}
|
|
3886
4202
|
function checkpointToS3(graph, client, bucket, opts) {
|
|
3887
4203
|
const { prefix = "checkpoints/", debounceMs, compactEvery, onError } = opts ?? {};
|
|
3888
4204
|
const adapter = {
|
|
3889
|
-
save(data) {
|
|
4205
|
+
save(_key, data) {
|
|
3890
4206
|
const ms = Math.floor(wallClockNs() / 1e6);
|
|
3891
|
-
const
|
|
4207
|
+
const s3Key = `${prefix}${graph.name}/checkpoint-${ms}.json`;
|
|
3892
4208
|
let body;
|
|
3893
4209
|
try {
|
|
3894
4210
|
body = JSON.stringify(data);
|
|
@@ -3898,7 +4214,7 @@ function checkpointToS3(graph, client, bucket, opts) {
|
|
|
3898
4214
|
}
|
|
3899
4215
|
void client.putObject({
|
|
3900
4216
|
Bucket: bucket,
|
|
3901
|
-
Key:
|
|
4217
|
+
Key: s3Key,
|
|
3902
4218
|
Body: body,
|
|
3903
4219
|
ContentType: "application/json"
|
|
3904
4220
|
}).catch((err) => onError?.(err));
|
|
@@ -3908,9 +4224,9 @@ function checkpointToS3(graph, client, bucket, opts) {
|
|
|
3908
4224
|
}
|
|
3909
4225
|
function checkpointToRedis(graph, client, opts) {
|
|
3910
4226
|
const { prefix = "graphrefly:checkpoint:", debounceMs, compactEvery, onError } = opts ?? {};
|
|
3911
|
-
const
|
|
4227
|
+
const redisKey = `${prefix}${graph.name}`;
|
|
3912
4228
|
const adapter = {
|
|
3913
|
-
save(data) {
|
|
4229
|
+
save(_key, data) {
|
|
3914
4230
|
let body;
|
|
3915
4231
|
try {
|
|
3916
4232
|
body = JSON.stringify(data);
|
|
@@ -3918,7 +4234,7 @@ function checkpointToRedis(graph, client, opts) {
|
|
|
3918
4234
|
onError?.(err);
|
|
3919
4235
|
return;
|
|
3920
4236
|
}
|
|
3921
|
-
void client.set(
|
|
4237
|
+
void client.set(redisKey, body).catch((err) => onError?.(err));
|
|
3922
4238
|
}
|
|
3923
4239
|
};
|
|
3924
4240
|
return graph.autoCheckpoint(adapter, { debounceMs, compactEvery, onError });
|
|
@@ -3956,8 +4272,67 @@ function toSqlite(source, db, table, opts) {
|
|
|
3956
4272
|
params: [JSON.stringify(v)]
|
|
3957
4273
|
}),
|
|
3958
4274
|
onTransportError,
|
|
4275
|
+
batchInsert = false,
|
|
4276
|
+
maxBatchSize = 1e3,
|
|
4277
|
+
flushIntervalMs = 0,
|
|
3959
4278
|
...rest
|
|
3960
4279
|
} = opts ?? {};
|
|
4280
|
+
const { errorsNode, handler } = createSinkErrorHandler(onTransportError);
|
|
4281
|
+
const pendingInserts = [];
|
|
4282
|
+
let flushing = false;
|
|
4283
|
+
let disposed = false;
|
|
4284
|
+
let timer;
|
|
4285
|
+
function flushTransaction() {
|
|
4286
|
+
if (pendingInserts.length === 0 || flushing) return;
|
|
4287
|
+
flushing = true;
|
|
4288
|
+
try {
|
|
4289
|
+
db.query("BEGIN", []);
|
|
4290
|
+
} catch (err) {
|
|
4291
|
+
flushing = false;
|
|
4292
|
+
handler({
|
|
4293
|
+
stage: "send",
|
|
4294
|
+
error: err instanceof Error ? err : new Error(String(err)),
|
|
4295
|
+
value: void 0
|
|
4296
|
+
});
|
|
4297
|
+
return;
|
|
4298
|
+
}
|
|
4299
|
+
const batch2 = pendingInserts.splice(0);
|
|
4300
|
+
let firstError;
|
|
4301
|
+
for (const q of batch2) {
|
|
4302
|
+
try {
|
|
4303
|
+
db.query(q.sql, q.params);
|
|
4304
|
+
} catch (err) {
|
|
4305
|
+
firstError = err instanceof Error ? err : new Error(String(err));
|
|
4306
|
+
break;
|
|
4307
|
+
}
|
|
4308
|
+
}
|
|
4309
|
+
if (firstError) {
|
|
4310
|
+
try {
|
|
4311
|
+
db.query("ROLLBACK", []);
|
|
4312
|
+
} catch {
|
|
4313
|
+
}
|
|
4314
|
+
handler({ stage: "send", error: firstError, value: void 0 });
|
|
4315
|
+
} else {
|
|
4316
|
+
try {
|
|
4317
|
+
db.query("COMMIT", []);
|
|
4318
|
+
} catch (err) {
|
|
4319
|
+
handler({
|
|
4320
|
+
stage: "send",
|
|
4321
|
+
error: err instanceof Error ? err : new Error(String(err)),
|
|
4322
|
+
value: void 0
|
|
4323
|
+
});
|
|
4324
|
+
}
|
|
4325
|
+
}
|
|
4326
|
+
flushing = false;
|
|
4327
|
+
}
|
|
4328
|
+
const scheduleFlush = () => {
|
|
4329
|
+
if (batchInsert && flushIntervalMs > 0 && timer === void 0 && !disposed) {
|
|
4330
|
+
timer = setTimeout(() => {
|
|
4331
|
+
timer = void 0;
|
|
4332
|
+
flushTransaction();
|
|
4333
|
+
}, flushIntervalMs);
|
|
4334
|
+
}
|
|
4335
|
+
};
|
|
3961
4336
|
const inner = node([source], () => void 0, {
|
|
3962
4337
|
describeKind: "effect",
|
|
3963
4338
|
...rest,
|
|
@@ -3968,29 +4343,140 @@ function toSqlite(source, db, table, opts) {
|
|
|
3968
4343
|
try {
|
|
3969
4344
|
query = toSQL(value, table);
|
|
3970
4345
|
} catch (err) {
|
|
3971
|
-
|
|
4346
|
+
handler({
|
|
3972
4347
|
stage: "serialize",
|
|
3973
4348
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
3974
4349
|
value
|
|
3975
4350
|
});
|
|
3976
4351
|
return true;
|
|
3977
4352
|
}
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
})
|
|
4353
|
+
if (batchInsert) {
|
|
4354
|
+
pendingInserts.push(query);
|
|
4355
|
+
if (pendingInserts.length >= maxBatchSize) flushTransaction();
|
|
4356
|
+
else scheduleFlush();
|
|
4357
|
+
} else {
|
|
4358
|
+
try {
|
|
4359
|
+
db.query(query.sql, query.params);
|
|
4360
|
+
} catch (err) {
|
|
4361
|
+
handler({
|
|
4362
|
+
stage: "send",
|
|
4363
|
+
error: err instanceof Error ? err : new Error(String(err)),
|
|
4364
|
+
value
|
|
4365
|
+
});
|
|
4366
|
+
}
|
|
3986
4367
|
}
|
|
3987
4368
|
return true;
|
|
3988
4369
|
}
|
|
4370
|
+
if (batchInsert && messageTier(msg[0]) >= 3) {
|
|
4371
|
+
flushTransaction();
|
|
4372
|
+
}
|
|
3989
4373
|
return false;
|
|
3990
4374
|
}
|
|
3991
4375
|
});
|
|
3992
|
-
|
|
4376
|
+
const unsub = inner.subscribe(() => {
|
|
3993
4377
|
});
|
|
4378
|
+
const dispose = () => {
|
|
4379
|
+
if (disposed) return;
|
|
4380
|
+
disposed = true;
|
|
4381
|
+
if (timer !== void 0) {
|
|
4382
|
+
clearTimeout(timer);
|
|
4383
|
+
timer = void 0;
|
|
4384
|
+
}
|
|
4385
|
+
if (batchInsert) flushTransaction();
|
|
4386
|
+
unsub();
|
|
4387
|
+
errorsNode.down([[TEARDOWN]]);
|
|
4388
|
+
};
|
|
4389
|
+
return {
|
|
4390
|
+
dispose,
|
|
4391
|
+
errors: errorsNode,
|
|
4392
|
+
flush: batchInsert ? async () => {
|
|
4393
|
+
if (!disposed) flushTransaction();
|
|
4394
|
+
} : void 0
|
|
4395
|
+
};
|
|
4396
|
+
}
|
|
4397
|
+
function fromPrisma(model, opts) {
|
|
4398
|
+
const { args, mapRow = (r) => r, ...rest } = opts ?? {};
|
|
4399
|
+
return producer(
|
|
4400
|
+
(_d, a) => {
|
|
4401
|
+
let active = true;
|
|
4402
|
+
void model.findMany(args).then((rows) => {
|
|
4403
|
+
if (!active) return;
|
|
4404
|
+
const mapped = rows.map(mapRow);
|
|
4405
|
+
batch(() => {
|
|
4406
|
+
for (const item of mapped) {
|
|
4407
|
+
a.emit(item);
|
|
4408
|
+
}
|
|
4409
|
+
});
|
|
4410
|
+
a.down([[COMPLETE]]);
|
|
4411
|
+
}).catch((err) => {
|
|
4412
|
+
if (!active) return;
|
|
4413
|
+
try {
|
|
4414
|
+
a.down([[ERROR, err instanceof Error ? err : new Error(String(err))]]);
|
|
4415
|
+
} catch {
|
|
4416
|
+
}
|
|
4417
|
+
});
|
|
4418
|
+
return () => {
|
|
4419
|
+
active = false;
|
|
4420
|
+
};
|
|
4421
|
+
},
|
|
4422
|
+
{ ...rest, describeKind: "producer", completeWhenDepsComplete: false }
|
|
4423
|
+
);
|
|
4424
|
+
}
|
|
4425
|
+
function fromDrizzle(query, opts) {
|
|
4426
|
+
const { mapRow = (r) => r, ...rest } = opts ?? {};
|
|
4427
|
+
return producer(
|
|
4428
|
+
(_d, a) => {
|
|
4429
|
+
let active = true;
|
|
4430
|
+
void query.execute().then((rows) => {
|
|
4431
|
+
if (!active) return;
|
|
4432
|
+
const mapped = rows.map(mapRow);
|
|
4433
|
+
batch(() => {
|
|
4434
|
+
for (const item of mapped) {
|
|
4435
|
+
a.emit(item);
|
|
4436
|
+
}
|
|
4437
|
+
});
|
|
4438
|
+
a.down([[COMPLETE]]);
|
|
4439
|
+
}).catch((err) => {
|
|
4440
|
+
if (!active) return;
|
|
4441
|
+
try {
|
|
4442
|
+
a.down([[ERROR, err instanceof Error ? err : new Error(String(err))]]);
|
|
4443
|
+
} catch {
|
|
4444
|
+
}
|
|
4445
|
+
});
|
|
4446
|
+
return () => {
|
|
4447
|
+
active = false;
|
|
4448
|
+
};
|
|
4449
|
+
},
|
|
4450
|
+
{ ...rest, describeKind: "producer", completeWhenDepsComplete: false }
|
|
4451
|
+
);
|
|
4452
|
+
}
|
|
4453
|
+
function fromKysely(query, opts) {
|
|
4454
|
+
const { mapRow = (r) => r, ...rest } = opts ?? {};
|
|
4455
|
+
return producer(
|
|
4456
|
+
(_d, a) => {
|
|
4457
|
+
let active = true;
|
|
4458
|
+
void query.execute().then((rows) => {
|
|
4459
|
+
if (!active) return;
|
|
4460
|
+
const mapped = rows.map(mapRow);
|
|
4461
|
+
batch(() => {
|
|
4462
|
+
for (const item of mapped) {
|
|
4463
|
+
a.emit(item);
|
|
4464
|
+
}
|
|
4465
|
+
});
|
|
4466
|
+
a.down([[COMPLETE]]);
|
|
4467
|
+
}).catch((err) => {
|
|
4468
|
+
if (!active) return;
|
|
4469
|
+
try {
|
|
4470
|
+
a.down([[ERROR, err instanceof Error ? err : new Error(String(err))]]);
|
|
4471
|
+
} catch {
|
|
4472
|
+
}
|
|
4473
|
+
});
|
|
4474
|
+
return () => {
|
|
4475
|
+
active = false;
|
|
4476
|
+
};
|
|
4477
|
+
},
|
|
4478
|
+
{ ...rest, describeKind: "producer", completeWhenDepsComplete: false }
|
|
4479
|
+
);
|
|
3994
4480
|
}
|
|
3995
4481
|
|
|
3996
4482
|
// src/extra/backpressure.ts
|
|
@@ -4037,6 +4523,205 @@ function createWatermarkController(sendUp, opts) {
|
|
|
4037
4523
|
};
|
|
4038
4524
|
}
|
|
4039
4525
|
|
|
4526
|
+
// src/extra/cascading-cache.ts
|
|
4527
|
+
function lru() {
|
|
4528
|
+
const map2 = /* @__PURE__ */ new Map();
|
|
4529
|
+
let head = null;
|
|
4530
|
+
let tail = null;
|
|
4531
|
+
function unlink(n) {
|
|
4532
|
+
if (n.prev) n.prev.next = n.next;
|
|
4533
|
+
else head = n.next;
|
|
4534
|
+
if (n.next) n.next.prev = n.prev;
|
|
4535
|
+
else tail = n.prev;
|
|
4536
|
+
n.prev = null;
|
|
4537
|
+
n.next = null;
|
|
4538
|
+
}
|
|
4539
|
+
function pushFront(n) {
|
|
4540
|
+
n.next = head;
|
|
4541
|
+
n.prev = null;
|
|
4542
|
+
if (head) head.prev = n;
|
|
4543
|
+
head = n;
|
|
4544
|
+
if (tail === null) tail = n;
|
|
4545
|
+
}
|
|
4546
|
+
return {
|
|
4547
|
+
insert(key) {
|
|
4548
|
+
if (map2.has(key)) {
|
|
4549
|
+
this.touch(key);
|
|
4550
|
+
return;
|
|
4551
|
+
}
|
|
4552
|
+
const n = { key, prev: null, next: null };
|
|
4553
|
+
map2.set(key, n);
|
|
4554
|
+
pushFront(n);
|
|
4555
|
+
},
|
|
4556
|
+
touch(key) {
|
|
4557
|
+
const n = map2.get(key);
|
|
4558
|
+
if (!n) return;
|
|
4559
|
+
unlink(n);
|
|
4560
|
+
pushFront(n);
|
|
4561
|
+
},
|
|
4562
|
+
delete(key) {
|
|
4563
|
+
const n = map2.get(key);
|
|
4564
|
+
if (!n) return;
|
|
4565
|
+
unlink(n);
|
|
4566
|
+
map2.delete(key);
|
|
4567
|
+
},
|
|
4568
|
+
evict(count) {
|
|
4569
|
+
const victims = [];
|
|
4570
|
+
for (let i = 0; i < count && tail !== null; i++) {
|
|
4571
|
+
const n = tail;
|
|
4572
|
+
victims.push(n.key);
|
|
4573
|
+
unlink(n);
|
|
4574
|
+
map2.delete(n.key);
|
|
4575
|
+
}
|
|
4576
|
+
return victims;
|
|
4577
|
+
},
|
|
4578
|
+
size() {
|
|
4579
|
+
return map2.size;
|
|
4580
|
+
}
|
|
4581
|
+
};
|
|
4582
|
+
}
|
|
4583
|
+
function cascadingCache(tiers, opts) {
|
|
4584
|
+
const entries = /* @__PURE__ */ new Map();
|
|
4585
|
+
const maxSize = opts?.maxSize ?? 0;
|
|
4586
|
+
const policy = maxSize > 0 ? opts?.eviction ?? lru() : null;
|
|
4587
|
+
const writeThrough = opts?.writeThrough ?? false;
|
|
4588
|
+
function promote(key, value, hitTierIndex) {
|
|
4589
|
+
for (let i = 0; i < hitTierIndex; i++) {
|
|
4590
|
+
const tier = tiers[i];
|
|
4591
|
+
if (tier.save) tier.save(key, value);
|
|
4592
|
+
}
|
|
4593
|
+
}
|
|
4594
|
+
function cascade(key, nd) {
|
|
4595
|
+
for (let tierIndex = 0; tierIndex < tiers.length; tierIndex++) {
|
|
4596
|
+
let result;
|
|
4597
|
+
try {
|
|
4598
|
+
result = tiers[tierIndex].load(key);
|
|
4599
|
+
} catch {
|
|
4600
|
+
continue;
|
|
4601
|
+
}
|
|
4602
|
+
if (result != null) {
|
|
4603
|
+
nd.down([[DATA, result]]);
|
|
4604
|
+
promote(key, result, tierIndex);
|
|
4605
|
+
return;
|
|
4606
|
+
}
|
|
4607
|
+
}
|
|
4608
|
+
}
|
|
4609
|
+
function evictIfNeeded() {
|
|
4610
|
+
if (!policy || maxSize <= 0) return;
|
|
4611
|
+
while (policy.size() >= maxSize) {
|
|
4612
|
+
const victims = policy.evict(1);
|
|
4613
|
+
if (victims.length === 0) break;
|
|
4614
|
+
for (const key of victims) {
|
|
4615
|
+
const nd = entries.get(key);
|
|
4616
|
+
if (nd) {
|
|
4617
|
+
const value = nd.get();
|
|
4618
|
+
if (value !== void 0) {
|
|
4619
|
+
for (let i = tiers.length - 1; i >= 0; i--) {
|
|
4620
|
+
if (tiers[i].save) {
|
|
4621
|
+
tiers[i].save(key, value);
|
|
4622
|
+
for (let j = 0; j < i; j++) {
|
|
4623
|
+
if (tiers[j].clear) tiers[j].clear(key);
|
|
4624
|
+
}
|
|
4625
|
+
break;
|
|
4626
|
+
}
|
|
4627
|
+
}
|
|
4628
|
+
}
|
|
4629
|
+
nd.down([[TEARDOWN]]);
|
|
4630
|
+
}
|
|
4631
|
+
entries.delete(key);
|
|
4632
|
+
}
|
|
4633
|
+
}
|
|
4634
|
+
}
|
|
4635
|
+
return {
|
|
4636
|
+
load(key) {
|
|
4637
|
+
const existing = entries.get(key);
|
|
4638
|
+
if (existing) {
|
|
4639
|
+
policy?.touch(key);
|
|
4640
|
+
return existing;
|
|
4641
|
+
}
|
|
4642
|
+
if (policy && maxSize > 0 && policy.size() >= maxSize) {
|
|
4643
|
+
evictIfNeeded();
|
|
4644
|
+
}
|
|
4645
|
+
const nd = state(void 0);
|
|
4646
|
+
entries.set(key, nd);
|
|
4647
|
+
if (policy) {
|
|
4648
|
+
policy.insert(key);
|
|
4649
|
+
}
|
|
4650
|
+
cascade(key, nd);
|
|
4651
|
+
return nd;
|
|
4652
|
+
},
|
|
4653
|
+
save(key, value) {
|
|
4654
|
+
if (writeThrough) {
|
|
4655
|
+
for (const tier of tiers) {
|
|
4656
|
+
if (tier.save) tier.save(key, value);
|
|
4657
|
+
}
|
|
4658
|
+
} else if (tiers[0]?.save) {
|
|
4659
|
+
tiers[0].save(key, value);
|
|
4660
|
+
}
|
|
4661
|
+
const existing = entries.get(key);
|
|
4662
|
+
if (existing) {
|
|
4663
|
+
existing.down([[DATA, value]]);
|
|
4664
|
+
policy?.touch(key);
|
|
4665
|
+
} else {
|
|
4666
|
+
if (policy && maxSize > 0 && policy.size() >= maxSize) {
|
|
4667
|
+
evictIfNeeded();
|
|
4668
|
+
}
|
|
4669
|
+
const nd = state(value);
|
|
4670
|
+
entries.set(key, nd);
|
|
4671
|
+
if (policy) {
|
|
4672
|
+
policy.insert(key);
|
|
4673
|
+
}
|
|
4674
|
+
}
|
|
4675
|
+
},
|
|
4676
|
+
invalidate(key) {
|
|
4677
|
+
const existing = entries.get(key);
|
|
4678
|
+
if (existing) {
|
|
4679
|
+
cascade(key, existing);
|
|
4680
|
+
}
|
|
4681
|
+
},
|
|
4682
|
+
delete(key) {
|
|
4683
|
+
policy?.delete(key);
|
|
4684
|
+
const nd = entries.get(key);
|
|
4685
|
+
if (nd) nd.down([[TEARDOWN]]);
|
|
4686
|
+
entries.delete(key);
|
|
4687
|
+
for (const tier of tiers) {
|
|
4688
|
+
if (tier.clear) tier.clear(key);
|
|
4689
|
+
}
|
|
4690
|
+
},
|
|
4691
|
+
has(key) {
|
|
4692
|
+
return entries.has(key);
|
|
4693
|
+
},
|
|
4694
|
+
get size() {
|
|
4695
|
+
return entries.size;
|
|
4696
|
+
}
|
|
4697
|
+
};
|
|
4698
|
+
}
|
|
4699
|
+
function adapterToTier(adapter) {
|
|
4700
|
+
return {
|
|
4701
|
+
load: (key) => adapter.load(key),
|
|
4702
|
+
save: (key, value) => adapter.save(key, value),
|
|
4703
|
+
clear: (key) => adapter.clear(key)
|
|
4704
|
+
};
|
|
4705
|
+
}
|
|
4706
|
+
function tieredStorage(adapters, opts) {
|
|
4707
|
+
const inner = cascadingCache(adapters.map(adapterToTier), {
|
|
4708
|
+
maxSize: opts?.maxSize,
|
|
4709
|
+
eviction: opts?.eviction,
|
|
4710
|
+
writeThrough: true
|
|
4711
|
+
});
|
|
4712
|
+
return {
|
|
4713
|
+
load: (key) => inner.load(key),
|
|
4714
|
+
save: (key, value) => inner.save(key, value),
|
|
4715
|
+
invalidate: (key) => inner.invalidate(key),
|
|
4716
|
+
delete: (key) => inner.delete(key),
|
|
4717
|
+
has: (key) => inner.has(key),
|
|
4718
|
+
get size() {
|
|
4719
|
+
return inner.size;
|
|
4720
|
+
},
|
|
4721
|
+
cache: inner
|
|
4722
|
+
};
|
|
4723
|
+
}
|
|
4724
|
+
|
|
4040
4725
|
// src/extra/checkpoint.ts
|
|
4041
4726
|
var import_node_crypto2 = require("crypto");
|
|
4042
4727
|
var import_node_fs2 = require("fs");
|
|
@@ -4057,60 +4742,61 @@ function sortJsonValue(value) {
|
|
|
4057
4742
|
}
|
|
4058
4743
|
return out;
|
|
4059
4744
|
}
|
|
4060
|
-
function
|
|
4061
|
-
for (const [path, node2] of Object.entries(data.nodes)) {
|
|
4062
|
-
const v = node2.value;
|
|
4063
|
-
if (v === void 0 || v === null) continue;
|
|
4064
|
-
if (typeof v === "function" || typeof v === "symbol" || typeof v === "bigint") {
|
|
4065
|
-
console.warn(
|
|
4066
|
-
`checkpoint: node "${path}" has non-JSON-serializable value (${typeof v}); it will be lost on round-trip`
|
|
4067
|
-
);
|
|
4068
|
-
}
|
|
4069
|
-
}
|
|
4070
|
-
}
|
|
4071
|
-
function stableSnapshotJson(data) {
|
|
4072
|
-
warnNonJsonValues(data);
|
|
4745
|
+
function stableJsonString(data) {
|
|
4073
4746
|
return `${JSON.stringify(sortJsonValue(data), void 0, 0)}
|
|
4074
4747
|
`;
|
|
4075
4748
|
}
|
|
4076
4749
|
var MemoryCheckpointAdapter = class {
|
|
4077
|
-
#data =
|
|
4078
|
-
save(data) {
|
|
4079
|
-
this.#data
|
|
4750
|
+
#data = /* @__PURE__ */ new Map();
|
|
4751
|
+
save(key, data) {
|
|
4752
|
+
this.#data.set(key, JSON.parse(JSON.stringify(data)));
|
|
4753
|
+
}
|
|
4754
|
+
load(key) {
|
|
4755
|
+
const v = this.#data.get(key);
|
|
4756
|
+
return v === void 0 ? null : JSON.parse(JSON.stringify(v));
|
|
4080
4757
|
}
|
|
4081
|
-
|
|
4082
|
-
|
|
4758
|
+
clear(key) {
|
|
4759
|
+
this.#data.delete(key);
|
|
4083
4760
|
}
|
|
4084
4761
|
};
|
|
4085
4762
|
var DictCheckpointAdapter = class {
|
|
4086
4763
|
#storage;
|
|
4087
|
-
|
|
4088
|
-
constructor(storage, key = "graphrefly_checkpoint") {
|
|
4764
|
+
constructor(storage) {
|
|
4089
4765
|
this.#storage = storage;
|
|
4090
|
-
this.#key = key;
|
|
4091
4766
|
}
|
|
4092
|
-
save(data) {
|
|
4093
|
-
this.#storage[
|
|
4767
|
+
save(key, data) {
|
|
4768
|
+
this.#storage[key] = JSON.parse(JSON.stringify(data));
|
|
4769
|
+
}
|
|
4770
|
+
load(key) {
|
|
4771
|
+
const raw = this.#storage[key];
|
|
4772
|
+
return raw === void 0 ? null : JSON.parse(JSON.stringify(raw));
|
|
4094
4773
|
}
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
return raw !== null && typeof raw === "object" && !Array.isArray(raw) ? JSON.parse(JSON.stringify(raw)) : null;
|
|
4774
|
+
clear(key) {
|
|
4775
|
+
delete this.#storage[key];
|
|
4098
4776
|
}
|
|
4099
4777
|
};
|
|
4100
4778
|
var FileCheckpointAdapter = class {
|
|
4101
|
-
#
|
|
4102
|
-
constructor(
|
|
4103
|
-
this.#
|
|
4104
|
-
}
|
|
4105
|
-
|
|
4106
|
-
const
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4779
|
+
#dir;
|
|
4780
|
+
constructor(dir) {
|
|
4781
|
+
this.#dir = dir;
|
|
4782
|
+
}
|
|
4783
|
+
#pathFor(key) {
|
|
4784
|
+
const safeName = key.replace(
|
|
4785
|
+
/[^a-zA-Z0-9_-]/g,
|
|
4786
|
+
(c) => `%${c.charCodeAt(0).toString(16).padStart(2, "0")}`
|
|
4787
|
+
);
|
|
4788
|
+
return (0, import_node_path2.join)(this.#dir, `${safeName}.json`);
|
|
4789
|
+
}
|
|
4790
|
+
save(key, data) {
|
|
4791
|
+
(0, import_node_fs2.mkdirSync)(this.#dir, { recursive: true });
|
|
4792
|
+
const filePath = this.#pathFor(key);
|
|
4793
|
+
const payload = stableJsonString(data);
|
|
4794
|
+
const base = (0, import_node_path2.basename)(filePath);
|
|
4795
|
+
const dir = (0, import_node_path2.dirname)(filePath);
|
|
4110
4796
|
const tmp = (0, import_node_path2.join)(dir, `.${base}.${(0, import_node_crypto2.randomBytes)(8).toString("hex")}.tmp`);
|
|
4111
4797
|
try {
|
|
4112
4798
|
(0, import_node_fs2.writeFileSync)(tmp, payload, "utf8");
|
|
4113
|
-
(0, import_node_fs2.renameSync)(tmp,
|
|
4799
|
+
(0, import_node_fs2.renameSync)(tmp, filePath);
|
|
4114
4800
|
} catch (e) {
|
|
4115
4801
|
try {
|
|
4116
4802
|
(0, import_node_fs2.unlinkSync)(tmp);
|
|
@@ -4119,36 +4805,42 @@ var FileCheckpointAdapter = class {
|
|
|
4119
4805
|
throw e;
|
|
4120
4806
|
}
|
|
4121
4807
|
}
|
|
4122
|
-
load() {
|
|
4808
|
+
load(key) {
|
|
4123
4809
|
try {
|
|
4124
|
-
const text = (0, import_node_fs2.readFileSync)(this.#
|
|
4810
|
+
const text = (0, import_node_fs2.readFileSync)(this.#pathFor(key), "utf8").trim();
|
|
4125
4811
|
if (!text) return null;
|
|
4126
|
-
|
|
4127
|
-
return data !== null && typeof data === "object" && !Array.isArray(data) ? data : null;
|
|
4812
|
+
return JSON.parse(text);
|
|
4128
4813
|
} catch {
|
|
4129
4814
|
return null;
|
|
4130
4815
|
}
|
|
4131
4816
|
}
|
|
4817
|
+
clear(key) {
|
|
4818
|
+
try {
|
|
4819
|
+
(0, import_node_fs2.unlinkSync)(this.#pathFor(key));
|
|
4820
|
+
} catch (e) {
|
|
4821
|
+
if (e.code !== "ENOENT") throw e;
|
|
4822
|
+
}
|
|
4823
|
+
}
|
|
4132
4824
|
};
|
|
4133
4825
|
var SqliteCheckpointAdapter = class {
|
|
4134
4826
|
#db;
|
|
4135
|
-
|
|
4136
|
-
constructor(path, key = "graphrefly_checkpoint") {
|
|
4827
|
+
constructor(path) {
|
|
4137
4828
|
this.#db = new import_node_sqlite.DatabaseSync(path);
|
|
4138
|
-
this.#key = key;
|
|
4139
4829
|
this.#db.exec(
|
|
4140
4830
|
`CREATE TABLE IF NOT EXISTS graphrefly_checkpoint (k TEXT PRIMARY KEY, v TEXT NOT NULL)`
|
|
4141
4831
|
);
|
|
4142
4832
|
}
|
|
4143
|
-
save(data) {
|
|
4144
|
-
const payload =
|
|
4145
|
-
this.#db.prepare(`INSERT OR REPLACE INTO graphrefly_checkpoint (k, v) VALUES (?, ?)`).run(
|
|
4833
|
+
save(key, data) {
|
|
4834
|
+
const payload = stableJsonString(data).trimEnd();
|
|
4835
|
+
this.#db.prepare(`INSERT OR REPLACE INTO graphrefly_checkpoint (k, v) VALUES (?, ?)`).run(key, payload);
|
|
4146
4836
|
}
|
|
4147
|
-
load() {
|
|
4148
|
-
const row = this.#db.prepare(`SELECT v FROM graphrefly_checkpoint WHERE k = ?`).get(
|
|
4837
|
+
load(key) {
|
|
4838
|
+
const row = this.#db.prepare(`SELECT v FROM graphrefly_checkpoint WHERE k = ?`).get(key);
|
|
4149
4839
|
if (row === void 0 || typeof row.v !== "string" || row.v.trim() === "") return null;
|
|
4150
|
-
|
|
4151
|
-
|
|
4840
|
+
return JSON.parse(row.v);
|
|
4841
|
+
}
|
|
4842
|
+
clear(key) {
|
|
4843
|
+
this.#db.prepare(`DELETE FROM graphrefly_checkpoint WHERE k = ?`).run(key);
|
|
4152
4844
|
}
|
|
4153
4845
|
/** Close the underlying SQLite connection (safe to call more than once). */
|
|
4154
4846
|
close() {
|
|
@@ -4159,10 +4851,10 @@ var SqliteCheckpointAdapter = class {
|
|
|
4159
4851
|
}
|
|
4160
4852
|
};
|
|
4161
4853
|
function saveGraphCheckpoint(graph, adapter) {
|
|
4162
|
-
adapter.save(graph.snapshot());
|
|
4854
|
+
adapter.save(graph.name, graph.snapshot());
|
|
4163
4855
|
}
|
|
4164
4856
|
function restoreGraphCheckpoint(graph, adapter) {
|
|
4165
|
-
const data = adapter.load();
|
|
4857
|
+
const data = adapter.load(graph.name);
|
|
4166
4858
|
if (data === null) return false;
|
|
4167
4859
|
graph.restore(data);
|
|
4168
4860
|
return true;
|
|
@@ -4451,7 +5143,7 @@ var DynamicNodeImpl = class {
|
|
|
4451
5143
|
_actions;
|
|
4452
5144
|
_boundEmitToSinks;
|
|
4453
5145
|
// Mutable state
|
|
4454
|
-
_cached;
|
|
5146
|
+
_cached = NO_VALUE;
|
|
4455
5147
|
_status = "disconnected";
|
|
4456
5148
|
_terminal = false;
|
|
4457
5149
|
_connected = false;
|
|
@@ -4545,7 +5237,7 @@ var DynamicNodeImpl = class {
|
|
|
4545
5237
|
return this._guard(normalizeActor(actor), "observe");
|
|
4546
5238
|
}
|
|
4547
5239
|
get() {
|
|
4548
|
-
return this._cached;
|
|
5240
|
+
return this._cached === NO_VALUE ? void 0 : this._cached;
|
|
4549
5241
|
}
|
|
4550
5242
|
down(messages, options) {
|
|
4551
5243
|
if (messages.length === 0) return;
|
|
@@ -4603,6 +5295,7 @@ var DynamicNodeImpl = class {
|
|
|
4603
5295
|
}
|
|
4604
5296
|
if (this._terminal && this._resubscribable) {
|
|
4605
5297
|
this._terminal = false;
|
|
5298
|
+
this._cached = NO_VALUE;
|
|
4606
5299
|
this._status = "disconnected";
|
|
4607
5300
|
this._onResubscribe?.();
|
|
4608
5301
|
}
|
|
@@ -4680,10 +5373,13 @@ var DynamicNodeImpl = class {
|
|
|
4680
5373
|
const t = m[0];
|
|
4681
5374
|
if (t === DATA) this._cached = m[1];
|
|
4682
5375
|
if (t === INVALIDATE) {
|
|
4683
|
-
this._cached =
|
|
5376
|
+
this._cached = NO_VALUE;
|
|
5377
|
+
this._status = "dirty";
|
|
4684
5378
|
}
|
|
4685
|
-
if (t === DATA
|
|
5379
|
+
if (t === DATA) {
|
|
4686
5380
|
this._status = "settled";
|
|
5381
|
+
} else if (t === RESOLVED) {
|
|
5382
|
+
this._status = "resolved";
|
|
4687
5383
|
} else if (t === DIRTY) {
|
|
4688
5384
|
this._status = "dirty";
|
|
4689
5385
|
} else if (t === COMPLETE) {
|
|
@@ -4694,7 +5390,7 @@ var DynamicNodeImpl = class {
|
|
|
4694
5390
|
this._terminal = true;
|
|
4695
5391
|
}
|
|
4696
5392
|
if (t === TEARDOWN) {
|
|
4697
|
-
if (this._resetOnTeardown) this._cached =
|
|
5393
|
+
if (this._resetOnTeardown) this._cached = NO_VALUE;
|
|
4698
5394
|
try {
|
|
4699
5395
|
this._propagateToMeta(t);
|
|
4700
5396
|
} finally {
|
|
@@ -4717,7 +5413,15 @@ var DynamicNodeImpl = class {
|
|
|
4717
5413
|
}
|
|
4718
5414
|
_emitAutoValue(value) {
|
|
4719
5415
|
const wasDirty = this._status === "dirty";
|
|
4720
|
-
|
|
5416
|
+
let unchanged;
|
|
5417
|
+
try {
|
|
5418
|
+
unchanged = this._cached !== NO_VALUE && this._equals(this._cached, value);
|
|
5419
|
+
} catch (eqErr) {
|
|
5420
|
+
const eqMsg = eqErr instanceof Error ? eqErr.message : String(eqErr);
|
|
5421
|
+
const wrapped = new Error(`Node "${this.name}": equals threw: ${eqMsg}`, { cause: eqErr });
|
|
5422
|
+
this._downInternal([[ERROR, wrapped]]);
|
|
5423
|
+
return;
|
|
5424
|
+
}
|
|
4721
5425
|
if (unchanged) {
|
|
4722
5426
|
this._downInternal(wasDirty ? [[RESOLVED]] : [[DIRTY], [RESOLVED]]);
|
|
4723
5427
|
return;
|
|
@@ -6027,48 +6731,6 @@ function audit(source, ms, opts) {
|
|
|
6027
6731
|
}
|
|
6028
6732
|
});
|
|
6029
6733
|
}
|
|
6030
|
-
function timeout(source, ms, opts) {
|
|
6031
|
-
const { with: withPayload, ...timeoutNodeOpts } = opts ?? {};
|
|
6032
|
-
let timer;
|
|
6033
|
-
const err = withPayload ?? new Error("timeout");
|
|
6034
|
-
function arm(a) {
|
|
6035
|
-
clearTimeout(timer);
|
|
6036
|
-
timer = setTimeout(() => {
|
|
6037
|
-
timer = void 0;
|
|
6038
|
-
a.down([[ERROR, err]]);
|
|
6039
|
-
}, ms);
|
|
6040
|
-
}
|
|
6041
|
-
return node(
|
|
6042
|
-
[source],
|
|
6043
|
-
([_v], a) => {
|
|
6044
|
-
arm(a);
|
|
6045
|
-
return () => clearTimeout(timer);
|
|
6046
|
-
},
|
|
6047
|
-
{
|
|
6048
|
-
...operatorOpts3(timeoutNodeOpts),
|
|
6049
|
-
completeWhenDepsComplete: false,
|
|
6050
|
-
onMessage(msg, _i, a) {
|
|
6051
|
-
const t = msg[0];
|
|
6052
|
-
if (t === DATA) {
|
|
6053
|
-
arm(a);
|
|
6054
|
-
a.down([msg]);
|
|
6055
|
-
return true;
|
|
6056
|
-
}
|
|
6057
|
-
if (t === COMPLETE || t === ERROR) {
|
|
6058
|
-
clearTimeout(timer);
|
|
6059
|
-
a.down([msg]);
|
|
6060
|
-
return true;
|
|
6061
|
-
}
|
|
6062
|
-
if (t === DIRTY || t === RESOLVED) {
|
|
6063
|
-
a.down([msg]);
|
|
6064
|
-
return true;
|
|
6065
|
-
}
|
|
6066
|
-
a.down([msg]);
|
|
6067
|
-
return true;
|
|
6068
|
-
}
|
|
6069
|
-
}
|
|
6070
|
-
);
|
|
6071
|
-
}
|
|
6072
6734
|
function buffer(source, notifier, opts) {
|
|
6073
6735
|
const buf = [];
|
|
6074
6736
|
return node([source, notifier], () => void 0, {
|
|
@@ -7625,11 +8287,14 @@ function workerSelf(target, opts) {
|
|
|
7625
8287
|
NS_PER_MS,
|
|
7626
8288
|
NS_PER_SEC,
|
|
7627
8289
|
SqliteCheckpointAdapter,
|
|
8290
|
+
TimeoutError,
|
|
7628
8291
|
audit,
|
|
7629
8292
|
buffer,
|
|
7630
8293
|
bufferCount,
|
|
7631
8294
|
bufferTime,
|
|
8295
|
+
cache,
|
|
7632
8296
|
cached,
|
|
8297
|
+
cascadingCache,
|
|
7633
8298
|
catchError,
|
|
7634
8299
|
checkpointNodeValue,
|
|
7635
8300
|
checkpointToRedis,
|
|
@@ -7654,6 +8319,7 @@ function workerSelf(target, opts) {
|
|
|
7654
8319
|
escapeRegexChar,
|
|
7655
8320
|
exhaustMap,
|
|
7656
8321
|
exponential,
|
|
8322
|
+
fallback,
|
|
7657
8323
|
fibonacci,
|
|
7658
8324
|
filter,
|
|
7659
8325
|
find,
|
|
@@ -7666,6 +8332,7 @@ function workerSelf(target, opts) {
|
|
|
7666
8332
|
fromCSV,
|
|
7667
8333
|
fromClickHouseWatch,
|
|
7668
8334
|
fromCron,
|
|
8335
|
+
fromDrizzle,
|
|
7669
8336
|
fromEvent,
|
|
7670
8337
|
fromFSWatch,
|
|
7671
8338
|
fromGitHook,
|
|
@@ -7674,10 +8341,12 @@ function workerSelf(target, opts) {
|
|
|
7674
8341
|
fromIDBTransaction,
|
|
7675
8342
|
fromIter,
|
|
7676
8343
|
fromKafka,
|
|
8344
|
+
fromKysely,
|
|
7677
8345
|
fromMCP,
|
|
7678
8346
|
fromNATS,
|
|
7679
8347
|
fromNDJSON,
|
|
7680
8348
|
fromOTel,
|
|
8349
|
+
fromPrisma,
|
|
7681
8350
|
fromPrometheus,
|
|
7682
8351
|
fromPromise,
|
|
7683
8352
|
fromPulsar,
|
|
@@ -7695,6 +8364,7 @@ function workerSelf(target, opts) {
|
|
|
7695
8364
|
last,
|
|
7696
8365
|
linear,
|
|
7697
8366
|
logSlice,
|
|
8367
|
+
lru,
|
|
7698
8368
|
map,
|
|
7699
8369
|
matchesAnyPattern,
|
|
7700
8370
|
matchesCron,
|
|
@@ -7744,6 +8414,7 @@ function workerSelf(target, opts) {
|
|
|
7744
8414
|
throttle,
|
|
7745
8415
|
throttleTime,
|
|
7746
8416
|
throwError,
|
|
8417
|
+
tieredStorage,
|
|
7747
8418
|
timeout,
|
|
7748
8419
|
toArray,
|
|
7749
8420
|
toCSV,
|