@zio.dev/zio-blocks 0.0.27 → 0.0.28

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/scope.md CHANGED
@@ -1,4 +1,7 @@
1
- # ZIO Blocks — Scope (`zio.blocks.scope`)
1
+ ---
2
+ id: scope
3
+ title: "Scope"
4
+ ---
2
5
 
3
6
  `zio.blocks.scope` is a **compile-time safe, zero-cost** resource management library for **Scala 3** (and Scala 2.13). It prevents a large class of lifetime bugs by tagging allocated values with an *unnameable*, scope-specific type and restricting how those values may be used.
4
7
 
@@ -153,6 +156,58 @@ Scope.global.scoped { scope =>
153
156
  }
154
157
  ```
155
158
 
159
+ ##### N-ary `$`: accessing multiple scoped values at once
160
+
161
+ When a result depends on **two or more** scoped values simultaneously, use the N-ary overloads (`N = 2..5`):
162
+
163
+ ```scala
164
+ $(sa1, sa2)((v1, v2) => v1.method(v2.result()))
165
+ $(sa1, sa2, sa3)((v1, v2, v3) => v1.query(v2.key()) + v3.tag())
166
+ ```
167
+
168
+ The same receiver-only grammar applies to every parameter: each `vi` may only appear as a method receiver (e.g., `vi.method()`). Feeding the *result* of one parameter to a method of another is permitted:
169
+
170
+ ```scala
171
+ Scope.global.scoped { scope =>
172
+ import scope.*
173
+ val db: $[Database] = Resource.from[Database].allocate
174
+ val cache: $[Cache] = Resource.from[Cache].allocate
175
+
176
+ // d1 and d2 are both receivers; d2.key() produces a plain String arg
177
+ val result: String = $(db, cache)((d1, d2) => d1.query(d2.key()))
178
+ }
179
+ ```
180
+
181
+ Rejected at compile time (same rules as N=1, applied to each parameter independently):
182
+
183
+ ```scala
184
+ $(db, cache)((d1, d2) => d2) // d2 returned directly
185
+ $(db, cache)((d1, d2) => store(d1)) // d1 passed as argument
186
+ $(db, cache)((d1, d2) => d1.method(d2)) // d2 as bare arg (not a receiver)
187
+ $(db, cache)((d1, d2) => () => d2.query()) // d2 captured in closure
188
+ ```
189
+
190
+ The error messages name the offending parameter:
191
+
192
+ ```
193
+ Parameter 2 ('d2') cannot be passed as an argument to a function or method.
194
+ Scoped values may only be used as a method receiver (e.g., d2.method()).
195
+ ```
196
+
197
+ **Infix syntax** (`scope $ sa`) is only available for N=1. For N≥2, use unqualified syntax after `import scope.*`:
198
+
199
+ ```scala
200
+ $(db, cache)((d, c) => d.query(c.key())) // ✓ unqualified
201
+ ```
202
+
203
+ **For N>5**, extract each value in sequence (all results are `Unscoped` strings/values and can be freely combined):
204
+
205
+ ```scala
206
+ val q1 = $(db1)(_.query("a"))
207
+ val q2 = $(db2)(_.query("b"))
208
+ q1 + q2
209
+ ```
210
+
156
211
  ---
157
212
 
158
213
  ### 3) `Resource[A]`: acquisition + finalization
@@ -931,17 +986,33 @@ This module produces two kinds of compile-time feedback:
931
986
 
932
987
  ### Unsafe use inside `$`
933
988
 
934
- Typical messages include:
989
+ All messages name the offending parameter by its 1-based index and source name, and end with the receiver-only reminder. Typical messages:
935
990
 
936
991
  ```
