@streamsy/storage 0.4.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/bun.d.ts +1 -2
- package/dist/bun.js +6 -8
- package/dist/durable-object.d.ts +1 -2
- package/dist/durable-object.js +3 -4
- package/dist/index.d.ts +1 -2
- package/dist/index.js +3 -4
- package/dist/{rolldown-runtime-D7D4PA-g.js → rolldown-runtime-D8jQpDG7.js} +1 -2
- package/dist/{storage-CpnFxwO5.js → storage-D3Ubo2kB.js} +18 -26
- package/dist/{storage-CrMmTyyG.d.ts → storage-kHdg037u.d.ts} +2 -9
- package/package.json +3 -3
package/dist/bun.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as SqlStorageOptions } from "./storage-
|
|
1
|
+
import { r as SqlStorageOptions } from "./storage-kHdg037u.js";
|
|
2
2
|
import { Layer } from "effect";
|
|
3
3
|
import { StorageFault, Streamsy } from "@streamsy/core";
|
|
4
4
|
import { Protocol } from "@streamsy/core/protocol";
|
|
@@ -16,5 +16,4 @@ declare const storageLayer: (options: BunStorageOptions) => Layer.Layer<import("
|
|
|
16
16
|
/** Complete persistent protocol Layer for an HttpRouter application. */
|
|
17
17
|
declare const layerProtocol: (options: Options) => Layer.Layer<import("@streamsy/core").CommitBoundary | import("@streamsy/core/internal").OwnerRecords | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient | import("@streamsy/core").Storage | import("@streamsy/core/protocol").StreamsReader | import("@streamsy/core/protocol").StreamsWriter, StorageFault, never>;
|
|
18
18
|
declare function layer<const Keys extends ReadonlyArray<Streamsy.Any>>(group: Streamsy.Group<Keys>, options: Options): Layer.Layer<Layer.Success<ReturnType<typeof storageLayer>> | Streamsy.Host<Streamsy.Group<Keys>>, Layer.Error<ReturnType<typeof storageLayer>>>;
|
|
19
|
-
//#endregion
|
|
20
19
|
export { bun_storage_d_exports as BunStorage };
|
package/dist/bun.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { t as __exportAll } from "./rolldown-runtime-
|
|
2
|
-
import { a as storageLayer$1, d as retryWithPolicy, f as transactionRetryPolicy, o as inspectFormat, s as newerVersionFault, u as sharedSqlClientLayer } from "./storage-
|
|
3
|
-
import { Cause, Effect, FileSystem, Layer, Option, Path, Result, Schema } from "effect";
|
|
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";
|
|
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";
|
|
6
6
|
import * as BunFileSystem from "@effect/platform-bun/BunFileSystem";
|
|
7
7
|
import * as BunPath from "@effect/platform-bun/BunPath";
|
|
8
8
|
import { SqliteClient } from "@effect/sql-sqlite-bun";
|
|
9
9
|
import { Database } from "bun:sqlite";
|
|
10
|
-
|
|
10
|
+
// src/sqlite-file.ts
|
|
11
11
|
const openFault$1 = (message) => new StorageFault({
|
|
12
12
|
operation: "migration.open",
|
|
13
13
|
message,
|
|
@@ -16,7 +16,7 @@ const openFault$1 = (message) => new StorageFault({
|
|
|
16
16
|
const decodeTableNames = Schema.decodeUnknownSync(Schema.Array(Schema.Struct({ name: Schema.String })));
|
|
17
17
|
const decodeVersions = Schema.decodeUnknownSync(Schema.Array(Schema.Struct({ version: Schema.NullOr(Schema.Finite) })));
|
|
18
18
|
const readFormat = (reader) => {
|
|
19
|
-
const names = new Set(decodeTableNames(reader.all("SELECT name FROM sqlite_master WHERE type='table'"))
|
|
19
|
+
const names = new Set(Array.map(decodeTableNames(reader.all("SELECT name FROM sqlite_master WHERE type='table'")), ({ name }) => name));
|
|
20
20
|
return {
|
|
21
21
|
names,
|
|
22
22
|
version: names.has("streamsy_schema") ? decodeVersions(reader.all(`SELECT MAX(version) version FROM streamsy_schema`)).at(0)?.version ?? 0 : 0
|
|
@@ -54,8 +54,7 @@ const prepare = (driver, options, retry) => Effect.gen(function* () {
|
|
|
54
54
|
create: options.create ?? true
|
|
55
55
|
}, ["PRAGMA busy_timeout=0", "PRAGMA journal_mode=WAL"]));
|
|
56
56
|
});
|
|
57
|
-
|
|
58
|
-
//#region src/bun-storage.ts
|
|
57
|
+
// src/bun-storage.ts
|
|
59
58
|
var bun_storage_exports = /* @__PURE__ */ __exportAll({
|
|
60
59
|
layer: () => layer,
|
|
61
60
|
layerProtocol: () => layerProtocol
|
|
@@ -105,5 +104,4 @@ function layer(group, options) {
|
|
|
105
104
|
const protocol = Protocol.layer(options).pipe(Layer.provideMerge(storage));
|
|
106
105
|
return Protocol.bind(protocol, group).pipe(Layer.provideMerge(storage));
|
|
107
106
|
}
|
|
108
|
-
//#endregion
|
|
109
107
|
export { bun_storage_exports as BunStorage };
|
package/dist/durable-object.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as SqlStorageOptions } from "./storage-
|
|
1
|
+
import { r as SqlStorageOptions } from "./storage-kHdg037u.js";
|
|
2
2
|
import { Layer } from "effect";
|
|
3
3
|
import { Streamsy } from "@streamsy/core";
|
|
4
4
|
import { Protocol } from "@streamsy/core/protocol";
|
|
@@ -20,5 +20,4 @@ declare const storageLayer: (options: DurableObjectStorageOptions) => Layer.Laye
|
|
|
20
20
|
/** Protocol over the official Durable Object SQLite layer. */
|
|
21
21
|
declare const layerProtocol: (options: Options) => Layer.Layer<import("@streamsy/core").CommitBoundary | import("@streamsy/core/internal").OwnerRecords | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient | import("@streamsy/core").Storage | import("@streamsy/core/protocol").StreamsReader | import("@streamsy/core/protocol").StreamsWriter, import("@streamsy/core").StorageFault, never>;
|
|
22
22
|
declare function layer<const Keys extends ReadonlyArray<Streamsy.Any>>(group: Streamsy.Group<Keys>, options: Options): Layer.Layer<Layer.Success<ReturnType<typeof storageLayer>> | Streamsy.Host<Streamsy.Group<Keys>>, Layer.Error<ReturnType<typeof storageLayer>>>;
|
|
23
|
-
//#endregion
|
|
24
23
|
export { durable_object_storage_d_exports as DurableObjectStorage };
|
package/dist/durable-object.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { t as __exportAll } from "./rolldown-runtime-
|
|
2
|
-
import { i as layerWithDurableObjectTransactions, u as sharedSqlClientLayer } from "./storage-
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-D8jQpDG7.js";
|
|
2
|
+
import { i as layerWithDurableObjectTransactions, u as sharedSqlClientLayer } from "./storage-D3Ubo2kB.js";
|
|
3
3
|
import { Layer } from "effect";
|
|
4
4
|
import "@streamsy/core";
|
|
5
5
|
import { Protocol } from "@streamsy/core/protocol";
|
|
6
6
|
import { SqliteClient } from "@effect/sql-sqlite-do";
|
|
7
|
-
|
|
7
|
+
// src/durable-object-storage.ts
|
|
8
8
|
var durable_object_storage_exports = /* @__PURE__ */ __exportAll({
|
|
9
9
|
DEFAULT_LONG_POLL_TIMEOUT_MS: () => DEFAULT_LONG_POLL_TIMEOUT_MS,
|
|
10
10
|
layer: () => layer,
|
|
@@ -29,5 +29,4 @@ function layer(group, options) {
|
|
|
29
29
|
}).pipe(Layer.provideMerge(storage));
|
|
30
30
|
return Protocol.bind(protocol, group).pipe(Layer.provideMerge(storage));
|
|
31
31
|
}
|
|
32
|
-
//#endregion
|
|
33
32
|
export { durable_object_storage_exports as DurableObjectStorage };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
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-
|
|
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";
|
|
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
|
}
|
|
5
|
-
//#endregion
|
|
6
5
|
export { sql_storage_d_exports as SqlStorage };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { t as __exportAll } from "./rolldown-runtime-
|
|
2
|
-
import { l as clientLayer, n as layer, r as layerProtocol, t as DEFAULT_REPAIR_INTERVAL_MS } from "./storage-
|
|
3
|
-
|
|
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";
|
|
3
|
+
// src/sql-storage.ts
|
|
4
4
|
var sql_storage_exports = /* @__PURE__ */ __exportAll({
|
|
5
5
|
DEFAULT_REPAIR_INTERVAL_MS: () => DEFAULT_REPAIR_INTERVAL_MS,
|
|
6
6
|
DEFAULT_TRANSACTION_RETRY_ATTEMPTS: () => 16,
|
|
@@ -9,5 +9,4 @@ var sql_storage_exports = /* @__PURE__ */ __exportAll({
|
|
|
9
9
|
layer: () => layer,
|
|
10
10
|
layerProtocol: () => layerProtocol
|
|
11
11
|
});
|
|
12
|
-
//#endregion
|
|
13
12
|
export { sql_storage_exports as SqlStorage };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// \0rolldown/runtime.js
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __exportAll = (all, no_symbols) => {
|
|
4
4
|
let target = {};
|
|
@@ -9,5 +9,4 @@ var __exportAll = (all, no_symbols) => {
|
|
|
9
9
|
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
10
10
|
return target;
|
|
11
11
|
};
|
|
12
|
-
//#endregion
|
|
13
12
|
export { __exportAll as t };
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { Clock, Context, Deferred, Effect, Fiber, Layer, Option, Predicate, Queue, Schedule, Schema, Stream } from "effect";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import * as SqlClient from "effect/sql/SqlClient";
|
|
5
|
-
import { isSqlError } from "effect/sql/SqlError";
|
|
1
|
+
import { Array, Clock, Context, Deferred, Effect, Fiber, Layer, Option, Order, Predicate, Queue, Schedule, Scheduler, Schema, Stream } from "effect";
|
|
2
|
+
import { Reactivity } from "effect/reactivity";
|
|
3
|
+
import { SqlClient, SqlError } from "effect/sql";
|
|
6
4
|
import { OwnerRecords, attachOwner, ownerOf } from "@streamsy/core/internal";
|
|
7
5
|
import { CommitBoundary, MutationRejected, Mutations, Offset, OperationResults, Storage, StorageFault, StreamId, ZERO_OFFSET } from "@streamsy/core";
|
|
8
6
|
import { Protocol } from "@streamsy/core/protocol";
|
|
@@ -22,8 +20,7 @@ const retryWithPolicy = (transaction, policy, isRetryable) => transaction.pipe(E
|
|
|
22
20
|
schedule: Schedule.spaced(policy.delayMs),
|
|
23
21
|
while: isRetryable
|
|
24
22
|
}));
|
|
25
|
-
|
|
26
|
-
//#region src/boundary.ts
|
|
23
|
+
// src/boundary.ts
|
|
27
24
|
var PendingInvalidations = class extends Context.Service()("@streamsy/storage/PendingInvalidations") {};
|
|
28
25
|
const noop = () => {};
|
|
29
26
|
var BoundaryRuntimeService = class extends Context.Service()("@streamsy/storage/BoundaryRuntime") {};
|
|
@@ -60,7 +57,7 @@ const makeBoundary = (repairIntervalMs, transactionRetry, probe, transactionMaxO
|
|
|
60
57
|
const transactionBody = body.pipe(Effect.provideService(PendingInvalidations, pending), Effect.tap(() => Effect.sync(() => {
|
|
61
58
|
bodyCompleted = true;
|
|
62
59
|
})));
|
|
63
|
-
const transaction = sql.withTransaction(transactionBody).pipe(Effect.catchIf((error) => bodyCompleted && isSqlError(error), (error) => Effect.die(error)));
|
|
60
|
+
const transaction = sql.withTransaction(transactionBody).pipe(Effect.catchIf((error) => bodyCompleted && SqlError.isSqlError(error), (error) => Effect.die(error)));
|
|
64
61
|
return (transactionMaxOpsBeforeYield === void 0 ? transaction : transaction.pipe(Effect.provideService(Scheduler.MaxOpsBeforeYield, transactionMaxOpsBeforeYield))).pipe(Effect.tap(() => {
|
|
65
62
|
if (pending.size === 0) return Effect.void;
|
|
66
63
|
if (probe !== void 0) probe.invalidations += 1;
|
|
@@ -82,7 +79,7 @@ const makeBoundary = (repairIntervalMs, transactionRetry, probe, transactionMaxO
|
|
|
82
79
|
for (const key of keys) pending.value.add(key);
|
|
83
80
|
});
|
|
84
81
|
}));
|
|
85
|
-
return Option.isSome(ambient) ? run : retryWithPolicy(ownedTransaction(run), transactionRetry, (error) => isSqlError(error) ? error.isRetryable : retryable(error));
|
|
82
|
+
return Option.isSome(ambient) ? run : retryWithPolicy(ownedTransaction(run), transactionRetry, (error) => SqlError.isSqlError(error) ? error.isRetryable : retryable(error));
|
|
86
83
|
})).pipe(Effect.onExit(() => Effect.sync(() => {
|
|
87
84
|
if (probe !== void 0) probe.completedMutations += 1;
|
|
88
85
|
})));
|
|
@@ -141,8 +138,7 @@ const makeBoundary = (repairIntervalMs, transactionRetry, probe, transactionMaxO
|
|
|
141
138
|
};
|
|
142
139
|
});
|
|
143
140
|
const boundaryLayer = (repairIntervalMs, transactionRetry, probe, transactionMaxOpsBeforeYield) => Layer.effect(BoundaryRuntimeService, makeBoundary(repairIntervalMs, transactionRetry, probe, transactionMaxOpsBeforeYield));
|
|
144
|
-
|
|
145
|
-
//#region src/dialect.ts
|
|
141
|
+
// src/dialect.ts
|
|
146
142
|
/** The client's dialect. Other dialects fail with a non-retryable fault. */
|
|
147
143
|
const storageDialect = (sql) => sql.onDialectOrElse({
|
|
148
144
|
sqlite: () => Effect.succeed("sqlite"),
|
|
@@ -154,8 +150,7 @@ const storageDialect = (sql) => sql.onDialectOrElse({
|
|
|
154
150
|
retryable: false
|
|
155
151
|
}))
|
|
156
152
|
});
|
|
157
|
-
|
|
158
|
-
//#region src/schema.ts
|
|
153
|
+
// src/schema.ts
|
|
159
154
|
const STORAGE_VERSION_TABLE = "streamsy_schema";
|
|
160
155
|
/** Version tables of earlier formats. A database that holds one must not be migrated. */
|
|
161
156
|
const LEGACY_VERSION_TABLES = ["streamsy_schema_version", "streamsy_storage_schema_version"];
|
|
@@ -258,8 +253,7 @@ const STORAGE_MIGRATIONS = [{
|
|
|
258
253
|
) ENGINE=InnoDB`
|
|
259
254
|
]
|
|
260
255
|
}];
|
|
261
|
-
|
|
262
|
-
//#region src/migrations.ts
|
|
256
|
+
// src/migrations.ts
|
|
263
257
|
/** Fixed `pg_advisory_xact_lock` key: "streamsy" in ASCII, read as a 64-bit integer. */
|
|
264
258
|
const PG_MIGRATION_LOCK_KEY = "8319400191411975033";
|
|
265
259
|
/** Named lock that serialises MySQL migrations, whose DDL cannot share one transaction. */
|
|
@@ -275,7 +269,7 @@ const sqlAttempt = (operation, effect) => effect.pipe(Effect.mapError((error) =>
|
|
|
275
269
|
/** Return whether the database already holds this format, or fail on an older format. */
|
|
276
270
|
const inspectFormat = (tables) => {
|
|
277
271
|
const ownsFormat = tables.has(STORAGE_VERSION_TABLE);
|
|
278
|
-
return
|
|
272
|
+
return Array.some(LEGACY_VERSION_TABLES, (name) => tables.has(name)) || !ownsFormat && Array.some(STORAGE_TABLES, (name) => tables.has(name)) ? Effect.fail(new StorageFault({
|
|
279
273
|
operation: "migration.open",
|
|
280
274
|
message: "Unsupported older Streamsy storage format; use a fresh database path (the database was not modified)",
|
|
281
275
|
retryable: false
|
|
@@ -292,7 +286,7 @@ const listTables = (sql, dialect) => sqlAttempt("migration.inspect", {
|
|
|
292
286
|
WHERE table_schema = current_schema()`,
|
|
293
287
|
mysql: () => sql`SELECT table_name AS name FROM information_schema.tables
|
|
294
288
|
WHERE table_schema = DATABASE()`
|
|
295
|
-
}[dialect]()).pipe(Effect.map((rows) => new Set(
|
|
289
|
+
}[dialect]()).pipe(Effect.map((rows) => new Set(Array.map(rows, ({ name }) => name))));
|
|
296
290
|
const migrateVersions = (sql, dialect, hooks) => Effect.gen(function* () {
|
|
297
291
|
if (!(yield* inspectFormat(yield* listTables(sql, dialect)))) yield* sqlAttempt("migration.create-version-table", sql.unsafe(STORAGE_VERSION_TABLE_DDL[dialect]).pipe(Effect.asVoid));
|
|
298
292
|
const current = yield* sqlAttempt("migration.read-version", sql`SELECT MAX(version) AS version FROM ${sql(STORAGE_VERSION_TABLE)}`.pipe(Effect.map((rows) => Number(rows[0]?.version ?? 0))));
|
|
@@ -332,9 +326,8 @@ const migrate = (sql, hooks = {}, transactionRetry = transactionRetryPolicy({}))
|
|
|
332
326
|
hooks.onTransactionAttempt?.();
|
|
333
327
|
if (dialect === "mysql") return migrateMysql(sql, hooks);
|
|
334
328
|
return sql.withTransaction(dialect === "pg" ? sqlAttempt("migration.lock", sql`SELECT pg_advisory_xact_lock(${sql.literal(PG_MIGRATION_LOCK_KEY)})`).pipe(Effect.andThen(migrateVersions(sql, dialect, hooks))) : migrateVersions(sql, dialect, hooks));
|
|
335
|
-
}), transactionRetry, (error) => isSqlError(error) ? error.isRetryable : error.retryable).pipe(Effect.catchIf(isSqlError, (error) => Effect.fail(fault("migration.transaction", error)))));
|
|
336
|
-
|
|
337
|
-
//#region src/storage.ts
|
|
329
|
+
}), transactionRetry, (error) => SqlError.isSqlError(error) ? error.isRetryable : error.retryable).pipe(Effect.catchIf(SqlError.isSqlError, (error) => Effect.fail(fault("migration.transaction", error)))));
|
|
330
|
+
// src/storage.ts
|
|
338
331
|
const DEFAULT_REPAIR_INTERVAL_MS = 1e3;
|
|
339
332
|
const STORAGE_KEY = "streamsy:storage";
|
|
340
333
|
const RecordRow = Schema.Struct({
|
|
@@ -467,7 +460,7 @@ const oversizedKey = (mutation) => {
|
|
|
467
460
|
* Sorted ids give every writer one lock order. SQLite already has one writer.
|
|
468
461
|
*/
|
|
469
462
|
const lockStreams = (sql, ids) => {
|
|
470
|
-
const sorted =
|
|
463
|
+
const sorted = Array.sort(new Set(ids), Order.String);
|
|
471
464
|
return sql.onDialectOrElse({
|
|
472
465
|
sqlite: () => Effect.void,
|
|
473
466
|
orElse: () => execute("mutate.lock", sql`SELECT stream_id FROM streamsy_streams WHERE stream_id IN ${sql.in(sorted)}
|
|
@@ -493,7 +486,7 @@ const lockingRead = (sql, lock) => sql.onDialectOrElse({
|
|
|
493
486
|
* mutation. Outside a transaction the read stays plain and takes no lock.
|
|
494
487
|
*/
|
|
495
488
|
const planningLock = (sql) => Effect.map(Effect.serviceOption(sql.transactionService), (open) => Option.isSome(open) ? "update" : void 0);
|
|
496
|
-
const lockIds = (mutation) => mutation.operations
|
|
489
|
+
const lockIds = (mutation) => Array.flatMap(mutation.operations, (operation) => Predicate.isTagged(operation, "Create") ? operation.forkSource === void 0 ? [operation.record.id] : [operation.record.id, operation.forkSource.id] : [operation.streamId]);
|
|
497
490
|
const recordColumns = (sql) => sql.literal("stream_id,content_type,ttl_seconds,expires_at,created_at,current_offset,last_seq,closed,closed_at,forked_from,fork_offset,fork_sub_offset,soft_deleted,expires_at_ms");
|
|
498
491
|
const readRecord = (sql, id, lock) => attempt("record", sql`SELECT ${recordColumns(sql)} FROM streamsy_streams WHERE stream_id = ${id}${lockingRead(sql, lock)}`).pipe(Effect.flatMap((rows) => {
|
|
499
492
|
const row = rows[0];
|
|
@@ -689,7 +682,7 @@ const readMessages = (sql, id, window) => Effect.gen(function* () {
|
|
|
689
682
|
until = record.value.lifecycle.forkOffset;
|
|
690
683
|
}
|
|
691
684
|
const messages = [];
|
|
692
|
-
for (const segment of
|
|
685
|
+
for (const segment of Array.reverse(chain)) {
|
|
693
686
|
if (remaining === 0) break;
|
|
694
687
|
const upper = segment.until === void 0 ? window.until : window.until === void 0 || segment.until < window.until ? segment.until : window.until;
|
|
695
688
|
const predicates = [sql`stream_id = ${segment.id}`];
|
|
@@ -724,7 +717,7 @@ const makeStorage = (sql, boundary) => Storage.of({
|
|
|
724
717
|
messages: Effect.fn("SqlStorage.messages")((id, window) => readMessages(sql, id, window)),
|
|
725
718
|
producer: Effect.fn("SqlStorage.producer")((id, producerId) => Effect.flatMap(planningLock(sql), (lock) => readProducer(sql, "producer", id, producerId, lock))),
|
|
726
719
|
mutate: Effect.fn("SqlStorage.mutate")((mutation) => {
|
|
727
|
-
const ids = mutation.operations
|
|
720
|
+
const ids = Array.map(mutation.operations, (operation) => Predicate.isTagged(operation, "Create") ? operation.record.id : operation.streamId);
|
|
728
721
|
if (ids.length === 0 || new Set(ids).size !== ids.length) return Effect.die(/* @__PURE__ */ new Error("Mutation requires distinct streams within atomicScope"));
|
|
729
722
|
const oversized = oversizedKey(mutation);
|
|
730
723
|
if (Option.isSome(oversized)) return Effect.fail(oversized.value);
|
|
@@ -732,7 +725,7 @@ const makeStorage = (sql, boundary) => Storage.of({
|
|
|
732
725
|
keys: [STORAGE_KEY],
|
|
733
726
|
effect: applyMutation(sql, mutation),
|
|
734
727
|
retryable: (error) => Predicate.isTagged(error, "StorageFault") && error.retryable
|
|
735
|
-
}).pipe(Effect.catchIf(isSqlError, (error) => Effect.fail(sqlFault("mutate.transaction", error))));
|
|
728
|
+
}).pipe(Effect.catchIf(SqlError.isSqlError, (error) => Effect.fail(sqlFault("mutate.transaction", error))));
|
|
736
729
|
}),
|
|
737
730
|
changes: (id) => boundary.changes({
|
|
738
731
|
keys: [STORAGE_KEY],
|
|
@@ -834,5 +827,4 @@ function layer(group, options = {}) {
|
|
|
834
827
|
const protocol = Protocol.layer(options).pipe(Layer.provideMerge(storage));
|
|
835
828
|
return Protocol.bind(protocol, group).pipe(Layer.provideMerge(storage));
|
|
836
829
|
}
|
|
837
|
-
//#endregion
|
|
838
830
|
export { storageLayer as a, STORAGE_VERSION_TABLE as c, retryWithPolicy as d, transactionRetryPolicy as f, layerWithDurableObjectTransactions as i, clientLayer as l, layer as n, inspectFormat as o, layerProtocol as r, newerVersionFault as s, DEFAULT_REPAIR_INTERVAL_MS as t, sharedSqlClientLayer as u };
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
import { Context, Effect, Layer, Queue, Scope, Stream } from "effect";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import "effect/sql/SqlError";
|
|
2
|
+
import { Reactivity } from "effect/reactivity";
|
|
3
|
+
import { SqlClient, SqlError } from "effect/sql";
|
|
5
4
|
import { OwnerRecords } from "@streamsy/core/internal";
|
|
6
5
|
import { CommitBoundary, Storage, StorageFault, Streamsy } from "@streamsy/core";
|
|
7
6
|
import { Protocol } from "@streamsy/core/protocol";
|
|
8
|
-
//#region src/transaction-retry.d.ts
|
|
9
7
|
declare const DEFAULT_TRANSACTION_RETRY_ATTEMPTS = 16;
|
|
10
8
|
declare const DEFAULT_TRANSACTION_RETRY_DELAY_MS = 25;
|
|
11
|
-
//#endregion
|
|
12
|
-
//#region src/boundary.d.ts
|
|
13
9
|
/**
|
|
14
10
|
* Build a `SqlClient` and provide it with the `Reactivity` it captured, so the
|
|
15
11
|
* client and the storage boundary share one change graph.
|
|
@@ -21,8 +17,6 @@ declare const DEFAULT_TRANSACTION_RETRY_DELAY_MS = 25;
|
|
|
21
17
|
* ```
|
|
22
18
|
*/
|
|
23
19
|
declare const clientLayer: <A extends SqlClient.SqlClient, E>(makeClient: Effect.Effect<A, E, Scope.Scope | Reactivity.Reactivity>) => Layer.Layer<SqlClient.SqlClient | Reactivity.Reactivity, E>;
|
|
24
|
-
//#endregion
|
|
25
|
-
//#region src/storage.d.ts
|
|
26
20
|
declare const DEFAULT_REPAIR_INTERVAL_MS = 1000;
|
|
27
21
|
interface SqlStorageOptions {
|
|
28
22
|
/** Cross-process and post-commit-interruption staleness bound. */
|
|
@@ -39,5 +33,4 @@ interface Options extends SqlStorageOptions, Protocol.ProtocolOptions {}
|
|
|
39
33
|
/** Protocol over SQL storage. */
|
|
40
34
|
declare const layerProtocol: (options?: Options) => Layer.Layer<CommitBoundary | OwnerRecords | Storage | import("@streamsy/core/protocol").StreamsReader | import("@streamsy/core/protocol").StreamsWriter, StorageFault, Reactivity.Reactivity | SqlClient.SqlClient>;
|
|
41
35
|
declare function layer<const Keys extends ReadonlyArray<Streamsy.Any>>(group: Streamsy.Group<Keys>, options?: Options): Layer.Layer<Layer.Success<ReturnType<typeof storageLayer>> | Streamsy.Host<Streamsy.Group<Keys>>, Layer.Error<ReturnType<typeof storageLayer>>, Layer.Services<ReturnType<typeof storageLayer>>>;
|
|
42
|
-
//#endregion
|
|
43
36
|
export { layerProtocol as a, DEFAULT_TRANSACTION_RETRY_DELAY_MS as c, layer as i, Options as n, clientLayer as o, SqlStorageOptions as r, DEFAULT_TRANSACTION_RETRY_ATTEMPTS as s, DEFAULT_REPAIR_INTERVAL_MS as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@streamsy/storage",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.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.
|
|
45
|
+
"@streamsy/core": "^0.5.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.
|
|
55
|
+
"@streamsy/serve": "0.5.0",
|
|
56
56
|
"@types/bun": "^1.4.3",
|
|
57
57
|
"effect": "4.0.5",
|
|
58
58
|
"miniflare": "4.20260730.0",
|