git.iko.soy/rowtype-yoga/purescript-yoga-om-layer
on main help sign in
fix runLayer safety and release yoga-om-layer v2.0.0 (#1)

* fix runLayer safety for open rows Prevent runLayer from accepting open requirement rows so missing dependencies fail at compile time instead of crashing at runtime. Add regression coverage for the bad case and preserve support for running closed-row layers with superset contexts. * release v2.0.0 Bump yoga-om-layer to the new yoga-om 2.x dependency line and refresh the lockfile for the published resolver state.

commit301b7d16f44cd5f56dba42418d040ec1f071b39b authorMark Eibes <mark.eibes@gmail.com> dateSat 21 Mar 2026, 00:23 (6 months ago) parentc6ad2c1
5 files changed+40−5
compile-fail-tests/RunLayerOpenRowMissingDep.purs+19 spago.lock+3−3 spago.yaml+2−2 src/Yoga/Om/Layer.purs+4 test/Test/Yoga/Om/Layer/InstancesSpec.purs+12
compile-fail-tests/RunLayerOpenRowMissingDep.pursnew file+19
@@ -0,0 +1,19 @@
1+-- EXPECT: Prim.RowList.RowToList
2+module Yoga.Om.Layer.CompileFailTest where
3+
4+import Prelude
5+
6+import Yoga.Om as Om
7+import Yoga.Om.Layer (OmLayer, makeLayer, runLayer)
8+
9+type Fastify = String
10+type Connection = String
11+
12+apiLayer :: forall r. OmLayer (fastify :: Fastify, sqlite :: Connection | r) () {}
13+apiLayer = makeLayer do
14+ { fastify, sqlite } <- Om.ask
15+ let _ = fastify <> sqlite
16+ pure {}
17+
18+bad :: Om.Om { fastify :: Fastify } () {}
19+bad = runLayer { fastify: "server" } apiLayer
spago.lock+3−3
@@ -63,7 +63,7 @@
6363 "variant": ">=8.0.0 <9.0.0"
6464 },
6565 {
66− "yoga-om": ">=1.5.2 <2.0.0"
66+ "yoga-om": ">=2.0.0 <3.0.0"
6767 }
6868 ]
6969 },
@@ -1225,8 +1225,8 @@
12251225 },
12261226 "yoga-om": {
12271227 "type": "registry",
1228− "version": "1.5.2",
1229− "integrity": "sha256-2ys14BF6NPgzFDFUIFk0EDxmqkA8+yghIA9TXHlOmE0=",
1228+ "version": "2.0.0",
1229+ "integrity": "sha256-eenoujD2rJzR6gYJbbIiqLhXHC1C5dagu91HZkAEt/Y=",
12301230 "dependencies": [
12311231 "aff",
12321232 "aff-retry",
spago.yaml+2−2
@@ -2,7 +2,7 @@ workspace: {}
22package:
33 name: yoga-om-layer
44 publish:
5− version: 1.2.2
5+ version: 2.0.0
66 license: MIT
77 location:
88 githubOwner: rowtype-yoga
@@ -27,7 +27,7 @@ package:
2727 - typelevel-prelude: ">=7.0.0 <8.0.0"
2828 - unsafe-coerce: ">=6.0.0 <7.0.0"
2929 - variant: ">=8.0.0 <9.0.0"
30− - yoga-om: ">=1.5.2 <2.0.0"
30+ - yoga-om: ">=2.0.0 <3.0.0"
3131 test:
3232 main: Test.Main
3333 dependencies:
src/Yoga/Om/Layer.purs+4
@@ -340,9 +340,13 @@ else instance
340340-- =============================================================================
341341
342342-- | Run a layer with a given context, with custom error if requirements aren't met.
343+-- | `runLayer` requires a closed requirement row. If you have an open layer like
344+-- | `OmLayer (db :: Db | r) err a`, specialize it to a closed row before running
345+-- | it directly.
343346runLayer
344347 :: forall req err a available
345348 . CheckAllProvided req available
349+ => Keys req
346350 => Record available
347351 -> OmLayer req err a
348352 -> Om (Record available) err a
test/Test/Yoga/Om/Layer/InstancesSpec.purs+12
@@ -46,6 +46,18 @@ spec = do
4646 result <- Om.runOm {} { exception: \_ -> pure { result: 0 } } (runLayer {} layer)
4747 result.result `shouldEqual` 15
4848
49+ it "runs layers against a superset context" do
50+ let
51+ layer :: OmLayer (a :: Int) () { out :: Int }
52+ layer = makeLayer do
53+ { a } <- Om.ask
54+ pure { out: a + 1 }
55+
56+ ctx = { a: 41, extra: "ok" }
57+
58+ result <- Om.runOm ctx { exception: \_ -> pure { out: 0 } } (runLayer ctx layer)
59+ result.out `shouldEqual` 42
60+
4961 describe "Parallel" do
5062
5163 it "runs layers in parallel via parApply" do