937
- Unsafe use of scoped value: the lambda parameter cannot be passed as an argument to a function or method.
992
+ Parameter 1 ('d') cannot be passed as an argument to a function or method.
993
+ Scoped values may only be used as a method receiver (e.g., d.method()).
938
994
  ```
939
995
 
940
- Other variants:
996
+ ```
997
+ Parameter 1 ('d') must only be used as a method receiver.
998
+ It cannot be returned, stored, passed as an argument, or captured.
999
+ Scoped values may only be used as a method receiver (e.g., d.method()).
1000
+ ```
1001
+
1002
+ ```
1003
+ Parameter 1 ('d') cannot be captured in a nested lambda, def, or anonymous class.
1004
+ Scoped values may only be used as a method receiver (e.g., d.method()).
1005
+ ```
1006
+
1007
+ ```
1008
+ Parameter 2 ('cache') cannot be passed as an argument to a function or method.
1009
+ Scoped values may only be used as a method receiver (e.g., cache.method()).
1010
+ ```
941
1011
 
942
- - `Unsafe use of scoped value: the lambda parameter cannot be captured in a nested lambda or closure.`
943
- - `Unsafe use of scoped value: the lambda parameter must only be used as a method receiver ...`
944
- - `$ requires a lambda literal: (scope $ x)(a => a.method()). Method references and variables are not supported.`
1012
+ ```
1013
+ $ requires a lambda literal, e.g. $(x)(a => a.method()).
1014
+ Method references and variables are not supported.
1015
+ ```
945
1016
 
946
1017
  ### Not a class (`Wire.shared/unique` on a trait / abstract)
947
1018
 
@@ -1155,8 +1226,15 @@ def scoped[A](f: (child: Scope.Child[this.type]) => A)(using Unscoped[A]): A
1155
1226
  def allocate[A](resource: Resource[A]): $[A]
1156
1227
  def allocate[A <: AutoCloseable](value: => A): $[A]
1157
1228
 
1229
+ // N=1 (infix available: `scope $ sa`)
1158
1230
  infix transparent inline def $[A, B](sa: $[A])(inline f: A => B): B | $[B]
1159
1231
 
1232
+ // N=2..5 (unqualified syntax: `$(sa1, sa2)(f)` after `import scope.*`)
1233
+ transparent inline def $[A1, A2, B](sa1: $[A1], sa2: $[A2])(inline f: (A1, A2) => B): B | $[B]
1234
+ transparent inline def $[A1, A2, A3, B](sa1: $[A1], sa2: $[A2], sa3: $[A3])(inline f: (A1, A2, A3) => B): B | $[B]
1235
+ transparent inline def $[A1, A2, A3, A4, B](sa1: $[A1], sa2: $[A2], sa3: $[A3], sa4: $[A4])(inline f: (A1, A2, A3, A4) => B): B | $[B]
1236
+ transparent inline def $[A1, A2, A3, A4, A5, B](sa1: $[A1], sa2: $[A2], sa3: $[A3], sa4: $[A4], sa5: $[A5])(inline f: (A1, A2, A3, A4, A5) => B): B | $[B]
1237
+
1160
1238
  def lower[A](value: parent.$[A]): $[A]
1161
1239
 
1162
1240
  override def defer(f: => Unit): DeferHandle
@@ -1168,8 +1246,10 @@ inline def leak[A](inline sa: $[A]): A
1168
1246
 
1169
1247
  Notes:
1170
1248
 
1171
- - `$` requires a **lambda literal** and enforces safe receiver-only usage.
1249
+ - `$` (all arities) requires a **lambda literal** and enforces safe receiver-only usage at compile time.
1172
1250
  - `$` returns `B` if `Unscoped[B]` exists; otherwise returns `$[B]`.
1251
+ - N=1 is `infix`; N≥2 are not — use unqualified syntax after `import scope.*`.
1252
+ - For N>5, call `$` once per resource and combine the resulting plain (Unscoped) values.
1173
1253
  - If the scope is closed, `$`, `allocate`, and `open` throw `IllegalStateException` with a detailed error message. `defer` and `lower` are unaffected.
1174
1254
 
1175
1255
  Syntax enrichments available after `import scope.*` inside a scope:
@@ -1333,7 +1413,9 @@ object Unscoped:
1333
1413
  ## Practical guidance (summary)
1334
1414
 
1335
1415
  - Allocate in a scope: `resource.allocate` (inside `Scope.global.scoped { scope => import scope.* ... }`)
1336
- - Use scoped values only through: `(scope $ value)(...)`
1416
+ - Access one scoped value: `$(sa)(v => v.method())` — parameter can only be a receiver
1417
+ - Access two or more scoped values simultaneously: `$(sa1, sa2)((v1, v2) => v1.method(v2.result()))` (N=2..5)
1418
+ - For N>5: call `$` once per resource, combine the plain results
1337
1419
  - Return only `Unscoped` data from `scoped` blocks
1338
1420
  - Use `lower` to use parent values inside a child
1339
1421
  - If `$` returns `$[Resource[A]]`, call `.allocate` on it (scoped resource chaining)
package/sidebars.js CHANGED
@@ -7,13 +7,20 @@ const sidebars = {
7
7
  link: { type: "doc", id: "index" },
8
8
  items: [
9
9
  "reference/schema",
10
+ "reference/allows",
10
11
  "reference/reflect",
11
12
  "reference/binding",
13
+ "reference/binding-resolver",
12
14
  "reference/registers",
13
15
  "reference/typeid",
16
+ "reference/allows",
14
17
  "reference/modifier",
15
18
  "reference/dynamic-value",
19
+ "reference/dynamic-schema",
20
+ "reference/lazy",
21
+ "reference/structural-types",
16
22
  "reference/optics",
23
+ "reference/patch",
17
24
  "reference/schema-expr",
18
25
  "reference/dynamic-optic",
19
26
  "reference/type-class-derivation",
@@ -23,11 +30,22 @@ const sidebars = {
23
30
  "reference/chunk",
24
31
  "reference/schema-error",
25
32
  "reference/validation",
26
- "reference/schema-evolution",
33
+ {
34
+ type: "category",
35
+ label: "Schema Evolution",
36
+ link: { type: "doc", id: "reference/schema-evolution/index" },
37
+ items: [
38
+ "reference/schema-evolution/into",
39
+ "reference/schema-evolution/as",
40
+ ]
41
+ },
27
42
  "reference/context",
43
+ "scope",
28
44
  "reference/docs",
29
45
  "reference/json",
46
+ "reference/json-patch",
30
47
  "reference/json-schema",
48
+ "reference/xml",
31
49
  "reference/syntax",
32
50
  "reference/media-type",
33
51
  ]