@shivaedev/sql 0.42.0 → 0.43.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/CHANGELOG.md +8 -0
- package/README.md +5 -1
- package/dist/PostgresChangeListener.d.ts +7 -0
- package/dist/PostgresChangeListener.d.ts.map +1 -0
- package/dist/PostgresChangeListener.js +4 -0
- package/dist/PostgresChangeListener.js.map +1 -0
- package/dist/PostgresChangeResync.d.ts +8 -0
- package/dist/PostgresChangeResync.d.ts.map +1 -0
- package/dist/PostgresChangeResync.js +4 -0
- package/dist/PostgresChangeResync.js.map +1 -0
- package/dist/adapters/registerClock.d.ts +7 -0
- package/dist/adapters/registerClock.d.ts.map +1 -0
- package/dist/adapters/registerClock.js +10 -0
- package/dist/adapters/registerClock.js.map +1 -0
- package/dist/coordinateWorkerRelease.d.ts +4 -3
- package/dist/coordinateWorkerRelease.d.ts.map +1 -1
- package/dist/coordinateWorkerRelease.js +3 -7
- package/dist/coordinateWorkerRelease.js.map +1 -1
- package/dist/listenForChanges.d.ts +4 -1
- package/dist/listenForChanges.d.ts.map +1 -1
- package/dist/listenForChanges.js +8 -2
- package/dist/listenForChanges.js.map +1 -1
- package/dist/makeWorkerRelease.d.ts +5 -4
- package/dist/makeWorkerRelease.d.ts.map +1 -1
- package/dist/makeWorkerRelease.js +5 -9
- package/dist/makeWorkerRelease.js.map +1 -1
- package/dist/postgresChanges.d.ts.map +1 -1
- package/dist/postgresChanges.js +3 -1
- package/dist/postgresChanges.js.map +1 -1
- package/dist/worker-release/initialize.d.ts +7 -0
- package/dist/worker-release/initialize.d.ts.map +1 -0
- package/dist/{initializeWorkerRelease.js → worker-release/initialize.js} +2 -2
- package/dist/worker-release/initialize.js.map +1 -0
- package/dist/{registerWorkerRelease.d.ts → worker-release/register.d.ts} +2 -2
- package/dist/worker-release/register.d.ts.map +1 -0
- package/dist/worker-release/register.js +15 -0
- package/dist/worker-release/register.js.map +1 -0
- package/dist/{WorkerRelease.d.ts → worker-release/service.d.ts} +3 -2
- package/dist/worker-release/service.d.ts.map +1 -0
- package/dist/{WorkerRelease.js → worker-release/service.js} +5 -4
- package/dist/worker-release/service.js.map +1 -0
- package/dist/worker-release/setActive.d.ts +4 -0
- package/dist/worker-release/setActive.d.ts.map +1 -0
- package/dist/worker-release/setActive.js +15 -0
- package/dist/worker-release/setActive.js.map +1 -0
- package/package.json +7 -7
- package/src/PostgresChangeListener.ts +6 -0
- package/src/PostgresChangeResync.ts +5 -0
- package/src/adapters/registerClock.ts +14 -0
- package/src/coordinateWorkerRelease.ts +3 -7
- package/src/listenForChanges.ts +11 -3
- package/src/makeWorkerRelease.ts +5 -9
- package/src/postgresChanges.ts +7 -1
- package/src/{initializeWorkerRelease.ts → worker-release/initialize.ts} +2 -2
- package/src/worker-release/register.ts +16 -0
- package/src/{WorkerRelease.ts → worker-release/service.ts} +4 -3
- package/src/worker-release/setActive.ts +18 -0
- package/dist/WorkerRelease.d.ts.map +0 -1
- package/dist/WorkerRelease.js.map +0 -1
- package/dist/initializeWorkerRelease.d.ts +0 -7
- package/dist/initializeWorkerRelease.d.ts.map +0 -1
- package/dist/initializeWorkerRelease.js.map +0 -1
- package/dist/registerWorkerRelease.d.ts.map +0 -1
- package/dist/registerWorkerRelease.js +0 -14
- package/dist/registerWorkerRelease.js.map +0 -1
- package/dist/setWorkerReleaseActive.d.ts +0 -4
- package/dist/setWorkerReleaseActive.d.ts.map +0 -1
- package/dist/setWorkerReleaseActive.js +0 -13
- package/dist/setWorkerReleaseActive.js.map +0 -1
- package/src/registerWorkerRelease.ts +0 -15
- package/src/setWorkerReleaseActive.ts +0 -17
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.43.0 - 2026-11-05
|
|
4
|
+
|
|
5
|
+
### Breaking
|
|
6
|
+
|
|
7
|
+
- Import `WorkerRelease` from `@shivaedev/sql/worker-release/service.ts`. Its Layer owns the release gate and exposes traced `register` and `setActive` operations. Import the owned-state helpers from `worker-release/initialize.ts`, `worker-release/register.ts` and `worker-release/setActive.ts` when using them directly; keep `initializeWorkerRelease` and `registerWorkerRelease`, and rename the activation helper import from `setWorkerReleaseActive` to `setActive`. Prefer `WorkerRelease.layer` over constructing state directly; initializer state now holds a native `lock` semaphore and registered Effects.
|
|
8
|
+
- Run `makeWorkerRelease()` in a scope. It builds the gate through `WorkerRelease.layer` and keeps its `{ service, setActive }` result.
|
|
9
|
+
- Direct callers of `listenForChanges` pass only channel and timing settings and provide `SqlClient`, `Reactivity`, `PostgresChangeListener` and `PostgresChangeResync` in the environment. `postgresChanges(options)` supplies these dependencies internally and keeps its existing single-Layer API.
|
|
10
|
+
|
|
3
11
|
## 0.42.0 - 2026-11-05
|
|
4
12
|
|
|
5
13
|
### Breaking
|
package/README.md
CHANGED
|
@@ -973,11 +973,15 @@ For a structured readiness readout, use `pendingPostgresMigrations({ loader, tab
|
|
|
973
973
|
|
|
974
974
|
Pass an optional `release` string to `migratePostgres` to record the owning release after all ledger migrations and schema components succeed. A failed component publishes no release and preserves any existing marker. PostgreSQL timestamps each invocation before discovery and locking, and the marker accepts only a strictly newer timestamp, so an older invocation finishing later cannot replace a newer release. Release labels are opaque strings; they are not sorted. To deploy an earlier release again, start a new invocation. The final `postgresRelease(release, table?)` schema component owns a one-row `<ledger>_release` table with typed `release` and UTC `recorded_at timestamptz` columns, plus a `<ledger>_workers` table with typed process identity, release and UTC heartbeat columns. `readPostgresRelease(table?)` from `postgresRelease.ts` returns the recorded release and `recordedAt` Date of the invocation's start, or `undefined` for a missing marker. A standalone `postgresRelease` component timestamps the start of its `apply` effect. `pendingPostgresMigrations({ loader, release, table? })` reports a missing or different release as a pending component. Without `release`, migration and readiness calls neither write nor read these tables.
|
|
975
975
|
|
|
976
|
+
`WorkerRelease` is imported from `@shivaedev/sql/worker-release/service.ts`. Its Layer owns the active flag, registrations and lock; `register(control)` keeps a worker control registered until the caller’s scope closes, and `setActive(active)` serializes activation and draining with registration. Both operations are traced. `makeWorkerRelease()` from `@shivaedev/sql/makeWorkerRelease.ts` builds a fresh gate through that Layer in the caller’s scope and returns `{ service, setActive }`.
|
|
977
|
+
|
|
976
978
|
`appDatabase` from `@shivaedev/server/appDatabase.ts` supplies the optional `WorkerRelease` Context service in migration mode `"wait"` with a release. Startup waits for that marker within `waitTimeout`; subsequent checks run every `pollInterval`. Each worker database Layer claims a process row only when its release owns the marker and no live row of another release remains. Heartbeats continue every poll while jobs drain, including after a connection blip. Each failed heartbeat or ownership poll logs its cause and retries three times, one quarter of a polling interval apart; exhausted retries close the worker scope with the failure cause. Completed drain and clean shutdown remove the row. Rows older than five polling intervals count as gone, bounding takeover after a crash (five seconds at the default one-second poll). Reserve SQL pool capacity for heartbeats alongside active jobs and the change listener. Release equality decides ownership, so a new migration invocation publishing an earlier release resumes that release's worker. `@shivaedev/jobs` reads the service automatically; applications do not connect a signal themselves. Web's `"check"` mode ignores the marker.
|
|
977
979
|
|
|
978
980
|
### PostgreSQL delivery between processes
|
|
979
981
|
|
|
980
|
-
`postgresChanges` from `@shivaedev/sql/postgresChanges.ts` returns a scoped Layer for the `transact` channel. Provide it to every process that writes, including job workers. Every server uses the same database and channel, its own native PostgreSQL client and its own Reactivity service. Create the server's `makeLiveServer` with that same Reactivity service and supply its `resync` Effect to the binding.
|
|
982
|
+
`postgresChanges` from `@shivaedev/sql/postgresChanges.ts` returns a scoped Layer for the `transact` channel. The Layer supplies the change listener’s SQL client, listener connection and resync service internally, so consumers provide this one Layer. Provide it to every process that writes, including job workers. Every server uses the same database and channel, its own native PostgreSQL client and its own Reactivity service. Create the server's `makeLiveServer` with that same Reactivity service and supply its `resync` Effect to the binding.
|
|
983
|
+
|
|
984
|
+
Direct users of `listenForChanges` from `@shivaedev/sql/listenForChanges.ts` pass only channel and timing settings and provide `SqlClient`, `Reactivity`, `PostgresChangeListener` from `@shivaedev/sql/PostgresChangeListener.ts` and `PostgresChangeResync` from `@shivaedev/sql/PostgresChangeResync.ts` through the environment.
|
|
981
985
|
|
|
982
986
|
```ts
|
|
983
987
|
const delivery = postgresChanges({
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Context } from "effect";
|
|
2
|
+
import type { PostgresChangeClient } from "./postgresChanges.ts";
|
|
3
|
+
declare const PostgresChangeListener_base: Context.ServiceClass<PostgresChangeListener, "@shivaedev/sql/PostgresChangeListener", Pick<PostgresChangeClient, "listen">>;
|
|
4
|
+
export declare class PostgresChangeListener extends PostgresChangeListener_base {
|
|
5
|
+
}
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=PostgresChangeListener.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostgresChangeListener.d.ts","sourceRoot":"","sources":["../src/PostgresChangeListener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACjC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;;AAEjE,qBAAa,sBAAuB,SAAQ,2BAE3C;CAAG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostgresChangeListener.js","sourceRoot":"","sources":["../src/PostgresChangeListener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGjC,MAAM,OAAO,sBAAuB,SAAQ,OAAO,CAAC,OAAO,EAAgE,CAC1H,uCAAuC,CACvC;CAAG"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Context, type Effect } from "effect";
|
|
2
|
+
declare const PostgresChangeResync_base: Context.ServiceClass<PostgresChangeResync, "@shivaedev/sql/PostgresChangeResync", {
|
|
3
|
+
readonly resync: Effect.Effect<number>;
|
|
4
|
+
}>;
|
|
5
|
+
export declare class PostgresChangeResync extends PostgresChangeResync_base {
|
|
6
|
+
}
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=PostgresChangeResync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostgresChangeResync.d.ts","sourceRoot":"","sources":["../src/PostgresChangeResync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;;qBAEqD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;;AAAxH,qBAAa,oBAAqB,SAAQ,yBAEzC;CAAG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostgresChangeResync.js","sourceRoot":"","sources":["../src/PostgresChangeResync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAe,MAAM,QAAQ,CAAC;AAE9C,MAAM,OAAO,oBAAqB,SAAQ,OAAO,CAAC,OAAO,EAAoE,CAC5H,qCAAqC,CACrC;CAAG"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Effect, type Schema } from "effect";
|
|
2
|
+
import type { SqlError } from "effect/sql/SqlError";
|
|
3
|
+
export declare const registerClock: <R>(tick: {
|
|
4
|
+
readonly heartbeat: Effect.Effect<void, SqlError | Schema.SchemaError>;
|
|
5
|
+
readonly poll: Effect.Effect<void, SqlError | Schema.SchemaError, R>;
|
|
6
|
+
}) => Effect.Effect<void, never, R | import("effect/Scope").Scope>;
|
|
7
|
+
//# sourceMappingURL=registerClock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registerClock.d.ts","sourceRoot":"","sources":["../../src/adapters/registerClock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAU,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGpD,eAAO,MAAM,aAAa,GAAuD,CAAC;wBAC7D,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC;mBACvD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;kEAOnE,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Effect, Option } from "effect";
|
|
2
|
+
import { WorkerReleaseClock } from "#WorkerReleaseClock.ts";
|
|
3
|
+
export const registerClock = Effect.fn("WorkerRelease.registerClock")(function* (tick) {
|
|
4
|
+
const testing = yield* Effect.serviceOption(WorkerReleaseClock);
|
|
5
|
+
if (Option.isSome(testing)) {
|
|
6
|
+
const context = yield* Effect.context();
|
|
7
|
+
yield* testing.value.register({ heartbeat: tick.heartbeat, poll: tick.poll.pipe(Effect.provideContext(context)) });
|
|
8
|
+
}
|
|
9
|
+
});
|
|
10
|
+
//# sourceMappingURL=registerClock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registerClock.js","sourceRoot":"","sources":["../../src/adapters/registerClock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAe,MAAM,QAAQ,CAAC;AAErD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,EAAE,CAAC,6BAA6B,CAAC,CAAC,QAAQ,CAAC,EAAK,IAGnF;IACA,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC;IAChE,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,EAAK,CAAC;QAC3C,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IACpH,CAAC;AACF,CAAC,CAAC,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Duration, Effect, Scope } from "effect";
|
|
2
|
-
export declare const coordinateWorkerRelease: (release: string, pollInterval?: Duration.Input | undefined, table?: any) => Effect.Effect<{
|
|
3
|
-
register: <E>(control: (active: boolean) => Effect.Effect<void, E>) => Effect.Effect<void, E, Scope.Scope>;
|
|
4
|
-
|
|
2
|
+
export declare const coordinateWorkerRelease: (release: string, pollInterval?: Duration.Input | undefined, table?: any) => Effect.Effect<Readonly<{
|
|
3
|
+
readonly register: <E>(control: (active: boolean) => Effect.Effect<void, E, never>) => Effect.Effect<void, E, Scope.Scope>;
|
|
4
|
+
readonly setActive: (next: boolean) => Effect.Effect<void, unknown, never>;
|
|
5
|
+
}>, import("effect/Schema").SchemaError | import("effect/sql/SqlError").SqlError, Scope.Scope | import("effect/sql/SqlClient").SqlClient>;
|
|
5
6
|
//# sourceMappingURL=coordinateWorkerRelease.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coordinateWorkerRelease.d.ts","sourceRoot":"","sources":["../src/coordinateWorkerRelease.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"coordinateWorkerRelease.d.ts","sourceRoot":"","sources":["../src/coordinateWorkerRelease.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAA6B,KAAK,EAAE,MAAM,QAAQ,CAAC;AAW5E,eAAO,MAAM,uBAAuB;;;yIA2DlC,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Duration, Effect, Exit,
|
|
1
|
+
import { Duration, Effect, Exit, Predicate, Schedule, Scope } from "effect";
|
|
2
2
|
import { isSqlError } from "effect/sql/SqlError";
|
|
3
|
-
import {
|
|
3
|
+
import { registerClock } from "#adapters/registerClock.ts";
|
|
4
4
|
import { makeWorkerRelease } from "./makeWorkerRelease.js";
|
|
5
5
|
import { readPostgresRelease } from "./postgresRelease.js";
|
|
6
6
|
import { releaseWorkers } from "./releaseWorkers.js";
|
|
@@ -42,11 +42,7 @@ export const coordinateWorkerRelease = Effect.fn("EffectSql.coordinateWorkerRele
|
|
|
42
42
|
yield* loop("heartbeat", rows.heartbeat);
|
|
43
43
|
yield* tick("poll", poll).pipe(Scope.provide(scope));
|
|
44
44
|
yield* loop("poll", poll);
|
|
45
|
-
|
|
46
|
-
if (Option.isSome(testing)) {
|
|
47
|
-
const context = yield* Effect.context();
|
|
48
|
-
yield* testing.value.register({ heartbeat: rows.heartbeat, poll: poll.pipe(Effect.provideContext(context)) }).pipe(Scope.provide(scope));
|
|
49
|
-
}
|
|
45
|
+
yield* registerClock({ heartbeat: rows.heartbeat, poll }).pipe(Scope.provide(scope));
|
|
50
46
|
return gate.service;
|
|
51
47
|
});
|
|
52
48
|
//# sourceMappingURL=coordinateWorkerRelease.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coordinateWorkerRelease.js","sourceRoot":"","sources":["../src/coordinateWorkerRelease.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"coordinateWorkerRelease.js","sourceRoot":"","sources":["../src/coordinateWorkerRelease.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { Effect, Scope } from "effect";
|
|
2
2
|
import * as Reactivity from "effect/reactivity/Reactivity";
|
|
3
|
+
import { SqlClient } from "effect/sql";
|
|
3
4
|
import type { SqlError } from "effect/sql/SqlError";
|
|
5
|
+
import { PostgresChangeListener } from "./PostgresChangeListener.ts";
|
|
6
|
+
import { PostgresChangeResync } from "./PostgresChangeResync.ts";
|
|
4
7
|
import { PostgresListenerError } from "./PostgresListenerError.ts";
|
|
5
8
|
import type { PostgresChangesOptions } from "./postgresChanges.ts";
|
|
6
|
-
export declare const listenForChanges: (options: PostgresChangesOptions) => Effect.Effect<void, PostgresListenerError | SqlError, Reactivity.Reactivity | Scope.Scope>;
|
|
9
|
+
export declare const listenForChanges: (options: Omit<PostgresChangesOptions, "client" | "listenerClient" | "resync">) => Effect.Effect<void, PostgresListenerError | SqlError, PostgresChangeListener | PostgresChangeResync | Reactivity.Reactivity | Scope.Scope | SqlClient.SqlClient>;
|
|
7
10
|
//# sourceMappingURL=listenForChanges.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listenForChanges.d.ts","sourceRoot":"","sources":["../src/listenForChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,MAAM,EAAiB,KAAK,EAAE,MAAM,QAAQ,CAAC;AACjF,OAAO,KAAK,UAAU,MAAM,8BAA8B,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AASnE,eAAO,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"listenForChanges.d.ts","sourceRoot":"","sources":["../src/listenForChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,MAAM,EAAiB,KAAK,EAAE,MAAM,QAAQ,CAAC;AACjF,OAAO,KAAK,UAAU,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AASnE,eAAO,MAAM,gBAAgB,qPA4F3B,CAAC"}
|
package/dist/listenForChanges.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { Clock, Deferred, Duration, Effect, Queue, Random, Scope } from "effect";
|
|
2
2
|
import * as Reactivity from "effect/reactivity/Reactivity";
|
|
3
|
+
import { SqlClient } from "effect/sql";
|
|
3
4
|
import { decodeKeys, resyncPayload } from "./notifyPayload.js";
|
|
5
|
+
import { PostgresChangeListener } from "./PostgresChangeListener.js";
|
|
6
|
+
import { PostgresChangeResync } from "./PostgresChangeResync.js";
|
|
4
7
|
import { PostgresListenerError } from "./PostgresListenerError.js";
|
|
5
8
|
function listenerScope(timeout) {
|
|
6
9
|
// Release the native connection alongside listener cleanup, even when a listener finalizer stalls.
|
|
@@ -9,7 +12,10 @@ function listenerScope(timeout) {
|
|
|
9
12
|
export const listenForChanges = Effect.fn("PostgresChanges.listenForChanges")(function* (options) {
|
|
10
13
|
const ready = yield* Deferred.make();
|
|
11
14
|
const reactivity = yield* Reactivity.Reactivity;
|
|
12
|
-
const
|
|
15
|
+
const client = yield* SqlClient.SqlClient;
|
|
16
|
+
const listener = yield* PostgresChangeListener;
|
|
17
|
+
const { resync } = yield* PostgresChangeResync;
|
|
18
|
+
const { channel } = options;
|
|
13
19
|
const timeout = options.heartbeatTimeout ?? "10 seconds";
|
|
14
20
|
function deadline(effect) {
|
|
15
21
|
return effect.pipe(Effect.timeoutOrElse({
|
|
@@ -20,7 +26,7 @@ export const listenForChanges = Effect.fn("PostgresChanges.listenForChanges")(fu
|
|
|
20
26
|
let lostAt;
|
|
21
27
|
const attempt = Effect.scoped(Effect.gen(function* () {
|
|
22
28
|
const scope = yield* listenerScope(timeout);
|
|
23
|
-
const notifications = yield*
|
|
29
|
+
const notifications = yield* listener.listen(channel).pipe(Scope.provide(scope), deadline);
|
|
24
30
|
const interval = Duration.toMillis(Duration.fromInputUnsafe(options.heartbeatInterval ?? "5 seconds"));
|
|
25
31
|
const lifetime = Duration.toMillis(Duration.fromInputUnsafe(options.connectionTTL ?? Duration.infinity));
|
|
26
32
|
const renewAt = (yield* Clock.currentTimeMillis) + (lifetime === 0 ? interval : lifetime);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listenForChanges.js","sourceRoot":"","sources":["../src/listenForChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AACjF,OAAO,KAAK,UAAU,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"listenForChanges.js","sourceRoot":"","sources":["../src/listenForChanges.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
export declare const makeWorkerRelease: () => Effect.Effect<{
|
|
3
|
-
service: {
|
|
4
|
-
register: <E>(control: (active: boolean) => Effect.Effect<void, E>) => Effect.Effect<void, E, import("effect/Scope").Scope>;
|
|
5
|
-
|
|
3
|
+
service: Readonly<{
|
|
4
|
+
readonly register: <E>(control: (active: boolean) => Effect.Effect<void, E, never>) => Effect.Effect<void, E, import("effect/Scope").Scope>;
|
|
5
|
+
readonly setActive: (next: boolean) => Effect.Effect<void, unknown, never>;
|
|
6
|
+
}>;
|
|
6
7
|
setActive: (next: boolean) => Effect.Effect<void, unknown, never>;
|
|
7
|
-
}, never,
|
|
8
|
+
}, never, import("effect/Scope").Scope>;
|
|
8
9
|
//# sourceMappingURL=makeWorkerRelease.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"makeWorkerRelease.d.ts","sourceRoot":"","sources":["../src/makeWorkerRelease.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"makeWorkerRelease.d.ts","sourceRoot":"","sources":["../src/makeWorkerRelease.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,MAAM,EAAS,MAAM,QAAQ,CAAC;AAGhD,eAAO,MAAM,iBAAiB;;;;;;uCAI5B,CAAC"}
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
2
|
-
import {
|
|
3
|
-
import { registerWorkerRelease } from "./registerWorkerRelease.js";
|
|
4
|
-
import { setWorkerReleaseActive } from "./setWorkerReleaseActive.js";
|
|
1
|
+
import { Context, Effect, Layer } from "effect";
|
|
2
|
+
import { WorkerRelease } from "#worker-release/service.ts";
|
|
5
3
|
export const makeWorkerRelease = Effect.fn("EffectSql.makeWorkerRelease")(function* () {
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
setActive: setWorkerReleaseActive(state),
|
|
10
|
-
};
|
|
4
|
+
const context = yield* Layer.build(WorkerRelease.layer);
|
|
5
|
+
const service = Context.get(context, WorkerRelease);
|
|
6
|
+
return { service, setActive: service.setActive };
|
|
11
7
|
});
|
|
12
8
|
//# sourceMappingURL=makeWorkerRelease.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"makeWorkerRelease.js","sourceRoot":"","sources":["../src/makeWorkerRelease.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"makeWorkerRelease.js","sourceRoot":"","sources":["../src/makeWorkerRelease.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,EAAE,CAAC,6BAA6B,CAAC,CAAC,QAAQ,CAAC;IAClF,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IACpD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC;AAClD,CAAC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgresChanges.d.ts","sourceRoot":"","sources":["../src/postgresChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,EAAE,KAAK,KAAK,EAAE,MAAM,QAAQ,CAAC;AACvF,OAAO,KAAK,UAAU,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"postgresChanges.d.ts","sourceRoot":"","sources":["../src/postgresChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,EAAE,KAAK,KAAK,EAAE,MAAM,QAAQ,CAAC;AACvF,OAAO,KAAK,UAAU,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAQpD,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,oBAAqB,SAAQ,SAAS,CAAC,SAAS;IAChE,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,oBAAoB,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;CAC1H;AAED,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,eAAe,CAAC,EAAE,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAC;IACtD,QAAQ,CAAC,iBAAiB,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;IAC5C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;IAC3C,QAAQ,CAAC,cAAc,CAAC,EAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAC,CAAC;IAC/D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACvC,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;CACrC;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,oHAwC9D"}
|
package/dist/postgresChanges.js
CHANGED
|
@@ -4,10 +4,12 @@ import { SqlClient } from "effect/sql";
|
|
|
4
4
|
import { CommandPublication, CommandPublicationError } from "@shivaedev/changes/commandPublication.ts";
|
|
5
5
|
import { listenForChanges } from "./listenForChanges.js";
|
|
6
6
|
import { encodeKeys, resyncPayload } from "./notifyPayload.js";
|
|
7
|
+
import { PostgresChangeListener } from "./PostgresChangeListener.js";
|
|
8
|
+
import { PostgresChangeResync } from "./PostgresChangeResync.js";
|
|
7
9
|
import { BeforeCommit, CommittedSink, invalidateOnCommit, transact } from "./transact.js";
|
|
8
10
|
export function postgresChanges(options) {
|
|
9
11
|
return Layer.effectContext(Effect.gen(function* () {
|
|
10
|
-
yield* listenForChanges(options);
|
|
12
|
+
yield* listenForChanges(options).pipe(Effect.provideService(SqlClient.SqlClient, options.client), Effect.provideService(PostgresChangeListener, options.listenerClient ?? options.client), Effect.provideService(PostgresChangeResync, { resync: options.resync }));
|
|
11
13
|
const notify = Effect.fn("PostgresChanges.notify")(function* (keys) {
|
|
12
14
|
const sql = yield* SqlClient.SqlClient;
|
|
13
15
|
if (sql.transactionService !== options.client.transactionService) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgresChanges.js","sourceRoot":"","sources":["../src/postgresChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAiB,MAAM,EAAE,KAAK,EAA0B,MAAM,QAAQ,CAAC;AACvF,OAAO,KAAK,UAAU,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAyB,MAAM,0CAA0C,CAAC;AAC9H,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAsB1F,MAAM,UAAU,eAAe,CAAC,OAA+B;IAC9D,OAAO,KAAK,CAAC,aAAa,CACzB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnB,KAAK,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"postgresChanges.js","sourceRoot":"","sources":["../src/postgresChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAiB,MAAM,EAAE,KAAK,EAA0B,MAAM,QAAQ,CAAC;AACvF,OAAO,KAAK,UAAU,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAyB,MAAM,0CAA0C,CAAC;AAC9H,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAsB1F,MAAM,UAAU,eAAe,CAAC,OAA+B;IAC9D,OAAO,KAAK,CAAC,aAAa,CACzB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnB,KAAK,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,IAAI,CACpC,MAAM,CAAC,cAAc,CAAC,SAAS,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,EAC1D,MAAM,CAAC,cAAc,CAAC,sBAAsB,EAAE,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,EACvF,MAAM,CAAC,cAAc,CAAC,oBAAoB,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CACvE,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,wBAAwB,CAAC,CAAC,QAAQ,CAAC,EAAE,IAAwB;YACrF,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC;YACvC,IAAI,GAAG,CAAC,kBAAkB,KAAK,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;gBAClE,OAAO;YACR,CAAC;YACD,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACzC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAChC,KAAK,CAAC,CAAC,GAAG,CAAA,oBAAoB,OAAO,CAAC,OAAO,KAAK,OAAO,GAAG,CAAC;YAC9D,CAAC;QACF,CAAC,CAAC,CAAC;QACH,SAAS,SAAS,CAAC,IAAwB;YAC1C,OAAO,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE,CAClD,GAAG,CAAC,kBAAkB,KAAK,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CACxG,CAAC;QACH,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAClC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAA,oBAAoB,OAAO,CAAC,OAAO,KAAK,aAAa,GAAG,CAAC,EACtF,MAAM,CAAC,UAAU,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,uBAAuB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EACjF,MAAM,CAAC,MAAM,CACb,CAAC;QACF,MAAM,WAAW,GAAqB;YACrC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CACjB,kBAAkB,CAAC,IAAI,CAAC,CAAC,IAAI,CAC5B,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,EAC1C,MAAM,CAAC,cAAc,CAAC,SAAS,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,EAC1D,MAAM,CAAC,UAAU,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,uBAAuB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CACjF;YACF,OAAO;SACP,CAAC;QACF,OAAO,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAAC,CAAC;IACrI,CAAC,CAAC,CACF,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Effect, Semaphore } from "effect";
|
|
2
|
+
export declare const initializeWorkerRelease: Effect.Effect<{
|
|
3
|
+
active: boolean;
|
|
4
|
+
controls: Set<Effect.Effect<void, unknown, never>>;
|
|
5
|
+
lock: Semaphore.Semaphore;
|
|
6
|
+
}, never, never>;
|
|
7
|
+
//# sourceMappingURL=initialize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initialize.d.ts","sourceRoot":"","sources":["../../src/worker-release/initialize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAE3C,eAAO,MAAM,uBAAuB;;;;gBAIjC,CAAC"}
|
|
@@ -2,6 +2,6 @@ import { Effect, Semaphore } from "effect";
|
|
|
2
2
|
export const initializeWorkerRelease = Effect.sync(() => ({
|
|
3
3
|
active: false,
|
|
4
4
|
controls: new Set(),
|
|
5
|
-
|
|
5
|
+
lock: Semaphore.makeUnsafe(1),
|
|
6
6
|
}));
|
|
7
|
-
//# sourceMappingURL=
|
|
7
|
+
//# sourceMappingURL=initialize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initialize.js","sourceRoot":"","sources":["../../src/worker-release/initialize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAE3C,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACzD,MAAM,EAAE,KAAK;IACb,QAAQ,EAAE,IAAI,GAAG,EAAgC;IACjD,IAAI,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC;CAC7B,CAAC,CAAC,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
|
-
import type { initializeWorkerRelease } from "./
|
|
2
|
+
import type { initializeWorkerRelease } from "./initialize.ts";
|
|
3
3
|
export declare function registerWorkerRelease(state: Effect.Success<typeof initializeWorkerRelease>): <E>(control: (active: boolean) => Effect.Effect<void, E>) => Effect.Effect<void, E, import("effect/Scope").Scope>;
|
|
4
|
-
//# sourceMappingURL=
|
|
4
|
+
//# sourceMappingURL=register.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/worker-release/register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAE/D,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,uBAAuB,CAAC,IACpC,CAAC,oBAAoB,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,0DAW7G"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
export function registerWorkerRelease(state) {
|
|
3
|
+
return Effect.fn("WorkerRelease.register")(function* (control) {
|
|
4
|
+
const registered = Effect.suspend(() => control(state.active));
|
|
5
|
+
const attach = Effect.gen(function* () {
|
|
6
|
+
state.controls.add(registered);
|
|
7
|
+
yield* registered;
|
|
8
|
+
});
|
|
9
|
+
const detach = Effect.sync(() => {
|
|
10
|
+
state.controls.delete(registered);
|
|
11
|
+
});
|
|
12
|
+
return yield* Effect.acquireRelease(state.lock.withPermits(1)(attach), () => state.lock.withPermits(1)(detach));
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=register.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/worker-release/register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,MAAM,UAAU,qBAAqB,CAAC,KAAqD;IAC1F,OAAO,MAAM,CAAC,EAAE,CAAC,wBAAwB,CAAC,CAAC,QAAQ,CAAC,EAAK,OAAoD;QAC5G,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/D,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC/B,KAAK,CAAC,CAAC,UAAU,CAAC;QACnB,CAAC,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;YAC/B,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QACH,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACjH,CAAC,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export declare const WorkerRelease: import("effect/Context").Service<"@shivaedev/sql/WorkerRelease", Readonly<{
|
|
2
|
-
readonly register: <E>(control: (active: boolean) => import("effect/Effect").Effect<void, E>) => import("effect/Effect").Effect<void, E, import("effect/Scope").Scope>;
|
|
2
|
+
readonly register: <E>(control: (active: boolean) => import("effect/Effect").Effect<void, E, never>) => import("effect/Effect").Effect<void, E, import("effect/Scope").Scope>;
|
|
3
|
+
readonly setActive: (next: boolean) => import("effect/Effect").Effect<void, unknown, never>;
|
|
3
4
|
}>> & {
|
|
4
5
|
readonly layer: import("effect/Layer").Layer<"@shivaedev/sql/WorkerRelease", never, never>;
|
|
5
6
|
};
|
|
6
|
-
//# sourceMappingURL=
|
|
7
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/worker-release/service.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,aAAa;;;;;CAKxB,CAAC"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { defineService } from "@shivaedev/service/defineService.ts";
|
|
2
2
|
import { genericMethod } from "@shivaedev/service/genericMethod.ts";
|
|
3
|
-
import { initializeWorkerRelease } from "./
|
|
4
|
-
import { registerWorkerRelease } from "./
|
|
3
|
+
import { initializeWorkerRelease } from "./initialize.js";
|
|
4
|
+
import { registerWorkerRelease } from "./register.js";
|
|
5
|
+
import { setActive } from "./setActive.js";
|
|
5
6
|
export const WorkerRelease = defineService({
|
|
6
7
|
id: "@shivaedev/sql/WorkerRelease",
|
|
7
8
|
initialize: initializeWorkerRelease,
|
|
8
|
-
methods: (state) => ({ register: genericMethod(registerWorkerRelease(state)) }),
|
|
9
|
+
methods: (state) => ({ register: genericMethod(registerWorkerRelease(state)), setActive: setActive(state) }),
|
|
9
10
|
requires: [],
|
|
10
11
|
});
|
|
11
|
-
//# sourceMappingURL=
|
|
12
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/worker-release/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC;IAC1C,EAAE,EAAE,8BAA8B;IAClC,UAAU,EAAE,uBAAuB;IACnC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,aAAa,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;IAC5G,QAAQ,EAAE,EAAE;CACZ,CAAC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import type { initializeWorkerRelease } from "./initialize.ts";
|
|
3
|
+
export declare function setActive(state: Effect.Success<typeof initializeWorkerRelease>): (next: boolean) => Effect.Effect<void, unknown, never>;
|
|
4
|
+
//# sourceMappingURL=setActive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setActive.d.ts","sourceRoot":"","sources":["../../src/worker-release/setActive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAE/D,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,uBAAuB,CAAC,0DAc9E"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
export function setActive(state) {
|
|
3
|
+
return Effect.fn("WorkerRelease.setActive")(function* (next) {
|
|
4
|
+
yield* state.lock
|
|
5
|
+
.withPermits(1)(Effect.gen(function* () {
|
|
6
|
+
if (next === state.active) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
state.active = next;
|
|
10
|
+
yield* Effect.all(state.controls, { concurrency: "unbounded", discard: true });
|
|
11
|
+
}))
|
|
12
|
+
.pipe(Effect.uninterruptible);
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=setActive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setActive.js","sourceRoot":"","sources":["../../src/worker-release/setActive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,MAAM,UAAU,SAAS,CAAC,KAAqD;IAC9E,OAAO,MAAM,CAAC,EAAE,CAAC,yBAAyB,CAAC,CAAC,QAAQ,CAAC,EAAE,IAAa;QACnE,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI;aACf,WAAW,CAAC,CAAC,CAAC,CACd,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YACnB,IAAI,IAAI,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC3B,OAAO;YACR,CAAC;YACD,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;YACpB,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAChF,CAAC,CAAC,CACF;aACA,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shivaedev/sql",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.43.0",
|
|
4
4
|
"description": "Schema-derived repositories over native Effect SQL",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"effect"
|
|
@@ -50,12 +50,12 @@
|
|
|
50
50
|
"@effect/platform-node": "4.1.0",
|
|
51
51
|
"@effect/sql-pg": "4.1.0",
|
|
52
52
|
"@effect/sql-sqlite-node": "4.1.0",
|
|
53
|
-
"@shivaedev/contract": "0.
|
|
54
|
-
"@shivaedev/jobs": "0.
|
|
55
|
-
"@shivaedev/quality": "0.
|
|
56
|
-
"@shivaedev/test-kits": "0.8.
|
|
57
|
-
"@shivaedev/test-sql": "0.24.
|
|
58
|
-
"@shivaedev/test-story": "0.42.
|
|
53
|
+
"@shivaedev/contract": "0.40.0",
|
|
54
|
+
"@shivaedev/jobs": "0.40.0",
|
|
55
|
+
"@shivaedev/quality": "0.66.0",
|
|
56
|
+
"@shivaedev/test-kits": "0.8.1",
|
|
57
|
+
"@shivaedev/test-sql": "0.24.1",
|
|
58
|
+
"@shivaedev/test-story": "0.42.1",
|
|
59
59
|
"@types/node": "24.19.2",
|
|
60
60
|
"effect": "4.1.0",
|
|
61
61
|
"typescript": "7.0.2",
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Context } from "effect";
|
|
2
|
+
import type { PostgresChangeClient } from "./postgresChanges.ts";
|
|
3
|
+
|
|
4
|
+
export class PostgresChangeListener extends Context.Service<PostgresChangeListener, Pick<PostgresChangeClient, "listen">>()(
|
|
5
|
+
"@shivaedev/sql/PostgresChangeListener",
|
|
6
|
+
) {}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Effect, Option, type Schema } from "effect";
|
|
2
|
+
import type { SqlError } from "effect/sql/SqlError";
|
|
3
|
+
import { WorkerReleaseClock } from "#WorkerReleaseClock.ts";
|
|
4
|
+
|
|
5
|
+
export const registerClock = Effect.fn("WorkerRelease.registerClock")(function* <R>(tick: {
|
|
6
|
+
readonly heartbeat: Effect.Effect<void, SqlError | Schema.SchemaError>;
|
|
7
|
+
readonly poll: Effect.Effect<void, SqlError | Schema.SchemaError, R>;
|
|
8
|
+
}) {
|
|
9
|
+
const testing = yield* Effect.serviceOption(WorkerReleaseClock);
|
|
10
|
+
if (Option.isSome(testing)) {
|
|
11
|
+
const context = yield* Effect.context<R>();
|
|
12
|
+
yield* testing.value.register({ heartbeat: tick.heartbeat, poll: tick.poll.pipe(Effect.provideContext(context)) });
|
|
13
|
+
}
|
|
14
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Duration, Effect, Exit,
|
|
1
|
+
import { Duration, Effect, Exit, Predicate, Schedule, Scope } from "effect";
|
|
2
2
|
import { isSqlError } from "effect/sql/SqlError";
|
|
3
|
-
import {
|
|
3
|
+
import { registerClock } from "#adapters/registerClock.ts";
|
|
4
4
|
import { makeWorkerRelease } from "./makeWorkerRelease.ts";
|
|
5
5
|
import { readPostgresRelease } from "./postgresRelease.ts";
|
|
6
6
|
import { releaseWorkers } from "./releaseWorkers.ts";
|
|
@@ -66,10 +66,6 @@ export const coordinateWorkerRelease = Effect.fn("EffectSql.coordinateWorkerRele
|
|
|
66
66
|
yield* loop("heartbeat", rows.heartbeat);
|
|
67
67
|
yield* tick("poll", poll).pipe(Scope.provide(scope));
|
|
68
68
|
yield* loop("poll", poll);
|
|
69
|
-
|
|
70
|
-
if (Option.isSome(testing)) {
|
|
71
|
-
const context = yield* Effect.context<Effect.Services<typeof poll>>();
|
|
72
|
-
yield* testing.value.register({ heartbeat: rows.heartbeat, poll: poll.pipe(Effect.provideContext(context)) }).pipe(Scope.provide(scope));
|
|
73
|
-
}
|
|
69
|
+
yield* registerClock({ heartbeat: rows.heartbeat, poll }).pipe(Scope.provide(scope));
|
|
74
70
|
return gate.service;
|
|
75
71
|
});
|
package/src/listenForChanges.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { Clock, Deferred, Duration, Effect, Queue, Random, Scope } from "effect";
|
|
2
2
|
import * as Reactivity from "effect/reactivity/Reactivity";
|
|
3
|
+
import { SqlClient } from "effect/sql";
|
|
3
4
|
import type { SqlError } from "effect/sql/SqlError";
|
|
4
5
|
import { decodeKeys, resyncPayload } from "./notifyPayload.ts";
|
|
6
|
+
import { PostgresChangeListener } from "./PostgresChangeListener.ts";
|
|
7
|
+
import { PostgresChangeResync } from "./PostgresChangeResync.ts";
|
|
5
8
|
import { PostgresListenerError } from "./PostgresListenerError.ts";
|
|
6
9
|
import type { PostgresChangesOptions } from "./postgresChanges.ts";
|
|
7
10
|
|
|
@@ -12,10 +15,15 @@ function listenerScope(timeout: Duration.Input) {
|
|
|
12
15
|
);
|
|
13
16
|
}
|
|
14
17
|
|
|
15
|
-
export const listenForChanges = Effect.fn("PostgresChanges.listenForChanges")(function* (
|
|
18
|
+
export const listenForChanges = Effect.fn("PostgresChanges.listenForChanges")(function* (
|
|
19
|
+
options: Omit<PostgresChangesOptions, "client" | "listenerClient" | "resync">,
|
|
20
|
+
) {
|
|
16
21
|
const ready = yield* Deferred.make<void, SqlError | PostgresListenerError>();
|
|
17
22
|
const reactivity = yield* Reactivity.Reactivity;
|
|
18
|
-
const
|
|
23
|
+
const client = yield* SqlClient.SqlClient;
|
|
24
|
+
const listener = yield* PostgresChangeListener;
|
|
25
|
+
const { resync } = yield* PostgresChangeResync;
|
|
26
|
+
const { channel } = options;
|
|
19
27
|
const timeout = options.heartbeatTimeout ?? "10 seconds";
|
|
20
28
|
function deadline<A, E, R>(effect: Effect.Effect<A, E, R>) {
|
|
21
29
|
return effect.pipe(
|
|
@@ -29,7 +37,7 @@ export const listenForChanges = Effect.fn("PostgresChanges.listenForChanges")(fu
|
|
|
29
37
|
const attempt = Effect.scoped(
|
|
30
38
|
Effect.gen(function* () {
|
|
31
39
|
const scope = yield* listenerScope(timeout);
|
|
32
|
-
const notifications = yield*
|
|
40
|
+
const notifications = yield* listener.listen(channel).pipe(Scope.provide(scope), deadline);
|
|
33
41
|
const interval = Duration.toMillis(Duration.fromInputUnsafe(options.heartbeatInterval ?? "5 seconds"));
|
|
34
42
|
const lifetime = Duration.toMillis(Duration.fromInputUnsafe(options.connectionTTL ?? Duration.infinity));
|
|
35
43
|
const renewAt = (yield* Clock.currentTimeMillis) + (lifetime === 0 ? interval : lifetime);
|
package/src/makeWorkerRelease.ts
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
2
|
-
import {
|
|
3
|
-
import { registerWorkerRelease } from "./registerWorkerRelease.ts";
|
|
4
|
-
import { setWorkerReleaseActive } from "./setWorkerReleaseActive.ts";
|
|
1
|
+
import { Context, Effect, Layer } from "effect";
|
|
2
|
+
import { WorkerRelease } from "#worker-release/service.ts";
|
|
5
3
|
|
|
6
4
|
export const makeWorkerRelease = Effect.fn("EffectSql.makeWorkerRelease")(function* () {
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
setActive: setWorkerReleaseActive(state),
|
|
11
|
-
};
|
|
5
|
+
const context = yield* Layer.build(WorkerRelease.layer);
|
|
6
|
+
const service = Context.get(context, WorkerRelease);
|
|
7
|
+
return { service, setActive: service.setActive };
|
|
12
8
|
});
|
package/src/postgresChanges.ts
CHANGED
|
@@ -5,6 +5,8 @@ import type { SqlError } from "effect/sql/SqlError";
|
|
|
5
5
|
import { CommandPublication, CommandPublicationError, type CommandPublisher } from "@shivaedev/changes/commandPublication.ts";
|
|
6
6
|
import { listenForChanges } from "./listenForChanges.ts";
|
|
7
7
|
import { encodeKeys, resyncPayload } from "./notifyPayload.ts";
|
|
8
|
+
import { PostgresChangeListener } from "./PostgresChangeListener.ts";
|
|
9
|
+
import { PostgresChangeResync } from "./PostgresChangeResync.ts";
|
|
8
10
|
import { BeforeCommit, CommittedSink, invalidateOnCommit, transact } from "./transact.ts";
|
|
9
11
|
|
|
10
12
|
export interface PostgresNotification {
|
|
@@ -30,7 +32,11 @@ export interface PostgresChangesOptions {
|
|
|
30
32
|
export function postgresChanges(options: PostgresChangesOptions) {
|
|
31
33
|
return Layer.effectContext(
|
|
32
34
|
Effect.gen(function* () {
|
|
33
|
-
yield* listenForChanges(options)
|
|
35
|
+
yield* listenForChanges(options).pipe(
|
|
36
|
+
Effect.provideService(SqlClient.SqlClient, options.client),
|
|
37
|
+
Effect.provideService(PostgresChangeListener, options.listenerClient ?? options.client),
|
|
38
|
+
Effect.provideService(PostgresChangeResync, { resync: options.resync }),
|
|
39
|
+
);
|
|
34
40
|
const notify = Effect.fn("PostgresChanges.notify")(function* (keys: readonly unknown[]) {
|
|
35
41
|
const sql = yield* SqlClient.SqlClient;
|
|
36
42
|
if (sql.transactionService !== options.client.transactionService) {
|
|
@@ -2,6 +2,6 @@ import { Effect, Semaphore } from "effect";
|
|
|
2
2
|
|
|
3
3
|
export const initializeWorkerRelease = Effect.sync(() => ({
|
|
4
4
|
active: false,
|
|
5
|
-
controls: new Set<
|
|
6
|
-
|
|
5
|
+
controls: new Set<Effect.Effect<void, unknown>>(),
|
|
6
|
+
lock: Semaphore.makeUnsafe(1),
|
|
7
7
|
}));
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import type { initializeWorkerRelease } from "./initialize.ts";
|
|
3
|
+
|
|
4
|
+
export function registerWorkerRelease(state: Effect.Success<typeof initializeWorkerRelease>) {
|
|
5
|
+
return Effect.fn("WorkerRelease.register")(function* <E>(control: (active: boolean) => Effect.Effect<void, E>) {
|
|
6
|
+
const registered = Effect.suspend(() => control(state.active));
|
|
7
|
+
const attach = Effect.gen(function* () {
|
|
8
|
+
state.controls.add(registered);
|
|
9
|
+
yield* registered;
|
|
10
|
+
});
|
|
11
|
+
const detach = Effect.sync(() => {
|
|
12
|
+
state.controls.delete(registered);
|
|
13
|
+
});
|
|
14
|
+
return yield* Effect.acquireRelease(state.lock.withPermits(1)(attach), () => state.lock.withPermits(1)(detach));
|
|
15
|
+
});
|
|
16
|
+
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { defineService } from "@shivaedev/service/defineService.ts";
|
|
2
2
|
import { genericMethod } from "@shivaedev/service/genericMethod.ts";
|
|
3
|
-
import { initializeWorkerRelease } from "./
|
|
4
|
-
import { registerWorkerRelease } from "./
|
|
3
|
+
import { initializeWorkerRelease } from "./initialize.ts";
|
|
4
|
+
import { registerWorkerRelease } from "./register.ts";
|
|
5
|
+
import { setActive } from "./setActive.ts";
|
|
5
6
|
|
|
6
7
|
export const WorkerRelease = defineService({
|
|
7
8
|
id: "@shivaedev/sql/WorkerRelease",
|
|
8
9
|
initialize: initializeWorkerRelease,
|
|
9
|
-
methods: (state) => ({ register: genericMethod(registerWorkerRelease(state)) }),
|
|
10
|
+
methods: (state) => ({ register: genericMethod(registerWorkerRelease(state)), setActive: setActive(state) }),
|
|
10
11
|
requires: [],
|
|
11
12
|
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import type { initializeWorkerRelease } from "./initialize.ts";
|
|
3
|
+
|
|
4
|
+
export function setActive(state: Effect.Success<typeof initializeWorkerRelease>) {
|
|
5
|
+
return Effect.fn("WorkerRelease.setActive")(function* (next: boolean) {
|
|
6
|
+
yield* state.lock
|
|
7
|
+
.withPermits(1)(
|
|
8
|
+
Effect.gen(function* () {
|
|
9
|
+
if (next === state.active) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
state.active = next;
|
|
13
|
+
yield* Effect.all(state.controls, { concurrency: "unbounded", discard: true });
|
|
14
|
+
}),
|
|
15
|
+
)
|
|
16
|
+
.pipe(Effect.uninterruptible);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"WorkerRelease.d.ts","sourceRoot":"","sources":["../src/WorkerRelease.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,aAAa;;;;CAKxB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"WorkerRelease.js","sourceRoot":"","sources":["../src/WorkerRelease.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC;IAC1C,EAAE,EAAE,8BAA8B;IAClC,UAAU,EAAE,uBAAuB;IACnC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,aAAa,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;IAC/E,QAAQ,EAAE,EAAE;CACZ,CAAC,CAAC"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
2
|
-
export declare const initializeWorkerRelease: Effect.Effect<{
|
|
3
|
-
active: boolean;
|
|
4
|
-
controls: Set<(active: boolean) => Effect.Effect<void, unknown>>;
|
|
5
|
-
locked: <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
|
|
6
|
-
}, never, never>;
|
|
7
|
-
//# sourceMappingURL=initializeWorkerRelease.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"initializeWorkerRelease.d.ts","sourceRoot":"","sources":["../src/initializeWorkerRelease.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAa,MAAM,QAAQ,CAAC;AAE3C,eAAO,MAAM,uBAAuB;;2BAER,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC;;gBAEjE,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"initializeWorkerRelease.js","sourceRoot":"","sources":["../src/initializeWorkerRelease.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAE3C,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACzD,MAAM,EAAE,KAAK;IACb,QAAQ,EAAE,IAAI,GAAG,EAAqD;IACtE,MAAM,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;CAC9C,CAAC,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"registerWorkerRelease.d.ts","sourceRoot":"","sources":["../src/registerWorkerRelease.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAE5E,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,uBAAuB,CAAC,IACjE,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,0DAUhF"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
2
|
-
export function registerWorkerRelease(state) {
|
|
3
|
-
return function register(control) {
|
|
4
|
-
const attach = Effect.gen(function* () {
|
|
5
|
-
state.controls.add(control);
|
|
6
|
-
yield* control(state.active);
|
|
7
|
-
});
|
|
8
|
-
const detach = Effect.sync(() => {
|
|
9
|
-
state.controls.delete(control);
|
|
10
|
-
});
|
|
11
|
-
return Effect.acquireRelease(state.locked(attach), () => state.locked(detach));
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
//# sourceMappingURL=registerWorkerRelease.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"registerWorkerRelease.js","sourceRoot":"","sources":["../src/registerWorkerRelease.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,MAAM,UAAU,qBAAqB,CAAC,KAAqD;IAC1F,OAAO,SAAS,QAAQ,CAAI,OAAoD;QAC/E,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC5B,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;YAC/B,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAChF,CAAC,CAAC;AACH,CAAC"}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
2
|
-
import type { initializeWorkerRelease } from "./initializeWorkerRelease.ts";
|
|
3
|
-
export declare function setWorkerReleaseActive(state: Effect.Success<typeof initializeWorkerRelease>): (next: boolean) => Effect.Effect<void, unknown, never>;
|
|
4
|
-
//# sourceMappingURL=setWorkerReleaseActive.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"setWorkerReleaseActive.d.ts","sourceRoot":"","sources":["../src/setWorkerReleaseActive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAE5E,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,uBAAuB,CAAC,UAC7E,OAAO,yCAYrB"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
2
|
-
export function setWorkerReleaseActive(state) {
|
|
3
|
-
return (next) => state
|
|
4
|
-
.locked(Effect.gen(function* () {
|
|
5
|
-
if (next === state.active) {
|
|
6
|
-
return;
|
|
7
|
-
}
|
|
8
|
-
state.active = next;
|
|
9
|
-
yield* Effect.forEach(state.controls, (control) => control(state.active), { concurrency: "unbounded", discard: true });
|
|
10
|
-
}))
|
|
11
|
-
.pipe(Effect.uninterruptible);
|
|
12
|
-
}
|
|
13
|
-
//# sourceMappingURL=setWorkerReleaseActive.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"setWorkerReleaseActive.js","sourceRoot":"","sources":["../src/setWorkerReleaseActive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,MAAM,UAAU,sBAAsB,CAAC,KAAqD;IAC3F,OAAO,CAAC,IAAa,EAAE,EAAE,CACxB,KAAK;SACH,MAAM,CACN,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnB,IAAI,IAAI,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;YAC3B,OAAO;QACR,CAAC;QACD,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;QACpB,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IACxH,CAAC,CAAC,CACF;SACA,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
2
|
-
import type { initializeWorkerRelease } from "./initializeWorkerRelease.ts";
|
|
3
|
-
|
|
4
|
-
export function registerWorkerRelease(state: Effect.Success<typeof initializeWorkerRelease>) {
|
|
5
|
-
return function register<E>(control: (active: boolean) => Effect.Effect<void, E>) {
|
|
6
|
-
const attach = Effect.gen(function* () {
|
|
7
|
-
state.controls.add(control);
|
|
8
|
-
yield* control(state.active);
|
|
9
|
-
});
|
|
10
|
-
const detach = Effect.sync(() => {
|
|
11
|
-
state.controls.delete(control);
|
|
12
|
-
});
|
|
13
|
-
return Effect.acquireRelease(state.locked(attach), () => state.locked(detach));
|
|
14
|
-
};
|
|
15
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
2
|
-
import type { initializeWorkerRelease } from "./initializeWorkerRelease.ts";
|
|
3
|
-
|
|
4
|
-
export function setWorkerReleaseActive(state: Effect.Success<typeof initializeWorkerRelease>) {
|
|
5
|
-
return (next: boolean) =>
|
|
6
|
-
state
|
|
7
|
-
.locked(
|
|
8
|
-
Effect.gen(function* () {
|
|
9
|
-
if (next === state.active) {
|
|
10
|
-
return;
|
|
11
|
-
}
|
|
12
|
-
state.active = next;
|
|
13
|
-
yield* Effect.forEach(state.controls, (control) => control(state.active), { concurrency: "unbounded", discard: true });
|
|
14
|
-
}),
|
|
15
|
-
)
|
|
16
|
-
.pipe(Effect.uninterruptible);
|
|
17
|
-
}
|