@streamsy/storage 0.5.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.
package/dist/bun.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { r as SqlStorageOptions } from "./storage-kHdg037u.js";
1
+ import { r as SqlStorageOptions } from "./storage-Cb_kOO_g.js";
2
2
  import { Layer } from "effect";
3
3
  import { StorageFault, Streamsy } from "@streamsy/core";
4
4
  import { Protocol } from "@streamsy/core/protocol";
package/dist/bun.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D8jQpDG7.js";
2
- import { a as storageLayer$1, d as retryWithPolicy, f as transactionRetryPolicy, o as inspectFormat, s as newerVersionFault, u as sharedSqlClientLayer } from "./storage-D3Ubo2kB.js";
2
+ import { a as storageLayer$1, d as retryWithPolicy, f as transactionRetryPolicy, o as inspectFormat, s as newerVersionFault, u as sharedSqlClientLayer } from "./storage-DFCZf1UK.js";
3
3
  import { Array, Cause, Effect, FileSystem, Layer, Option, Path, Result, Schema } from "effect";
4
4
  import { StorageFault } from "@streamsy/core";
5
5
  import { Protocol } from "@streamsy/core/protocol";
@@ -1,4 +1,4 @@
1
- import { r as SqlStorageOptions } from "./storage-kHdg037u.js";
1
+ import { r as SqlStorageOptions } from "./storage-Cb_kOO_g.js";
2
2
  import { Layer } from "effect";
3
3
  import { Streamsy } from "@streamsy/core";
4
4
  import { Protocol } from "@streamsy/core/protocol";
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D8jQpDG7.js";
2
- import { i as layerWithDurableObjectTransactions, u as sharedSqlClientLayer } from "./storage-D3Ubo2kB.js";
2
+ import { i as layerWithDurableObjectTransactions, u as sharedSqlClientLayer } from "./storage-DFCZf1UK.js";
3
3
  import { Layer } from "effect";
4
4
  import "@streamsy/core";
5
5
  import { Protocol } from "@streamsy/core/protocol";
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as layerProtocol, c as DEFAULT_TRANSACTION_RETRY_DELAY_MS, i as layer, n as Options, o as clientLayer, s as DEFAULT_TRANSACTION_RETRY_ATTEMPTS, t as DEFAULT_REPAIR_INTERVAL_MS } from "./storage-kHdg037u.js";
1
+ import { a as layerProtocol, c as DEFAULT_TRANSACTION_RETRY_DELAY_MS, i as layer, n as Options, o as clientLayer, s as DEFAULT_TRANSACTION_RETRY_ATTEMPTS, t as DEFAULT_REPAIR_INTERVAL_MS } from "./storage-Cb_kOO_g.js";
2
2
  declare namespace sql_storage_d_exports {
3
3
  export { DEFAULT_REPAIR_INTERVAL_MS, DEFAULT_TRANSACTION_RETRY_ATTEMPTS, DEFAULT_TRANSACTION_RETRY_DELAY_MS, Options, clientLayer, layer, layerProtocol };
4
4
  }
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D8jQpDG7.js";
2
- import { l as clientLayer, n as layer, r as layerProtocol, t as DEFAULT_REPAIR_INTERVAL_MS } from "./storage-D3Ubo2kB.js";
2
+ import { l as clientLayer, n as layer, r as layerProtocol, t as DEFAULT_REPAIR_INTERVAL_MS } from "./storage-DFCZf1UK.js";
3
3
  // src/sql-storage.ts
