@graphrefly/graphrefly 0.4.0 → 0.6.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.
@@ -75,6 +75,8 @@ __export(extra_exports, {
75
75
  cached: () => cached,
76
76
  catchError: () => catchError,
77
77
  checkpointNodeValue: () => checkpointNodeValue,
78
+ checkpointToRedis: () => checkpointToRedis,
79
+ checkpointToS3: () => checkpointToS3,
78
80
  circuitBreaker: () => circuitBreaker,
79
81
  combine: () => combine,
80
82
  combineLatest: () => combineLatest,
@@ -116,11 +118,15 @@ __export(extra_exports, {
116
118
  fromIter: () => fromIter,
117
119
  fromKafka: () => fromKafka,
118
120
  fromMCP: () => fromMCP,
121
+ fromNATS: () => fromNATS,
119
122
  fromNDJSON: () => fromNDJSON,
120
123
  fromOTel: () => fromOTel,
121
124
  fromPrometheus: () => fromPrometheus,
122
125
  fromPromise: () => fromPromise,
126
+ fromPulsar: () => fromPulsar,
127
+ fromRabbitMQ: () => fromRabbitMQ,
123
128
  fromRedisStream: () => fromRedisStream,
129
+ fromSqlite: () => fromSqlite,
124
130
  fromStatsD: () => fromStatsD,
125
131
  fromSyslog: () => fromSyslog,
126
132
  fromTimer: () => fromTimer,
@@ -183,11 +189,23 @@ __export(extra_exports, {
183
189
  throwError: () => throwError,
184
190
  timeout: () => timeout,
185
191
  toArray: () => toArray,
192
+ toCSV: () => toCSV,
193
+ toClickHouse: () => toClickHouse,
194
+ toFile: () => toFile,
186
195
  toKafka: () => toKafka,
196
+ toLoki: () => toLoki,
187
197
  toMessages$: () => toMessages$,
198
+ toMongo: () => toMongo,
199
+ toNATS: () => toNATS,
188
200
  toObservable: () => toObservable,
201
+ toPostgres: () => toPostgres,
202
+ toPulsar: () => toPulsar,
203
+ toRabbitMQ: () => toRabbitMQ,
189
204
  toRedisStream: () => toRedisStream,
205
+ toS3: () => toS3,
190
206
  toSSE: () => toSSE,
207
+ toSqlite: () => toSqlite,
208
+ toTempo: () => toTempo,
191
209
  toWebSocket: () => toWebSocket,
192
210
  tokenBucket: () => tokenBucket,
193
211
  tokenTracker: () => tokenTracker,
@@ -989,7 +1007,7 @@ function toWebSocket(source, socket, opts) {
989
1007
  };
990
1008
  const inner = node([source], () => void 0, {
991
1009
  describeKind: "effect",
992
- onMessage(msg) {
1010
+ onMessage(msg, _depIndex, _actions) {
993
1011
  if (msg[0] === DATA) {
994
1012
  let serialized;
995
1013
  try {
@@ -1440,7 +1458,7 @@ function toKafka(source, kafkaProducer, topic, opts) {
1440
1458
  const inner = node([source], () => void 0, {
1441
1459
  describeKind: "effect",
1442
1460
  ...rest,
1443
- onMessage(msg) {
1461
+ onMessage(msg, _depIndex, _actions) {
1444
1462
  if (msg[0] === DATA) {
1445
1463
  const value = msg[1];
1446
1464
  const key = keyExtractor?.(value) ?? null;
@@ -1539,7 +1557,7 @@ function toRedisStream(source, client, key, opts) {
1539
1557
  const inner = node([source], () => void 0, {
1540
1558
  describeKind: "effect",
1541
1559
  ...rest,
1542
- onMessage(msg) {
1560
+ onMessage(msg, _depIndex, _actions) {
1543
1561
  if (msg[0] === DATA) {
1544
1562
  const value = msg[1];
1545
1563
  let fields;
@@ -1744,6 +1762,866 @@ function fromClickHouseWatch(client, query, opts) {
1744
1762
  };
1745
1763
  }, sourceOpts(rest));
1746
1764
  }
1765
+ function fromPulsar(consumer, opts) {
1766
+ const {
1767
+ autoAck = true,
1768
+ deserialize = (buf) => {
1769
+ try {
1770
+ return JSON.parse(buf.toString());
1771
+ } catch {
1772
+ return buf.toString();
1773
+ }
1774
+ },
1775
+ ...rest
1776
+ } = opts ?? {};
1777
+ return producer((_d, a) => {
1778
+ let active = true;
1779
+ const loop = async () => {
1780
+ while (active) {
1781
+ try {
1782
+ const msg = await consumer.receive();
1783
+ if (!active) return;
1784
+ a.emit({
1785
+ topic: msg.getTopicName(),
1786
+ messageId: msg.getMessageId().toString(),
1787
+ key: msg.getPartitionKey(),
1788
+ value: deserialize(msg.getData()),
1789
+ properties: msg.getProperties(),
1790
+ publishTime: msg.getPublishTimestamp(),
1791
+ eventTime: msg.getEventTimestamp(),
1792
+ timestampNs: wallClockNs()
1793
+ });
1794
+ if (autoAck) await consumer.acknowledge(msg);
1795
+ } catch (err) {
1796
+ if (active) a.down([[ERROR, err]]);
1797
+ return;
1798
+ }
1799
+ }
1800
+ };
1801
+ void loop();
1802
+ return () => {
1803
+ active = false;
1804
+ };
1805
+ }, sourceOpts(rest));
1806
+ }
1807
+ function toPulsar(source, pulsarProducer, opts) {
1808
+ const {
1809
+ serialize = (v) => Buffer.from(JSON.stringify(v)),
1810
+ keyExtractor,
1811
+ propertiesExtractor,
1812
+ onTransportError,
1813
+ ...rest
1814
+ } = opts ?? {};
1815
+ const inner = node([source], () => void 0, {
1816
+ describeKind: "effect",
1817
+ ...rest,
1818
+ onMessage(msg, _depIndex, _actions) {
1819
+ if (msg[0] === DATA) {
1820
+ const value = msg[1];
1821
+ let data;
1822
+ try {
1823
+ data = serialize(value);
1824
+ } catch (err) {
1825
+ onTransportError?.({
1826
+ stage: "serialize",
1827
+ error: err instanceof Error ? err : new Error(String(err)),
1828
+ value
1829
+ });
1830
+ return true;
1831
+ }
1832
+ void pulsarProducer.send({
1833
+ data,
1834
+ partitionKey: keyExtractor?.(value),
1835
+ properties: propertiesExtractor?.(value)
1836
+ }).catch((err) => {
1837
+ onTransportError?.({
1838
+ stage: "send",
1839
+ error: err instanceof Error ? err : new Error(String(err)),
1840
+ value
1841
+ });
1842
+ });
1843
+ return true;
1844
+ }
1845
+ return false;
1846
+ }
1847
+ });
1848
+ return inner.subscribe(() => {
1849
+ });
1850
+ }
1851
+ function fromNATS(client, subject, opts) {
1852
+ const decoder = new TextDecoder();
1853
+ const {
1854
+ queue,
1855
+ deserialize = (data) => {
1856
+ const text = decoder.decode(data);
1857
+ try {
1858
+ return JSON.parse(text);
1859
+ } catch {
1860
+ return text;
1861
+ }
1862
+ },
1863
+ ...rest
1864
+ } = opts ?? {};
1865
+ return producer((_d, a) => {
1866
+ let active = true;
1867
+ const sub = client.subscribe(subject, queue ? { queue } : void 0);
1868
+ const loop = async () => {
1869
+ try {
1870
+ for await (const msg of sub) {
1871
+ if (!active) return;
1872
+ const headers = {};
1873
+ if (msg.headers) {
1874
+ for (const k of msg.headers.keys()) {
1875
+ headers[k] = msg.headers.get(k);
1876
+ }
1877
+ }
1878
+ a.emit({
1879
+ subject: msg.subject,
1880
+ data: deserialize(msg.data),
1881
+ headers,
1882
+ reply: msg.reply,
1883
+ sid: msg.sid,
1884
+ timestampNs: wallClockNs()
1885
+ });
1886
+ }
1887
+ if (active) a.down([[COMPLETE]]);
1888
+ } catch (err) {
1889
+ if (active) a.down([[ERROR, err]]);
1890
+ }
1891
+ };
1892
+ void loop();
1893
+ return () => {
1894
+ active = false;
1895
+ };
1896
+ }, sourceOpts(rest));
1897
+ }
1898
+ function toNATS(source, client, subject, opts) {
1899
+ const encoder = new TextEncoder();
1900
+ const {
1901
+ serialize = (v) => encoder.encode(JSON.stringify(v)),
1902
+ onTransportError,
1903
+ ...rest
1904
+ } = opts ?? {};
1905
+ const inner = node([source], () => void 0, {
1906
+ describeKind: "effect",
1907
+ ...rest,
1908
+ onMessage(msg, _depIndex, _actions) {
1909
+ if (msg[0] === DATA) {
1910
+ const value = msg[1];
1911
+ let data;
1912
+ try {
1913
+ data = serialize(value);
1914
+ } catch (err) {
1915
+ onTransportError?.({
1916
+ stage: "serialize",
1917
+ error: err instanceof Error ? err : new Error(String(err)),
1918
+ value
1919
+ });
1920
+ return true;
1921
+ }
1922
+ try {
1923
+ client.publish(subject, data);
1924
+ } catch (err) {
1925
+ onTransportError?.({
1926
+ stage: "send",
1927
+ error: err instanceof Error ? err : new Error(String(err)),
1928
+ value
1929
+ });
1930
+ }
1931
+ return true;
1932
+ }
1933
+ return false;
1934
+ }
1935
+ });
1936
+ return inner.subscribe(() => {
1937
+ });
1938
+ }
1939
+ function fromRabbitMQ(channel, queue, opts) {
1940
+ const {
1941
+ autoAck = true,
1942
+ deserialize = (buf) => {
1943
+ try {
1944
+ return JSON.parse(buf.toString());
1945
+ } catch {
1946
+ return buf.toString();
1947
+ }
1948
+ },
1949
+ ...rest
1950
+ } = opts ?? {};
1951
+ return producer((_d, a) => {
1952
+ let active = true;
1953
+ let consumerTag;
1954
+ const start = async () => {
1955
+ try {
1956
+ const result = await channel.consume(
1957
+ queue,
1958
+ (msg) => {
1959
+ if (!active) return;
1960
+ if (msg === null) {
1961
+ if (active) a.down([[ERROR, new Error("Consumer cancelled by broker")]]);
1962
+ return;
1963
+ }
1964
+ a.emit({
1965
+ queue,
1966
+ routingKey: msg.fields.routingKey,
1967
+ exchange: msg.fields.exchange,
1968
+ content: deserialize(msg.content),
1969
+ properties: msg.properties,
1970
+ deliveryTag: msg.fields.deliveryTag,
1971
+ redelivered: msg.fields.redelivered,
1972
+ timestampNs: wallClockNs()
1973
+ });
1974
+ if (autoAck) channel.ack(msg);
1975
+ },
1976
+ { noAck: false }
1977
+ );
1978
+ consumerTag = result.consumerTag;
1979
+ } catch (err) {
1980
+ if (active) a.down([[ERROR, err]]);
1981
+ }
1982
+ };
1983
+ void start();
1984
+ return () => {
1985
+ active = false;
1986
+ if (consumerTag !== void 0) {
1987
+ void channel.cancel(consumerTag);
1988
+ }
1989
+ };
1990
+ }, sourceOpts(rest));
1991
+ }
1992
+ function toRabbitMQ(source, channel, exchange, opts) {
1993
+ const {
1994
+ serialize = (v) => Buffer.from(JSON.stringify(v)),
1995
+ routingKeyExtractor = () => "",
1996
+ onTransportError,
1997
+ ...rest
1998
+ } = opts ?? {};
1999
+ const inner = node([source], () => void 0, {
2000
+ describeKind: "effect",
2001
+ ...rest,
2002
+ onMessage(msg, _depIndex, _actions) {
2003
+ if (msg[0] === DATA) {
2004
+ const value = msg[1];
2005
+ let routingKey;
2006
+ try {
2007
+ routingKey = routingKeyExtractor(value);
2008
+ } catch (err) {
2009
+ onTransportError?.({
2010
+ stage: "routing_key",
2011
+ error: err instanceof Error ? err : new Error(String(err)),
2012
+ value
2013
+ });
2014
+ return true;
2015
+ }
2016
+ let content;
2017
+ try {
2018
+ content = serialize(value);
2019
+ } catch (err) {
2020
+ onTransportError?.({
2021
+ stage: "serialize",
2022
+ error: err instanceof Error ? err : new Error(String(err)),
2023
+ value
2024
+ });
2025
+ return true;
2026
+ }
2027
+ try {
2028
+ channel.publish(exchange, routingKey, content);
2029
+ } catch (err) {
2030
+ onTransportError?.({
2031
+ stage: "send",
2032
+ error: err instanceof Error ? err : new Error(String(err)),
2033
+ value
2034
+ });
2035
+ }
2036
+ return true;
2037
+ }
2038
+ return false;
2039
+ }
2040
+ });
2041
+ return inner.subscribe(() => {
2042
+ });
2043
+ }
2044
+ function toFile(source, writer, opts) {
2045
+ const {
2046
+ serialize = (v) => `${JSON.stringify(v)}
2047
+ `,
2048
+ flushIntervalMs = 0,
2049
+ batchSize = Number.POSITIVE_INFINITY,
2050
+ onTransportError,
2051
+ mode: _mode,
2052
+ ...rest
2053
+ } = opts ?? {};
2054
+ let buffer2 = [];
2055
+ let timer;
2056
+ const doFlush = () => {
2057
+ if (buffer2.length === 0) return;
2058
+ const chunk = buffer2.join("");
2059
+ buffer2 = [];
2060
+ try {
2061
+ writer.write(chunk);
2062
+ } catch (err) {
2063
+ onTransportError?.({
2064
+ stage: "send",
2065
+ error: err instanceof Error ? err : new Error(String(err)),
2066
+ value: chunk
2067
+ });
2068
+ }
2069
+ };
2070
+ const scheduleFlush = () => {
2071
+ if (flushIntervalMs > 0 && timer === void 0) {
2072
+ timer = setTimeout(() => {
2073
+ timer = void 0;
2074
+ doFlush();
2075
+ }, flushIntervalMs);
2076
+ }
2077
+ };
2078
+ const buffered = flushIntervalMs > 0 || batchSize < Number.POSITIVE_INFINITY;
2079
+ const inner = node([source], () => void 0, {
2080
+ describeKind: "effect",
2081
+ ...rest,
2082
+ onMessage(msg, _depIndex, _actions) {
2083
+ if (msg[0] === DATA) {
2084
+ const value = msg[1];
2085
+ let line;
2086
+ try {
2087
+ line = serialize(value);
2088
+ } catch (err) {
2089
+ onTransportError?.({
2090
+ stage: "serialize",
2091
+ error: err instanceof Error ? err : new Error(String(err)),
2092
+ value
2093
+ });
2094
+ return true;
2095
+ }
2096
+ if (buffered) {
2097
+ buffer2.push(line);
2098
+ if (buffer2.length >= batchSize) doFlush();
2099
+ else scheduleFlush();
2100
+ } else {
2101
+ try {
2102
+ writer.write(line);
2103
+ } catch (err) {
2104
+ onTransportError?.({
2105
+ stage: "send",
2106
+ error: err instanceof Error ? err : new Error(String(err)),
2107
+ value
2108
+ });
2109
+ }
2110
+ }
2111
+ return true;
2112
+ }
2113
+ if (msg[0] === COMPLETE || msg[0] === TEARDOWN) {
2114
+ doFlush();
2115
+ }
2116
+ return false;
2117
+ }
2118
+ });
2119
+ const unsub = inner.subscribe(() => {
2120
+ });
2121
+ const dispose = () => {
2122
+ if (timer !== void 0) {
2123
+ clearTimeout(timer);
2124
+ timer = void 0;
2125
+ }
2126
+ doFlush();
2127
+ writer.end();
2128
+ unsub();
2129
+ };
2130
+ return {
2131
+ dispose,
2132
+ flush: async () => {
2133
+ doFlush();
2134
+ }
2135
+ };
2136
+ }
2137
+ function escapeCSVField(value, delimiter) {
2138
+ if (value.includes(delimiter) || value.includes('"') || value.includes("\n")) {
2139
+ return `"${value.replace(/"/g, '""')}"`;
2140
+ }
2141
+ return value;
2142
+ }
2143
+ function toCSV(source, writer, opts) {
2144
+ const {
2145
+ columns,
2146
+ delimiter = ",",
2147
+ writeHeader = true,
2148
+ cellExtractor = (row, col) => String(row[col] ?? ""),
2149
+ flushIntervalMs = 0,
2150
+ batchSize = Number.POSITIVE_INFINITY,
2151
+ onTransportError,
2152
+ ...rest
2153
+ } = opts;
2154
+ let headerWritten = false;
2155
+ const serializeRow = (row) => {
2156
+ if (!headerWritten && writeHeader) {
2157
+ headerWritten = true;
2158
+ const header = columns.map((c) => escapeCSVField(c, delimiter)).join(delimiter);
2159
+ const data = columns.map((c) => escapeCSVField(cellExtractor(row, c), delimiter)).join(delimiter);
2160
+ return `${header}
2161
+ ${data}
2162
+ `;
2163
+ }
2164
+ return `${columns.map((c) => escapeCSVField(cellExtractor(row, c), delimiter)).join(delimiter)}
2165
+ `;
2166
+ };
2167
+ return toFile(source, writer, {
2168
+ serialize: serializeRow,
2169
+ flushIntervalMs,
2170
+ batchSize,
2171
+ onTransportError,
2172
+ ...rest
2173
+ });
2174
+ }
2175
+ function toClickHouse(source, client, table, opts) {
2176
+ const {
2177
+ batchSize = 1e3,
2178
+ flushIntervalMs = 5e3,
2179
+ format = "JSONEachRow",
2180
+ transform = (v) => v,
2181
+ onTransportError,
2182
+ ...rest
2183
+ } = opts ?? {};
2184
+ let buffer2 = [];
2185
+ let timer;
2186
+ let lastFlush = Promise.resolve();
2187
+ const doFlush = () => {
2188
+ if (buffer2.length === 0) return Promise.resolve();
2189
+ const batch2 = buffer2;
2190
+ buffer2 = [];
2191
+ try {
2192
+ const p = client.insert({ table, values: batch2, format }).catch((err) => {
2193
+ onTransportError?.({
2194
+ stage: "send",
2195
+ error: err instanceof Error ? err : new Error(String(err)),
2196
+ value: batch2
2197
+ });
2198
+ });
2199
+ lastFlush = p;
2200
+ return p;
2201
+ } catch (err) {
2202
+ onTransportError?.({
2203
+ stage: "send",
2204
+ error: err instanceof Error ? err : new Error(String(err)),
2205
+ value: batch2
2206
+ });
2207
+ return Promise.resolve();
2208
+ }
2209
+ };
2210
+ const scheduleFlush = () => {
2211
+ if (timer === void 0) {
2212
+ timer = setTimeout(() => {
2213
+ timer = void 0;
2214
+ doFlush();
2215
+ }, flushIntervalMs);
2216
+ }
2217
+ };
2218
+ const inner = node([source], () => void 0, {
2219
+ describeKind: "effect",
2220
+ ...rest,
2221
+ onMessage(msg, _depIndex, _actions) {
2222
+ if (msg[0] === DATA) {
2223
+ const value = msg[1];
2224
+ try {
2225
+ buffer2.push(transform(value));
2226
+ } catch (err) {
2227
+ onTransportError?.({
2228
+ stage: "serialize",
2229
+ error: err instanceof Error ? err : new Error(String(err)),
2230
+ value
2231
+ });
2232
+ return true;
2233
+ }
2234
+ if (buffer2.length >= batchSize) doFlush();
2235
+ else scheduleFlush();
2236
+ return true;
2237
+ }
2238
+ if (msg[0] === COMPLETE || msg[0] === TEARDOWN) {
2239
+ doFlush();
2240
+ }
2241
+ return false;
2242
+ }
2243
+ });
2244
+ const unsub = inner.subscribe(() => {
2245
+ });
2246
+ const dispose = () => {
2247
+ if (timer !== void 0) {
2248
+ clearTimeout(timer);
2249
+ timer = void 0;
2250
+ }
2251
+ doFlush();
2252
+ unsub();
2253
+ };
2254
+ return {
2255
+ dispose,
2256
+ flush: () => doFlush().then(() => lastFlush)
2257
+ };
2258
+ }
2259
+ function toS3(source, client, bucket, opts) {
2260
+ const {
2261
+ format = "ndjson",
2262
+ keyGenerator = (seq2, timestampNs) => {
2263
+ const ms = Math.floor(timestampNs / 1e6);
2264
+ const ts = new Date(ms).toISOString().replace(/[:.]/g, "-");
2265
+ return `data/${ts}-${seq2}.${format === "ndjson" ? "ndjson" : "json"}`;
2266
+ },
2267
+ batchSize = 1e3,
2268
+ flushIntervalMs = 1e4,
2269
+ transform = (v) => v,
2270
+ onTransportError,
2271
+ ...rest
2272
+ } = opts ?? {};
2273
+ let buffer2 = [];
2274
+ let timer;
2275
+ let seq = 0;
2276
+ let lastFlush = Promise.resolve();
2277
+ const doFlush = () => {
2278
+ if (buffer2.length === 0) return Promise.resolve();
2279
+ const batch2 = buffer2;
2280
+ buffer2 = [];
2281
+ seq += 1;
2282
+ const body = format === "ndjson" ? `${batch2.map((v) => JSON.stringify(v)).join("\n")}
2283
+ ` : JSON.stringify(batch2);
2284
+ const contentType = format === "ndjson" ? "application/x-ndjson" : "application/json";
2285
+ const key = keyGenerator(seq, wallClockNs());
2286
+ try {
2287
+ const p = client.putObject({ Bucket: bucket, Key: key, Body: body, ContentType: contentType }).then(() => {
2288
+ }).catch((err) => {
2289
+ onTransportError?.({
2290
+ stage: "send",
2291
+ error: err instanceof Error ? err : new Error(String(err)),
2292
+ value: batch2
2293
+ });
2294
+ });
2295
+ lastFlush = p;
2296
+ return p;
2297
+ } catch (err) {
2298
+ onTransportError?.({
2299
+ stage: "send",
2300
+ error: err instanceof Error ? err : new Error(String(err)),
2301
+ value: batch2
2302
+ });
2303
+ return Promise.resolve();
2304
+ }
2305
+ };
2306
+ const scheduleFlush = () => {
2307
+ if (timer === void 0) {
2308
+ timer = setTimeout(() => {
2309
+ timer = void 0;
2310
+ doFlush();
2311
+ }, flushIntervalMs);
2312
+ }
2313
+ };
2314
+ const inner = node([source], () => void 0, {
2315
+ describeKind: "effect",
2316
+ ...rest,
2317
+ onMessage(msg, _depIndex, _actions) {
2318
+ if (msg[0] === DATA) {
2319
+ const value = msg[1];
2320
+ try {
2321
+ buffer2.push(transform(value));
2322
+ } catch (err) {
2323
+ onTransportError?.({
2324
+ stage: "serialize",
2325
+ error: err instanceof Error ? err : new Error(String(err)),
2326
+ value
2327
+ });
2328
+ return true;
2329
+ }
2330
+ if (buffer2.length >= batchSize) doFlush();
2331
+ else scheduleFlush();
2332
+ return true;
2333
+ }
2334
+ if (msg[0] === COMPLETE || msg[0] === TEARDOWN) {
2335
+ doFlush();
2336
+ }
2337
+ return false;
2338
+ }
2339
+ });
2340
+ const unsub = inner.subscribe(() => {
2341
+ });
2342
+ const dispose = () => {
2343
+ if (timer !== void 0) {
2344
+ clearTimeout(timer);
2345
+ timer = void 0;
2346
+ }
2347
+ doFlush();
2348
+ unsub();
2349
+ };
2350
+ return {
2351
+ dispose,
2352
+ flush: () => doFlush().then(() => lastFlush)
2353
+ };
2354
+ }
2355
+ function toPostgres(source, client, table, opts) {
2356
+ const {
2357
+ toSQL = (v, t) => ({
2358
+ sql: `INSERT INTO "${t.replace(/"/g, '""')}" (data) VALUES ($1)`,
2359
+ params: [JSON.stringify(v)]
2360
+ }),
2361
+ onTransportError,
2362
+ ...rest
2363
+ } = opts ?? {};
2364
+ const inner = node([source], () => void 0, {
2365
+ describeKind: "effect",
2366
+ ...rest,
2367
+ onMessage(msg, _depIndex, _actions) {
2368
+ if (msg[0] === DATA) {
2369
+ const value = msg[1];
2370
+ let query;
2371
+ try {
2372
+ query = toSQL(value, table);
2373
+ } catch (err) {
2374
+ onTransportError?.({
2375
+ stage: "serialize",
2376
+ error: err instanceof Error ? err : new Error(String(err)),
2377
+ value
2378
+ });
2379
+ return true;
2380
+ }
2381
+ void client.query(query.sql, query.params).catch((err) => {
2382
+ onTransportError?.({
2383
+ stage: "send",
2384
+ error: err instanceof Error ? err : new Error(String(err)),
2385
+ value
2386
+ });
2387
+ });
2388
+ return true;
2389
+ }
2390
+ return false;
2391
+ }
2392
+ });
2393
+ return inner.subscribe(() => {
2394
+ });
2395
+ }
2396
+ function toMongo(source, collection, opts) {
2397
+ const { toDocument = (v) => v, onTransportError, ...rest } = opts ?? {};
2398
+ const inner = node([source], () => void 0, {
2399
+ describeKind: "effect",
2400
+ ...rest,
2401
+ onMessage(msg, _depIndex, _actions) {
2402
+ if (msg[0] === DATA) {
2403
+ const value = msg[1];
2404
+ let doc;
2405
+ try {
2406
+ doc = toDocument(value);
2407
+ } catch (err) {
2408
+ onTransportError?.({
2409
+ stage: "serialize",
2410
+ error: err instanceof Error ? err : new Error(String(err)),
2411
+ value
2412
+ });
2413
+ return true;
2414
+ }
2415
+ void collection.insertOne(doc).catch((err) => {
2416
+ onTransportError?.({
2417
+ stage: "send",
2418
+ error: err instanceof Error ? err : new Error(String(err)),
2419
+ value
2420
+ });
2421
+ });
2422
+ return true;
2423
+ }
2424
+ return false;
2425
+ }
2426
+ });
2427
+ return inner.subscribe(() => {
2428
+ });
2429
+ }
2430
+ function toLoki(source, client, opts) {
2431
+ const {
2432
+ labels = {},
2433
+ toLine = (v) => JSON.stringify(v),
2434
+ toLabels,
2435
+ onTransportError,
2436
+ ...rest
2437
+ } = opts ?? {};
2438
+ const inner = node([source], () => void 0, {
2439
+ describeKind: "effect",
2440
+ ...rest,
2441
+ onMessage(msg, _depIndex, _actions) {
2442
+ if (msg[0] === DATA) {
2443
+ const value = msg[1];
2444
+ let line;
2445
+ try {
2446
+ line = toLine(value);
2447
+ } catch (err) {
2448
+ onTransportError?.({
2449
+ stage: "serialize",
2450
+ error: err instanceof Error ? err : new Error(String(err)),
2451
+ value
2452
+ });
2453
+ return true;
2454
+ }
2455
+ let streamLabels;
2456
+ try {
2457
+ streamLabels = toLabels ? { ...labels, ...toLabels(value) } : labels;
2458
+ } catch (err) {
2459
+ onTransportError?.({
2460
+ stage: "serialize",
2461
+ error: err instanceof Error ? err : new Error(String(err)),
2462
+ value
2463
+ });
2464
+ return true;
2465
+ }
2466
+ const ts = `${wallClockNs()}`;
2467
+ void client.push({ streams: [{ stream: streamLabels, values: [[ts, line]] }] }).catch((err) => {
2468
+ onTransportError?.({
2469
+ stage: "send",
2470
+ error: err instanceof Error ? err : new Error(String(err)),
2471
+ value
2472
+ });
2473
+ });
2474
+ return true;
2475
+ }
2476
+ return false;
2477
+ }
2478
+ });
2479
+ return inner.subscribe(() => {
2480
+ });
2481
+ }
2482
+ function toTempo(source, client, opts) {
2483
+ const { toResourceSpans = (v) => [v], onTransportError, ...rest } = opts ?? {};
2484
+ const inner = node([source], () => void 0, {
2485
+ describeKind: "effect",
2486
+ ...rest,
2487
+ onMessage(msg, _depIndex, _actions) {
2488
+ if (msg[0] === DATA) {
2489
+ const value = msg[1];
2490
+ let spans;
2491
+ try {
2492
+ spans = toResourceSpans(value);
2493
+ } catch (err) {
2494
+ onTransportError?.({
2495
+ stage: "serialize",
2496
+ error: err instanceof Error ? err : new Error(String(err)),
2497
+ value
2498
+ });
2499
+ return true;
2500
+ }
2501
+ void client.push({ resourceSpans: spans }).catch((err) => {
2502
+ onTransportError?.({
2503
+ stage: "send",
2504
+ error: err instanceof Error ? err : new Error(String(err)),
2505
+ value
2506
+ });
2507
+ });
2508
+ return true;
2509
+ }
2510
+ return false;
2511
+ }
2512
+ });
2513
+ return inner.subscribe(() => {
2514
+ });
2515
+ }
2516
+ function checkpointToS3(graph, client, bucket, opts) {
2517
+ const { prefix = "checkpoints/", debounceMs, compactEvery, onError } = opts ?? {};
2518
+ const adapter = {
2519
+ save(data) {
2520
+ const ms = Math.floor(wallClockNs() / 1e6);
2521
+ const key = `${prefix}${graph.name}/checkpoint-${ms}.json`;
2522
+ let body;
2523
+ try {
2524
+ body = JSON.stringify(data);
2525
+ } catch (err) {
2526
+ onError?.(err);
2527
+ return;
2528
+ }
2529
+ void client.putObject({
2530
+ Bucket: bucket,
2531
+ Key: key,
2532
+ Body: body,
2533
+ ContentType: "application/json"
2534
+ }).catch((err) => onError?.(err));
2535
+ }
2536
+ };
2537
+ return graph.autoCheckpoint(adapter, { debounceMs, compactEvery, onError });
2538
+ }
2539
+ function checkpointToRedis(graph, client, opts) {
2540
+ const { prefix = "graphrefly:checkpoint:", debounceMs, compactEvery, onError } = opts ?? {};
2541
+ const key = `${prefix}${graph.name}`;
2542
+ const adapter = {
2543
+ save(data) {
2544
+ let body;
2545
+ try {
2546
+ body = JSON.stringify(data);
2547
+ } catch (err) {
2548
+ onError?.(err);
2549
+ return;
2550
+ }
2551
+ void client.set(key, body).catch((err) => onError?.(err));
2552
+ }
2553
+ };
2554
+ return graph.autoCheckpoint(adapter, { debounceMs, compactEvery, onError });
2555
+ }
2556
+ function fromSqlite(db, query, opts) {
2557
+ const { mapRow = (r) => r, params, ...rest } = opts ?? {};
2558
+ return producer(
2559
+ (_d, a) => {
2560
+ let mapped;
2561
+ try {
2562
+ const rows = db.query(query, params);
2563
+ mapped = rows.map(mapRow);
2564
+ } catch (err) {
2565
+ a.down([[ERROR, err instanceof Error ? err : new Error(String(err))]]);
2566
+ return void 0;
2567
+ }
2568
+ batch(() => {
2569
+ for (const item of mapped) {
2570
+ a.down([[DATA, item]]);
2571
+ }
2572
+ a.down([[COMPLETE]]);
2573
+ });
2574
+ return void 0;
2575
+ },
2576
+ { describeKind: "producer", completeWhenDepsComplete: false, ...rest }
2577
+ );
2578
+ }
2579
+ function toSqlite(source, db, table, opts) {
2580
+ if (table.includes("\0") || table.length === 0) {
2581
+ throw new Error(`toSqlite: invalid table name: ${JSON.stringify(table)}`);
2582
+ }
2583
+ const {
2584
+ toSQL = (v, t) => ({
2585
+ sql: `INSERT INTO "${t.replace(/"/g, '""')}" (data) VALUES (?)`,
2586
+ params: [JSON.stringify(v)]
2587
+ }),
2588
+ onTransportError,
2589
+ ...rest
2590
+ } = opts ?? {};
2591
+ const inner = node([source], () => void 0, {
2592
+ describeKind: "effect",
2593
+ ...rest,
2594
+ onMessage(msg, _depIndex, _actions) {
2595
+ if (msg[0] === DATA) {
2596
+ const value = msg[1];
2597
+ let query;
2598
+ try {
2599
+ query = toSQL(value, table);
2600
+ } catch (err) {
2601
+ onTransportError?.({
2602
+ stage: "serialize",
2603
+ error: err instanceof Error ? err : new Error(String(err)),
2604
+ value
2605
+ });
2606
+ return true;
2607
+ }
2608
+ try {
2609
+ db.query(query.sql, query.params);
2610
+ } catch (err) {
2611
+ onTransportError?.({
2612
+ stage: "send",
2613
+ error: err instanceof Error ? err : new Error(String(err)),
2614
+ value
2615
+ });
2616
+ }
2617
+ return true;
2618
+ }
2619
+ return false;
2620
+ }
2621
+ });
2622
+ return inner.subscribe(() => {
2623
+ });
2624
+ }
1747
2625
 
1748
2626
  // src/extra/checkpoint.ts
1749
2627
  import { randomBytes } from "crypto";
@@ -4708,6 +5586,24 @@ export {
4708
5586
  fromCSV,
4709
5587
  fromNDJSON,
4710
5588
  fromClickHouseWatch,
5589
+ fromPulsar,
5590
+ toPulsar,
5591
+ fromNATS,
5592
+ toNATS,
5593
+ fromRabbitMQ,
5594
+ toRabbitMQ,
5595
+ toFile,
5596
+ toCSV,
5597
+ toClickHouse,
5598
+ toS3,
5599
+ toPostgres,
5600
+ toMongo,
5601
+ toLoki,
5602
+ toTempo,
5603
+ checkpointToS3,
5604
+ checkpointToRedis,
5605
+ fromSqlite,
5606
+ toSqlite,
4711
5607
  MemoryCheckpointAdapter,
4712
5608
  DictCheckpointAdapter,
4713
5609
  FileCheckpointAdapter,
@@ -4782,4 +5678,4 @@ export {
4782
5678
  workerSelf,
4783
5679
  extra_exports
4784
5680
  };
4785
- //# sourceMappingURL=chunk-VPS7L64N.js.map
5681
+ //# sourceMappingURL=chunk-V3UACY6A.js.map