@zio.dev/zio-blocks 0.0.26 → 0.0.27
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/guides/query-dsl-extending.md +1 -1
- package/guides/query-dsl-fluent-builder.md +1 -1
- package/guides/query-dsl-reified-optics.md +1 -1
- package/guides/query-dsl-sql.md +1 -1
- package/guides/zio-schema-migration.md +1195 -0
- package/index.md +14 -11
- package/package.json +1 -1
- package/reference/allows.md +352 -0
- package/reference/codec.md +10 -10
- package/reference/docs.md +1 -1
- package/reference/media-type.md +2 -2
- package/reference/modifier.md +9 -9
- package/reference/schema-error.md +569 -0
- package/reference/schema-expr.md +2 -2
- package/reference/schema.md +29 -0
- package/reference/type-class-derivation.md +329 -324
- package/reference/validation.md +1 -1
- package/reference/xml.md +743 -0
- package/scope.md +150 -8
- package/sidebars.js +2 -0
package/scope.md
CHANGED
|
@@ -417,16 +417,52 @@ A `scoped { ... }` block can only return pure data (or `Nothing`). Resources and
|
|
|
417
417
|
|
|
418
418
|
**Pragmatic safety.** The type-level tagging prevents *accidental* scope misuse in normal code, but it is not a security boundary. A determined developer can bypass it via `leak` (which emits a compiler warning), unsafe casts (`asInstanceOf`), or storing scoped references in mutable state (`var`).
|
|
419
419
|
|
|
420
|
-
### Closed-scope
|
|
420
|
+
### Closed-scope safety (runtime)
|
|
421
421
|
|
|
422
|
-
If a scope escapes and is
|
|
422
|
+
If a scope reference escapes its `scoped { }` block and an operation is attempted after closing, Scope throws `IllegalStateException` with a detailed, actionable error message:
|
|
423
423
|
|
|
424
|
-
-
|
|
425
|
-
- `$` does not run the lambda when closed
|
|
426
|
-
- `defer` on a closed scope is ignored
|
|
427
|
-
- `scoped` creates a born-closed child if the parent is already closed
|
|
424
|
+
- **`allocate`** on a closed scope:
|
|
428
425
|
|
|
429
|
-
|
|
426
|
+
```
|
|
427
|
+
── Scope Error ─────────────────────────────────────────────────────────────────
|
|
428
|
+
|
|
429
|
+
Cannot allocate resource: scope is already closed.
|
|
430
|
+
|
|
431
|
+
Scope: Scope.Child
|
|
432
|
+
|
|
433
|
+
What happened:
|
|
434
|
+
A call to allocate was made on a scope whose finalizers have
|
|
435
|
+
already run. The resource was never acquired.
|
|
436
|
+
|
|
437
|
+
Common causes:
|
|
438
|
+
• A scope reference escaped a scoped { } block (e.g. stored in a
|
|
439
|
+
field, captured in a Future or passed to another thread).
|
|
440
|
+
• close() was called on an OpenScope before all
|
|
441
|
+
allocations inside it completed.
|
|
442
|
+
|
|
443
|
+
Fix:
|
|
444
|
+
Call allocate only inside a live scoped { } block, or before
|
|
445
|
+
calling close() on an OpenScope.
|
|
446
|
+
|
|
447
|
+
// Correct usage:
|
|
448
|
+
Scope.global.scoped { scope =>
|
|
449
|
+
import scope.*
|
|
450
|
+
val db = allocate(Resource(new Database))
|
|
451
|
+
$(db)(_.query("SELECT 1"))
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
────────────────────────────────────────────────────────────────────────────────
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
- **`open()`** on a closed scope gives the same treatment, explaining that no child scope was created and directing the user to call `open()` only on a live scope.
|
|
458
|
+
|
|
459
|
+
- **`$`** on a closed scope explains that the resource may have already been released and accessing it would be undefined behaviour.
|
|
460
|
+
|
|
461
|
+
The following operations on a closed scope do **not** throw:
|
|
462
|
+
|
|
463
|
+
- `defer` — silently ignored (no-op)
|
|
464
|
+
- `scoped` — runs normally but creates a born-closed child scope
|
|
465
|
+
- `lower` — zero-cost cast, no closed check needed
|
|
430
466
|
|
|
431
467
|
### Thread ownership rule (JVM)
|
|
432
468
|
|
|
@@ -780,6 +816,112 @@ val appResource: Resource[App] =
|
|
|
780
816
|
|
|
781
817
|
---
|
|
782
818
|
|
|
819
|
+
## Common runtime errors (and what they mean)
|
|
820
|
+
|
|
821
|
+
These `IllegalStateException`s are thrown when a scope operation is attempted on a closed scope. Each message identifies the scope type, explains what went wrong, lists common causes, and shows a correct usage example.
|
|
822
|
+
|
|
823
|
+
### `allocate` on a closed scope
|
|
824
|
+
|
|
825
|
+
```
|
|
826
|
+
── Scope Error ─────────────────────────────────────────────────────────────────
|
|
827
|
+
|
|
828
|
+
Cannot allocate resource: scope is already closed.
|
|
829
|
+
|
|
830
|
+
Scope: Scope.Child
|
|
831
|
+
|
|
832
|
+
What happened:
|
|
833
|
+
A call to allocate was made on a scope whose finalizers have
|
|
834
|
+
already run. The resource was never acquired.
|
|
835
|
+
|
|
836
|
+
Common causes:
|
|
837
|
+
• A scope reference escaped a scoped { } block (e.g. stored in a
|
|
838
|
+
field, captured in a Future or passed to another thread).
|
|
839
|
+
• close() was called on an OpenScope before all
|
|
840
|
+
allocations inside it completed.
|
|
841
|
+
|
|
842
|
+
Fix:
|
|
843
|
+
Call allocate only inside a live scoped { } block, or before
|
|
844
|
+
calling close() on an OpenScope.
|
|
845
|
+
|
|
846
|
+
// Correct usage:
|
|
847
|
+
Scope.global.scoped { scope =>
|
|
848
|
+
import scope.*
|
|
849
|
+
val db = allocate(Resource(new Database))
|
|
850
|
+
$(db)(_.query("SELECT 1"))
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
────────────────────────────────────────────────────────────────────────────────
|
|
854
|
+
```
|
|
855
|
+
|
|
856
|
+
### `open()` on a closed scope
|
|
857
|
+
|
|
858
|
+
```
|
|
859
|
+
── Scope Error ─────────────────────────────────────────────────────────────────
|
|
860
|
+
|
|
861
|
+
Cannot open child scope: scope is already closed.
|
|
862
|
+
|
|
863
|
+
Scope: Scope.Child
|
|
864
|
+
|
|
865
|
+
What happened:
|
|
866
|
+
A call to open() was made on a scope whose finalizers have
|
|
867
|
+
already run. No child scope was created.
|
|
868
|
+
|
|
869
|
+
Common causes:
|
|
870
|
+
• A scope reference escaped a scoped { } block and open()
|
|
871
|
+
was called after the block exited.
|
|
872
|
+
• close() was called on the parent OpenScope before
|
|
873
|
+
open() was called on it.
|
|
874
|
+
|
|
875
|
+
Fix:
|
|
876
|
+
Call open() only on a live (not yet closed) scope.
|
|
877
|
+
|
|
878
|
+
// Correct usage:
|
|
879
|
+
Scope.global.scoped { scope =>
|
|
880
|
+
import scope.*
|
|
881
|
+
val child = open()
|
|
882
|
+
$(child)(_.scope.allocate(Resource(new Database)))
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
────────────────────────────────────────────────────────────────────────────────
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
### `$` on a closed scope
|
|
889
|
+
|
|
890
|
+
```
|
|
891
|
+
── Scope Error ─────────────────────────────────────────────────────────────────
|
|
892
|
+
|
|
893
|
+
Cannot access scoped value: scope is already closed.
|
|
894
|
+
|
|
895
|
+
Scope: Scope.Child
|
|
896
|
+
|
|
897
|
+
What happened:
|
|
898
|
+
The $ operator was called on a scope whose finalizers have
|
|
899
|
+
already run. The underlying resource may have been released.
|
|
900
|
+
Accessing it would be undefined behavior.
|
|
901
|
+
|
|
902
|
+
Common causes:
|
|
903
|
+
• A $[A] value or its owning scope escaped a scoped { }
|
|
904
|
+
block (e.g. captured in a Future, stored in a field, or
|
|
905
|
+
passed to another thread).
|
|
906
|
+
• close() was called on an OpenScope that still has
|
|
907
|
+
live $[A] values being accessed.
|
|
908
|
+
|
|
909
|
+
Fix:
|
|
910
|
+
Ensure all $ calls occur strictly within the scoped { }
|
|
911
|
+
block that owns the value, and that the scope has not been closed.
|
|
912
|
+
|
|
913
|
+
// Correct usage:
|
|
914
|
+
Scope.global.scoped { scope =>
|
|
915
|
+
import scope.*
|
|
916
|
+
val db = allocate(Resource(new Database))
|
|
917
|
+
$(db)(_.query("SELECT 1")) // $ used inside the block
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
────────────────────────────────────────────────────────────────────────────────
|
|
921
|
+
```
|
|
922
|
+
|
|
923
|
+
---
|
|
924
|
+
|
|
783
925
|
## Common compile errors (and what they mean)
|
|
784
926
|
|
|
785
927
|
This module produces two kinds of compile-time feedback:
|
|
@@ -1028,7 +1170,7 @@ Notes:
|
|
|
1028
1170
|
|
|
1029
1171
|
- `$` requires a **lambda literal** and enforces safe receiver-only usage.
|
|
1030
1172
|
- `$` returns `B` if `Unscoped[B]` exists; otherwise returns `$[B]`.
|
|
1031
|
-
- If the scope is closed,
|
|
1173
|
+
- If the scope is closed, `$`, `allocate`, and `open` throw `IllegalStateException` with a detailed error message. `defer` and `lower` are unaffected.
|
|
1032
1174
|
|
|
1033
1175
|
Syntax enrichments available after `import scope.*` inside a scope:
|
|
1034
1176
|
|
package/sidebars.js
CHANGED
|
@@ -21,6 +21,7 @@ const sidebars = {
|
|
|
21
21
|
"reference/formats",
|
|
22
22
|
"path-interpolator",
|
|
23
23
|
"reference/chunk",
|
|
24
|
+
"reference/schema-error",
|
|
24
25
|
"reference/validation",
|
|
25
26
|
"reference/schema-evolution",
|
|
26
27
|
"reference/context",
|
|
@@ -35,6 +36,7 @@ const sidebars = {
|
|
|
35
36
|
type: "category",
|
|
36
37
|
label: "Guides",
|
|
37
38
|
items: [
|
|
39
|
+
"guides/zio-schema-migration",
|
|
38
40
|
"guides/query-dsl-reified-optics",
|
|
39
41
|
"guides/query-dsl-sql",
|
|
40
42
|
"guides/query-dsl-extending",
|