4
4
  var sql_storage_exports = /* @__PURE__ */ __exportAll({
5
5
  DEFAULT_REPAIR_INTERVAL_MS: () => DEFAULT_REPAIR_INTERVAL_MS,
@@ -1,8 +1,8 @@
1
- import { Context, Effect, Layer, Queue, Scope, Stream } from "effect";
1
+ import { Context, Effect, Layer, PubSub, Queue, Scope, Stream } from "effect";
2
2
  import { Reactivity } from "effect/reactivity";
3
3
  import { SqlClient, SqlError } from "effect/sql";
4
4
  import { OwnerRecords } from "@streamsy/core/internal";
5
- import { CommitBoundary, Storage, StorageFault, Streamsy } from "@streamsy/core";
5
+ import { CommitBoundary, Storage, StorageFault, StreamId, Streamsy } from "@streamsy/core";
6
6
  import { Protocol } from "@streamsy/core/protocol";
7
7
  declare const DEFAULT_TRANSACTION_RETRY_ATTEMPTS = 16;
8
8
  declare const DEFAULT_TRANSACTION_RETRY_DELAY_MS = 25;
@@ -1,4 +1,4 @@
1
- import { Array, Clock, Context, Deferred, Effect, Fiber, Layer, Option, Order, Predicate, Queue, Schedule, Scheduler, Schema, Stream } from "effect";
1
+ import { Array, Clock, Context, Deferred, Effect, Fiber, Layer, Option, Order, Predicate, PubSub, Queue, Schedule, Scheduler, Schema, Stream } from "effect";
2
2
  import { Reactivity } from "effect/reactivity";
3
3
  import { SqlClient, SqlError } from "effect/sql";
4
4
  import { OwnerRecords, attachOwner, ownerOf } from "@streamsy/core/internal";
@@ -41,6 +41,7 @@ const makeBoundary = (repairIntervalMs, transactionRetry, probe, transactionMaxO
41
41
  const sql = yield* SqlClient.SqlClient;
42
42
  const reactivity = yield* Reactivity.Reactivity;
43
43
  const subscriptions = /* @__PURE__ */ new Set();
44
+ const feed = yield* Effect.acquireRelease(PubSub.unbounded(), PubSub.shutdown);
44
45
  let closed = false;
45
46
  yield* Effect.addFinalizer(() => Effect.gen(function* () {
46
47
  const active = yield* Effect.sync(() => {
@@ -52,17 +53,20 @@ const makeBoundary = (repairIntervalMs, transactionRetry, probe, transactionMaxO
52
53
  }));
53
54
  const ownedTransaction = (body) => Effect.suspend(() => {
54
55
  if (probe !== void 0) probe.transactionAttempts += 1;
55
- const pending = /* @__PURE__ */ new Set();
56
+ const pending = {
57
+ keys: /* @__PURE__ */ new Set(),
58
+ ids: /* @__PURE__ */ new Set()
59
+ };
56
60
  let bodyCompleted = false;
57
61
  const transactionBody = body.pipe(Effect.provideService(PendingInvalidations, pending), Effect.tap(() => Effect.sync(() => {
58
62
  bodyCompleted = true;
59
63
  })));
60
64
  const transaction = sql.withTransaction(transactionBody).pipe(Effect.catchIf((error) => bodyCompleted && SqlError.isSqlError(error), (error) => Effect.die(error)));
61
65
  return (transactionMaxOpsBeforeYield === void 0 ? transaction : transaction.pipe(Effect.provideService(Scheduler.MaxOpsBeforeYield, transactionMaxOpsBeforeYield))).pipe(Effect.tap(() => {
62
- if (pending.size === 0) return Effect.void;
66
+ if (pending.keys.size === 0) return Effect.void;
63
67
  if (probe !== void 0) probe.invalidations += 1;
64
- return reactivity.invalidate([...pending]);
65
- }));
68
+ return reactivity.invalidate([...pending.keys]);
69
+ }), Effect.tap(() => pending.ids.size === 0 ? Effect.void : PubSub.publish(feed, [...pending.ids])));
66
70
  });
67
71
  const withTransaction = (body) => Effect.flatMap(Effect.serviceOption(PendingInvalidations), (owned) => {
68
72
  if (Option.isSome(owned)) return body;
@@ -71,12 +75,13 @@ const makeBoundary = (repairIntervalMs, transactionRetry, probe, transactionMaxO
71
75
  return ownedTransaction(body);
72
76
  });
73
77
  });
74
- const mutation = ({ keys, effect, retryable }) => Effect.flatMap(Effect.serviceOption(sql.transactionService), (ambient) => Effect.flatMap(Effect.serviceOption(PendingInvalidations), (pendingBefore) => {
78
+ const mutation = ({ keys, ids, effect, retryable }) => Effect.flatMap(Effect.serviceOption(sql.transactionService), (ambient) => Effect.flatMap(Effect.serviceOption(PendingInvalidations), (pendingBefore) => {
75
79
  if (Option.isSome(ambient) && Option.isNone(pendingBefore)) return Effect.die(/* @__PURE__ */ new Error("Ambient SQL transaction is not owned by CommitBoundary"));
76
80
  const run = Effect.tap(effect, () => Effect.flatMap(Effect.serviceOption(PendingInvalidations), (pending) => {
77
81
  if (Option.isNone(pending)) return Effect.die(/* @__PURE__ */ new Error("CommitBoundary owner context disappeared"));
78
82
  return Effect.sync(() => {
79
- for (const key of keys) pending.value.add(key);
83
+ for (const key of keys) pending.value.keys.add(key);
84
+ for (const id of ids) pending.value.ids.add(id);
80
85
  });
81
86
  }));
82
87
  return Option.isSome(ambient) ? run : retryWithPolicy(ownedTransaction(run), transactionRetry, (error) => SqlError.isSqlError(error) ? error.isRetryable : retryable(error));
@@ -134,7 +139,8 @@ const makeBoundary = (repairIntervalMs, transactionRetry, probe, transactionMaxO
134
139
  return {
135
140
  withTransaction,
136
141
  mutation,
137
- changes
142
+ changes,
143
+ committed: PubSub.subscribe(feed)
138
144
  };
139
145
  });
140
146
  const boundaryLayer = (repairIntervalMs, transactionRetry, probe, transactionMaxOpsBeforeYield) => Layer.effect(BoundaryRuntimeService, makeBoundary(repairIntervalMs, transactionRetry, probe, transactionMaxOpsBeforeYield));
@@ -723,6 +729,7 @@ const makeStorage = (sql, boundary) => Storage.of({
723
729
  if (Option.isSome(oversized)) return Effect.fail(oversized.value);
724
730
  return boundary.mutation({
725
731
  keys: [STORAGE_KEY],
732
+ ids,
726
733
  effect: applyMutation(sql, mutation),
727
734
  retryable: (error) => Predicate.isTagged(error, "StorageFault") && error.retryable
728
735
  }).pipe(Effect.catchIf(SqlError.isSqlError, (error) => Effect.fail(sqlFault("mutate.transaction", error))));
@@ -731,6 +738,7 @@ const makeStorage = (sql, boundary) => Storage.of({
731
738
  keys: [STORAGE_KEY],
732
739
  read: snapshot(sql, id)
733
740
  }),
741
+ committed: boundary.committed,
734
742
  nextExpiry: attempt("nextExpiry", sql`SELECT expires_at_ms AS at, stream_id FROM streamsy_streams
735
743
  WHERE expires_at_ms IS NOT NULL AND soft_deleted = 0
736
744
  ORDER BY expires_at_ms, stream_id LIMIT 1`).pipe(Effect.flatMap((rows) => rows[0] === void 0 ? Effect.succeed(Option.none()) : decodeExpiryRow(rows[0]).pipe(Effect.map(({ at, stream_id: streamId }) => Option.some({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@streamsy/storage",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Effect SQL storage for Streamsy on SQLite, Postgres and MySQL, with Bun and Durable Object SQLite host layers.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -42,7 +42,7 @@
42
42
  "test:dialects": "bun --bun vitest run test/dialects"
43
43
  },
44
44
  "dependencies": {
45
- "@streamsy/core": "^0.5.0"
45
+ "@streamsy/core": "^0.6.0"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@cloudflare/workers-types": "4.20251228.0",
@@ -52,7 +52,7 @@
52
52
  "@effect/sql-sqlite-bun": "4.0.5",
53
53
  "@effect/sql-sqlite-do": "4.0.5",
54
54
  "@effect/vitest": "4.0.5",
55
- "@streamsy/serve": "0.5.0",
55
+ "@streamsy/serve": "0.6.0",
56
56
  "@types/bun": "^1.4.3",
57
57
  "effect": "4.0.5",
58
58
  "miniflare": "4.20260730.0",