@graphrefly/graphrefly 0.1.0 → 0.5.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/dist/index.cjs CHANGED
@@ -98,6 +98,8 @@ __export(index_exports, {
98
98
  cached: () => cached,
99
99
  catchError: () => catchError,
100
100
  checkpointNodeValue: () => checkpointNodeValue,
101
+ checkpointToRedis: () => checkpointToRedis,
102
+ checkpointToS3: () => checkpointToS3,
101
103
  circuitBreaker: () => circuitBreaker,
102
104
  combine: () => combine,
103
105
  combineLatest: () => combineLatest,
@@ -152,10 +154,13 @@ __export(index_exports, {
152
154
  fromIter: () => fromIter,
153
155
  fromKafka: () => fromKafka,
154
156
  fromMCP: () => fromMCP,
157
+ fromNATS: () => fromNATS,
155
158
  fromNDJSON: () => fromNDJSON,
156
159
  fromOTel: () => fromOTel,
157
160
  fromPrometheus: () => fromPrometheus,
158
161
  fromPromise: () => fromPromise,
162
+ fromPulsar: () => fromPulsar,
163
+ fromRabbitMQ: () => fromRabbitMQ,
159
164
  fromRedisStream: () => fromRedisStream,
160
165
  fromStatsD: () => fromStatsD,
161
166
  fromSyslog: () => fromSyslog,
@@ -253,11 +258,22 @@ __export(index_exports, {
253
258
  throwError: () => throwError,
254
259
  timeout: () => timeout,
255
260
  toArray: () => toArray,
261
+ toCSV: () => toCSV,
262
+ toClickHouse: () => toClickHouse,
263
+ toFile: () => toFile,
256
264
  toKafka: () => toKafka,
265
+ toLoki: () => toLoki,
257
266
  toMessages$: () => toMessages$,
267
+ toMongo: () => toMongo,
268
+ toNATS: () => toNATS,
258
269
  toObservable: () => toObservable,
270
+ toPostgres: () => toPostgres,
271
+ toPulsar: () => toPulsar,
272
+ toRabbitMQ: () => toRabbitMQ,
259
273
  toRedisStream: () => toRedisStream,
274
+ toS3: () => toS3,
260
275
  toSSE: () => toSSE,
276
+ toTempo: () => toTempo,
261
277
  toWebSocket: () => toWebSocket,
262
278
  tokenBucket: () => tokenBucket,
263
279
  tokenTracker: () => tokenTracker,
@@ -6541,6 +6557,8 @@ __export(extra_exports, {
6541
6557
  cached: () => cached,
6542
6558
  catchError: () => catchError,
6543
6559
  checkpointNodeValue: () => checkpointNodeValue,
6560
+ checkpointToRedis: () => checkpointToRedis,
6561
+ checkpointToS3: () => checkpointToS3,
6544
6562
  circuitBreaker: () => circuitBreaker,
6545
6563
  combine: () => combine,
6546
6564
  combineLatest: () => combineLatest,
@@ -6582,10 +6600,13 @@ __export(extra_exports, {
6582
6600
  fromIter: () => fromIter,
6583
6601
  fromKafka: () => fromKafka,
6584
6602
  fromMCP: () => fromMCP,
6603
+ fromNATS: () => fromNATS,
6585
6604
  fromNDJSON: () => fromNDJSON,
6586
6605
  fromOTel: () => fromOTel,
6587
6606
  fromPrometheus: () => fromPrometheus,
6588
6607
  fromPromise: () => fromPromise,
6608
+ fromPulsar: () => fromPulsar,
6609
+ fromRabbitMQ: () => fromRabbitMQ,
6589
6610
  fromRedisStream: () => fromRedisStream,
6590
6611
  fromStatsD: () => fromStatsD,
6591
6612
  fromSyslog: () => fromSyslog,
@@ -6649,11 +6670,22 @@ __export(extra_exports, {
6649
6670
  throwError: () => throwError,
6650
6671
  timeout: () => timeout,
6651
6672
  toArray: () => toArray,
6673
+ toCSV: () => toCSV,
6674
+ toClickHouse: () => toClickHouse,
6675
+ toFile: () => toFile,
6652
6676
  toKafka: () => toKafka,
6677
+ toLoki: () => toLoki,
6653
6678
  toMessages$: () => toMessages$,
6679
+ toMongo: () => toMongo,
6680
+ toNATS: () => toNATS,
6654
6681
  toObservable: () => toObservable,
6682
+ toPostgres: () => toPostgres,
6683
+ toPulsar: () => toPulsar,
6684
+ toRabbitMQ: () => toRabbitMQ,
6655
6685
  toRedisStream: () => toRedisStream,
6686
+ toS3: () => toS3,
6656
6687
  toSSE: () => toSSE,
6688
+ toTempo: () => toTempo,
6657
6689
  toWebSocket: () => toWebSocket,
6658
6690
  tokenBucket: () => tokenBucket,
6659
6691
  tokenTracker: () => tokenTracker,
@@ -8210,6 +8242,797 @@ function fromClickHouseWatch(client, query, opts) {
8210
8242
  };
8211
8243
  }, sourceOpts2(rest));
8212
8244
  }
8245
+ function fromPulsar(consumer, opts) {
8246
+ const {
8247
+ autoAck = true,
8248
+ deserialize = (buf) => {
8249
+ try {
8250
+ return JSON.parse(buf.toString());
8251
+ } catch {
8252
+ return buf.toString();
8253
+ }
8254
+ },
8255
+ ...rest
8256
+ } = opts ?? {};
8257
+ return producer((_d, a) => {
8258
+ let active = true;
8259
+ const loop2 = async () => {
8260
+ while (active) {
8261
+ try {
8262
+ const msg = await consumer.receive();
8263
+ if (!active) return;
8264
+ a.emit({
8265
+ topic: msg.getTopicName(),
8266
+ messageId: msg.getMessageId().toString(),
8267
+ key: msg.getPartitionKey(),
8268
+ value: deserialize(msg.getData()),
8269
+ properties: msg.getProperties(),
8270
+ publishTime: msg.getPublishTimestamp(),
8271
+ eventTime: msg.getEventTimestamp(),
8272
+ timestampNs: wallClockNs()
8273
+ });
8274
+ if (autoAck) await consumer.acknowledge(msg);
8275
+ } catch (err) {
8276
+ if (active) a.down([[ERROR, err]]);
8277
+ return;
8278
+ }
8279
+ }
8280
+ };
8281
+ void loop2();
8282
+ return () => {
8283
+ active = false;
8284
+ };
8285
+ }, sourceOpts2(rest));
8286
+ }
8287
+ function toPulsar(source, pulsarProducer, opts) {
8288
+ const {
8289
+ serialize = (v) => Buffer.from(JSON.stringify(v)),
8290
+ keyExtractor,
8291
+ propertiesExtractor,
8292
+ onTransportError,
8293
+ ...rest
8294
+ } = opts ?? {};
8295
+ const inner = node([source], () => void 0, {
8296
+ describeKind: "effect",
8297
+ ...rest,
8298
+ onMessage(msg) {
8299
+ if (msg[0] === DATA) {
8300
+ const value = msg[1];
8301
+ let data;
8302
+ try {
8303
+ data = serialize(value);
8304
+ } catch (err) {
8305
+ onTransportError?.({
8306
+ stage: "serialize",
8307
+ error: err instanceof Error ? err : new Error(String(err)),
8308
+ value
8309
+ });
8310
+ return true;
8311
+ }
8312
+ void pulsarProducer.send({
8313
+ data,
8314
+ partitionKey: keyExtractor?.(value),
8315
+ properties: propertiesExtractor?.(value)
8316
+ }).catch((err) => {
8317
+ onTransportError?.({
8318
+ stage: "send",
8319
+ error: err instanceof Error ? err : new Error(String(err)),
8320
+ value
8321
+ });
8322
+ });
8323
+ return true;
8324
+ }
8325
+ return false;
8326
+ }
8327
+ });
8328
+ return inner.subscribe(() => {
8329
+ });
8330
+ }
8331
+ function fromNATS(client, subject, opts) {
8332
+ const decoder = new TextDecoder();
8333
+ const {
8334
+ queue,
8335
+ deserialize = (data) => {
8336
+ const text = decoder.decode(data);
8337
+ try {
8338
+ return JSON.parse(text);
8339
+ } catch {
8340
+ return text;
8341
+ }
8342
+ },
8343
+ ...rest
8344
+ } = opts ?? {};
8345
+ return producer((_d, a) => {
8346
+ let active = true;
8347
+ const sub = client.subscribe(subject, queue ? { queue } : void 0);
8348
+ const loop2 = async () => {
8349
+ try {
8350
+ for await (const msg of sub) {
8351
+ if (!active) return;
8352
+ const headers = {};
8353
+ if (msg.headers) {
8354
+ for (const k of msg.headers.keys()) {
8355
+ headers[k] = msg.headers.get(k);
8356
+ }
8357
+ }
8358
+ a.emit({
8359
+ subject: msg.subject,
8360
+ data: deserialize(msg.data),
8361
+ headers,
8362
+ reply: msg.reply,
8363
+ sid: msg.sid,
8364
+ timestampNs: wallClockNs()
8365
+ });
8366
+ }
8367
+ if (active) a.down([[COMPLETE]]);
8368
+ } catch (err) {
8369
+ if (active) a.down([[ERROR, err]]);
8370
+ }
8371
+ };
8372
+ void loop2();
8373
+ return () => {
8374
+ active = false;
8375
+ };
8376
+ }, sourceOpts2(rest));
8377
+ }
8378
+ function toNATS(source, client, subject, opts) {
8379
+ const encoder = new TextEncoder();
8380
+ const {
8381
+ serialize = (v) => encoder.encode(JSON.stringify(v)),
8382
+ onTransportError,
8383
+ ...rest
8384
+ } = opts ?? {};
8385
+ const inner = node([source], () => void 0, {
8386
+ describeKind: "effect",
8387
+ ...rest,
8388
+ onMessage(msg) {
8389
+ if (msg[0] === DATA) {
8390
+ const value = msg[1];
8391
+ let data;
8392
+ try {
8393
+ data = serialize(value);
8394
+ } catch (err) {
8395
+ onTransportError?.({
8396
+ stage: "serialize",
8397
+ error: err instanceof Error ? err : new Error(String(err)),
8398
+ value
8399
+ });
8400
+ return true;
8401
+ }
8402
+ try {
8403
+ client.publish(subject, data);
8404
+ } catch (err) {
8405
+ onTransportError?.({
8406
+ stage: "send",
8407
+ error: err instanceof Error ? err : new Error(String(err)),
8408
+ value
8409
+ });
8410
+ }
8411
+ return true;
8412
+ }
8413
+ return false;
8414
+ }
8415
+ });
8416
+ return inner.subscribe(() => {
8417
+ });
8418
+ }
8419
+ function fromRabbitMQ(channel, queue, opts) {
8420
+ const {
8421
+ autoAck = true,
8422
+ deserialize = (buf) => {
8423
+ try {
8424
+ return JSON.parse(buf.toString());
8425
+ } catch {
8426
+ return buf.toString();
8427
+ }
8428
+ },
8429
+ ...rest
8430
+ } = opts ?? {};
8431
+ return producer((_d, a) => {
8432
+ let active = true;
8433
+ let consumerTag;
8434
+ const start = async () => {
8435
+ try {
8436
+ const result = await channel.consume(
8437
+ queue,
8438
+ (msg) => {
8439
+ if (!active) return;
8440
+ if (msg === null) {
8441
+ if (active) a.down([[ERROR, new Error("Consumer cancelled by broker")]]);
8442
+ return;
8443
+ }
8444
+ a.emit({
8445
+ queue,
8446
+ routingKey: msg.fields.routingKey,
8447
+ exchange: msg.fields.exchange,
8448
+ content: deserialize(msg.content),
8449
+ properties: msg.properties,
8450
+ deliveryTag: msg.fields.deliveryTag,
8451
+ redelivered: msg.fields.redelivered,
8452
+ timestampNs: wallClockNs()
8453
+ });
8454
+ if (autoAck) channel.ack(msg);
8455
+ },
8456
+ { noAck: false }
8457
+ );
8458
+ consumerTag = result.consumerTag;
8459
+ } catch (err) {
8460
+ if (active) a.down([[ERROR, err]]);
8461
+ }
8462
+ };
8463
+ void start();
8464
+ return () => {
8465
+ active = false;
8466
+ if (consumerTag !== void 0) {
8467
+ void channel.cancel(consumerTag);
8468
+ }
8469
+ };
8470
+ }, sourceOpts2(rest));
8471
+ }
8472
+ function toRabbitMQ(source, channel, exchange, opts) {
8473
+ const {
8474
+ serialize = (v) => Buffer.from(JSON.stringify(v)),
8475
+ routingKeyExtractor = () => "",
8476
+ onTransportError,
8477
+ ...rest
8478
+ } = opts ?? {};
8479
+ const inner = node([source], () => void 0, {
8480
+ describeKind: "effect",
8481
+ ...rest,
8482
+ onMessage(msg) {
8483
+ if (msg[0] === DATA) {
8484
+ const value = msg[1];
8485
+ let routingKey;
8486
+ try {
8487
+ routingKey = routingKeyExtractor(value);
8488
+ } catch (err) {
8489
+ onTransportError?.({
8490
+ stage: "routing_key",
8491
+ error: err instanceof Error ? err : new Error(String(err)),
8492
+ value
8493
+ });
8494
+ return true;
8495
+ }
8496
+ let content;
8497
+ try {
8498
+ content = serialize(value);
8499
+ } catch (err) {
8500
+ onTransportError?.({
8501
+ stage: "serialize",
8502
+ error: err instanceof Error ? err : new Error(String(err)),
8503
+ value
8504
+ });
8505
+ return true;
8506
+ }
8507
+ try {
8508
+ channel.publish(exchange, routingKey, content);
8509
+ } catch (err) {
8510
+ onTransportError?.({
8511
+ stage: "send",
8512
+ error: err instanceof Error ? err : new Error(String(err)),
8513
+ value
8514
+ });
8515
+ }
8516
+ return true;
8517
+ }
8518
+ return false;
8519
+ }
8520
+ });
8521
+ return inner.subscribe(() => {
8522
+ });
8523
+ }
8524
+ function toFile(source, writer, opts) {
8525
+ const {
8526
+ serialize = (v) => `${JSON.stringify(v)}
8527
+ `,
8528
+ flushIntervalMs = 0,
8529
+ batchSize = Number.POSITIVE_INFINITY,
8530
+ onTransportError,
8531
+ mode: _mode,
8532
+ ...rest
8533
+ } = opts ?? {};
8534
+ let buffer2 = [];
8535
+ let timer;
8536
+ const doFlush = () => {
8537
+ if (buffer2.length === 0) return;
8538
+ const chunk = buffer2.join("");
8539
+ buffer2 = [];
8540
+ try {
8541
+ writer.write(chunk);
8542
+ } catch (err) {
8543
+ onTransportError?.({
8544
+ stage: "send",
8545
+ error: err instanceof Error ? err : new Error(String(err)),
8546
+ value: chunk
8547
+ });
8548
+ }
8549
+ };
8550
+ const scheduleFlush = () => {
8551
+ if (flushIntervalMs > 0 && timer === void 0) {
8552
+ timer = setTimeout(() => {
8553
+ timer = void 0;
8554
+ doFlush();
8555
+ }, flushIntervalMs);
8556
+ }
8557
+ };
8558
+ const buffered = flushIntervalMs > 0 || batchSize < Number.POSITIVE_INFINITY;
8559
+ const inner = node([source], () => void 0, {
8560
+ describeKind: "effect",
8561
+ ...rest,
8562
+ onMessage(msg) {
8563
+ if (msg[0] === DATA) {
8564
+ const value = msg[1];
8565
+ let line;
8566
+ try {
8567
+ line = serialize(value);
8568
+ } catch (err) {
8569
+ onTransportError?.({
8570
+ stage: "serialize",
8571
+ error: err instanceof Error ? err : new Error(String(err)),
8572
+ value
8573
+ });
8574
+ return true;
8575
+ }
8576
+ if (buffered) {
8577
+ buffer2.push(line);
8578
+ if (buffer2.length >= batchSize) doFlush();
8579
+ else scheduleFlush();
8580
+ } else {
8581
+ try {
8582
+ writer.write(line);
8583
+ } catch (err) {
8584
+ onTransportError?.({
8585
+ stage: "send",
8586
+ error: err instanceof Error ? err : new Error(String(err)),
8587
+ value
8588
+ });
8589
+ }
8590
+ }
8591
+ return true;
8592
+ }
8593
+ if (msg[0] === COMPLETE || msg[0] === TEARDOWN) {
8594
+ doFlush();
8595
+ }
8596
+ return false;
8597
+ }
8598
+ });
8599
+ const unsub = inner.subscribe(() => {
8600
+ });
8601
+ const dispose = () => {
8602
+ if (timer !== void 0) {
8603
+ clearTimeout(timer);
8604
+ timer = void 0;
8605
+ }
8606
+ doFlush();
8607
+ writer.end();
8608
+ unsub();
8609
+ };
8610
+ return {
8611
+ dispose,
8612
+ flush: async () => {
8613
+ doFlush();
8614
+ }
8615
+ };
8616
+ }
8617
+ function escapeCSVField(value, delimiter) {
8618
+ if (value.includes(delimiter) || value.includes('"') || value.includes("\n")) {
8619
+ return `"${value.replace(/"/g, '""')}"`;
8620
+ }
8621
+ return value;
8622
+ }
8623
+ function toCSV(source, writer, opts) {
8624
+ const {
8625
+ columns,
8626
+ delimiter = ",",
8627
+ writeHeader = true,
8628
+ cellExtractor = (row, col) => String(row[col] ?? ""),
8629
+ flushIntervalMs = 0,
8630
+ batchSize = Number.POSITIVE_INFINITY,
8631
+ onTransportError,
8632
+ ...rest
8633
+ } = opts;
8634
+ let headerWritten = false;
8635
+ const serializeRow = (row) => {
8636
+ if (!headerWritten && writeHeader) {
8637
+ headerWritten = true;
8638
+ const header = columns.map((c) => escapeCSVField(c, delimiter)).join(delimiter);
8639
+ const data = columns.map((c) => escapeCSVField(cellExtractor(row, c), delimiter)).join(delimiter);
8640
+ return `${header}
8641
+ ${data}
8642
+ `;
8643
+ }
8644
+ return `${columns.map((c) => escapeCSVField(cellExtractor(row, c), delimiter)).join(delimiter)}
8645
+ `;
8646
+ };
8647
+ return toFile(source, writer, {
8648
+ serialize: serializeRow,
8649
+ flushIntervalMs,
8650
+ batchSize,
8651
+ onTransportError,
8652
+ ...rest
8653
+ });
8654
+ }
8655
+ function toClickHouse(source, client, table, opts) {
8656
+ const {
8657
+ batchSize = 1e3,
8658
+ flushIntervalMs = 5e3,
8659
+ format = "JSONEachRow",
8660
+ transform = (v) => v,
8661
+ onTransportError,
8662
+ ...rest
8663
+ } = opts ?? {};
8664
+ let buffer2 = [];
8665
+ let timer;
8666
+ let lastFlush = Promise.resolve();
8667
+ const doFlush = () => {
8668
+ if (buffer2.length === 0) return Promise.resolve();
8669
+ const batch2 = buffer2;
8670
+ buffer2 = [];
8671
+ try {
8672
+ const p = client.insert({ table, values: batch2, format }).catch((err) => {
8673
+ onTransportError?.({
8674
+ stage: "send",
8675
+ error: err instanceof Error ? err : new Error(String(err)),
8676
+ value: batch2
8677
+ });
8678
+ });
8679
+ lastFlush = p;
8680
+ return p;
8681
+ } catch (err) {
8682
+ onTransportError?.({
8683
+ stage: "send",
8684
+ error: err instanceof Error ? err : new Error(String(err)),
8685
+ value: batch2
8686
+ });
8687
+ return Promise.resolve();
8688
+ }
8689
+ };
8690
+ const scheduleFlush = () => {
8691
+ if (timer === void 0) {
8692
+ timer = setTimeout(() => {
8693
+ timer = void 0;
8694
+ doFlush();
8695
+ }, flushIntervalMs);
8696
+ }
8697
+ };
8698
+ const inner = node([source], () => void 0, {
8699
+ describeKind: "effect",
8700
+ ...rest,
8701
+ onMessage(msg) {
8702
+ if (msg[0] === DATA) {
8703
+ const value = msg[1];
8704
+ try {
8705
+ buffer2.push(transform(value));
8706
+ } catch (err) {
8707
+ onTransportError?.({
8708
+ stage: "serialize",
8709
+ error: err instanceof Error ? err : new Error(String(err)),
8710
+ value
8711
+ });
8712
+ return true;
8713
+ }
8714
+ if (buffer2.length >= batchSize) doFlush();
8715
+ else scheduleFlush();
8716
+ return true;
8717
+ }
8718
+ if (msg[0] === COMPLETE || msg[0] === TEARDOWN) {
8719
+ doFlush();
8720
+ }
8721
+ return false;
8722
+ }
8723
+ });
8724
+ const unsub = inner.subscribe(() => {
8725
+ });
8726
+ const dispose = () => {
8727
+ if (timer !== void 0) {
8728
+ clearTimeout(timer);
8729
+ timer = void 0;
8730
+ }
8731
+ doFlush();
8732
+ unsub();
8733
+ };
8734
+ return {
8735
+ dispose,
8736
+ flush: () => doFlush().then(() => lastFlush)
8737
+ };
8738
+ }
8739
+ function toS3(source, client, bucket, opts) {
8740
+ const {
8741
+ format = "ndjson",
8742
+ keyGenerator = (seq2, timestampNs) => {
8743
+ const ms = Math.floor(timestampNs / 1e6);
8744
+ const ts = new Date(ms).toISOString().replace(/[:.]/g, "-");
8745
+ return `data/${ts}-${seq2}.${format === "ndjson" ? "ndjson" : "json"}`;
8746
+ },
8747
+ batchSize = 1e3,
8748
+ flushIntervalMs = 1e4,
8749
+ transform = (v) => v,
8750
+ onTransportError,
8751
+ ...rest
8752
+ } = opts ?? {};
8753
+ let buffer2 = [];
8754
+ let timer;
8755
+ let seq = 0;
8756
+ let lastFlush = Promise.resolve();
8757
+ const doFlush = () => {
8758
+ if (buffer2.length === 0) return Promise.resolve();
8759
+ const batch2 = buffer2;
8760
+ buffer2 = [];
8761
+ seq += 1;
8762
+ const body = format === "ndjson" ? `${batch2.map((v) => JSON.stringify(v)).join("\n")}
8763
+ ` : JSON.stringify(batch2);
8764
+ const contentType = format === "ndjson" ? "application/x-ndjson" : "application/json";
8765
+ const key = keyGenerator(seq, wallClockNs());
8766
+ try {
8767
+ const p = client.putObject({ Bucket: bucket, Key: key, Body: body, ContentType: contentType }).then(() => {
8768
+ }).catch((err) => {
8769
+ onTransportError?.({
8770
+ stage: "send",
8771
+ error: err instanceof Error ? err : new Error(String(err)),
8772
+ value: batch2
8773
+ });
8774
+ });
8775
+ lastFlush = p;
8776
+ return p;
8777
+ } catch (err) {
8778
+ onTransportError?.({
8779
+ stage: "send",
8780
+ error: err instanceof Error ? err : new Error(String(err)),
8781
+ value: batch2
8782
+ });
8783
+ return Promise.resolve();
8784
+ }
8785
+ };
8786
+ const scheduleFlush = () => {
8787
+ if (timer === void 0) {
8788
+ timer = setTimeout(() => {
8789
+ timer = void 0;
8790
+ doFlush();
8791
+ }, flushIntervalMs);
8792
+ }
8793
+ };
8794
+ const inner = node([source], () => void 0, {
8795
+ describeKind: "effect",
8796
+ ...rest,
8797
+ onMessage(msg) {
8798
+ if (msg[0] === DATA) {
8799
+ const value = msg[1];
8800
+ try {
8801
+ buffer2.push(transform(value));
8802
+ } catch (err) {
8803
+ onTransportError?.({
8804
+ stage: "serialize",
8805
+ error: err instanceof Error ? err : new Error(String(err)),
8806
+ value
8807
+ });
8808
+ return true;
8809
+ }
8810
+ if (buffer2.length >= batchSize) doFlush();
8811
+ else scheduleFlush();
8812
+ return true;
8813
+ }
8814
+ if (msg[0] === COMPLETE || msg[0] === TEARDOWN) {
8815
+ doFlush();
8816
+ }
8817
+ return false;
8818
+ }
8819
+ });
8820
+ const unsub = inner.subscribe(() => {
8821
+ });
8822
+ const dispose = () => {
8823
+ if (timer !== void 0) {
8824
+ clearTimeout(timer);
8825
+ timer = void 0;
8826
+ }
8827
+ doFlush();
8828
+ unsub();
8829
+ };
8830
+ return {
8831
+ dispose,
8832
+ flush: () => doFlush().then(() => lastFlush)
8833
+ };
8834
+ }
8835
+ function toPostgres(source, client, table, opts) {
8836
+ const {
8837
+ toSQL = (v, t) => ({
8838
+ sql: `INSERT INTO "${t.replace(/"/g, '""')}" (data) VALUES ($1)`,
8839
+ params: [JSON.stringify(v)]
8840
+ }),
8841
+ onTransportError,
8842
+ ...rest
8843
+ } = opts ?? {};
8844
+ const inner = node([source], () => void 0, {
8845
+ describeKind: "effect",
8846
+ ...rest,
8847
+ onMessage(msg) {
8848
+ if (msg[0] === DATA) {
8849
+ const value = msg[1];
8850
+ let query;
8851
+ try {
8852
+ query = toSQL(value, table);
8853
+ } catch (err) {
8854
+ onTransportError?.({
8855
+ stage: "serialize",
8856
+ error: err instanceof Error ? err : new Error(String(err)),
8857
+ value
8858
+ });
8859
+ return true;
8860
+ }
8861
+ void client.query(query.sql, query.params).catch((err) => {
8862
+ onTransportError?.({
8863
+ stage: "send",
8864
+ error: err instanceof Error ? err : new Error(String(err)),
8865
+ value
8866
+ });
8867
+ });
8868
+ return true;
8869
+ }
8870
+ return false;
8871
+ }
8872
+ });
8873
+ return inner.subscribe(() => {
8874
+ });
8875
+ }
8876
+ function toMongo(source, collection2, opts) {
8877
+ const { toDocument = (v) => v, onTransportError, ...rest } = opts ?? {};
8878
+ const inner = node([source], () => void 0, {
8879
+ describeKind: "effect",
8880
+ ...rest,
8881
+ onMessage(msg) {
8882
+ if (msg[0] === DATA) {
8883
+ const value = msg[1];
8884
+ let doc;
8885
+ try {
8886
+ doc = toDocument(value);
8887
+ } catch (err) {
8888
+ onTransportError?.({
8889
+ stage: "serialize",
8890
+ error: err instanceof Error ? err : new Error(String(err)),
8891
+ value
8892
+ });
8893
+ return true;
8894
+ }
8895
+ void collection2.insertOne(doc).catch((err) => {
8896
+ onTransportError?.({
8897
+ stage: "send",
8898
+ error: err instanceof Error ? err : new Error(String(err)),
8899
+ value
8900
+ });
8901
+ });
8902
+ return true;
8903
+ }
8904
+ return false;
8905
+ }
8906
+ });
8907
+ return inner.subscribe(() => {
8908
+ });
8909
+ }
8910
+ function toLoki(source, client, opts) {
8911
+ const {
8912
+ labels = {},
8913
+ toLine = (v) => JSON.stringify(v),
8914
+ toLabels,
8915
+ onTransportError,
8916
+ ...rest
8917
+ } = opts ?? {};
8918
+ const inner = node([source], () => void 0, {
8919
+ describeKind: "effect",
8920
+ ...rest,
8921
+ onMessage(msg) {
8922
+ if (msg[0] === DATA) {
8923
+ const value = msg[1];
8924
+ let line;
8925
+ try {
8926
+ line = toLine(value);
8927
+ } catch (err) {
8928
+ onTransportError?.({
8929
+ stage: "serialize",
8930
+ error: err instanceof Error ? err : new Error(String(err)),
8931
+ value
8932
+ });
8933
+ return true;
8934
+ }
8935
+ let streamLabels;
8936
+ try {
8937
+ streamLabels = toLabels ? { ...labels, ...toLabels(value) } : labels;
8938
+ } catch (err) {
8939
+ onTransportError?.({
8940
+ stage: "serialize",
8941
+ error: err instanceof Error ? err : new Error(String(err)),
8942
+ value
8943
+ });
8944
+ return true;
8945
+ }
8946
+ const ts = `${wallClockNs()}`;
8947
+ void client.push({ streams: [{ stream: streamLabels, values: [[ts, line]] }] }).catch((err) => {
8948
+ onTransportError?.({
8949
+ stage: "send",
8950
+ error: err instanceof Error ? err : new Error(String(err)),
8951
+ value
8952
+ });
8953
+ });
8954
+ return true;
8955
+ }
8956
+ return false;
8957
+ }
8958
+ });
8959
+ return inner.subscribe(() => {
8960
+ });
8961
+ }
8962
+ function toTempo(source, client, opts) {
8963
+ const { toResourceSpans = (v) => [v], onTransportError, ...rest } = opts ?? {};
8964
+ const inner = node([source], () => void 0, {
8965
+ describeKind: "effect",
8966
+ ...rest,
8967
+ onMessage(msg) {
8968
+ if (msg[0] === DATA) {
8969
+ const value = msg[1];
8970
+ let spans;
8971
+ try {
8972
+ spans = toResourceSpans(value);
8973
+ } catch (err) {
8974
+ onTransportError?.({
8975
+ stage: "serialize",
8976
+ error: err instanceof Error ? err : new Error(String(err)),
8977
+ value
8978
+ });
8979
+ return true;
8980
+ }
8981
+ void client.push({ resourceSpans: spans }).catch((err) => {
8982
+ onTransportError?.({
8983
+ stage: "send",
8984
+ error: err instanceof Error ? err : new Error(String(err)),
8985
+ value
8986
+ });
8987
+ });
8988
+ return true;
8989
+ }
8990
+ return false;
8991
+ }
8992
+ });
8993
+ return inner.subscribe(() => {
8994
+ });
8995
+ }
8996
+ function checkpointToS3(graph, client, bucket, opts) {
8997
+ const { prefix = "checkpoints/", debounceMs, compactEvery, onError } = opts ?? {};
8998
+ const adapter = {
8999
+ save(data) {
9000
+ const ms = Math.floor(wallClockNs() / 1e6);
9001
+ const key = `${prefix}${graph.name}/checkpoint-${ms}.json`;
9002
+ let body;
9003
+ try {
9004
+ body = JSON.stringify(data);
9005
+ } catch (err) {
9006
+ onError?.(err);
9007
+ return;
9008
+ }
9009
+ void client.putObject({
9010
+ Bucket: bucket,
9011
+ Key: key,
9012
+ Body: body,
9013
+ ContentType: "application/json"
9014
+ }).catch((err) => onError?.(err));
9015
+ }
9016
+ };
9017
+ return graph.autoCheckpoint(adapter, { debounceMs, compactEvery, onError });
9018
+ }
9019
+ function checkpointToRedis(graph, client, opts) {
9020
+ const { prefix = "graphrefly:checkpoint:", debounceMs, compactEvery, onError } = opts ?? {};
9021
+ const key = `${prefix}${graph.name}`;
9022
+ const adapter = {
9023
+ save(data) {
9024
+ let body;
9025
+ try {
9026
+ body = JSON.stringify(data);
9027
+ } catch (err) {
9028
+ onError?.(err);
9029
+ return;
9030
+ }
9031
+ void client.set(key, body).catch((err) => onError?.(err));
9032
+ }
9033
+ };
9034
+ return graph.autoCheckpoint(adapter, { debounceMs, compactEvery, onError });
9035
+ }
8213
9036
 
8214
9037
  // src/extra/checkpoint.ts
8215
9038
  var import_node_crypto2 = require("crypto");
@@ -14661,6 +15484,8 @@ var version = "0.0.0";
14661
15484
  cached,
14662
15485
  catchError,
14663
15486
  checkpointNodeValue,
15487
+ checkpointToRedis,
15488
+ checkpointToS3,
14664
15489
  circuitBreaker,
14665
15490
  combine,
14666
15491
  combineLatest,
@@ -14715,10 +15540,13 @@ var version = "0.0.0";
14715
15540
  fromIter,
14716
15541
  fromKafka,
14717
15542
  fromMCP,
15543
+ fromNATS,
14718
15544
  fromNDJSON,
14719
15545
  fromOTel,
14720
15546
  fromPrometheus,
14721
15547
  fromPromise,
15548
+ fromPulsar,
15549
+ fromRabbitMQ,
14722
15550
  fromRedisStream,
14723
15551
  fromStatsD,
14724
15552
  fromSyslog,
@@ -14816,11 +15644,22 @@ var version = "0.0.0";
14816
15644
  throwError,
14817
15645
  timeout,
14818
15646
  toArray,
15647
+ toCSV,
15648
+ toClickHouse,
15649
+ toFile,
14819
15650
  toKafka,
15651
+ toLoki,
14820
15652
  toMessages$,
15653
+ toMongo,
15654
+ toNATS,
14821
15655
  toObservable,
15656
+ toPostgres,
15657
+ toPulsar,
15658
+ toRabbitMQ,
14822
15659
  toRedisStream,
15660
+ toS3,
14823
15661
  toSSE,
15662
+ toTempo,
14824
15663
  toWebSocket,
14825
15664
  tokenBucket,
14826
15665
  tokenTracker,