@voltro/sql-mssql 0.87.0 → 0.88.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 CHANGED
@@ -41,6 +41,166 @@ _Changes staged for the next release accumulate here (rolled up from
41
41
 
42
42
  ---
43
43
 
44
+ ## [0.88.0] — 2026-11-02
45
+
46
+ ### ⚠ BREAKING
47
+
48
+ - **Direct computed-cache key callers handle unencodable subjects** — `@voltro/runtime`, `@voltro/voltro`
49
+
50
+ `computedCacheKey()` can return `bypass: 'subject-not-encodable'` for claims that cannot safely identify a cache entry. Direct consumers with exhaustive bypass switches must handle this case by running without caching. `voltro update` identifies the direct imports to review. Queries using the native `cache:` declaration and `invoke()` tests need no manual key or code change.
51
+ - **The framework runs on effect 4.1.0** — `@voltro/cli`, `@voltro/devtools`, `@voltro/runtime`, `@voltro/database`, `@voltro/voltro`, `@voltro/sql-sqlite`, `@voltro/sql-mysql`, `@voltro/sql-mssql`, `@voltro/sql-postgres`
52
+
53
+ Every `@voltro/*` package now pins `effect` and its `@effect/*` companions to 4.1.0. Apps pin the same version and run `voltro add patches`: it writes the 4.1.0 patch files, retires the `patchedDependencies` entries an earlier CLI shipped for 4.0.1 (pnpm refuses an install over an unused patch) and moves the lockstep overrides. Two former patch fixes ship upstream in 4.1.0 (SQL Server request cancellation, the SQL Server message-storage MERGE). On SQL Server the shared transaction key now applies to every client in the process, not only the first one built.
54
+
55
+ `chunkRowsForInsert` from `@voltro/database` returns non-empty chunks (`NonEmptyReadonlyArray`), the shape effect 4.1's `sql.insert` requires; an empty input yields no chunk instead of one empty chunk.
56
+
57
+ SQL statement spans are named after their database, following the OpenTelemetry database conventions: the database name, else the server address, else the system name (`postgresql`, `mysql`, `microsoft.sql_server`, `sqlite`). Before, every statement span was `sql.execute`. Trace queries and dashboards that match that name should match the `db.query.text` attribute instead; the devtools trace panel and durable-trace sampling already do.
58
+
59
+ **`voltro update` carries you across this** — codemod `0.88.0/01_effect-4-1`. If you pin versions by hand and never run it, print the notes without changing anything: `voltro update --codemods-only --from <your current version> --dry-run` (this one ships in 0.88.0).
60
+ - **Runtime patch pins preserve third-party Effect majors** — `@voltro/cli`
61
+
62
+ `voltro add patches` scopes Effect pins to their current major instead of replacing unrelated libraries' Effect 3 dependencies. It migrates exact pins previously shipped by the framework, preserves unrelated policies, and refuses conflicting custom policies before writing files. In pnpm workspaces it names competing nonempty root `resolutions` or `pnpm.overrides` and explains their explicit reconciliation. Peer repair refuses cross-major global policy changes. Bun workspaces require Bun >=1.4.4 and a supported `packageManager` pin or `engines.bun` floor; upgrade the actual tool and older declarations before retrying, because Bun 1.2.0 ignored the scoped companion pin. `voltro update` carries the review as `0.88.0/06_effect-override-scope`.
63
+ - **Keep test runners out of production KV and workflow dependency closures** — `@voltro/kv`, `@voltro/workflow`
64
+
65
+ The test-only HotStore and workflow conformance suites now require their caller to supply runner operations. Pass `{ describe, it, expect }` as the third argument to `hotStoreConformance`, and `{ describe, test, expect, beforeAll, afterEach }` as the second argument to `runClusterEngineSuite` and `runJournalEncryptionSuite`. The exported structural runner interfaces have no dependency on Vitest. Both production packages remove their optional Vitest peer; an application's development runner can no longer enter a production deployment through those peer links. Keep Vitest in the test application's own devDependencies. Runtime KV/workflow calls and `runHotStoreSqlParity` are unchanged. `voltro update` identifies direct suite imports for review.
66
+ - **REST test handlers publish events under the request tenant** — `@voltro/testing`, `@voltro/cli`
67
+
68
+ When crossing 0.87.0, custom `makeTestApp({ restRoutes })` handlers receive a request-scoped `ctx.app` instead of the root fixture context. Event assertions must subscribe to that request tenant: the default anonymous request uses `acme` or `x-tenant`; an explicit `anonymous: 'no-tenant'` uses `''`, distinct from the event bus subscriber's default `null`. Pass the app's anonymous policy, select the subscriber tenant explicitly and assert delivered payloads even when HTTP success and `notified` already pass. Direct `invoke` retains its supplied context identity, and projected `publicApi` handlers already use request-scoped invocation. Plugin HTTP routes are not mounted by this request harness. `voltro update` locates raw request harness calls and prints the review steps.
69
+
70
+ ### Added
71
+
72
+ - **voltro add patches --ai accepts ai 7.0.156** — `@voltro/cli`, `@voltro/ai`
73
+
74
+ `voltro add patches --ai 7.0.156` wires the AI SDK declaration correction for `@ai-sdk/provider-utils` 5.0.70, regenerated with the original build from the release commit; JavaScript stays byte-identical to the published package. 7.0.105 and 7.0.132 remain selectable. `@voltro/ai` is built and tested against ai 7.0.156.
75
+ - **The retained invoice observations table is exported from the billing package** — `@voltro/plugin-billing`
76
+
77
+ `billingRetainedInvoiceObservationsTable` is exported from `@voltro/plugin-billing` beside the other billing tables, so an app can reference it.
78
+ - **plugin-billing accepts stripe 23** — `@voltro/plugin-billing`
79
+
80
+ The `stripe` peer range is `^22.6.1 || ^23.0.1`. stripe 23 pins Stripe API version `2026-09-30.endive`; the plugin still sends no `apiVersion` of its own, so the SDK's pinned version applies.
81
+
82
+ ### Changed
83
+
84
+ - **A booting server holds requests until the app is ready instead of answering 503** — `@voltro/runtime`, `@voltro/voltro`
85
+
86
+ `voltro serve`, `voltro start` and `voltro dev` used to answer every request that arrived before the boot finished with a plain-text `503 starting`. On a platform that scales to zero, that request is the visitor who woke the instance, and a browser does not act on `Retry-After` for a navigation. Requests and WebSocket upgrades that arrive while the app boots now wait and are handed to the app in arrival order once it is ready. The wait is bounded by `VOLTRO_BOOT_HOLD_MS` (default `30000`, at most five minutes, `0` restores the immediate `503`) and by 512 waiting requests. A request the wait cannot cover still gets `503` with `Retry-After: 1`, and a browser navigation gets a minimal page that reloads itself. `/internal/startup` reports waiting requests as `held`, and `bindBootListener` accepts `holdMs` and `maxHeld`. Probes are unchanged, so nothing changes under Kubernetes.
87
+ - **DocsLayout navigation nests collapsible groups with page counts** — `@voltro/ui-shadcn`
88
+
89
+ `DocsLayout` renders its sidebar as one tree: headerless groups are flat start links, other groups and sub-groups are collapsible rows with page counts, `DocsNavSubGroup` accepts nested `subgroups` and `trailingEntries`, the current page's link carries `aria-current="page"` (forwarded through `ShellLinkProps`), and the rail scrolls the active link into view after navigation.
90
+ - **Native Redis connections use ioredis 6 and keep the RESP2 protocol** — `@voltro/kv`, `@voltro/runtime`, `@voltro/cli`
91
+
92
+ The native Redis transport moved to ioredis 6, which defaults to RESP3. Registry connections set `protocol: 2`, so command replies, Pub/Sub and Lua results keep their shapes.
93
+ - **Connection drivers install only with the server runtime** — `@voltro/kv`, `@voltro/runtime`
94
+
95
+ `ioredis`, `@upstash/redis` and `@nats-io/transport-node` are optional peers of `@voltro/kv` and dependencies of `@voltro/runtime`. API apps keep all three without a step; web apps and SDKs that reach `@voltro/kv` only through types no longer download server drivers. Code that opens a connection without `@voltro/runtime` adds its driver, and a missing driver now fails naming the package.
96
+ - **The mobile template targets Expo SDK 58** — `@voltro/cli`
97
+
98
+ New mobile apps scaffold on Expo SDK 58 with React Native 0.88.1 and React 19.3.0, using the versions SDK 58 bundles for its native modules.
99
+ - **plugin-sentry runs on Sentry 11 and exports server spans over OTLP** — `@voltro/plugin-sentry`
100
+
101
+ Sentry 11 removed `SentrySpanProcessor`. The plugin now exports the framework's spans to the OTLP endpoint Sentry derives from the DSN and links errors and logs to the active span with `openTelemetryIntegration()`; the Sentry SDK records no spans of its own. `tracesSampleRate` keeps its meaning and is applied per trace id at the export. Server traces need the optional `@opentelemetry/sdk-trace-base` and `@opentelemetry/exporter-trace-otlp-http` packages (they replace `@sentry/opentelemetry`); without them the plugin warns and reports errors and breadcrumbs only. `init.tracesSampleRate` and `init.enableOpenTelemetrySetup` are ignored, and `init.skipOpenTelemetrySetup` no longer exists in Sentry 11.
102
+
103
+ ### Fixed
104
+
105
+ - **Deferred workflow starts retain their original caller receipt** — `@voltro/workflow`, `@voltro/cli`
106
+
107
+ A controlled workflow start now returns its existing queued receipt when another replica exhausts submission retries, or shared capacity moves, before its acceptance callback dispatches. It no longer reports an ordinary start failure while the committed submission remains unresolved. Execution identity, caller input, capacity ownership and retry limits stay unchanged; definite rejection and invalid ownership still fail explicitly.
108
+
109
+ - **Aggregate counters are non-negative safe integers on every dialect** — `@voltro/database`
110
+
111
+ A `count()` / `countDistinct()` / ranking counter now decodes to a number only when it is a non-negative safe integer; a fractional, negative, non-numeric or larger value is refused instead of passed through or rounded. SQLite and Turso decode counters too when the queried table has decimal columns, where they used to stay strings.
112
+ - **Cache clear honors connection namespace prefixes** — `@voltro/kv`, `@voltro/cache`
113
+
114
+ Clearing a cache through a named, namespaced Redis connection now binds logical cache keys to that connection's physical namespace. Redis-family engines and the local transport preserve neighboring caches and invalidation fences, while refusing foreign prefixes and forged key sets. The existing atomic cache command format remains unchanged.
115
+ - **Cache commands use the selected app's configuration and connections** — `@voltro/cli`
116
+
117
+ `voltro cache status`, `flush` and `invalidate` resolve `app.config.ts`, environment overrides and named Redis connections exactly like Dev and Serve, including an optional target app directory. Invalid configuration fails instead of silently reporting memory, in-process transports refuse CLI mutation, and diagnostics omit endpoint URLs and credentials.
118
+ - **Generated cache examples boot and upgrade reviews name affected lines** — `@voltro/cli`
119
+
120
+ The seeded core API example now uses an object cache declaration. Forced guide refresh discovers both flat and project-grouped app layouts, replacing stale nested examples without executing configs or crossing an app boundary. The shared cache/KV migration review lists authored code locations, including asserted backend literals, and a new review reaches applications that already crossed the original migration. It also identifies stale core guides for refresh; protected hand-maintained guides stay under their owner's control.
121
+ - **Subject query caches follow current authority** — `@voltro/runtime`, `@voltro/testing`
122
+
123
+ Subject-scoped computed queries key the complete subject claims and raw and resolved permission sets. Removing an admin grant, changing roles or switching tenant or credential type cannot reuse a result admitted under earlier authority. Authentication refreshes before lookup, and a change while a read is pending refuses retention and delivery. Connection-local state is never covered by subject scope; handlers that read it do not retain their results. The same decisions apply to `invoke` tests, memory caches and Redis caches.
124
+ - **Preserve connection declaration errors across module boundaries** — `@voltro/kv`
125
+
126
+ Redis, NATS, Storage, Analytics and SQL registries retain typed configuration diagnostics across module and VM boundaries instead of mislabeling them as dynamic credential failures. Errors returned by credential resolvers remain redacted.
127
+ - **Bind demo API tenants consistently in browser and server renders** — `@voltro/cli`
128
+
129
+ The fullstack, admin, SSR API and public status templates now send their explicit demo tenant to header-based anonymous APIs. SSR API and status pages use the same binding for server-side RPC reads, so a fresh scaffold renders successfully and its browser subscriptions select the same data. API refusals for missing tenants and access checks remain enforced. These demo bindings select rows and do not authenticate users; private production data requires verified authentication. Fresh-consumer diagnostics retain uppercase error log lines.
130
+ - **Two voltro dev processes starting together mint one set of secrets, not two** — `@voltro/cli`
131
+
132
+ `voltro dev` mints missing project secrets into `.env.local`. Two processes on one project starting at the same time (two local replicas, a dev server beside a test boot) each minted their own values; with field encryption the database recorded one key and refused the second process at boot. Minting now runs under a lock and adopts a value another process wrote meanwhile; a lock left by a crashed mint is taken over.
133
+ - **Event warnings follow workspace package exports** — `@voltro/cli`
134
+
135
+ Development event wiring warnings now recognise sibling `useEvent` consumers imported through package exports, TypeScript path aliases, named and namespace re-exports, and static local aliases. Each subscription is matched to its descriptor so an unused import or another API's same-named module does not hide a missing consumer. Workspace discovery supports declared pnpm, npm, Yarn and Bun members and excludes nested projects and build output.
136
+ - **Index audit preserves partial row coverage and uniqueness** — `@voltro/database`
137
+
138
+ The index audit recommends dropping an index only when another B-tree index preserves its row coverage and uniqueness. Partial unique indexes no longer make full indexes appear redundant; specialized index methods and unproved predicate relationships are excluded, and recommendations name only the safe replacement direction.
139
+ - **Migration logs identify which operations their count includes** — `@voltro/database`
140
+
141
+ Development auto-migration logs now identify their applied-operation count as the planner pass, excluding framework bootstrap and file-based migrations. A schema plan taken before boot can include work completed by those earlier stages; run a new plan after boot to verify that no operations remain.
142
+ - **Filter completed workflow pool owners before recovery transport** — `@voltro/cli`, `@voltro/voltro`, `@voltro/workflow`
143
+
144
+ Pool release recovery now persists its terminal settlement on submission and restart owners and filters those markers through indexed SQL predicates. Finished owner history no longer crosses the wire on every idle pass or after process restart. Lost release acknowledgements, held owners and missing evidence remain recoverable and reported; immutable owners and permit tombstones remain for receipt and replay safety. Normal framework schema migration adds two nullable settlement markers and their indexes; existing history is checked once in bounded pages. Settlement indexes use explicit short names within SQL identifier limits. Reconciliation cadence is unchanged.
145
+ - **Presence transport warnings follow actual subscription readiness** — `@voltro/plugin-presence`
146
+
147
+ Presence reports pending binding or subscription acquisition without a false missing-provider warning after five seconds. It reports cross-instance readiness only after acquiring the broadcast subscription, while local-only bindings and failed subscriptions still warn. Closing or replacing a binding prevents stale callbacks and releases subscriptions acquired afterward.
148
+ - **Self-updates finish after the old CLI installation is removed** — `@voltro/cli`, `@voltro/runtime`
149
+
150
+ `voltro update` loads its completion helpers before installing the target version, so removing the running CLI package no longer turns a successful upgrade into a missing-module failure. Error reporting uses the shared lightweight `@voltro/runtime/boot-refusal` entry loaded before dispatch; genuine failures keep their original message and exit code without loading the server dependency graph for help or version commands.
151
+ - **Compiled API servers start without a source-analysis dependency** — `@voltro/cli`
152
+
153
+ The development event-consumer audit loads its source compiler only when scanning. A compiled API server can start after relocation without app sources or a direct `ts-morph` dependency. Package-export consumer discovery keeps its existing scope and does not execute application modules.
154
+ - **SignalHeader centers its brand in the masthead** — `@voltro/ui-shadcn`
155
+
156
+ The `SignalHeader` brand slot is a centered flex row, so a brand link no longer sits on the text baseline and renders a few pixels above the masthead's center.
157
+ - **Update reports changed runtime patch assets before boot** — `@voltro/cli`
158
+
159
+ `voltro update` compares configured pnpm Effect and SQL-driver patches with the target CLI's assets during its codemod step, including `--codemods-only`. Changed bytes produce refresh and install instructions even without workflows. Same-version checks also report drift. Custom patch paths are named and files remain untouched.
160
+ - **Upgrade reviews omit locator counts and unchanged REST type plumbing** — `@voltro/cli`
161
+
162
+ The aggregate review excludes locator chains and local locator aliases while retaining uncertain query receivers. The idempotency review lists REST context constructions, context factories and guard definitions instead of every context or guard parameter annotation. Aliased imported calls in JavaScript custom hosts remain visible.
163
+
164
+ ### Internal (no consumer-facing effect)
165
+
166
+ - **Effect audits distinguish regression data from executable legacy APIs**
167
+
168
+ Effect migration audits allow test data to describe a foreign dependency's retained major. Removed package imports and obsolete bound API calls remain findings in tests and application code, while production migration-residue checks remain unchanged.
169
+ - **The doctor's table nullability manifest covers the billing history tables** — `@voltro/cli`
170
+
171
+ The generated nullability manifest `voltro doctor` reads was missing the invoice-history and customer-account tables the billing plugin added; it is regenerated from the declarations.
172
+ - **Installation checks refuse ambient workspaces and source overrides**
173
+
174
+ Installation checks require standalone directories before creating projects. Artifact consumers use shipped template and documentation assets without inheriting maintainer source overrides or Node module loaders. Registry, package-manager and explicit application settings remain available.
175
+ - **Installation checks require healthy applications and usable modules**
176
+
177
+ Installation checks require API readiness, successful web responses and transformed JavaScript modules while the development process remains running. HTTP errors and HTML fallbacks cannot satisfy those checks. Diagnostics distinguish application startup from shutdown.
178
+ - **Keep CLI fixture temporary roots and child outcomes explicit**
179
+
180
+ Automatic sidecar tests inspect the actual operating-system temporary directory and release their bound owner even when an assertion fails. Schema-boot fixtures retain the child's exit signal and assert the real exit tuple alongside readiness and migration counts, so a signal cannot become a false successful process result. Production security and signal guards remain unchanged.
181
+
182
+ Workflow recovery tests distinguish the recorded failure budget from concurrent dispatches already in flight. They retain the same prepared execution identity, require one body execution, and verify that stopped or accepted submissions cannot dispatch again.
183
+ - **Native SQL checks isolate schema ownership across fixtures**
184
+
185
+ Wallet and shop checks own separate server databases so concurrent schema creation cannot contend with another fixture's live writes. Independent pools within a fixture still share the real database. Cleanup closes all acquired pools before dropping only the owned namespace, and a native regression verifies isolation with identical wallet identities.
186
+ - **Native reload checks retain manifests published during SQL observation**
187
+
188
+ Native geometry checks establish the expected-version receiver before reload activation. A real transport regression holds the consumer until the new manifest arrives, so asynchronous SQL observation cannot hide a missed publication. Frame deadlines retain their original call sites.
189
+ - **Native snapshot probes join their scheduled driver**
190
+
191
+ Held-source stream probes quiesce and join the actual Host driver before directly pumping its captured graph. This prevents a scheduled turn from concurrently entering that graph and closing the fixture's native Session. Listener, SQL, controller, wire delivery, rights withdrawal and final cleanup assertions remain active; ordinary stream cases retain the running driver.
192
+ - **Bound the reviewed Sentry tool exception and retain every dependency instance**
193
+
194
+ The owner-reviewed exception accepts only sentry 0.45.0 under FSL-1.1-Apache-2.0 as unmodified external tooling for the Sentry integration. This does not classify FSL as permissive or remove its competing-use restriction. The runtime license walk checks every resolved instance, so an accepted version cannot hide a second version or license. Generated notices and the SBOM use actual package identities. Containment checks cover framework, workspace and scaffold patch files plus declared patches with arbitrary filenames; the API bundler leaves the tool external.
195
+ - **Stack scaffold checks require major-scoped runtime alignment**
196
+
197
+ The normal stack scaffold regression parses its generated workspace policy and verifies both Effect 4 selectors while refusing unqualified Effect and companion pins. Patch declaration and actual patch-byte checks remain, so the regression follows the preserved foreign-major contract instead of demanding its earlier unsafe global override. Its synthetic workspace declares its own pnpm version, making Compose baseline coverage independent of the test runner's package-manager environment.
198
+ - **Dependency security checks verify installed source remediations**
199
+
200
+ Dependency security checks accept a reviewed source remediation only after verifying exact patch and implementation hashes, patched references in every lockfile document, actual caller resolution and runtime behavior. Deepmerge's returned-object prototype protection preserves ordinary configuration merging. Unaffected dependency graphs receive no exception, and a local source remediation is never reported as an upstream fixed version.
201
+
202
+ ---
203
+
44
204
  ## [0.87.0] — 2026-10-31
45
205
 
46
206
  ### ⚠ BREAKING
@@ -3231,6 +3391,15 @@ _Changes staged for the next release accumulate here (rolled up from
3231
3391
  - **Prepare the exact XYFlow type correction before normal installation** — `@voltro/cli`
3232
3392
 
3233
3393
  `voltro add patches --xyflow 12.12.0` prepares the original XYFlow declaration correction and its complete license/notice before a normal package-manager or UI installation. Existing conflicting project patch assets are preserved and rejected before writes.
3394
+ - **Dispatchers drain accepted reads before store disposal** — `@voltro/runtime`, `@voltro/cli`
3395
+
3396
+ Runtime adds `Dispatcher.closeAndDrain()` to join accepted reads and deliveries before store disposal. Normal Dev and Serve API shutdown await it; synchronous `close()` remains available.
3397
+ - **Workflow cluster hosts declare shard groups and ClusterCron routing groups** — `@voltro/workflow`, `@voltro/cli`
3398
+
3399
+ Workflow cluster hosts can explicitly declare available/assigned shard groups and ClusterCron routing groups. Omitted settings retain existing routing; persistent journal migration is a separate prerequisite for changing groups.
3400
+ - **PostgreSQL workflow hosts can persist routing-generation admission** — `@voltro/workflow`, `@voltro/cli`
3401
+
3402
+ PostgreSQL workflow engine hosts can opt into persisted routing-generation admission with `journalRouting`; actual durable MessageStorage operations use the ownership guard. Full API-role wiring and maintenance rollout remain separate requirements.
3234
3403
 
3235
3404
  ### Changed
3236
3405
 
@@ -24321,9 +24490,3 @@ public registry yet.
24321
24490
 
24322
24491
  Subsequent releases record their deltas from here under dated headings, with
24323
24492
  `⚠ BREAKING` first.
24324
-
24325
- - Runtime adds `Dispatcher.closeAndDrain()` to join accepted reads and deliveries before store disposal. Normal Dev and Serve API shutdown await it; synchronous `close()` remains available.
24326
-
24327
- - Workflow cluster hosts can explicitly declare available/assigned shard groups and ClusterCron routing groups. Omitted settings retain existing routing; persistent journal migration is a separate prerequisite for changing groups.
24328
-
24329
- - PostgreSQL workflow engine hosts can opt into persisted routing-generation admission with `journalRouting`; actual durable MessageStorage operations use the ownership guard. Full API-role wiring and maintenance rollout remain separate requirements.
@@ -1,15 +1,15 @@
1
1
  # Third-Party Notices — @voltro/sql-mssql
2
2
 
3
- This package uses the open-source software listed below. Each is the
3
+ This package uses the third-party software listed below. Each is the
4
4
  property of its respective copyright holders and is used under the terms of
5
5
  its license. This file is provided for attribution; it grants no rights in
6
6
  @voltro/sql-mssql itself, which is proprietary (see LICENSE).
7
7
 
8
- Generated from the resolved runtime dependency closure (70 packages).
8
+ Generated from the resolved runtime dependency closure (72 packages).
9
9
 
10
10
  ---
11
11
 
12
- ## @azure-rest/core-client@2.6.0
12
+ ## @azure-rest/core-client@2.9.0
13
13
 
14
14
  License: MIT
15
15
 
@@ -37,14 +37,14 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
37
37
  SOFTWARE.
38
38
  ```
39
39
 
40
- ## @azure/abort-controller@2.1.2
40
+ ## @azure/abort-controller@2.2.0
41
41
 
42
42
  License: MIT
43
43
 
44
44
  ```
45
- The MIT License (MIT)
45
+ Copyright (c) Microsoft Corporation.
46
46
 
47
- Copyright (c) 2020 Microsoft
47
+ MIT License
48
48
 
49
49
  Permission is hereby granted, free of charge, to any person obtaining a copy
50
50
  of this software and associated documentation files (the "Software"), to deal
@@ -56,7 +56,7 @@ furnished to do so, subject to the following conditions:
56
56
  The above copyright notice and this permission notice shall be included in all
57
57
  copies or substantial portions of the Software.
58
58
 
59
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
59
+ THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
60
60
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
61
61
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
62
62
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
@@ -65,7 +65,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
65
65
  SOFTWARE.
66
66
  ```
67
67
 
68
- ## @azure/core-auth@1.10.1
68
+ ## @azure/core-auth@1.11.0
69
69
 
70
70
  License: MIT
71
71
 
@@ -93,7 +93,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
93
93
  SOFTWARE.
94
94
  ```
95
95
 
96
- ## @azure/core-client@1.10.1
96
+ ## @azure/core-client@1.11.1
97
97
 
98
98
  License: MIT
99
99
 
@@ -149,14 +149,42 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
149
149
  SOFTWARE.
150
150
  ```
151
151
 
152
- ## @azure/core-paging@1.6.2
152
+ ## @azure/core-paging@1.7.0
153
+
154
+ License: MIT
155
+
156
+ ```
157
+ Copyright (c) Microsoft Corporation.
158
+
159
+ MIT License
160
+
161
+ Permission is hereby granted, free of charge, to any person obtaining a copy
162
+ of this software and associated documentation files (the "Software"), to deal
163
+ in the Software without restriction, including without limitation the rights
164
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
165
+ copies of the Software, and to permit persons to whom the Software is
166
+ furnished to do so, subject to the following conditions:
167
+
168
+ The above copyright notice and this permission notice shall be included in all
169
+ copies or substantial portions of the Software.
170
+
171
+ THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
172
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
173
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
174
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
175
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
176
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
177
+ SOFTWARE.
178
+ ```
179
+
180
+ ## @azure/core-process@1.0.0
153
181
 
154
182
  License: MIT
155
183
 
156
184
  ```
157
185
  The MIT License (MIT)
158
186
 
159
- Copyright (c) 2020 Microsoft
187
+ Copyright (c) 2018 Microsoft
160
188
 
161
189
  Permission is hereby granted, free of charge, to any person obtaining a copy
162
190
  of this software and associated documentation files (the "Software"), to deal
@@ -177,7 +205,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
177
205
  SOFTWARE.
178
206
  ```
179
207
 
180
- ## @azure/core-rest-pipeline@1.24.0
208
+ ## @azure/core-rest-pipeline@1.25.0
181
209
 
182
210
  License: MIT
183
211
 
@@ -205,7 +233,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
205
233
  SOFTWARE.
206
234
  ```
207
235
 
208
- ## @azure/core-tracing@1.3.1
236
+ ## @azure/core-tracing@1.4.0
209
237
 
210
238
  License: MIT
211
239
 
@@ -233,7 +261,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
233
261
  SOFTWARE.
234
262
  ```
235
263
 
236
- ## @azure/core-util@1.13.1
264
+ ## @azure/core-util@1.14.0
237
265
 
238
266
  License: MIT
239
267
 
@@ -261,7 +289,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
261
289
  SOFTWARE.
262
290
  ```
263
291
 
264
- ## @azure/identity@4.13.1
292
+ ## @azure/identity@4.14.0
265
293
 
266
294
  License: MIT
267
295
 
@@ -345,7 +373,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
345
373
  SOFTWARE.
346
374
  ```
347
375
 
348
- ## @azure/logger@1.3.0
376
+ ## @azure/logger@1.4.0
349
377
 
350
378
  License: MIT
351
379
 
@@ -373,7 +401,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
373
401
  SOFTWARE.
374
402
  ```
375
403
 
376
- ## @azure/msal-browser@5.11.0
404
+ ## @azure/msal-browser@5.27.0
377
405
 
378
406
  License: MIT
379
407
 
@@ -401,7 +429,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
401
429
  SOFTWARE
402
430
  ```
403
431
 
404
- ## @azure/msal-common@16.6.2
432
+ ## @azure/msal-common@16.15.0
405
433
 
406
434
  License: MIT
407
435
 
@@ -429,7 +457,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
429
457
  SOFTWARE
430
458
  ```
431
459
 
432
- ## @azure/msal-node@7.1.1
460
+ ## @azure/msal-node@7.1.2
433
461
 
434
462
  License: MIT
435
463
 
@@ -457,7 +485,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
457
485
  SOFTWARE.
458
486
  ```
459
487
 
460
- ## @effect/sql-mssql@4.0.1
488
+ ## @effect/sql-mssql@4.1.0
461
489
 
462
490
  License: MIT
463
491
 
@@ -485,7 +513,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
485
513
  SOFTWARE.
486
514
  ```
487
515
 
488
- ## @js-joda/core@6.2.0
516
+ ## @js-joda/core@6.3.0
489
517
 
490
518
  License: BSD-3-Clause
491
519
 
@@ -525,7 +553,7 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
525
553
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
526
554
  ```
527
555
 
528
- ## @types/node@26.6.1
556
+ ## @types/node@26.6.6
529
557
 
530
558
  License: MIT
531
559
 
@@ -553,7 +581,7 @@ MIT License
553
581
  SOFTWARE
554
582
  ```
555
583
 
556
- ## @types/readable-stream@4.0.23
584
+ ## @types/readable-stream@4.0.25
557
585
 
558
586
  License: MIT
559
587
 
@@ -581,7 +609,7 @@ MIT License
581
609
  SOFTWARE
582
610
  ```
583
611
 
584
- ## @typespec/ts-http-runtime@0.3.5
612
+ ## @typespec/ts-http-runtime@0.3.9
585
613
 
586
614
  License: MIT
587
615
 
@@ -761,7 +789,7 @@ Redistribution and use in source and binary forms, with or without modification,
761
789
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
762
790
  ```
763
791
 
764
- ## bundle-name@4.1.0
792
+ ## bundle-name@4.1.1
765
793
 
766
794
  License: MIT
767
795
 
@@ -803,7 +831,7 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
803
831
  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
804
832
  ```
805
833
 
806
- ## default-browser@5.5.0
834
+ ## default-browser@5.5.1
807
835
 
808
836
  License: MIT
809
837
 
@@ -1257,6 +1285,22 @@ The above copyright notice and this permission notice shall be included in all c
1257
1285
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1258
1286
  ```
1259
1287
 
1288
+ ## is-in-ssh@1.0.0
1289
+
1290
+ License: MIT
1291
+
1292
+ ```
1293
+ MIT License
1294
+
1295
+ Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
1296
+
1297
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
1298
+
1299
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
1300
+
1301
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1302
+ ```
1303
+
1260
1304
  ## is-inside-container@1.0.0
1261
1305
 
1262
1306
  License: MIT
@@ -1751,7 +1795,23 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1751
1795
  SOFTWARE.
1752
1796
  ```
1753
1797
 
1754
- ## open@10.2.0
1798
+ ## open@11.0.4
1799
+
1800
+ License: MIT
1801
+
1802
+ ```
1803
+ MIT License
1804
+
1805
+ Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
1806
+
1807
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
1808
+
1809
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
1810
+
1811
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1812
+ ```
1813
+
1814
+ ## powershell-utils@0.2.1
1755
1815
 
1756
1816
  License: MIT
1757
1817
 
@@ -1796,7 +1856,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
1796
1856
  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1797
1857
  ```
1798
1858
 
1799
- ## readable-stream@4.7.0
1859
+ ## readable-stream@4.8.0
1800
1860
 
1801
1861
  License: MIT
1802
1862
 
@@ -1944,37 +2004,6 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
1944
2004
  IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1945
2005
  ```
1946
2006
 
1947
- ## sprintf-js@1.1.3
1948
-
1949
- License: BSD-3-Clause
1950
-
1951
- ```
1952
- Copyright (c) 2007-present, Alexandru Mărășteanu <hello@alexei.ro>
1953
- All rights reserved.
1954
-
1955
- Redistribution and use in source and binary forms, with or without
1956
- modification, are permitted provided that the following conditions are met:
1957
- * Redistributions of source code must retain the above copyright
1958
- notice, this list of conditions and the following disclaimer.
1959
- * Redistributions in binary form must reproduce the above copyright
1960
- notice, this list of conditions and the following disclaimer in the
1961
- documentation and/or other materials provided with the distribution.
1962
- * Neither the name of this software nor the names of its contributors may be
1963
- used to endorse or promote products derived from this software without
1964
- specific prior written permission.
1965
-
1966
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1967
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1968
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1969
- DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
1970
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1971
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1972
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1973
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1974
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1975
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1976
- ```
1977
-
1978
2007
  ## string_decoder@1.3.0
1979
2008
 
1980
2009
  License: MIT
@@ -2029,14 +2058,14 @@ IN THE SOFTWARE.
2029
2058
  """
2030
2059
  ```
2031
2060
 
2032
- ## tedious@20.3.3
2061
+ ## tedious@20.3.8
2033
2062
 
2034
2063
  License: MIT
2035
2064
 
2036
2065
  ```
2037
2066
  The MIT License
2038
2067
 
2039
- Copyright (c) 2010-2018 Mike D Pilsbury
2068
+ Copyright (c) 2010-2026 Mike D Pilsbury
2040
2069
 
2041
2070
  Permission is hereby granted, free of charge, to any person obtaining a copy
2042
2071
  of this software and associated documentation files (the "Software"), to deal
@@ -2132,7 +2161,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2132
2161
  SOFTWARE.
2133
2162
  ```
2134
2163
 
2135
- ## wsl-utils@0.1.0
2164
+ ## wsl-utils@1.0.1
2136
2165
 
2137
2166
  License: MIT
2138
2167
 
@@ -1,9 +1,8 @@
1
1
  import { TYPES as e } from "tedious";
2
- //#region src/binaryParameter.ts
2
+ // src/binaryParameter.ts
3
3
  var t = {
4
4
  ...e.VarBinary,
5
5
  resolveLength: (t) => Math.max(1, e.VarBinary.resolveLength(t)),
6
6
  validate: (t, n, r) => e.VarBinary.validate(t instanceof Uint8Array && !Buffer.isBuffer(t) ? Buffer.from(t.buffer, t.byteOffset, t.byteLength) : t, n, r)
7
7
  };
8
- //#endregion
9
8
  export { t as binaryParameter };
@@ -3,7 +3,7 @@ import { Effect as n } from "effect";
3
3
  import { decodeRowsFromSchema as r } from "@voltro/database";
4
4
  import { createLogger as i } from "@voltro/logger";
5
5
  import { SqlClient as a } from "effect/sql/SqlClient";
6
- //#region src/changeTrackingCdc.ts
6
+ // src/changeTrackingCdc.ts
7
7
  var o = {
8
8
  I: "insert",
9
9
  U: "update",
@@ -107,5 +107,4 @@ var o = {
107
107
  currentVersion: () => g
108
108
  };
109
109
  };
110
- //#endregion
111
110
  export { s as ensureChangeTracking, u as startChangeTrackingCdc };
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import { ensureChangeTracking as a, startChangeTrackingCdc as o } from "./change
4
4
  import { CDC_OFFSETS_TABLE as s, _voltroMssqlCdcOffsetsTable as c } from "./cdcOffsetsTable.js";
5
5
  import { makeMssqlStore as l } from "./store.js";
6
6
  import { mssqlReplicationAdapter as u } from "./replicationAdapter.js";
7
- //#region src/index.ts
7
+ // src/index.ts
8
8
  var d = {
9
9
  id: "mssql",
10
10
  makeSqlLayer: (e) => r(e),
@@ -12,5 +12,4 @@ var d = {
12
12
  compileContains: (e, t, n) => n`${e} LIKE ${`%${t.replace(/[\\%_[\]]/g, (e) => `\\${e}`)}%`} ESCAPE '\\'`,
13
13
  retryFilter: i
14
14
  };
15
- //#endregion
16
15
  export { s as CDC_OFFSETS_TABLE, e as MssqlClient, c as _voltroMssqlCdcOffsetsTable, t as connectionFromConfig, a as ensureChangeTracking, n as makeMssqlSqlLayer, r as makeMssqlSqlLayerFromConfig, l as makeMssqlStore, d as mssqlDialect, u as mssqlReplicationAdapter, i as mssqlRetryFilter, o as startChangeTrackingCdc };
@@ -1,6 +1,6 @@
1
1
  import { TYPES as e } from "tedious";
2
2
  import { resolveParameter as t } from "tedious/lib/data-type";
3
- //#region src/numberParameter.ts
3
+ // src/numberParameter.ts
4
4
  var n = (t) => typeof t == "bigint" ? e.BigInt : typeof t == "number" && Number.isSafeInteger(t) ? t >= -2147483648 && t <= 2147483647 ? e.Int : e.BigInt : e.Float, r = {
5
5
  ...e.Int,
6
6
  declaration: (e) => n(e.value).declaration(e),
@@ -15,5 +15,4 @@ var n = (t) => typeof t == "bigint" ? e.BigInt : typeof t == "number" && Number.
15
15
  return n(e).validate(e, t, r);
16
16
  }
17
17
  };
18
- //#endregion
19
18
  export { r as numberParameter };
@@ -1,6 +1,6 @@
1
1
  import { Effect as e } from "effect";
2
2
  import { SqlClient as t } from "effect/sql/SqlClient";
3
- //#region src/replicationAdapter.ts
3
+ // src/replicationAdapter.ts
4
4
  var n = (e) => e.__mssqlReplicationFriend ?? null, r = (e, t) => e === t ? 0 : e < t ? -1 : 1, i = () => ({
5
5
  async capturePrimaryPosition(r) {
6
6
  let i = n(r);
@@ -31,5 +31,4 @@ var n = (e) => e.__mssqlReplicationFriend ?? null, r = (e, t) => e === t ? 0 : e
31
31
  return r(t, e) >= 0 ? "caught-up" : "behind";
32
32
  }
33
33
  });
34
- //#endregion
35
34
  export { i as mssqlReplicationAdapter };
package/dist/retry.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { MSSQL_TRANSIENT_NUMBERS as e, causeBranches as t } from "@voltro/database";
2
- //#region src/retry.ts
2
+ // src/retry.ts
3
3
  var n = e, r = (e) => {
4
4
  let t = e;
5
5
  for (let e = 0; e < 5 && typeof t == "object" && t; e++) {
@@ -16,5 +16,4 @@ var n = e, r = (e) => {
16
16
  let t = r(e);
17
17
  return t !== void 0 && a.has(t);
18
18
  }), s = (e) => i(e) ? "retry" : "noRetry";
19
- //#endregion
20
19
  export { o as isDuplicateKeyMssqlFailure, i as isRetryableMssqlFailure, s as mssqlRetryFilter };
@@ -1,6 +1,6 @@
1
1
  import { Effect as e } from "effect";
2
2
  import { sqlError as t } from "@voltro/database";
3
- //#region src/rowResultProjection.ts
3
+ // src/rowResultProjection.ts
4
4
  var n = (n, r) => e.gen(function* () {
5
5
  let e = yield* n`
6
6
  SELECT name, system_type_id FROM sys.columns
@@ -12,5 +12,4 @@ var n = (n, r) => e.gen(function* () {
12
12
  let r = e.literal(`[${t.name.replaceAll("]", "]]")}]`), i = n ? e`${e(n)}.${r}` : r;
13
13
  return t.system_type_id === 106 || t.system_type_id === 108 ? e`CONVERT(varchar(80), ${i}) AS ${r}` : i;
14
14
  }));
15
- //#endregion
16
15
  export { r as mssqlRowResultProjection, n as readMssqlPhysicalColumns };
package/dist/sqlLayer.js CHANGED
@@ -4,7 +4,7 @@ import { MssqlClient as n } from "@effect/sql-mssql";
4
4
  import { TYPES as r } from "tedious";
5
5
  import { Config as i, Duration as a, Redacted as o } from "effect";
6
6
  import { DEFAULT_ACQUIRE_TIMEOUT_MS as s, SHARED_TRANSACTION_SERVICE as c } from "@voltro/database";
7
- //#region src/sqlLayer.ts
7
+ // src/sqlLayer.ts
8
8
  var l = {
9
9
  ...n.defaultParameterTypes,
10
10
  null: r.NVarChar,
@@ -74,5 +74,4 @@ var l = {
74
74
  ...t
75
75
  };
76
76
  }, m = (e) => d(p(e));
77
- //#endregion
78
77
  export { n as MssqlClient, p as connectionFromConfig, d as makeMssqlSqlLayer, m as makeMssqlSqlLayerFromConfig, u as resolveAcquireTimeoutMs, f as sslFromUrlQuery };
package/dist/store.js CHANGED
@@ -2,53 +2,53 @@ import { writeOutput as e } from "./writeOutput.js";
2
2
  import { isDuplicateKeyMssqlFailure as t, isRetryableMssqlFailure as n } from "./retry.js";
3
3
  import { startChangeTrackingCdc as r } from "./changeTrackingCdc.js";
4
4
  import { CDC_OFFSETS_TABLE as i } from "./cdcOffsetsTable.js";
5
- import { Effect as a, Layer as o, ManagedRuntime as s, Option as c } from "effect";
6
- import { EagerCardinalityError as l, attachEagerLoads as u, attributionFields as d, bulkInsertLimitsFor as f, chunkRowsForInsert as p, compileEagerJson as m, compileJsonPatch as h, compilePredicate as g, compileRawFragment as _, compileSelect as v, decodeRowsFromSchema as y, decodeSelectRows as b, emitCommittedChanges as x, encodeRowForSchema as S, externalChangeEvent as C, hasEagerLoads as w, isTableReactive as T, jsonPatchAssignments as E, makeEagerFallbackReporter as D, makeTransactionAbortTracker as O, observeDbOp as k, onTransaction as A, qualifyTable as j, quoteIdent as M, raiseChangeListenerCeiling as N, recordsTable as P, requireTable as F, rowKeyColumns as I, runSavepoint as L, runStoreTransaction as R, runWriteRecorders as z, stampGeneratedId as B, stampGeneratedIds as V, upsertUpdatePatch as H, upsertUpdateValues as U, withCapturedAttribution as W, writeImagesObserved as G } from "@voltro/database";
7
- import { EventEmitter as K } from "node:events";
8
- import { createLogger as q } from "@voltro/logger";
9
- import { SqlClient as J } from "effect/sql/SqlClient";
10
- //#region src/store.ts
11
- var Y = q({ scope: "voltro:mssql" }), X = async (e) => {
5
+ import { Array as a, Effect as o, Layer as s, ManagedRuntime as c, Option as l } from "effect";
6
+ import { EagerCardinalityError as u, attachEagerLoads as d, attributionFields as f, bulkInsertLimitsFor as p, chunkRowsForInsert as m, compileEagerJson as h, compileJsonPatch as g, compilePredicate as _, compileRawFragment as v, compileSelect as y, decodeRowsFromSchema as b, decodeSelectRows as x, emitCommittedChanges as S, encodeRowForSchema as C, externalChangeEvent as w, hasEagerLoads as T, isTableReactive as E, jsonPatchAssignments as D, makeEagerFallbackReporter as O, makeTransactionAbortTracker as k, observeDbOp as A, onTransaction as j, qualifyTable as M, quoteIdent as N, raiseChangeListenerCeiling as P, recordsTable as F, requireTable as I, rowKeyColumns as L, runSavepoint as R, runStoreTransaction as z, runWriteRecorders as B, stampGeneratedId as V, stampGeneratedIds as H, upsertUpdatePatch as U, upsertUpdateValues as W, withCapturedAttribution as G, writeImagesObserved as K } from "@voltro/database";
7
+ import { EventEmitter as q } from "node:events";
8
+ import { createLogger as J } from "@voltro/logger";
9
+ import { SqlClient as Y } from "effect/sql/SqlClient";
10
+ // src/store.ts
11
+ var X = J({ scope: "voltro:mssql" }), Z = async (e) => {
12
12
  let t = e.changeStrategy ?? "inline", n = t;
13
- t === "cdc" && !e.cdcConfig && (Y.warn("changeStrategy='cdc' requires cdcConfig (replicaId + includeTables); falling back to 'inline'."), n = "inline");
14
- let r = e.tracerLayer ? o.mergeAll(e.sqlLayer, e.tracerLayer) : e.sqlLayer, i = s.make(r), a = new Z(await i.runPromise(J), i, n);
13
+ t === "cdc" && !e.cdcConfig && (X.warn("changeStrategy='cdc' requires cdcConfig (replicaId + includeTables); falling back to 'inline'."), n = "inline");
14
+ let r = e.tracerLayer ? s.mergeAll(e.sqlLayer, e.tracerLayer) : e.sqlLayer, i = c.make(r), a = new Q(await i.runPromise(Y), i, n);
15
15
  return n === "cdc" && e.cdcConfig && await a.startCdcConsumer(e.cdcConfig), a;
16
- }, Z = class o {
16
+ }, Q = class s {
17
17
  sql;
18
18
  runtime;
19
19
  changeStrategy;
20
20
  namespace;
21
21
  emitter;
22
22
  inflightTxns = 0;
23
- reportEagerFallback = D(Y);
23
+ reportEagerFallback = O(X);
24
24
  cdcHandle = null;
25
25
  cdcCheckpointTimer = null;
26
26
  cdcPendingVersion = null;
27
27
  cdcReplicaId = "";
28
28
  cdcStreamName = "default";
29
29
  constructor(e, t, n = "inline", r = null, i) {
30
- this.sql = e, this.runtime = t, this.changeStrategy = n, this.namespace = r, this.emitter = i ?? new K(), N(this.emitter);
30
+ this.sql = e, this.runtime = t, this.changeStrategy = n, this.namespace = r, this.emitter = i ?? new q(), P(this.emitter);
31
31
  }
32
32
  get inlineEmit() {
33
33
  return this.changeStrategy === "inline";
34
34
  }
35
35
  withNamespace(e) {
36
- return e === this.namespace ? this : new o(this.sql, this.runtime, this.changeStrategy, e, this.emitter);
36
+ return e === this.namespace ? this : new s(this.sql, this.runtime, this.changeStrategy, e, this.emitter);
37
37
  }
38
38
  nsT(e) {
39
- return j(this.namespace, e);
39
+ return M(this.namespace, e);
40
40
  }
41
41
  __mssqlReplicationFriend = { runEffect: (e) => this.runtime.runPromise(e) };
42
42
  async executeQuery(e, t) {
43
- let n = v(e, this.sql, this.namespace), r = t ? a.provideService(n, this.sql.transactionService, t) : n, i = await k("mssql", "select", () => this.runtime.runPromise(r));
44
- return b(i, e, "mssql");
43
+ let n = y(e, this.sql, this.namespace), r = t ? o.provideService(n, this.sql.transactionService, t) : n, i = await A("mssql", "select", () => this.runtime.runPromise(r));
44
+ return x(i, e, "mssql");
45
45
  }
46
46
  decodeWritten(e, t) {
47
- return y([t], e, "mssql")[0] ?? t;
47
+ return b([t], e, "mssql")[0] ?? t;
48
48
  }
49
- async executeInsert(t, n, r, i, o) {
50
- n = B(t, n);
51
- let s = this.sql, c = e(s, this.nsT(t), (e) => s`INSERT INTO ${s(this.nsT(t))} ${s.insert(S(n, t)).returning(s`INSERTED.* INTO ${e}`)}`), l = r ? a.provideService(c, this.sql.transactionService, r) : c, u = (await this.runtime.runPromise(l))[0];
49
+ async executeInsert(t, n, r, i, a) {
50
+ n = V(t, n);
51
+ let s = this.sql, c = e(s, this.nsT(t), (e) => s`INSERT INTO ${s(this.nsT(t))} ${s.insert(C(n, t)).returning(s`INSERTED.* INTO ${e}`)}`), l = r ? o.provideService(c, this.sql.transactionService, r) : c, u = (await this.runtime.runPromise(l))[0];
52
52
  if (!u) throw Error(`MssqlStore.insert: row not returned post-insert in '${t}'`);
53
53
  let d = this.decodeWritten(t, u);
54
54
  return await this.routeEvent({
@@ -56,10 +56,10 @@ var Y = q({ scope: "voltro:mssql" }), X = async (e) => {
56
56
  op: "insert",
57
57
  old: null,
58
58
  new: d
59
- }, i, r, o), d;
59
+ }, i, r, a), d;
60
60
  }
61
- async executeUpdate(t, n, r, i, o, s) {
62
- let c = this.sql, l = e(c, this.nsT(t), (e) => c`UPDATE ${c(this.nsT(t))} SET ${c.update(S(r, t)).returning(c`INSERTED.* INTO ${e}`)} WHERE ${c.and(I(n).map(([e, t]) => c`${c(e)} = ${t}`))}`), u = i ? a.provideService(l, this.sql.transactionService, i) : l, d = (await this.runtime.runPromise(u))[0];
61
+ async executeUpdate(t, n, r, i, a, s) {
62
+ let c = this.sql, l = e(c, this.nsT(t), (e) => c`UPDATE ${c(this.nsT(t))} SET ${c.update(C(r, t)).returning(c`INSERTED.* INTO ${e}`)} WHERE ${c.and(L(n).map(([e, t]) => c`${c(e)} = ${t}`))}`), u = i ? o.provideService(l, this.sql.transactionService, i) : l, d = (await this.runtime.runPromise(u))[0];
63
63
  if (!d) return null;
64
64
  let f = this.decodeWritten(t, d);
65
65
  return await this.routeEvent({
@@ -67,45 +67,45 @@ var Y = q({ scope: "voltro:mssql" }), X = async (e) => {
67
67
  op: "update",
68
68
  old: null,
69
69
  new: f
70
- }, o, i, s), f;
71
- }
72
- async executeInsertMany(t, n, r, i, o, s) {
73
- if (n = V(t, n), n.length === 0) return [];
74
- let c = this.sql, l = p(n, f("mssql")), u = s?.returning === "none", d = u && !G(t), m = (n) => {
75
- let r = c.insert(n.map((e) => S(e, t)));
76
- return d ? a.as(c`INSERT INTO ${c(this.nsT(t))} ${r}`, []) : e(c, this.nsT(t), (e) => c`INSERT INTO ${c(this.nsT(t))} ${r.returning(c`INSERTED.* INTO ${e}`)}`);
77
- }, h;
78
- if (l.length === 1) {
79
- let e = m(l[0]), t = r ? a.provideService(e, this.sql.transactionService, r) : e;
80
- h = await this.runtime.runPromise(t);
70
+ }, a, i, s), f;
71
+ }
72
+ async executeInsertMany(t, n, r, i, s, c) {
73
+ if (n = H(t, n), n.length === 0) return [];
74
+ let l = this.sql, u = m(n, p("mssql")), d = c?.returning === "none", f = d && !K(t), h = (n) => {
75
+ let r = l.insert(a.map(n, (e) => C(e, t)));
76
+ return f ? o.as(l`INSERT INTO ${l(this.nsT(t))} ${r}`, []) : e(l, this.nsT(t), (e) => l`INSERT INTO ${l(this.nsT(t))} ${r.returning(l`INSERTED.* INTO ${e}`)}`);
77
+ }, g;
78
+ if (u.length === 1) {
79
+ let e = h(u[0]), t = r ? o.provideService(e, this.sql.transactionService, r) : e;
80
+ g = await this.runtime.runPromise(t);
81
81
  } else if (r) {
82
82
  let e = [];
83
- for (let t of l) e.push(...await this.runtime.runPromise(a.provideService(m(t), this.sql.transactionService, r)));
84
- h = e;
85
- } else h = await this.runtime.runPromise(c.withTransaction(a.map(a.forEach(l, m, { concurrency: 1 }), (e) => e.flat())));
86
- if (d) return [];
87
- let g = n.map((e) => e.id), _ = y(h, t, "mssql"), v = new Map(_.map((e) => [e.id, e])), b = g.map((e) => v.get(e)).filter((e) => e !== void 0), x = b.length === h.length ? b : _;
88
- for (let e of x) await this.routeEvent({
83
+ for (let t of u) e.push(...await this.runtime.runPromise(o.provideService(h(t), this.sql.transactionService, r)));
84
+ g = e;
85
+ } else g = await this.runtime.runPromise(l.withTransaction(o.map(o.forEach(u, h, { concurrency: 1 }), (e) => e.flat())));
86
+ if (f) return [];
87
+ let _ = n.map((e) => e.id), v = b(g, t, "mssql"), y = new Map(v.map((e) => [e.id, e])), x = _.map((e) => y.get(e)).filter((e) => e !== void 0), S = x.length === g.length ? x : v;
88
+ for (let e of S) await this.routeEvent({
89
89
  table: t,
90
90
  op: "insert",
91
91
  old: null,
92
92
  new: e
93
- }, i, r, o);
94
- return u ? [] : x;
93
+ }, i, r, s);
94
+ return d ? [] : S;
95
95
  }
96
- async executePatchJson(t, n, r, i, o, s, c, l) {
97
- let u = this.sql, d = S(E(n, r, l), t), f = u.csv([h(u, "mssql", r, i), ...Object.entries(d).map(([e, t]) => u`${u(e)} = ${t}`)]), p = e(u, this.nsT(t), (e) => u`UPDATE ${u(this.nsT(t))} SET ${f} OUTPUT INSERTED.* INTO ${e} WHERE ${u.and(I(n).map(([e, t]) => u`${u(e)} = ${t}`))}`), m = o ? a.provideService(p, this.sql.transactionService, o) : p, g = (await this.runtime.runPromise(m))[0];
98
- if (!g) return null;
99
- let _ = this.decodeWritten(t, g);
96
+ async executePatchJson(t, n, r, i, a, s, c, l) {
97
+ let u = this.sql, d = C(D(n, r, l), t), f = u.csv([g(u, "mssql", r, i), ...Object.entries(d).map(([e, t]) => u`${u(e)} = ${t}`)]), p = e(u, this.nsT(t), (e) => u`UPDATE ${u(this.nsT(t))} SET ${f} OUTPUT INSERTED.* INTO ${e} WHERE ${u.and(L(n).map(([e, t]) => u`${u(e)} = ${t}`))}`), m = a ? o.provideService(p, this.sql.transactionService, a) : p, h = (await this.runtime.runPromise(m))[0];
98
+ if (!h) return null;
99
+ let _ = this.decodeWritten(t, h);
100
100
  return await this.routeEvent({
101
101
  table: t,
102
102
  op: "update",
103
103
  old: null,
104
104
  new: _
105
- }, s, o, c), _;
105
+ }, s, a, c), _;
106
106
  }
107
- async executeDelete(t, n, r, i, o) {
108
- let s = this.sql, c = e(s, this.nsT(t), (e) => s`DELETE FROM ${s(this.nsT(t))} OUTPUT DELETED.* INTO ${e} WHERE ${s.and(I(n).map(([e, t]) => s`${s(e)} = ${t}`))}`), l = r ? a.provideService(c, this.sql.transactionService, r) : c, u = (await this.runtime.runPromise(l))[0];
107
+ async executeDelete(t, n, r, i, a) {
108
+ let s = this.sql, c = e(s, this.nsT(t), (e) => s`DELETE FROM ${s(this.nsT(t))} OUTPUT DELETED.* INTO ${e} WHERE ${s.and(L(n).map(([e, t]) => s`${s(e)} = ${t}`))}`), l = r ? o.provideService(c, this.sql.transactionService, r) : c, u = (await this.runtime.runPromise(l))[0];
109
109
  if (!u) return !1;
110
110
  let d = this.decodeWritten(t, u);
111
111
  return await this.routeEvent({
@@ -113,21 +113,21 @@ var Y = q({ scope: "voltro:mssql" }), X = async (e) => {
113
113
  op: "delete",
114
114
  old: d,
115
115
  new: null
116
- }, i, r, o), !0;
116
+ }, i, r, a), !0;
117
117
  }
118
118
  async appendInTxn(e, t, n) {
119
- let r = this.sql, i = r`INSERT INTO ${r(this.nsT(e))} ${r.insert(S(t, e))}`;
120
- await this.runtime.runPromise(n ? a.provideService(i, this.sql.transactionService, n) : i);
119
+ let r = this.sql, i = r`INSERT INTO ${r(this.nsT(e))} ${r.insert(C(t, e))}`;
120
+ await this.runtime.runPromise(n ? o.provideService(i, this.sql.transactionService, n) : i);
121
121
  }
122
122
  async maxInTxn(e, t, n, r) {
123
- let i = this.sql, o = Object.entries(n).map(([e, t]) => i`${i(e)} = ${t}`), s = i`SELECT MAX(${i(t)}) AS ${i("m")} FROM ${i(this.nsT(e))} WHERE ${i.and(o)}`, c = (await this.runtime.runPromise(r ? a.provideService(s, this.sql.transactionService, r) : s))[0]?.m;
123
+ let i = this.sql, a = Object.entries(n).map(([e, t]) => i`${i(e)} = ${t}`), s = i`SELECT MAX(${i(t)}) AS ${i("m")} FROM ${i(this.nsT(e))} WHERE ${i.and(a)}`, c = (await this.runtime.runPromise(r ? o.provideService(s, this.sql.transactionService, r) : s))[0]?.m;
124
124
  return c == null ? null : Number(c);
125
125
  }
126
126
  async routeEvent(e, t, n = null, r) {
127
127
  e = {
128
- ...d(r),
128
+ ...f(r),
129
129
  ...e
130
- }, P(e.table) && await z({
130
+ }, F(e.table) && await B({
131
131
  append: (e, t) => this.appendInTxn(e, t, n),
132
132
  maxOf: (e, t, r) => this.maxInTxn(e, t, r, n)
133
133
  }, {
@@ -137,7 +137,7 @@ var Y = q({ scope: "voltro:mssql" }), X = async (e) => {
137
137
  prev: e.old,
138
138
  traceId: e.traceId,
139
139
  subjectId: e.subjectId
140
- }), T(e.table) && (t === null ? this.inlineEmit && this.emitter.emit("change", e) : t.push(e));
140
+ }), E(e.table) && (t === null ? this.inlineEmit && this.emitter.emit("change", e) : t.push(e));
141
141
  }
142
142
  integrityQuery(e) {
143
143
  return this.query(e);
@@ -149,17 +149,17 @@ var Y = q({ scope: "voltro:mssql" }), X = async (e) => {
149
149
  return this.rawOn(e, null);
150
150
  }
151
151
  rawOn(e, t) {
152
- let n = _(e, this.sql), r = t ? a.provideService(n, this.sql.transactionService, t) : n;
153
- return k("mssql", "raw", () => this.runtime.runPromise(r));
152
+ let n = v(e, this.sql), r = t ? o.provideService(n, this.sql.transactionService, t) : n;
153
+ return A("mssql", "raw", () => this.runtime.runPromise(r));
154
154
  }
155
155
  async runWithEager(e, t) {
156
- if (!w(e)) return this.executeQuery(e, t);
157
- let n = this.namespace === null ? m(e, this.sql, "mssql") : null;
156
+ if (!T(e)) return this.executeQuery(e, t);
157
+ let n = this.namespace === null ? h(e, this.sql, "mssql") : null;
158
158
  if (n !== null) try {
159
- let e = t ? a.provideService(n.fragment, this.sql.transactionService, t) : n.fragment, r = await k("mssql", "select", () => this.runtime.runPromise(e));
159
+ let e = t ? o.provideService(n.fragment, this.sql.transactionService, t) : n.fragment, r = await A("mssql", "select", () => this.runtime.runPromise(e));
160
160
  return n.decode(r);
161
161
  } catch (t) {
162
- if (t instanceof l) throw t;
162
+ if (t instanceof u) throw t;
163
163
  this.reportEagerFallback({
164
164
  dialect: "mssql",
165
165
  table: e.table,
@@ -173,21 +173,21 @@ var Y = q({ scope: "voltro:mssql" }), X = async (e) => {
173
173
  reason: "not-compilable"
174
174
  });
175
175
  let r = await this.executeQuery(e, t);
176
- return u(r, e.eager, e.sourceTable ?? F(e.table), (e) => this.executeQuery(e, t));
176
+ return d(r, e.eager, e.sourceTable ?? I(e.table), (e) => this.executeQuery(e, t));
177
177
  }
178
178
  getInternalRunWithEager() {
179
179
  return this.runWithEager.bind(this);
180
180
  }
181
181
  localWrite(e, t, n) {
182
- let r = (e) => P(t) ? this.writeWithRecorders(n, e) : n(e, null, null);
183
- return k("mssql", e, () => W(r));
182
+ let r = (e) => F(t) ? this.writeWithRecorders(n, e) : n(e, null, null);
183
+ return A("mssql", e, () => G(r));
184
184
  }
185
185
  async writeWithRecorders(e, t) {
186
- let n = [], r = this.sql, i = await this.runtime.runPromise(r.withTransaction(a.flatMap(a.serviceOption(this.sql.transactionService), (r) => c.isNone(r) ? a.fail(/* @__PURE__ */ Error("MssqlStore.write: TransactionConnection missing.")) : a.tryPromise({
186
+ let n = [], r = this.sql, i = await this.runtime.runPromise(r.withTransaction(o.flatMap(o.serviceOption(this.sql.transactionService), (r) => l.isNone(r) ? o.fail(/* @__PURE__ */ Error("MssqlStore.write: TransactionConnection missing.")) : o.tryPromise({
187
187
  try: () => e(t, r.value, n),
188
188
  catch: (e) => e
189
189
  }))));
190
- return x(n, (e) => this.emitChange(e)), i;
190
+ return S(n, (e) => this.emitChange(e)), i;
191
191
  }
192
192
  insert(e, t) {
193
193
  return this.localWrite("insert", e, (n, r, i) => this.executeInsert(e, t, r, i, n));
@@ -210,32 +210,32 @@ var Y = q({ scope: "voltro:mssql" }), X = async (e) => {
210
210
  deleteMany(e, t) {
211
211
  return this.executeDeleteMany(e, t, null, null);
212
212
  }
213
- async executeUpdateMany(t, n, r, i, o, s) {
214
- let c = this.sql, l = g(r.where, c, this.namespace), u = c.update(S(n, t));
215
- if (!G(t)) return this.countWritten(c`UPDATE ${c(this.nsT(t))} SET ${u} WHERE ${l}`, "update", i);
216
- let d = e(c, this.nsT(t), (e) => c`UPDATE ${c(this.nsT(t))} SET ${u} OUTPUT INSERTED.* INTO ${e} WHERE ${l}`), f = i ? a.provideService(d, this.sql.transactionService, i) : d, p = await k("mssql", "update", () => this.runtime.runPromise(f));
217
- for (let e of y(p, t, "mssql")) await this.routeEvent({
213
+ async executeUpdateMany(t, n, r, i, a, s) {
214
+ let c = this.sql, l = _(r.where, c, this.namespace), u = c.update(C(n, t));
215
+ if (!K(t)) return this.countWritten(c`UPDATE ${c(this.nsT(t))} SET ${u} WHERE ${l}`, "update", i);
216
+ let d = e(c, this.nsT(t), (e) => c`UPDATE ${c(this.nsT(t))} SET ${u} OUTPUT INSERTED.* INTO ${e} WHERE ${l}`), f = i ? o.provideService(d, this.sql.transactionService, i) : d, p = await A("mssql", "update", () => this.runtime.runPromise(f));
217
+ for (let e of b(p, t, "mssql")) await this.routeEvent({
218
218
  table: t,
219
219
  op: "update",
220
220
  old: null,
221
221
  new: e
222
- }, o, i, s);
222
+ }, a, i, s);
223
223
  return p.length;
224
224
  }
225
225
  async countWritten(e, t, n) {
226
- let r = this.sql`${e}; SELECT @@ROWCOUNT AS n`, i = n ? a.provideService(r, this.sql.transactionService, n) : r, [o] = await k("mssql", t, () => this.runtime.runPromise(i));
227
- return Number(o?.n ?? 0);
228
- }
229
- async executeDeleteMany(t, n, r, i, o) {
230
- let s = this.sql, c = g(n.where, s, this.namespace);
231
- if (!G(t)) return this.countWritten(s`DELETE FROM ${s(this.nsT(t))} WHERE ${c}`, "delete", r);
232
- let l = e(s, this.nsT(t), (e) => s`DELETE FROM ${s(this.nsT(t))} OUTPUT DELETED.* INTO ${e} WHERE ${c}`), u = r ? a.provideService(l, this.sql.transactionService, r) : l, d = await k("mssql", "delete", () => this.runtime.runPromise(u));
233
- for (let e of y(d, t, "mssql")) await this.routeEvent({
226
+ let r = (0, this.sql)`${e}; SELECT @@ROWCOUNT AS n`, i = n ? o.provideService(r, this.sql.transactionService, n) : r, [a] = await A("mssql", t, () => this.runtime.runPromise(i));
227
+ return Number(a?.n ?? 0);
228
+ }
229
+ async executeDeleteMany(t, n, r, i, a) {
230
+ let s = this.sql, c = _(n.where, s, this.namespace);
231
+ if (!K(t)) return this.countWritten(s`DELETE FROM ${s(this.nsT(t))} WHERE ${c}`, "delete", r);
232
+ let l = e(s, this.nsT(t), (e) => s`DELETE FROM ${s(this.nsT(t))} OUTPUT DELETED.* INTO ${e} WHERE ${c}`), u = r ? o.provideService(l, this.sql.transactionService, r) : l, d = await A("mssql", "delete", () => this.runtime.runPromise(u));
233
+ for (let e of b(d, t, "mssql")) await this.routeEvent({
234
234
  table: t,
235
235
  op: "delete",
236
236
  old: e,
237
237
  new: null
238
- }, i, r, o);
238
+ }, i, r, a);
239
239
  return d.length;
240
240
  }
241
241
  upsert(e, t, n) {
@@ -248,24 +248,24 @@ var Y = q({ scope: "voltro:mssql" }), X = async (e) => {
248
248
  return this.localWrite("upsert", e, (r, i, a) => this.executeInsertIgnore(e, t, n, i, a, r));
249
249
  }
250
250
  async executeUpsert(e, n, r, i, a, o) {
251
- if (U(r), n = B(e, n), typeof r.update != "function" && r.conflictColumns.length > 0) return this.mergeUpsert(e, n, {
251
+ if (W(r), n = V(e, n), typeof r.update != "function" && r.conflictColumns.length > 0) return this.mergeUpsert(e, n, {
252
252
  conflictColumns: r.conflictColumns,
253
253
  ...r.update === void 0 ? {} : { update: r.update },
254
254
  ...r.updateValues === void 0 ? {} : { updateValues: r.updateValues }
255
255
  }, i, a, o);
256
256
  let s = await this.findByConflict(e, n, r.conflictColumns, i);
257
- if (s) return await this.executeUpdate(e, Object.fromEntries(r.conflictColumns.map((e) => [e, s[e]])), H(n, s, r), i, a, o) ?? s;
257
+ if (s) return await this.executeUpdate(e, Object.fromEntries(r.conflictColumns.map((e) => [e, s[e]])), U(n, s, r), i, a, o) ?? s;
258
258
  try {
259
259
  return await this.executeInsert(e, n, i, a, o);
260
260
  } catch (s) {
261
261
  if (!t(s)) throw s;
262
262
  let c = await this.findByConflict(e, n, r.conflictColumns, i);
263
263
  if (!c) throw s;
264
- return await this.executeUpdate(e, Object.fromEntries(r.conflictColumns.map((e) => [e, c[e]])), H(n, c, r), i, a, o) ?? c;
264
+ return await this.executeUpdate(e, Object.fromEntries(r.conflictColumns.map((e) => [e, c[e]])), U(n, c, r), i, a, o) ?? c;
265
265
  }
266
266
  }
267
- async mergeUpsert(t, n, r, i, o, s) {
268
- let c = this.sql, l = Object.keys(n), u = Array.isArray(r.update) ? r.update.filter((e) => l.includes(e)) : l.filter((e) => e !== "id" && !r.conflictColumns.includes(e)), d = S(n, t), f = l.map((e) => c`${d[e]}`), p = l.map((e) => c`${c(e)}`), m = r.conflictColumns.map((e) => c`tgt.${c(e)} = src.${c(e)}`), h = l.map((e) => c`${c(e)}`), g = l.map((e) => c`src.${c(e)}`), _ = U(r), v = S(_, t), y = [...u.filter((e) => !Object.hasOwn(_, e)).map((e) => c`tgt.${c(e)} = src.${c(e)}`), ...Object.entries(v).map(([e, t]) => c`tgt.${c(e)} = ${t}`)];
267
+ async mergeUpsert(t, n, r, i, a, s) {
268
+ let c = this.sql, l = Object.keys(n), u = Array.isArray(r.update) ? r.update.filter((e) => l.includes(e)) : l.filter((e) => e !== "id" && !r.conflictColumns.includes(e)), d = C(n, t), f = l.map((e) => c`${d[e]}`), p = l.map((e) => c`${c(e)}`), m = r.conflictColumns.map((e) => c`tgt.${c(e)} = src.${c(e)}`), h = l.map((e) => c`${c(e)}`), g = l.map((e) => c`src.${c(e)}`), _ = W(r), v = C(_, t), y = [...u.filter((e) => !Object.hasOwn(_, e)).map((e) => c`tgt.${c(e)} = src.${c(e)}`), ...Object.entries(v).map(([e, t]) => c`tgt.${c(e)} = ${t}`)];
269
269
  y.length === 0 && y.push(c`tgt.${c(r.conflictColumns[0])} = src.${c(r.conflictColumns[0])}`);
270
270
  let b = e(c, this.nsT(t), (e) => c`
271
271
  MERGE ${c(this.nsT(t))} WITH (HOLDLOCK) AS tgt
@@ -273,18 +273,18 @@ var Y = q({ scope: "voltro:mssql" }), X = async (e) => {
273
273
  ON ${c.and(m)}
274
274
  WHEN MATCHED THEN UPDATE SET ${c.csv(y)}
275
275
  WHEN NOT MATCHED THEN INSERT (${c.csv(h)}) VALUES (${c.csv(g)})
276
- OUTPUT $action AS ${c("__action")}, INSERTED.* INTO ${e};`, !0), x = i ? a.provideService(b, this.sql.transactionService, i) : b, C = (await this.runtime.runPromise(x))[0];
277
- if (!C) throw Error(`MssqlStore.upsert: MERGE returned no row for '${t}'`);
278
- let w = C.__action, { __action: T, ...E } = C, D = this.decodeWritten(t, E);
276
+ OUTPUT $action AS ${c("__action")}, INSERTED.* INTO ${e};`, !0), x = i ? o.provideService(b, this.sql.transactionService, i) : b, S = (await this.runtime.runPromise(x))[0];
277
+ if (!S) throw Error(`MssqlStore.upsert: MERGE returned no row for '${t}'`);
278
+ let w = S.__action, { __action: T, ...E } = S, D = this.decodeWritten(t, E);
279
279
  return await this.routeEvent({
280
280
  table: t,
281
281
  op: w === "INSERT" ? "insert" : "update",
282
282
  old: null,
283
283
  new: D
284
- }, o, i, s), D;
284
+ }, a, i, s), D;
285
285
  }
286
286
  async executeInsertIgnore(e, n, r, i, a, o) {
287
- n = B(e, n);
287
+ n = V(e, n);
288
288
  let s = await this.findByConflict(e, n, r.conflictColumns, i);
289
289
  if (s) return {
290
290
  row: s,
@@ -307,7 +307,7 @@ var Y = q({ scope: "voltro:mssql" }), X = async (e) => {
307
307
  }
308
308
  async findByConflict(e, t, n, r) {
309
309
  if (n.length === 0) return;
310
- let i = this.sql, o = n.map((e) => i`${i(e)} = ${t[e]}`), s = i`SELECT TOP 1 * FROM ${i(this.nsT(e))} WHERE ${i.and(o)}`, c = r ? a.provideService(s, this.sql.transactionService, r) : s, l = (await this.runtime.runPromise(c))[0];
310
+ let i = this.sql, a = n.map((e) => i`${i(e)} = ${t[e]}`), s = i`SELECT TOP 1 * FROM ${i(this.nsT(e))} WHERE ${i.and(a)}`, c = r ? o.provideService(s, this.sql.transactionService, r) : s, l = (await this.runtime.runPromise(c))[0];
311
311
  return l ? this.decodeWritten(e, l) : void 0;
312
312
  }
313
313
  emitChange(e) {
@@ -317,7 +317,7 @@ var Y = q({ scope: "voltro:mssql" }), X = async (e) => {
317
317
  if (this.cdcHandle) return;
318
318
  this.cdcReplicaId = e.replicaId;
319
319
  let t = e.includeTables ?? [];
320
- t.length === 0 && Y.warn("cdc: no reactive tables to tail; Change Tracking reader idle. Set includeTables to enable.");
320
+ t.length === 0 && X.warn("cdc: no reactive tables to tail; Change Tracking reader idle. Set includeTables to enable.");
321
321
  let n = await this.readCdcOffset(e.replicaId);
322
322
  this.cdcHandle = await r({
323
323
  run: this.__mssqlReplicationFriend.runEffect,
@@ -327,9 +327,9 @@ var Y = q({ scope: "voltro:mssql" }), X = async (e) => {
327
327
  onVersion: (e) => {
328
328
  this.cdcPendingVersion = e;
329
329
  },
330
- onError: (e) => Y.warn("cdc: consumer error", {}, e),
330
+ onError: (e) => X.warn("cdc: consumer error", {}, e),
331
331
  onResync: () => {
332
- Y.warn("cdc: resynced to current CT version after retention gap — subscriptions self-heal on the next change");
332
+ X.warn("cdc: resynced to current CT version after retention gap — subscriptions self-heal on the next change");
333
333
  }
334
334
  }), this.cdcCheckpointTimer = setInterval(() => {
335
335
  this.flushCdcOffset();
@@ -340,12 +340,12 @@ var Y = q({ scope: "voltro:mssql" }), X = async (e) => {
340
340
  let t = this.sql, n = (await this.runtime.runPromise(t`
341
341
  SELECT TOP 1 ${t("ctVersion")} FROM ${t(i)}
342
342
  WHERE ${t("id")} = ${e}`))[0]?.ctVersion;
343
- return n ? (Y.info("cdc: resuming from persisted CT version", {
343
+ return n ? (X.info("cdc: resuming from persisted CT version", {
344
344
  replicaId: e,
345
345
  version: n
346
346
  }), n) : null;
347
347
  } catch (t) {
348
- return Y.warn("cdc: no readable offset; starting at current CT version", { replicaId: e }, t), null;
348
+ return X.warn("cdc: no readable offset; starting at current CT version", { replicaId: e }, t), null;
349
349
  }
350
350
  }
351
351
  async flushCdcOffset() {
@@ -365,7 +365,7 @@ var Y = q({ scope: "voltro:mssql" }), X = async (e) => {
365
365
  update: ["ctVersion", "updatedAt"]
366
366
  }, null, null);
367
367
  } catch (t) {
368
- this.cdcPendingVersion = e, Y.warn("cdc: checkpoint write failed", {}, t);
368
+ this.cdcPendingVersion = e, X.warn("cdc: checkpoint write failed", {}, t);
369
369
  }
370
370
  }
371
371
  }
@@ -420,16 +420,16 @@ var Y = q({ scope: "voltro:mssql" }), X = async (e) => {
420
420
  }
421
421
  async emptyTablesOn(e, t) {
422
422
  if (e.length === 0) return;
423
- let n = this.sql, r = (e) => this.nsT(e), i = (e, t) => n.unsafe(`ALTER TABLE ${M(r(e), "mssql")} ${t ? "WITH CHECK CHECK" : "NOCHECK"} CONSTRAINT ALL`), o = a.acquireUseRelease(a.forEach(e, (e) => i(e, !1), { discard: !0 }), () => a.forEach(e, (e) => n`DELETE FROM ${n(r(e))}`, { discard: !0 }), () => a.orDie(a.ignore(a.forEach(e, (e) => i(e, !0), { discard: !0 })))), s = t === null ? n.withTransaction(o) : a.provideService(o, this.sql.transactionService, t);
423
+ let n = this.sql, r = (e) => this.nsT(e), i = (e, t) => n.unsafe(`ALTER TABLE ${N(r(e), "mssql")} ${t ? "WITH CHECK CHECK" : "NOCHECK"} CONSTRAINT ALL`), a = o.acquireUseRelease(o.forEach(e, (e) => i(e, !1), { discard: !0 }), () => o.forEach(e, (e) => n`DELETE FROM ${n(r(e))}`, { discard: !0 }), () => o.orDie(o.ignore(o.forEach(e, (e) => i(e, !0), { discard: !0 })))), s = t === null ? n.withTransaction(a) : o.provideService(a, this.sql.transactionService, t);
424
424
  await this.runtime.runPromise(s);
425
425
  }
426
426
  async transactional(e) {
427
427
  this.inflightTxns++;
428
428
  try {
429
- return await R({
429
+ return await z({
430
430
  ...this.txnSpec("MssqlStore.transactional"),
431
431
  work: e,
432
- makeView: (e, t) => new Q(this, e, t)
432
+ makeView: (e, t) => new $(this, e, t)
433
433
  });
434
434
  } finally {
435
435
  this.inflightTxns--;
@@ -464,7 +464,7 @@ var Y = q({ scope: "voltro:mssql" }), X = async (e) => {
464
464
  return this.changeStrategy === "cdc" ? "fleet" : "local";
465
465
  }
466
466
  injectExternalChange(e) {
467
- T(e.table) && this.emitter.emit("change", C(e));
467
+ E(e.table) && this.emitter.emit("change", w(e));
468
468
  }
469
469
  run(e) {
470
470
  return this.runtime.runPromise(e);
@@ -477,7 +477,7 @@ var Y = q({ scope: "voltro:mssql" }), X = async (e) => {
477
477
  if (this.inflightTxns > 0) {
478
478
  let t = Date.now() + e;
479
479
  for (; this.inflightTxns > 0 && Date.now() < t;) await new Promise((e) => setTimeout(e, 25));
480
- this.inflightTxns > 0 && Y.warn("close: grace period expired with in-flight transactions", {
480
+ this.inflightTxns > 0 && X.warn("close: grace period expired with in-flight transactions", {
481
481
  gracePeriodMs: e,
482
482
  inflight: this.inflightTxns
483
483
  });
@@ -487,12 +487,12 @@ var Y = q({ scope: "voltro:mssql" }), X = async (e) => {
487
487
  async ping() {
488
488
  await this.runtime.runPromise(this.sql`SELECT 1`);
489
489
  }
490
- }, Q = class {
490
+ }, $ = class {
491
491
  parent;
492
492
  txn;
493
493
  attr;
494
494
  events = [];
495
- aborts = O((e) => n(e));
495
+ aborts = k((e) => n(e));
496
496
  committed = !1;
497
497
  constructor(e, t, n = void 0) {
498
498
  this.parent = e, this.txn = t, this.attr = n;
@@ -500,11 +500,11 @@ var Y = q({ scope: "voltro:mssql" }), X = async (e) => {
500
500
  async savepoint(e) {
501
501
  let t = this.events.length;
502
502
  try {
503
- return await L({
503
+ return await R({
504
504
  tracker: this.aborts,
505
505
  name: `voltro_sp_${++this.savepointCounter}`,
506
506
  spelling: "mssql",
507
- exec: (e) => this.parent.run(a.provideService(J.pipe(a.flatMap((t) => t.unsafe(e))), this.parent.transactionService, this.txn))
507
+ exec: (e) => this.parent.run(o.provideService(Y.pipe(o.flatMap((t) => t.unsafe(e))), this.parent.transactionService, this.txn))
508
508
  }, e);
509
509
  } catch (e) {
510
510
  throw this.events.length = t, e;
@@ -512,7 +512,7 @@ var Y = q({ scope: "voltro:mssql" }), X = async (e) => {
512
512
  }
513
513
  savepointCounter = 0;
514
514
  run(e) {
515
- return this.aborts.track(() => this.parent.run(A(e, this.parent.transactionService, this.txn)));
515
+ return this.aborts.track(() => this.parent.run(j(e, this.parent.transactionService, this.txn)));
516
516
  }
517
517
  abortedBy() {
518
518
  return this.aborts.abortedBy();
@@ -569,8 +569,7 @@ var Y = q({ scope: "voltro:mssql" }), X = async (e) => {
569
569
  throw Error("MssqlTransactionalView.injectExternalChange: not supported inside a transaction.");
570
570
  }
571
571
  commitEvents() {
572
- this.committed || (this.committed = !0, x(this.events, (e) => this.parent.emitChange(e)), this.events.length = 0);
572
+ this.committed || (this.committed = !0, S(this.events, (e) => this.parent.emitChange(e)), this.events.length = 0);
573
573
  }
574
574
  };
575
- //#endregion
576
- export { Z as MssqlStore, X as makeMssqlStore };
575
+ export { Q as MssqlStore, Z as makeMssqlStore };
@@ -1,6 +1,6 @@
1
1
  import { mssqlRowResultProjection as e, readMssqlPhysicalColumns as t } from "./rowResultProjection.js";
2
2
  import { Effect as n } from "effect";
3
- //#region src/writeOutput.ts
3
+ // src/writeOutput.ts
4
4
  var r = (r, i, a, o = !1) => n.uninterruptible(n.gen(function* () {
5
5
  let n = r.literal("[#voltro_write_output]"), s = yield* t(r, i), c = r.join(", ", !1)(s.map((e) => {
6
6
  let t = r.literal(`[${e.name.replaceAll("]", "]]")}]`);
@@ -14,5 +14,4 @@ var r = (r, i, a, o = !1) => n.uninterruptible(n.gen(function* () {
14
14
  DROP TABLE ${n};
15
15
  `;
16
16
  }));
17
- //#endregion
18
17
  export { r as writeOutput };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voltro/sql-mssql",
3
- "version": "0.87.0",
3
+ "version": "0.88.0",
4
4
  "description": "SQL Server (mssql) dialect adapter for Voltro's cross-dialect DataStore (OUTPUT-clause returning, OFFSET/FETCH paging, inline reactivity).",
5
5
  "keywords": [
6
6
  "voltro",
@@ -33,13 +33,13 @@
33
33
  "node": ">=24.0.0"
34
34
  },
35
35
  "dependencies": {
36
- "@effect/sql-mssql": "4.0.1",
37
- "@voltro/database": "0.87.0",
38
- "@voltro/logger": "0.87.0",
39
- "tedious": "20.3.3"
36
+ "@effect/sql-mssql": "4.1.0",
37
+ "@voltro/database": "0.88.0",
38
+ "@voltro/logger": "0.88.0",
39
+ "tedious": "20.3.8"
40
40
  },
41
41
  "peerDependencies": {
42
- "effect": "4.0.1"
42
+ "effect": "4.1.0"
43
43
  },
44
44
  "publishConfig": {
45
45
  "access": "public"